NeoMutt  2018-07-16 +1360-3df4a2
Teaching an old dog new tricks
DOXYGEN
handler.c File Reference

Decide how to display email content. More...

#include "config.h"
#include <stddef.h>
#include <ctype.h>
#include <iconv.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "email/lib.h"
#include "mutt.h"
#include "handler.h"
#include "copy.h"
#include "enriched.h"
#include "filter.h"
#include "globals.h"
#include "keymap.h"
#include "mutt_attach.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "ncrypt/ncrypt.h"
#include "opcodes.h"
#include "options.h"
#include "rfc1524.h"
#include "rfc3676.h"
#include "state.h"
#include <libintl.h>
+ Include dependency graph for handler.c:

Go to the source code of this file.

Macros

#define BUFI_SIZE   1000
 
#define BUFO_SIZE   2000
 
#define TXTHTML   1
 
#define TXTPLAIN   2
 
#define TXTENRICHED   3
 

Typedefs

typedef int(* handler_t) (struct Body *b, struct State *s)
 typedef handler_t - Manage a PGP or S/MIME encrypted MIME part More...
 

Functions

static void print_part_line (struct State *s, struct Body *b, int n)
 Print a separator for the Mime part. More...
 
static void convert_to_state (iconv_t cd, char *bufi, size_t *l, struct State *s)
 Convert text and write it to a file. More...
 
static void decode_xbit (struct State *s, long len, bool istext, iconv_t cd)
 Decode xbit-encoded text. More...
 
static int qp_decode_triple (char *s, char *d)
 Decode a quoted-printable triplet. More...
 
static void qp_decode_line (char *dest, char *src, size_t *l, int last)
 Decode a line of quoted-printable text. More...
 
static void decode_quoted (struct State *s, long len, bool istext, iconv_t cd)
 Decode an attachment encoded with quoted-printable. More...
 
static unsigned char decode_byte (char ch)
 Decode a uuencoded byte. More...
 
static void decode_uuencoded (struct State *s, long len, bool istext, iconv_t cd)
 Decode uuencoded text. More...
 
static bool is_mmnoask (const char *buf)
 Metamail compatibility: should the attachment be autoviewed? More...
 
static bool is_autoview (struct Body *b)
 Should email body be filtered by mailcap. More...
 
static int autoview_handler (struct Body *a, struct State *s)
 Handler for autoviewable attachments - Implements handler_t. More...
 
static int text_plain_handler (struct Body *b, struct State *s)
 Handler for plain text - Implements handler_t. More...
 
static int message_handler (struct Body *a, struct State *s)
 Handler for message/rfc822 body parts - Implements handler_t. More...
 
static int external_body_handler (struct Body *b, struct State *s)
 Handler for external-body emails - Implements handler_t. More...
 
static int alternative_handler (struct Body *a, struct State *s)
 Handler for multipart alternative emails - Implements handler_t. More...
 
static int multilingual_handler (struct Body *a, struct State *s)
 Handler for multi-lingual emails - Implements handler_t. More...
 
static int multipart_handler (struct Body *a, struct State *s)
 Handler for multipart emails - Implements handler_t. More...
 
static int run_decode_and_handler (struct Body *b, struct State *s, handler_t handler, bool plaintext)
 Run an appropriate decoder for an email. More...
 
static int valid_pgp_encrypted_handler (struct Body *b, struct State *s)
 Handler for valid pgp-encrypted emails - Implements handler_t. More...
 
static int malformed_pgp_encrypted_handler (struct Body *b, struct State *s)
 Handler for invalid pgp-encrypted emails - Implements handler_t. More...
 
void mutt_decode_base64 (struct State *s, size_t len, bool istext, iconv_t cd)
 Decode base64-encoded text. More...
 
int mutt_body_handler (struct Body *b, struct State *s)
 Handler for the Body of an email. More...
 
bool mutt_can_decode (struct Body *a)
 Will decoding the attachment produce any output. More...
 
void mutt_decode_attachment (struct Body *b, struct State *s)
 Decode an email's attachment. More...
 

Variables

bool C_HonorDisposition
 Config: Don't display MIME parts inline if they have a disposition of 'attachment'. More...
 
bool C_ImplicitAutoview
 Config: Display MIME attachments inline if a 'copiousoutput' mailcap entry exists. More...
 
bool C_IncludeOnlyfirst
 Config: Only include the first attachment when replying. More...
 
char * C_PreferredLanguages
 Config: Preferred languages for multilingual MIME. More...
 
bool C_ReflowText
 Config: Reformat paragraphs of 'format=flowed' text. More...
 
char * C_ShowMultipartAlternative
 Config: How to display 'multipart/alternative' MIME parts. More...
 

Detailed Description

Decide how to display email content.

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 handler.c.

Macro Definition Documentation

#define BUFI_SIZE   1000

Definition at line 71 of file handler.c.

#define BUFO_SIZE   2000

Definition at line 72 of file handler.c.

#define TXTHTML   1

Definition at line 74 of file handler.c.

#define TXTPLAIN   2

Definition at line 75 of file handler.c.

#define TXTENRICHED   3

Definition at line 76 of file handler.c.

Typedef Documentation

typedef int(* handler_t) (struct Body *b, struct State *s)

typedef handler_t - Manage a PGP or S/MIME encrypted MIME part

Parameters
mBody of the email
sState of text being processed
Return values
0Success
-1Error

Definition at line 85 of file handler.c.

Function Documentation

static void print_part_line ( struct State s,
struct Body b,
int  n 
)
static

Print a separator for the Mime part.

Parameters
sState of text being processed
bBody of the email
nPart number for multipart emails (0 otherwise)

Definition at line 93 of file handler.c.

94 {
95  char length[5];
96  mutt_str_pretty_size(length, sizeof(length), b->length);
98  char *charset = mutt_param_get(&b->parameter, "charset");
99  if (n != 0)
100  {
101  state_printf(s, _("[-- Alternative Type #%d: %s/%s%s%s, Encoding: %s, Size: %s --]\n"),
102  n, TYPE(b), b->subtype, charset ? "; charset=" : "",
103  charset ? charset : "", ENCODING(b->encoding), length);
104  }
105  else
106  {
107  state_printf(s, _("[-- Type: %s/%s%s%s, Encoding: %s, Size: %s --]\n"),
108  TYPE(b), b->subtype, charset ? "; charset=" : "",
109  charset ? charset : "", ENCODING(b->encoding), length);
110  }
111 }
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:147
#define _(a)
Definition: message.h:28
#define ENCODING(x)
Definition: mime.h:85
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
#define TYPE(body)
Definition: mime.h:83
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: string.c:1014
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void convert_to_state ( iconv_t  cd,
char *  bufi,
size_t *  l,
struct State s 
)
static

Convert text and write it to a file.

Parameters
cdIconv conversion descriptor
bufiBuffer with text to convert
lLength of buffer
sState to write to

Definition at line 120 of file handler.c.

121 {
122  char bufo[BUFO_SIZE];
123  const char *ib = NULL;
124  char *ob = NULL;
125  size_t ibl, obl;
126 
127  if (!bufi)
128  {
129  if (cd != (iconv_t)(-1))
130  {
131  ob = bufo, obl = sizeof(bufo);
132  iconv(cd, NULL, NULL, &ob, &obl);
133  if (ob != bufo)
134  state_prefix_put(bufo, ob - bufo, s);
135  }
136  return;
137  }
138 
139  if (cd == (iconv_t)(-1))
140  {
141  state_prefix_put(bufi, *l, s);
142  *l = 0;
143  return;
144  }
145 
146  ib = bufi;
147  ibl = *l;
148  while (true)
149  {
150  ob = bufo, obl = sizeof(bufo);
151  mutt_ch_iconv(cd, &ib, &ibl, &ob, &obl, 0, "?", NULL);
152  if (ob == bufo)
153  break;
154  state_prefix_put(bufo, ob - bufo, s);
155  }
156  memmove(bufi, ib, ibl);
157  *l = ibl;
158 }
void state_prefix_put(const char *buf, size_t buflen, struct State *s)
Write a prefixed fixed-string to the State.
Definition: state.c:165
size_t mutt_ch_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, const char **inrepls, const char *outrepl, int *iconverrno)
Change the encoding of a string.
Definition: charset.c:584
#define BUFO_SIZE
Definition: handler.c:72

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void decode_xbit ( struct State s,
long  len,
bool  istext,
iconv_t  cd 
)
static

Decode xbit-encoded text.

Parameters
sState to work with
lenLength of text to decode
istextMime part is plain text
cdIconv conversion descriptor

Definition at line 167 of file handler.c.

168 {
169  if (!istext)
170  {
171  mutt_file_copy_bytes(s->fp_in, s->fp_out, len);
172  return;
173  }
174 
175  state_set_prefix(s);
176 
177  int c;
178  char bufi[BUFI_SIZE];
179  size_t l = 0;
180  while ((c = fgetc(s->fp_in)) != EOF && len--)
181  {
182  if ((c == '\r') && len)
183  {
184  const int ch = fgetc(s->fp_in);
185  if (ch == '\n')
186  {
187  c = ch;
188  len--;
189  }
190  else
191  ungetc(ch, s->fp_in);
192  }
193 
194  bufi[l++] = c;
195  if (l == sizeof(bufi))
196  convert_to_state(cd, bufi, &l, s);
197  }
198 
199  convert_to_state(cd, bufi, &l, s);
200  convert_to_state(cd, 0, 0, s);
201 
203 }
#define state_reset_prefix(state)
Definition: state.h:53
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
#define BUFI_SIZE
Definition: handler.c:71
#define state_set_prefix(state)
Definition: state.h:52
static void convert_to_state(iconv_t cd, char *bufi, size_t *l, struct State *s)
Convert text and write it to a file.
Definition: handler.c:120
int ch
raw key pressed
Definition: mutt_curses.h:109
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:236

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int qp_decode_triple ( char *  s,
char *  d 
)
static

Decode a quoted-printable triplet.

Parameters
sState to work with
dDecoded character
Return values
0Success
-1Error

Definition at line 212 of file handler.c.

213 {
214  /* soft line break */
215  if ((*s == '=') && !(*(s + 1)))
216  return 1;
217 
218  /* quoted-printable triple */
219  if ((*s == '=') && isxdigit((unsigned char) *(s + 1)) &&
220  isxdigit((unsigned char) *(s + 2)))
221  {
222  *d = (hexval(*(s + 1)) << 4) | hexval(*(s + 2));
223  return 0;
224  }
225 
226  /* something else */
227  return -1;
228 }
#define hexval(ch)
Definition: mime.h:75

+ Here is the caller graph for this function:

static void qp_decode_line ( char *  dest,
char *  src,
size_t *  l,
int  last 
)
static

Decode a line of quoted-printable text.

Parameters
destBuffer for result
srcText to decode
lBytes written to buffer
lastLast character of the line

Definition at line 237 of file handler.c.

238 {
239  char *d = NULL, *s = NULL;
240  char c = 0;
241 
242  int kind = -1;
243  bool soft = false;
244 
245  /* decode the line */
246 
247  for (d = dest, s = src; *s;)
248  {
249  switch ((kind = qp_decode_triple(s, &c)))
250  {
251  case 0:
252  *d++ = c;
253  s += 3;
254  break; /* qp triple */
255  case -1:
256  *d++ = *s++;
257  break; /* single character */
258  case 1:
259  soft = true;
260  s++;
261  break; /* soft line break */
262  }
263  }
264 
265  if (!soft && (last == '\n'))
266  {
267  /* neither \r nor \n as part of line-terminating CRLF
268  * may be qp-encoded, so remove \r and \n-terminate;
269  * see RFC2045, sect. 6.7, (1): General 8bit representation */
270  if ((kind == 0) && (c == '\r'))
271  *(d - 1) = '\n';
272  else
273  *d++ = '\n';
274  }
275 
276  *d = '\0';
277  *l = d - dest;
278 }
static int qp_decode_triple(char *s, char *d)
Decode a quoted-printable triplet.
Definition: handler.c:212

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void decode_quoted ( struct State s,
long  len,
bool  istext,
iconv_t  cd 
)
static

Decode an attachment encoded with quoted-printable.

Parameters
sState to work with
lenLength of text to decode
istextMime part is plain text
cdIconv conversion descriptor

Why doesn't this overflow any buffers? First, it's guaranteed that the length of a line grows when you en-code it to quoted-printable. That means that we always can store the result in a buffer of at most the same size.

Now, we don't special-case if the line we read with fgets() isn't terminated. We don't care about this, since 256 > 78, so corrupted input will just be corrupted a bit more. That implies that 256+1 bytes are always sufficient to store the result of qp_decode_line.

Finally, at soft line breaks, some part of a multibyte character may have been left over by convert_to_state(). This shouldn't be more than 6 characters, so 256+7 should be sufficient memory to store the decoded data.

Just to make sure that I didn't make some off-by-one error above, we just use 512 for the target buffer's size.

Definition at line 305 of file handler.c.

306 {
307  char line[256];
308  char decline[512];
309  size_t l = 0;
310  size_t l3;
311 
312  if (istext)
313  state_set_prefix(s);
314 
315  while (len > 0)
316  {
317  /* It's ok to use a fixed size buffer for input, even if the line turns
318  * out to be longer than this. Just process the line in chunks. This
319  * really shouldn't happen according the MIME spec, since Q-P encoded
320  * lines are at most 76 characters, but we should be liberal about what
321  * we accept. */
322  if (!fgets(line, MIN((ssize_t) sizeof(line), len + 1), s->fp_in))
323  break;
324 
325  size_t linelen = strlen(line);
326  len -= linelen;
327 
328  /* inspect the last character we read so we can tell if we got the
329  * entire line. */
330  const int last = linelen ? line[linelen - 1] : 0;
331 
332  /* chop trailing whitespace if we got the full line */
333  if (last == '\n')
334  {
335  while (linelen > 0 && ISSPACE(line[linelen - 1]))
336  linelen--;
337  line[linelen] = '\0';
338  }
339 
340  /* decode and do character set conversion */
341  qp_decode_line(decline + l, line, &l3, last);
342  l += l3;
343  convert_to_state(cd, decline, &l, s);
344  }
345 
346  convert_to_state(cd, 0, 0, s);
348 }
#define MIN(a, b)
Definition: memory.h:31
#define state_reset_prefix(state)
Definition: state.h:53
FILE * fp_in
File to read from.
Definition: state.h:46
static void qp_decode_line(char *dest, char *src, size_t *l, int last)
Decode a line of quoted-printable text.
Definition: handler.c:237
const char * line
Definition: common.c:35
#define ISSPACE(ch)
Definition: string2.h:37
#define state_set_prefix(state)
Definition: state.h:52
static void convert_to_state(iconv_t cd, char *bufi, size_t *l, struct State *s)
Convert text and write it to a file.
Definition: handler.c:120

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static unsigned char decode_byte ( char  ch)
static

Decode a uuencoded byte.

Parameters
chCharacter to decode
Return values
numDecoded value

Definition at line 355 of file handler.c.

356 {
357  if (ch == 96)
358  return 0;
359  return ch - 32;
360 }
int ch
raw key pressed
Definition: mutt_curses.h:109

+ Here is the caller graph for this function:

static void decode_uuencoded ( struct State s,
long  len,
bool  istext,
iconv_t  cd 
)
static

Decode uuencoded text.

Parameters
sState to work with
lenLength of text to decode
istextMime part is plain text
cdIconv conversion descriptor

Definition at line 369 of file handler.c.

370 {
371  char tmps[128];
372  char *pt = NULL;
373  char bufi[BUFI_SIZE];
374  size_t k = 0;
375 
376  if (istext)
377  state_set_prefix(s);
378 
379  while (len > 0)
380  {
381  if (!fgets(tmps, sizeof(tmps), s->fp_in))
382  return;
383  len -= mutt_str_strlen(tmps);
384  if (mutt_str_startswith(tmps, "begin ", CASE_MATCH))
385  break;
386  }
387  while (len > 0)
388  {
389  if (!fgets(tmps, sizeof(tmps), s->fp_in))
390  return;
391  len -= mutt_str_strlen(tmps);
392  if (mutt_str_startswith(tmps, "end", CASE_MATCH))
393  break;
394  pt = tmps;
395  const unsigned char linelen = decode_byte(*pt);
396  pt++;
397  for (unsigned char c = 0; c < linelen;)
398  {
399  for (char l = 2; l <= 6; l += 2)
400  {
401  char out = decode_byte(*pt) << l;
402  pt++;
403  out |= (decode_byte(*pt) >> (6 - l));
404  bufi[k++] = out;
405  c++;
406  if (c == linelen)
407  break;
408  }
409  convert_to_state(cd, bufi, &k, s);
410  pt++;
411  }
412  }
413 
414  convert_to_state(cd, bufi, &k, s);
415  convert_to_state(cd, 0, 0, s);
416 
418 }
#define state_reset_prefix(state)
Definition: state.h:53
Match case when comparing strings.
Definition: string2.h:66
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:662
static unsigned char decode_byte(char ch)
Decode a uuencoded byte.
Definition: handler.c:355
FILE * fp_in
File to read from.
Definition: state.h:46
#define BUFI_SIZE
Definition: handler.c:71
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:165
#define state_set_prefix(state)
Definition: state.h:52
static void convert_to_state(iconv_t cd, char *bufi, size_t *l, struct State *s)
Convert text and write it to a file.
Definition: handler.c:120

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool is_mmnoask ( const char *  buf)
static

Metamail compatibility: should the attachment be autoviewed?

Parameters
bufMime type, e.g. 'text/plain'
Return values
trueMetamail "no ask" is true

Test if the MM_NOASK environment variable should allow autoviewing of the attachment.

Note
If MM_NOASK=1 then the function will automatically return true.

Definition at line 430 of file handler.c.

431 {
432  char *p = NULL;
433  char tmp[1024], *q = NULL;
434 
435  const char *val = mutt_str_getenv("MM_NOASK");
436  if (!val)
437  return false;
438 
439  if (mutt_str_strcmp(val, "1") == 0)
440  return true;
441 
442  mutt_str_strfcpy(tmp, val, sizeof(tmp));
443  p = tmp;
444 
445  while ((p = strtok(p, ",")))
446  {
447  q = strrchr(p, '/');
448  if (q)
449  {
450  if (*(q + 1) == '*')
451  {
452  if (mutt_str_strncasecmp(buf, p, q - p) == 0)
453  return true;
454  }
455  else
456  {
457  if (mutt_str_strcasecmp(buf, p) == 0)
458  return true;
459  }
460  }
461  else
462  {
463  const size_t plen = mutt_str_startswith(buf, p, CASE_IGNORE);
464  if ((plen != 0) && (buf[plen] == '/'))
465  return true;
466  }
467 
468  p = NULL;
469  }
470 
471  return false;
472 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:1048
int mutt_str_strncasecmp(const char *a, const char *b, size_t l)
Compare two strings ignoring case (to a maximum), safely.
Definition: string.c:652
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:741
Ignore case when comparing strings.
Definition: string2.h:67
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:165
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:611

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool is_autoview ( struct Body b)
static

Should email body be filtered by mailcap.

Parameters
bBody of the email
Return values
1body part should be filtered by a mailcap entry prior to viewing inline
0otherwise

Definition at line 480 of file handler.c.

481 {
482  char type[128];
483  bool is_av = false;
484 
485  snprintf(type, sizeof(type), "%s/%s", TYPE(b), b->subtype);
486 
487  if (C_ImplicitAutoview)
488  {
489  /* $implicit_autoview is essentially the same as "auto_view *" */
490  is_av = true;
491  }
492  else
493  {
494  /* determine if this type is on the user's auto_view list */
495  mutt_check_lookup_list(b, type, sizeof(type));
496  struct ListNode *np = NULL;
497  STAILQ_FOREACH(np, &AutoViewList, entries)
498  {
499  int i = mutt_str_strlen(np->data) - 1;
500  if (((i > 0) && (np->data[i - 1] == '/') && (np->data[i] == '*') &&
501  (mutt_str_strncasecmp(type, np->data, i) == 0)) ||
502  (mutt_str_strcasecmp(type, np->data) == 0))
503  {
504  is_av = true;
505  break;
506  }
507  }
508 
509  if (is_mmnoask(type))
510  is_av = true;
511  }
512 
513  /* determine if there is a mailcap entry suitable for auto_view
514  *
515  * @warning type is altered by this call as a result of 'mime_lookup' support */
516  if (is_av)
517  return rfc1524_mailcap_lookup(b, type, NULL, MUTT_MC_AUTOVIEW);
518 
519  return false;
520 }
bool rfc1524_mailcap_lookup(struct Body *a, char *type, struct Rfc1524MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: rfc1524.c:437
Mailcap autoview field.
Definition: rfc1524.h:61
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:662
static bool is_mmnoask(const char *buf)
Metamail compatibility: should the attachment be autoviewed?
Definition: handler.c:430
char * subtype
content-type subtype
Definition: body.h:37
int mutt_str_strncasecmp(const char *a, const char *b, size_t l)
Compare two strings ignoring case (to a maximum), safely.
Definition: string.c:652
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define TYPE(body)
Definition: mime.h:83
char * data
Definition: list.h:35
void mutt_check_lookup_list(struct Body *b, char *type, size_t len)
Update the mime type.
Definition: mutt_attach.c:323
bool C_ImplicitAutoview
Config: Display MIME attachments inline if a &#39;copiousoutput&#39; mailcap entry exists.
Definition: handler.c:65
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
A List node for strings.
Definition: list.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int autoview_handler ( struct Body a,
struct State s 
)
static

Handler for autoviewable attachments - Implements handler_t.

Definition at line 525 of file handler.c.

526 {
527  struct Rfc1524MailcapEntry *entry = rfc1524_new_entry();
528  char buf[1024];
529  char type[256];
530  char cmd[STR_COMMAND];
531  char tempfile[PATH_MAX] = "";
532  char *fname = NULL;
533  FILE *fp_in = NULL;
534  FILE *fp_out = NULL;
535  FILE *fp_err = NULL;
536  int piped = false;
537  pid_t pid;
538  int rc = 0;
539 
540  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
541  rfc1524_mailcap_lookup(a, type, entry, MUTT_MC_AUTOVIEW);
542 
543  fname = mutt_str_strdup(a->filename);
544  mutt_file_sanitize_filename(fname, true);
545  rfc1524_expand_filename(entry->nametemplate, fname, tempfile, sizeof(tempfile));
546  FREE(&fname);
547 
548  if (entry->command)
549  {
550  mutt_str_strfcpy(cmd, entry->command, sizeof(cmd));
551 
552  /* rfc1524_expand_command returns 0 if the file is required */
553  piped = rfc1524_expand_command(a, tempfile, type, cmd, sizeof(cmd));
554 
555  if (s->flags & MUTT_DISPLAY)
556  {
558  state_printf(s, _("[-- Autoview using %s --]\n"), cmd);
559  mutt_message(_("Invoking autoview command: %s"), cmd);
560  }
561 
562  fp_in = mutt_file_fopen(tempfile, "w+");
563  if (!fp_in)
564  {
565  mutt_perror("fopen");
566  rfc1524_free_entry(&entry);
567  return -1;
568  }
569 
570  mutt_file_copy_bytes(s->fp_in, fp_in, a->length);
571 
572  if (!piped)
573  {
574  mutt_file_fclose(&fp_in);
575  pid = mutt_create_filter(cmd, NULL, &fp_out, &fp_err);
576  }
577  else
578  {
579  unlink(tempfile);
580  fflush(fp_in);
581  rewind(fp_in);
582  pid = mutt_create_filter_fd(cmd, NULL, &fp_out, &fp_err, fileno(fp_in), -1, -1);
583  }
584 
585  if (pid < 0)
586  {
587  mutt_perror(_("Can't create filter"));
588  if (s->flags & MUTT_DISPLAY)
589  {
591  state_printf(s, _("[-- Can't run %s. --]\n"), cmd);
592  }
593  rc = -1;
594  goto bail;
595  }
596 
597  if (s->prefix)
598  {
599  while (fgets(buf, sizeof(buf), fp_out))
600  {
601  state_puts(s->prefix, s);
602  state_puts(buf, s);
603  }
604  /* check for data on stderr */
605  if (fgets(buf, sizeof(buf), fp_err))
606  {
607  if (s->flags & MUTT_DISPLAY)
608  {
610  state_printf(s, _("[-- Autoview stderr of %s --]\n"), cmd);
611  }
612 
613  state_puts(s->prefix, s);
614  state_puts(buf, s);
615  while (fgets(buf, sizeof(buf), fp_err))
616  {
617  state_puts(s->prefix, s);
618  state_puts(buf, s);
619  }
620  }
621  }
622  else
623  {
624  mutt_file_copy_stream(fp_out, s->fp_out);
625  /* Check for stderr messages */
626  if (fgets(buf, sizeof(buf), fp_err))
627  {
628  if (s->flags & MUTT_DISPLAY)
629  {
631  state_printf(s, _("[-- Autoview stderr of %s --]\n"), cmd);
632  }
633 
634  state_puts(buf, s);
635  mutt_file_copy_stream(fp_err, s->fp_out);
636  }
637  }
638 
639  bail:
640  mutt_file_fclose(&fp_out);
641  mutt_file_fclose(&fp_err);
642 
643  mutt_wait_filter(pid);
644  if (piped)
645  mutt_file_fclose(&fp_in);
646  else
647  mutt_file_unlink(tempfile);
648 
649  if (s->flags & MUTT_DISPLAY)
651  }
652  rfc1524_free_entry(&entry);
653 
654  return rc;
655 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:216
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:147
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
#define mutt_perror(...)
Definition: logging.h:89
bool rfc1524_mailcap_lookup(struct Body *a, char *type, struct Rfc1524MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: rfc1524.c:437
Mailcap autoview field.
Definition: rfc1524.h:61
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_message(...)
Definition: logging.h:87
void mutt_file_sanitize_filename(char *fp, bool slash)
Replace unsafe characters in a filename.
Definition: file.c:576
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:191
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
char * nametemplate
Definition: rfc1524.h:45
char * subtype
content-type subtype
Definition: body.h:37
void rfc1524_free_entry(struct Rfc1524MailcapEntry **entry)
Deallocate an struct Rfc1524MailcapEntry.
Definition: rfc1524.c:409
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
#define PATH_MAX
Definition: mutt.h:48
pid_t mutt_create_filter_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:64
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:741
A mailcap entry.
Definition: rfc1524.h:37
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
#define STR_COMMAND
Enough space for a long command line.
Definition: string2.h:34
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:546
#define TYPE(body)
Definition: mime.h:83
#define state_puts(str, state)
Definition: state.h:54
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
int rfc1524_expand_command(struct Body *a, const char *filename, const char *type, char *command, int clen)
Expand expandos in a command.
Definition: rfc1524.c:72
struct Rfc1524MailcapEntry * rfc1524_new_entry(void)
Allocate memory for a new rfc1524 entry.
Definition: rfc1524.c:400
#define FREE(x)
Definition: memory.h:40
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:263
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:227
int rfc1524_expand_filename(const char *nametemplate, const char *oldfile, char *newfile, size_t nflen)
Expand a new filename from a template or existing filename.
Definition: rfc1524.c:503
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:236

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int text_plain_handler ( struct Body b,
struct State s 
)
static

Handler for plain text - Implements handler_t.

Return values
0Always

When generating format=flowed ($text_flowed is set) from format=fixed, strip all trailing spaces to improve interoperability; if $text_flowed is unset, simply verbatim copy input.

Definition at line 665 of file handler.c.

666 {
667  char *buf = NULL;
668  size_t l = 0, sz = 0;
669 
670  while ((buf = mutt_file_read_line(buf, &sz, s->fp_in, NULL, 0)))
671  {
672  if ((mutt_str_strcmp(buf, "-- ") != 0) && C_TextFlowed)
673  {
674  l = mutt_str_strlen(buf);
675  while (l > 0 && buf[l - 1] == ' ')
676  buf[--l] = '\0';
677  }
678  if (s->prefix)
679  state_puts(s->prefix, s);
680  state_puts(buf, s);
681  state_putc('\n', s);
682  }
683 
684  FREE(&buf);
685  return 0;
686 }
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:630
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:662
FILE * fp_in
File to read from.
Definition: state.h:46
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:263
#define state_puts(str, state)
Definition: state.h:54
#define state_putc(str, state)
Definition: state.h:55
#define FREE(x)
Definition: memory.h:40
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:611

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int message_handler ( struct Body a,
struct State s 
)
static

Handler for message/rfc822 body parts - Implements handler_t.

Definition at line 691 of file handler.c.

692 {
693  struct stat st;
694  struct Body *b = NULL;
695  LOFF_T off_start;
696  int rc = 0;
697 
698  off_start = ftello(s->fp_in);
699  if (off_start < 0)
700  return -1;
701 
702  if ((a->encoding == ENC_BASE64) || (a->encoding == ENC_QUOTED_PRINTABLE) ||
703  (a->encoding == ENC_UUENCODED))
704  {
705  fstat(fileno(s->fp_in), &st);
706  b = mutt_body_new();
707  b->length = (LOFF_T) st.st_size;
709  }
710  else
711  b = a;
712 
713  if (b->parts)
714  {
715  mutt_copy_hdr(s->fp_in, s->fp_out, off_start, b->parts->offset,
716  (((s->flags & MUTT_WEED) ||
717  ((s->flags & (MUTT_DISPLAY | MUTT_PRINTING)) && C_Weed)) ?
718  (CH_WEED | CH_REORDER) :
719  0) |
720  (s->prefix ? CH_PREFIX : 0) | CH_DECODE | CH_FROM |
721  ((s->flags & MUTT_DISPLAY) ? CH_DISPLAY : 0),
722  s->prefix);
723 
724  if (s->prefix)
725  state_puts(s->prefix, s);
726  state_putc('\n', s);
727 
728  rc = mutt_body_handler(b->parts, s);
729  }
730 
731  if ((a->encoding == ENC_BASE64) || (a->encoding == ENC_QUOTED_PRINTABLE) ||
732  (a->encoding == ENC_UUENCODED))
733  {
734  mutt_body_free(&b);
735  }
736 
737  return rc;
738 }
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
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:46
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:55
FILE * fp_out
File to write to.
Definition: state.h:47
#define MUTT_PRINTING
Are we printing? - MUTT_DISPLAY "light".
Definition: state.h:37
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Body * mutt_rfc822_parse_message(FILE *fp, struct Body *parent)
parse a Message/RFC822 body
Definition: parse.c:1421
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
#define CH_WEED
Weed the headers?
Definition: copy.h:52
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
Base-64 encoded text.
Definition: mime.h:52
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
#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
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
#define MUTT_WEED
Weed headers even when not in display mode.
Definition: state.h:35
#define state_puts(str, state)
Definition: state.h:54
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
#define state_putc(str, state)
Definition: state.h:55
Quoted-printable text.
Definition: mime.h:51
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1524
#define CH_PREFIX
Quote header using C_IndentString string?
Definition: copy.h:56
int mutt_copy_hdr(FILE *fp_in, FILE *fp_out, LOFF_T off_start, LOFF_T off_end, CopyHeaderFlags chflags, const char *prefix)
Copy header from one file to another.
Definition: copy.c:72
UUEncoded text.
Definition: mime.h:54
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int external_body_handler ( struct Body b,
struct State s 
)
static

Handler for external-body emails - Implements handler_t.

Definition at line 743 of file handler.c.

744 {
745  const char *str = NULL;
746  char strbuf[1024];
747 
748  const char *access_type = mutt_param_get(&b->parameter, "access-type");
749  if (!access_type)
750  {
751  if (s->flags & MUTT_DISPLAY)
752  {
754  state_puts(_("[-- Error: message/external-body has no access-type "
755  "parameter --]\n"),
756  s);
757  return 0;
758  }
759  else
760  return -1;
761  }
762 
763  const char *expiration = mutt_param_get(&b->parameter, "expiration");
764  time_t expire;
765  if (expiration)
766  expire = mutt_date_parse_date(expiration, NULL);
767  else
768  expire = -1;
769 
770  if (mutt_str_strcasecmp(access_type, "x-mutt-deleted") == 0)
771  {
772  if (s->flags & (MUTT_DISPLAY | MUTT_PRINTING))
773  {
774  char pretty_size[10];
775  char *length = mutt_param_get(&b->parameter, "length");
776  if (length)
777  {
778  long size = strtol(length, NULL, 10);
779  mutt_str_pretty_size(pretty_size, sizeof(pretty_size), size);
780  if (expire != -1)
781  {
782  str = ngettext(
783  /* L10N: If the translation of this string is a multi line string, then
784  each line should start with "[-- " and end with " --]".
785  The first "%s/%s" is a MIME type, e.g. "text/plain". The last %s
786  expands to a date as returned by `mutt_date_parse_date()`.
787 
788  Note: The size argument printed is not the actual number as passed
789  to gettext but the prettified version, e.g. size = 2048 will be
790  printed as 2K. Your language might be sensitive to that: For
791  example although '1K' and '1024' represent the same number your
792  language might inflect the noun 'byte' differently.
793 
794  Sadly, we cannot do anything about that at the moment besides
795  passing the precise size in bytes. If you are interested the
796  function responsible for the prettification is
797  mutt_str_pretty_size() in mutt/string.c. */
798  "[-- This %s/%s attachment (size %s byte) has been deleted --]\n"
799  "[-- on %s --]\n",
800  "[-- This %s/%s attachment (size %s bytes) has been deleted --]\n"
801  "[-- on %s --]\n",
802  size);
803  }
804  else
805  {
806  str = ngettext(
807  /* L10N: If the translation of this string is a multi line string, then
808  each line should start with "[-- " and end with " --]".
809  The first "%s/%s" is a MIME type, e.g. "text/plain".
810 
811  Note: The size argument printed is not the actual number as passed
812  to gettext but the prettified version, e.g. size = 2048 will be
813  printed as 2K. Your language might be sensitive to that: For
814  example although '1K' and '1024' represent the same number your
815  language might inflect the noun 'byte' differently.
816 
817  Sadly, we cannot do anything about that at the moment besides
818  passing the precise size in bytes. If you are interested the
819  function responsible for the prettification is
820  mutt_str_pretty_size() in mutt/string.c. */
821  "[-- This %s/%s attachment (size %s byte) has been deleted --]\n",
822  "[-- This %s/%s attachment (size %s bytes) has been deleted "
823  "--]\n",
824  size);
825  }
826  }
827  else
828  {
829  pretty_size[0] = '\0';
830  if (expire != -1)
831  {
832  /* L10N: If the translation of this string is a multi line string, then
833  each line should start with "[-- " and end with " --]".
834  The first "%s/%s" is a MIME type, e.g. "text/plain". The last %s
835  expands to a date as returned by `mutt_date_parse_date()`.
836 
837  Caution: Argument three %3$ is also defined but should not be used
838  in this translation! */
839  str = _("[-- This %s/%s attachment has been deleted --]\n[-- on %4$s "
840  "--]\n");
841  }
842  else
843  {
844  /* L10N: If the translation of this string is a multi line string, then
845  each line should start with "[-- " and end with " --]".
846  The first "%s/%s" is a MIME type, e.g. "text/plain". */
847  str = _("[-- This %s/%s attachment has been deleted --]\n");
848  }
849  }
850 
851  snprintf(strbuf, sizeof(strbuf), str, TYPE(b->parts), b->parts->subtype,
852  pretty_size, expiration);
853  state_attach_puts(strbuf, s);
854  if (b->parts->filename)
855  {
857  state_printf(s, _("[-- name: %s --]\n"), b->parts->filename);
858  }
859 
860  mutt_copy_hdr(s->fp_in, s->fp_out, ftello(s->fp_in), b->parts->offset,
861  (C_Weed ? (CH_WEED | CH_REORDER) : 0) | CH_DECODE, NULL);
862  }
863  }
864  else if (expiration && (expire < time(NULL)))
865  {
866  if (s->flags & MUTT_DISPLAY)
867  {
868  /* L10N: If the translation of this string is a multi line string, then
869  each line should start with "[-- " and end with " --]".
870  The "%s/%s" is a MIME type, e.g. "text/plain". */
871  snprintf(strbuf, sizeof(strbuf), _("[-- This %s/%s attachment is not included, --]\n[-- and the indicated external source has --]\n[-- expired. --]\n"),
872  TYPE(b->parts), b->parts->subtype);
873  state_attach_puts(strbuf, s);
874 
875  mutt_copy_hdr(s->fp_in, s->fp_out, ftello(s->fp_in), b->parts->offset,
876  (C_Weed ? (CH_WEED | CH_REORDER) : 0) | CH_DECODE | CH_DISPLAY, NULL);
877  }
878  }
879  else
880  {
881  if (s->flags & MUTT_DISPLAY)
882  {
883  /* L10N: If the translation of this string is a multi line string, then
884  each line should start with "[-- " and end with " --]".
885  The "%s/%s" is a MIME type, e.g. "text/plain". The %s after
886  access-type is an access-type as defined by the MIME RFCs, e.g. "FTP",
887  "LOCAL-FILE", "MAIL-SERVER". */
888  snprintf(strbuf, sizeof(strbuf), _("[-- This %s/%s attachment is not included, --]\n[-- and the indicated access-type %s is unsupported --]\n"),
889  TYPE(b->parts), b->parts->subtype, access_type);
890  state_attach_puts(strbuf, s);
891 
892  mutt_copy_hdr(s->fp_in, s->fp_out, ftello(s->fp_in), b->parts->offset,
893  (C_Weed ? (CH_WEED | CH_REORDER) : 0) | CH_DECODE | CH_DISPLAY, NULL);
894  }
895  }
896 
897  return 0;
898 }
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:147
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
LOFF_T offset
offset where the actual data begins
Definition: body.h:46
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
#define MUTT_PRINTING
Are we printing? - MUTT_DISPLAY "light".
Definition: state.h:37
time_t mutt_date_parse_date(const char *s, struct Tz *tz_out)
Parse a date string in RFC822 format.
Definition: date.c:443
void state_attach_puts(const char *t, struct State *s)
Write a string to the state.
Definition: state.c:64
FILE * fp_in
File to read from.
Definition: state.h:46
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
#define CH_WEED
Weed the headers?
Definition: copy.h:52
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
#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
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
#define TYPE(body)
Definition: mime.h:83
#define state_puts(str, state)
Definition: state.h:54
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: string.c:1014
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
int mutt_copy_hdr(FILE *fp_in, FILE *fp_out, LOFF_T off_start, LOFF_T off_end, CopyHeaderFlags chflags, const char *prefix)
Copy header from one file to another.
Definition: copy.c:72
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int alternative_handler ( struct Body a,
struct State s 
)
static

Handler for multipart alternative emails - Implements handler_t.

Definition at line 903 of file handler.c.

904 {
905  struct Body *choice = NULL;
906  struct Body *b = NULL;
907  bool mustfree = false;
908  int rc = 0;
909 
910  if ((a->encoding == ENC_BASE64) || (a->encoding == ENC_QUOTED_PRINTABLE) ||
911  (a->encoding == ENC_UUENCODED))
912  {
913  struct stat st;
914  mustfree = true;
915  fstat(fileno(s->fp_in), &st);
916  b = mutt_body_new();
917  b->length = (long) st.st_size;
919  s->fp_in, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
920  (mutt_str_strcasecmp("digest", a->subtype) == 0));
921  }
922  else
923  b = a;
924 
925  a = b;
926 
927  /* First, search list of preferred types */
928  struct ListNode *np = NULL;
929  STAILQ_FOREACH(np, &AlternativeOrderList, entries)
930  {
931  int btlen; /* length of basetype */
932  bool wild; /* do we have a wildcard to match all subtypes? */
933 
934  char *c = strchr(np->data, '/');
935  if (c)
936  {
937  wild = ((c[1] == '*') && (c[2] == '\0'));
938  btlen = c - np->data;
939  }
940  else
941  {
942  wild = true;
943  btlen = mutt_str_strlen(np->data);
944  }
945 
946  if (a->parts)
947  b = a->parts;
948  else
949  b = a;
950  while (b)
951  {
952  const char *bt = TYPE(b);
953  if ((mutt_str_strncasecmp(bt, np->data, btlen) == 0) && (bt[btlen] == 0))
954  {
955  /* the basetype matches */
956  if (wild || (mutt_str_strcasecmp(np->data + btlen + 1, b->subtype) == 0))
957  {
958  choice = b;
959  }
960  }
961  b = b->next;
962  }
963 
964  if (choice)
965  break;
966  }
967 
968  /* Next, look for an autoviewable type */
969  if (!choice)
970  {
971  if (a->parts)
972  b = a->parts;
973  else
974  b = a;
975  while (b)
976  {
977  if (is_autoview(b))
978  choice = b;
979  b = b->next;
980  }
981  }
982 
983  /* Then, look for a text entry */
984  if (!choice)
985  {
986  if (a->parts)
987  b = a->parts;
988  else
989  b = a;
990  int type = 0;
991  while (b)
992  {
993  if (b->type == TYPE_TEXT)
994  {
995  if ((mutt_str_strcasecmp("plain", b->subtype) == 0) && (type <= TXTPLAIN))
996  {
997  choice = b;
998  type = TXTPLAIN;
999  }
1000  else if ((mutt_str_strcasecmp("enriched", b->subtype) == 0) && (type <= TXTENRICHED))
1001  {
1002  choice = b;
1003  type = TXTENRICHED;
1004  }
1005  else if ((mutt_str_strcasecmp("html", b->subtype) == 0) && (type <= TXTHTML))
1006  {
1007  choice = b;
1008  type = TXTHTML;
1009  }
1010  }
1011  b = b->next;
1012  }
1013  }
1014 
1015  /* Finally, look for other possibilities */
1016  if (!choice)
1017  {
1018  if (a->parts)
1019  b = a->parts;
1020  else
1021  b = a;
1022  while (b)
1023  {
1024  if (mutt_can_decode(b))
1025  choice = b;
1026  b = b->next;
1027  }
1028  }
1029 
1030  if (choice)
1031  {
1032  if (s->flags & MUTT_DISPLAY && !C_Weed)
1033  {
1034  fseeko(s->fp_in, choice->hdr_offset, SEEK_SET);
1035  mutt_file_copy_bytes(s->fp_in, s->fp_out, choice->offset - choice->hdr_offset);
1036  }
1037 
1038  if (mutt_str_strcmp("info", C_ShowMultipartAlternative) == 0)
1039  {
1040  print_part_line(s, choice, 0);
1041  }
1042  mutt_body_handler(choice, s);
1043 
1044  if (mutt_str_strcmp("info", C_ShowMultipartAlternative) == 0)
1045  {
1046  if (a->parts)
1047  b = a->parts;
1048  else
1049  b = a;
1050  int count = 0;
1051  while (b)
1052  {
1053  if (choice != b)
1054  {
1055  count += 1;
1056  if (count == 1)
1057  state_putc('\n', s);
1058 
1059  print_part_line(s, b, count);
1060  }
1061  b = b->next;
1062  }
1063  }
1064  }
1065  else if (s->flags & MUTT_DISPLAY)
1066  {
1067  /* didn't find anything that we could display! */
1068  state_mark_attach(s);
1069  state_puts(_("[-- Error: Could not display any parts of "
1070  "Multipart/Alternative --]\n"),
1071  s);
1072  rc = -1;
1073  }
1074 
1075  if (mustfree)
1076  mutt_body_free(&a);
1077 
1078  return rc;
1079 }
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition: handler.c:480
LOFF_T offset
offset where the actual data begins
Definition: body.h:46
#define _(a)
Definition: message.h:28
struct Body * mutt_parse_multipart(FILE *fp, const char *boundary, LOFF_T end_off, bool digest)
parse a multipart structure
Definition: parse.c:1323
struct Body * next
next attachment in the list
Definition: body.h:58
FILE * fp_out
File to write to.
Definition: state.h:47
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:662
FILE * fp_in
File to read from.
Definition: state.h:46
#define TXTPLAIN
Definition: handler.c:75
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
#define TXTENRICHED
Definition: handler.c:76
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
int mutt_str_strncasecmp(const char *a, const char *b, size_t l)
Compare two strings ignoring case (to a maximum), safely.
Definition: string.c:652
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
Type: &#39;text/*&#39;.
Definition: mime.h:38
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1707
static void print_part_line(struct State *s, struct Body *b, int n)
Print a separator for the Mime part.
Definition: handler.c:93
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
unsigned int type
content-type primary type
Definition: body.h:70
#define TXTHTML
Definition: handler.c:74
#define TYPE(body)
Definition: mime.h:83
#define state_puts(str, state)
Definition: state.h:54
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * data
Definition: list.h:35
#define state_putc(str, state)
Definition: state.h:55
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
Quoted-printable text.
Definition: mime.h:51
char * C_ShowMultipartAlternative
Config: How to display &#39;multipart/alternative&#39; MIME parts.
Definition: handler.c:69
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1524
long hdr_offset
offset in stream where the headers begin.
Definition: body.h:42
A List node for strings.
Definition: list.h:33
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:611
UUEncoded text.
Definition: mime.h:54
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39
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:236

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int multilingual_handler ( struct Body a,
struct State s 
)
static

Handler for multi-lingual emails - Implements handler_t.

Return values
0Always

Definition at line 1085 of file handler.c.

1086 {
1087  struct Body *choice = NULL;
1088  struct Body *b = NULL;
1089  bool mustfree = false;
1090  int rc = 0;
1091  struct Body *first_part = NULL;
1092  struct Body *zxx_part = NULL;
1093  char *lang = NULL;
1094 
1096  "RFC8255 >> entering in handler multilingual handler\n");
1097  if ((a->encoding == ENC_BASE64) || (a->encoding == ENC_QUOTED_PRINTABLE) ||
1098  (a->encoding == ENC_UUENCODED))
1099  {
1100  struct stat st;
1101  mustfree = true;
1102  fstat(fileno(s->fp_in), &st);
1103  b = mutt_body_new();
1104  b->length = (long) st.st_size;
1106  s->fp_in, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
1107  (mutt_str_strcasecmp("digest", a->subtype) == 0));
1108  }
1109  else
1110  b = a;
1111 
1112  a = b;
1113 
1114  if (a->parts)
1115  b = a->parts;
1116  else
1117  b = a;
1118 
1119  char *preferred_languages = NULL;
1121  {
1122  mutt_debug(LL_DEBUG2, "RFC8255 >> preferred_languages set in config to '%s'\n",
1124  preferred_languages = mutt_str_strdup(C_PreferredLanguages);
1125  lang = strtok(preferred_languages, ",");
1126  }
1127 
1128  while (lang)
1129  {
1130  while (b)
1131  {
1132  if (mutt_can_decode(b))
1133  {
1134  if (!first_part)
1135  first_part = b;
1136 
1137  if (b->language && (mutt_str_strcmp("zxx", b->language) == 0))
1138  zxx_part = b;
1139 
1140  mutt_debug(LL_DEBUG2, "RFC8255 >> comparing configuration preferred_language='%s' to mail part content-language='%s'\n",
1141  lang, b->language);
1142  if (lang && b->language && (mutt_str_strcmp(lang, b->language) == 0))
1143  {
1144  mutt_debug(LL_DEBUG2, "RFC8255 >> preferred_language='%s' matches content-language='%s' >> part selected to be displayed\n",
1145  lang, b->language);
1146  choice = b;
1147  break;
1148  }
1149  }
1150 
1151  b = b->next;
1152  }
1153 
1154  if (choice)
1155  break;
1156 
1157  lang = strtok(NULL, ",");
1158 
1159  if (a->parts)
1160  b = a->parts;
1161  else
1162  b = a;
1163  }
1164 
1165  if (choice)
1166  mutt_body_handler(choice, s);
1167  else
1168  {
1169  if (zxx_part)
1170  mutt_body_handler(zxx_part, s);
1171  else
1172  mutt_body_handler(first_part, s);
1173  }
1174 
1175  if (mustfree)
1176  mutt_body_free(&a);
1177 
1178  FREE(&preferred_languages);
1179  return rc;
1180 }
struct Body * mutt_parse_multipart(FILE *fp, const char *boundary, LOFF_T end_off, bool digest)
parse a multipart structure
Definition: parse.c:1323
struct Body * next
next attachment in the list
Definition: body.h:58
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
Log at debug level 2.
Definition: logging.h:57
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1707
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
Quoted-printable text.
Definition: mime.h:51
#define FREE(x)
Definition: memory.h:40
char * language
content-language (RFC8255)
Definition: body.h:38
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1524
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
char * C_PreferredLanguages
Config: Preferred languages for multilingual MIME.
Definition: handler.c:67
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:611
UUEncoded text.
Definition: mime.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int multipart_handler ( struct Body a,
struct State s 
)
static

Handler for multipart emails - Implements handler_t.

Definition at line 1185 of file handler.c.

1186 {
1187  struct Body *b = NULL, *p = NULL;
1188  struct stat st;
1189  int count;
1190  int rc = 0;
1191 
1192  if ((a->encoding == ENC_BASE64) || (a->encoding == ENC_QUOTED_PRINTABLE) ||
1193  (a->encoding == ENC_UUENCODED))
1194  {
1195  fstat(fileno(s->fp_in), &st);
1196  b = mutt_body_new();
1197  b->length = (long) st.st_size;
1199  s->fp_in, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
1200  (mutt_str_strcasecmp("digest", a->subtype) == 0));
1201  }
1202  else
1203  b = a;
1204 
1205  for (p = b->parts, count = 1; p; p = p->next, count++)
1206  {
1207  if (s->flags & MUTT_DISPLAY)
1208  {
1209  state_mark_attach(s);
1210  if (p->description || p->filename || p->form_name)
1211  {
1212  /* L10N: %s is the attachment description, filename or form_name. */
1213  state_printf(s, _("[-- Attachment #%d: %s --]\n"), count,
1214  p->description ? p->description :
1215  p->filename ? p->filename : p->form_name);
1216  }
1217  else
1218  state_printf(s, _("[-- Attachment #%d --]\n"), count);
1219  print_part_line(s, p, 0);
1220  if (!C_Weed)
1221  {
1222  fseeko(s->fp_in, p->hdr_offset, SEEK_SET);
1223  mutt_file_copy_bytes(s->fp_in, s->fp_out, p->offset - p->hdr_offset);
1224  }
1225  else
1226  state_putc('\n', s);
1227  }
1228 
1229  rc = mutt_body_handler(p, s);
1230  state_putc('\n', s);
1231 
1232  if (rc != 0)
1233  {
1234  mutt_error(_("One or more parts of this message could not be displayed"));
1235  mutt_debug(LL_DEBUG1, "Failed on attachment #%d, type %s/%s.\n", count,
1236  TYPE(p), NONULL(p->subtype));
1237  }
1238 
1239  if ((s->flags & MUTT_REPLYING) && C_IncludeOnlyfirst && (s->flags & MUTT_FIRSTDONE))
1240  {
1241  break;
1242  }
1243  }
1244 
1245  if ((a->encoding == ENC_BASE64) || (a->encoding == ENC_QUOTED_PRINTABLE) ||
1246  (a->encoding == ENC_UUENCODED))
1247  {
1248  mutt_body_free(&b);
1249  }
1250 
1251  /* make failure of a single part non-fatal */
1252  if (rc < 0)
1253  rc = 1;
1254  return rc;
1255 }
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:147
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
#define NONULL(x)
Definition: string2.h:36
#define _(a)
Definition: message.h:28
struct Body * mutt_parse_multipart(FILE *fp, const char *boundary, LOFF_T end_off, bool digest)
parse a multipart structure
Definition: parse.c:1323
struct Body * next
next attachment in the list
Definition: body.h:58
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
static void print_part_line(struct State *s, struct Body *b, int n)
Print a separator for the Mime part.
Definition: handler.c:93
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
#define TYPE(body)
Definition: mime.h:83
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
Log at debug level 1.
Definition: logging.h:56
#define mutt_error(...)
Definition: logging.h:88
#define state_putc(str, state)
Definition: state.h:55
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
Quoted-printable text.
Definition: mime.h:51
#define MUTT_REPLYING
Are we replying?
Definition: state.h:38
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1524
#define MUTT_FIRSTDONE
The first attachment has been done.
Definition: state.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
bool C_IncludeOnlyfirst
Config: Only include the first attachment when replying.
Definition: handler.c:66
UUEncoded text.
Definition: mime.h:54
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39
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:236

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int run_decode_and_handler ( struct Body b,
struct State s,
handler_t  handler,
bool  plaintext 
)
static

Run an appropriate decoder for an email.

Parameters
bBody of the email
sState to work with
handlerCallback function to process the content - Implements handler_t
plaintextIs the content in plain text
Return values
0Success
-1Error

Definition at line 1266 of file handler.c.

1268 {
1269  char *save_prefix = NULL;
1270  FILE *fp = NULL;
1271  size_t tmplength = 0;
1272  LOFF_T tmpoffset = 0;
1273  int decode = 0;
1274  int rc = 0;
1275 
1276  fseeko(s->fp_in, b->offset, SEEK_SET);
1277 
1278 #ifdef USE_FMEMOPEN
1279  char *temp = NULL;
1280  size_t tempsize = 0;
1281 #endif
1282 
1283  /* see if we need to decode this part before processing it */
1284  if ((b->encoding == ENC_BASE64) || (b->encoding == ENC_QUOTED_PRINTABLE) ||
1285  (b->encoding == ENC_UUENCODED) || (plaintext || mutt_is_text_part(b)))
1286  /* text subtypes may require character set conversion even with 8bit encoding */
1287  {
1288  const int orig_type = b->type;
1289 #ifndef USE_FMEMOPEN
1290  char tempfile[PATH_MAX];
1291 #endif
1292  if (!plaintext)
1293  {
1294  /* decode to a tempfile, saving the original destination */
1295  fp = s->fp_out;
1296 #ifdef USE_FMEMOPEN
1297  s->fp_out = open_memstream(&temp, &tempsize);
1298  if (!s->fp_out)
1299  {
1300  mutt_error(_("Unable to open 'memory stream'"));
1301  mutt_debug(LL_DEBUG1, "Can't open 'memory stream'.\n");
1302  return -1;
1303  }
1304 #else
1305  mutt_mktemp(tempfile, sizeof(tempfile));
1306  s->fp_out = mutt_file_fopen(tempfile, "w");
1307  if (!s->fp_out)
1308  {
1309  mutt_error(_("Unable to open temporary file"));
1310  mutt_debug(LL_DEBUG1, "Can't open %s.\n", tempfile);
1311  return -1;
1312  }
1313 #endif
1314  /* decoding the attachment changes the size and offset, so save a copy
1315  * of the "real" values now, and restore them after processing */
1316  tmplength = b->length;
1317  tmpoffset = b->offset;
1318 
1319  /* if we are decoding binary bodies, we don't want to prefix each
1320  * line with the prefix or else the data will get corrupted. */
1321  save_prefix = s->prefix;
1322  s->prefix = NULL;
1323 
1324  decode = 1;
1325  }
1326  else
1327  b->type = TYPE_TEXT;
1328 
1329  mutt_decode_attachment(b, s);
1330 
1331  if (decode)
1332  {
1333  b->length = ftello(s->fp_out);
1334  b->offset = 0;
1335 #ifdef USE_FMEMOPEN
1336  /* When running under torify, mutt_file_fclose(&s->fp_out) does not seem to
1337  * update tempsize. On the other hand, fflush does. See
1338  * https://github.com/neomutt/neomutt/issues/440 */
1339  fflush(s->fp_out);
1340 #endif
1341  mutt_file_fclose(&s->fp_out);
1342 
1343  /* restore final destination and substitute the tempfile for input */
1344  s->fp_out = fp;
1345  fp = s->fp_in;
1346 #ifdef USE_FMEMOPEN
1347  if (tempsize)
1348  {
1349  s->fp_in = fmemopen(temp, tempsize, "r");
1350  }
1351  else
1352  { /* fmemopen cannot handle zero-length buffers */
1353  s->fp_in = mutt_file_fopen("/dev/null", "r");
1354  }
1355  if (!s->fp_in)
1356  {
1357  mutt_perror(_("failed to re-open 'memory stream'"));
1358  return -1;
1359  }
1360 #else
1361  s->fp_in = fopen(tempfile, "r");
1362  unlink(tempfile);
1363 #endif
1364  /* restore the prefix */
1365  s->prefix = save_prefix;
1366  }
1367 
1368  b->type = orig_type;
1369  }
1370 
1371  /* process the (decoded) body part */
1372  if (handler)
1373  {
1374  rc = handler(b, s);
1375  if (rc != 0)
1376  {
1377  mutt_debug(LL_DEBUG1, "Failed on attachment of type %s/%s.\n", TYPE(b),
1378  NONULL(b->subtype));
1379  }
1380 
1381  if (decode)
1382  {
1383  b->length = tmplength;
1384  b->offset = tmpoffset;
1385 
1386  /* restore the original source stream */
1387  mutt_file_fclose(&s->fp_in);
1388 #ifdef USE_FMEMOPEN
1389  FREE(&temp);
1390 #endif
1391  s->fp_in = fp;
1392  }
1393  }
1394  s->flags |= MUTT_FIRSTDONE;
1395 
1396  return rc;
1397 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1748
#define NONULL(x)
Definition: string2.h:36
#define mutt_perror(...)
Definition: logging.h:89
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
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:46
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:72
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
#define PATH_MAX
Definition: mutt.h:48
Type: &#39;text/*&#39;.
Definition: mime.h:38
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:427
unsigned int type
content-type primary type
Definition: body.h:70
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:546
#define TYPE(body)
Definition: mime.h:83
Log at debug level 1.
Definition: logging.h:56
#define mutt_error(...)
Definition: logging.h:88
Quoted-printable text.
Definition: mime.h:51
#define FREE(x)
Definition: memory.h:40
#define MUTT_FIRSTDONE
The first attachment has been done.
Definition: state.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
UUEncoded text.
Definition: mime.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int valid_pgp_encrypted_handler ( struct Body b,
struct State s 
)
static

Handler for valid pgp-encrypted emails - Implements handler_t.

Definition at line 1402 of file handler.c.

1403 {
1404  struct Body *octetstream = b->parts->next;
1405 
1406  /* clear out any mime headers before the handler, so they can't be spoofed. */
1408  mutt_env_free(&octetstream->mime_headers);
1409 
1410  int rc;
1411  /* Some clients improperly encode the octetstream part. */
1412  if (octetstream->encoding != ENC_7BIT)
1413  rc = run_decode_and_handler(octetstream, s, crypt_pgp_encrypted_handler, 0);
1414  else
1415  rc = crypt_pgp_encrypted_handler(octetstream, s);
1416  b->goodsig |= octetstream->goodsig;
1417 
1418  /* Relocate protected headers onto the multipart/encrypted part */
1419  if (!rc && octetstream->mime_headers)
1420  {
1421  b->mime_headers = octetstream->mime_headers;
1422  octetstream->mime_headers = NULL;
1423  }
1424 
1425  return rc;
1426 }
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:68
7-bit text
Definition: mime.h:49
struct Body * next
next attachment in the list
Definition: body.h:58
The body of an email.
Definition: body.h:34
int crypt_pgp_encrypted_handler(struct Body *a, struct State *s)
Wrapper for CryptModuleSpecs::encrypted_handler()
Definition: cryptglue.c:217
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
bool goodsig
good cryptographic signature
Definition: body.h:93
static int run_decode_and_handler(struct Body *b, struct State *s, handler_t handler, bool plaintext)
Run an appropriate decoder for an email.
Definition: handler.c:1266
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
void mutt_env_free(struct Envelope **p)
Free an Envelope.
Definition: envelope.c:53

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int malformed_pgp_encrypted_handler ( struct Body b,
struct State s 
)
static

Handler for invalid pgp-encrypted emails - Implements handler_t.

Definition at line 1431 of file handler.c.

1432 {
1433  struct Body *octetstream = b->parts->next->next;
1434 
1435  /* clear out any mime headers before the handler, so they can't be spoofed. */
1437  mutt_env_free(&octetstream->mime_headers);
1438 
1439  /* exchange encodes the octet-stream, so re-run it through the decoder */
1440  int rc = run_decode_and_handler(octetstream, s, crypt_pgp_encrypted_handler, false);
1441  b->goodsig |= octetstream->goodsig;
1442 
1443  /* Relocate protected headers onto the multipart/encrypted part */
1444  if (!rc && octetstream->mime_headers)
1445  {
1446  b->mime_headers = octetstream->mime_headers;
1447  octetstream->mime_headers = NULL;
1448  }
1449 
1450  return rc;
1451 }
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:68
struct Body * next
next attachment in the list
Definition: body.h:58
The body of an email.
Definition: body.h:34
int crypt_pgp_encrypted_handler(struct Body *a, struct State *s)
Wrapper for CryptModuleSpecs::encrypted_handler()
Definition: cryptglue.c:217
bool goodsig
good cryptographic signature
Definition: body.h:93
static int run_decode_and_handler(struct Body *b, struct State *s, handler_t handler, bool plaintext)
Run an appropriate decoder for an email.
Definition: handler.c:1266
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
void mutt_env_free(struct Envelope **p)
Free an Envelope.
Definition: envelope.c:53

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_decode_base64 ( struct State s,
size_t  len,
bool  istext,
iconv_t  cd 
)

Decode base64-encoded text.

Parameters
sState to work with
lenLength of text to decode
istextMime part is plain text
cdIconv conversion descriptor

Definition at line 1460 of file handler.c.

1461 {
1462  char buf[5];
1463  int ch, i;
1464  char bufi[BUFI_SIZE];
1465  size_t l = 0;
1466 
1467  buf[4] = '\0';
1468 
1469  if (istext)
1470  state_set_prefix(s);
1471 
1472  while (len > 0)
1473  {
1474  for (i = 0; (i < 4) && (len > 0); len--)
1475  {
1476  ch = fgetc(s->fp_in);
1477  if (ch == EOF)
1478  break;
1479  if ((ch >= 0) && (ch < 128) && ((base64val(ch) != -1) || (ch == '=')))
1480  buf[i++] = ch;
1481  }
1482  if (i != 4)
1483  {
1484  /* "i" may be zero if there is trailing whitespace, which is not an error */
1485  if (i != 0)
1486  mutt_debug(LL_DEBUG2, "didn't get a multiple of 4 chars.\n");
1487  break;
1488  }
1489 
1490  const int c1 = base64val(buf[0]);
1491  const int c2 = base64val(buf[1]);
1492  ch = (c1 << 2) | (c2 >> 4);
1493  bufi[l++] = ch;
1494 
1495  if (buf[2] == '=')
1496  break;
1497  const int c3 = base64val(buf[2]);
1498  ch = ((c2 & 0xf) << 4) | (c3 >> 2);
1499  bufi[l++] = ch;
1500 
1501  if (buf[3] == '=')
1502  break;
1503  const int c4 = base64val(buf[3]);
1504  ch = ((c3 & 0x3) << 6) | c4;
1505  bufi[l++] = ch;
1506 
1507  if ((l + 8) >= sizeof(bufi))
1508  convert_to_state(cd, bufi, &l, s);
1509  }
1510 
1511  convert_to_state(cd, bufi, &l, s);
1512  convert_to_state(cd, 0, 0, s);
1513 
1514  state_reset_prefix(s);
1515 }
#define state_reset_prefix(state)
Definition: state.h:53
FILE * fp_in
File to read from.
Definition: state.h:46
Log at debug level 2.
Definition: logging.h:57
#define BUFI_SIZE
Definition: handler.c:71
#define state_set_prefix(state)
Definition: state.h:52
#define base64val(ch)
Definition: base64.h:30
static void convert_to_state(iconv_t cd, char *bufi, size_t *l, struct State *s)
Convert text and write it to a file.
Definition: handler.c:120
#define mutt_debug(LEVEL,...)
Definition: logging.h:85

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_body_handler ( struct Body b,
struct State s 
)

Handler for the Body of an email.

Parameters
bBody of the email
sState to work with
Return values
0Success
-1Error

Definition at line 1524 of file handler.c.

1525 {
1526  if (!b || !s)
1527  return -1;
1528 
1529  bool plaintext = false;
1530  handler_t handler = NULL;
1531  int rc = 0;
1532 
1533  int oflags = s->flags;
1534 
1535  /* first determine which handler to use to process this part */
1536 
1537  if (is_autoview(b))
1538  {
1539  handler = autoview_handler;
1540  s->flags &= ~MUTT_CHARCONV;
1541  }
1542  else if (b->type == TYPE_TEXT)
1543  {
1544  if (mutt_str_strcasecmp("plain", b->subtype) == 0)
1545  {
1546  /* avoid copying this part twice since removing the transfer-encoding is
1547  * the only operation needed. */
1548  if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1550  else if (C_ReflowText &&
1551  (mutt_str_strcasecmp("flowed",
1552  mutt_param_get(&b->parameter, "format")) == 0))
1553  {
1554  handler = rfc3676_handler;
1555  }
1556  else
1557  {
1558  handler = text_plain_handler;
1559  }
1560  }
1561  else if (mutt_str_strcasecmp("enriched", b->subtype) == 0)
1562  handler = text_enriched_handler;
1563  else /* text body type without a handler */
1564  plaintext = false;
1565  }
1566  else if (b->type == TYPE_MESSAGE)
1567  {
1568  if (mutt_is_message_type(b->type, b->subtype))
1569  handler = message_handler;
1570  else if (mutt_str_strcasecmp("delivery-status", b->subtype) == 0)
1571  plaintext = true;
1572  else if (mutt_str_strcasecmp("external-body", b->subtype) == 0)
1573  handler = external_body_handler;
1574  }
1575  else if (b->type == TYPE_MULTIPART)
1576  {
1577  if ((mutt_str_strcmp("inline", C_ShowMultipartAlternative) != 0) &&
1578  (mutt_str_strcasecmp("alternative", b->subtype) == 0))
1579  {
1580  handler = alternative_handler;
1581  }
1582  else if ((mutt_str_strcmp("inline", C_ShowMultipartAlternative) != 0) &&
1583  (mutt_str_strcasecmp("multilingual", b->subtype) == 0))
1584  {
1585  handler = multilingual_handler;
1586  }
1587  else if ((WithCrypto != 0) && (mutt_str_strcasecmp("signed", b->subtype) == 0))
1588  {
1589  if (!mutt_param_get(&b->parameter, "protocol"))
1590  mutt_error(_("Error: multipart/signed has no protocol"));
1591  else if (s->flags & MUTT_VERIFY)
1592  handler = mutt_signed_handler;
1593  }
1595  {
1596  handler = valid_pgp_encrypted_handler;
1597  }
1599  {
1601  }
1602 
1603  if (!handler)
1604  handler = multipart_handler;
1605 
1606  if ((b->encoding != ENC_7BIT) && (b->encoding != ENC_8BIT) && (b->encoding != ENC_BINARY))
1607  {
1608  mutt_debug(LL_DEBUG1, "Bad encoding type %d for multipart entity, assuming 7 bit\n",
1609  b->encoding);
1610  b->encoding = ENC_7BIT;
1611  }
1612  }
1613  else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1614  {
1615  if (OptDontHandlePgpKeys && (mutt_str_strcasecmp("pgp-keys", b->subtype) == 0))
1616  {
1617  /* pass raw part through for key extraction */
1618  plaintext = true;
1619  }
1620  else if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1622  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(b))
1624  }
1625 
1626  /* only respect disposition == attachment if we're not
1627  * displaying from the attachment menu (i.e. pager) */
1628  if ((!C_HonorDisposition || ((b->disposition != DISP_ATTACH) || OptViewAttach)) &&
1629  (plaintext || handler))
1630  {
1631  rc = run_decode_and_handler(b, s, handler, plaintext);
1632  }
1633  /* print hint to use attachment menu for disposition == attachment
1634  * if we're not already being called from there */
1635  else if ((s->flags & MUTT_DISPLAY) || ((b->disposition == DISP_ATTACH) && !OptViewAttach &&
1636  C_HonorDisposition && (plaintext || handler)))
1637  {
1638  const char *str = NULL;
1639  char keystroke[128];
1640  keystroke[0] = '\0';
1641 
1642  if (!OptViewAttach)
1643  {
1644  if (km_expand_key(keystroke, sizeof(keystroke),
1645  km_find_func(MENU_PAGER, OP_VIEW_ATTACHMENTS)))
1646  {
1648  {
1649  /* L10N: Caution: Arguments %1$s and %2$s are also defined but should
1650  not be used in this translation!
1651  %3$s expands to a keystroke/key binding, e.g. 'v'. */
1652  str = _(
1653  "[-- This is an attachment (use '%3$s' to view this part) --]\n");
1654  }
1655  else
1656  {
1657  /* L10N: %s/%s is a MIME type, e.g. "text/plain".
1658  The last %s expands to a keystroke/key binding, e.g. 'v'. */
1659  str =
1660  _("[-- %s/%s is unsupported (use '%s' to view this part) --]\n");
1661  }
1662  }
1663  else
1664  {
1666  {
1667  str = _("[-- This is an attachment (need 'view-attachments' bound to "
1668  "key) --]\n");
1669  }
1670  else
1671  {
1672  /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1673  str = _("[-- %s/%s is unsupported (need 'view-attachments' bound to "
1674  "key) --]\n");
1675  }
1676  }
1677  }
1678  else
1679  {
1681  str = _("[-- This is an attachment --]\n");
1682  else
1683  {
1684  /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1685  str = _("[-- %s/%s is unsupported --]\n");
1686  }
1687  }
1688  state_mark_attach(s);
1689  state_printf(s, str, TYPE(b), b->subtype, keystroke);
1690  }
1691 
1692  s->flags = oflags | (s->flags & MUTT_FIRSTDONE);
1693  if (rc != 0)
1694  {
1695  mutt_debug(LL_DEBUG1, "Bailing on attachment of type %s/%s.\n", TYPE(b),
1696  NONULL(b->subtype));
1697  }
1698 
1699  return rc;
1700 }
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:147
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
#define NONULL(x)
Definition: string2.h:36
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1255
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition: handler.c:480
static int alternative_handler(struct Body *a, struct State *s)
Handler for multipart alternative emails - Implements handler_t.
Definition: handler.c:903
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
int(* handler_t)(struct Body *b, struct State *s)
typedef handler_t - Manage a PGP or S/MIME encrypted MIME part
Definition: handler.c:85
int crypt_pgp_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:204
7-bit text
Definition: mime.h:49
int mutt_signed_handler(struct Body *a, struct State *s)
Verify a "multipart/signed" body - Implements handler_t.
Definition: crypt.c:1074
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:442
#define _(a)
Definition: message.h:28
int text_enriched_handler(struct Body *a, struct State *s)
Handler for enriched text - Implements handler_t.
Definition: enriched.c:460
8-bit text
Definition: mime.h:50
struct Keymap * km_find_func(int menu, int func)
Find a function&#39;s mapping in a Menu.
Definition: keymap.c:794
int crypt_smime_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:385
unsigned int disposition
content-disposition
Definition: body.h:72
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
Pager pager (email viewer)
Definition: keymap.h:75
static int malformed_pgp_encrypted_handler(struct Body *b, struct State *s)
Handler for invalid pgp-encrypted emails - Implements handler_t.
Definition: handler.c:1431
Content is attached.
Definition: mime.h:63
WHERE bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:33
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
static int message_handler(struct Body *a, struct State *s)
Handler for message/rfc822 body parts - Implements handler_t.
Definition: handler.c:691
bool C_ReflowText
Config: Reformat paragraphs of &#39;format=flowed&#39; text.
Definition: handler.c:68
char * subtype
content-type subtype
Definition: body.h:37
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:525
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:766
#define MUTT_VERIFY
Perform signature verification.
Definition: state.h:33
Type: &#39;text/*&#39;.
Definition: mime.h:38
static int valid_pgp_encrypted_handler(struct Body *b, struct State *s)
Handler for valid pgp-encrypted emails - Implements handler_t.
Definition: handler.c:1402
static int run_decode_and_handler(struct Body *b, struct State *s, handler_t handler, bool plaintext)
Run an appropriate decoder for an email.
Definition: handler.c:1266
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:480
static int multilingual_handler(struct Body *a, struct State *s)
Handler for multi-lingual emails - Implements handler_t.
Definition: handler.c:1085
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:584
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
bool C_HonorDisposition
Config: Don&#39;t display MIME parts inline if they have a disposition of &#39;attachment&#39;.
Definition: handler.c:64
unsigned int type
content-type primary type
Definition: body.h:70
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
Type: &#39;message/*&#39;.
Definition: mime.h:35
#define TYPE(body)
Definition: mime.h:83
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Log at debug level 1.
Definition: logging.h:56
static int autoview_handler(struct Body *a, struct State *s)
Handler for autoviewable attachments - Implements handler_t.
Definition: handler.c:525
#define mutt_error(...)
Definition: logging.h:88
Binary.
Definition: mime.h:53
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
char * C_ShowMultipartAlternative
Config: How to display &#39;multipart/alternative&#39; MIME parts.
Definition: handler.c:69
static int multipart_handler(struct Body *a, struct State *s)
Handler for multipart emails - Implements handler_t.
Definition: handler.c:1185
WHERE bool OptViewAttach
(pseudo) signals that we are viewing attachments
Definition: options.h:52
#define MUTT_FIRSTDONE
The first attachment has been done.
Definition: state.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
int rfc3676_handler(struct Body *a, struct State *s)
Body handler implementing RFC3676 for format=flowed - Implements handler_t.
Definition: rfc3676.c:315
static int external_body_handler(struct Body *b, struct State *s)
Handler for external-body emails - Implements handler_t.
Definition: handler.c:743
static int text_plain_handler(struct Body *b, struct State *s)
Handler for plain text - Implements handler_t.
Definition: handler.c:665
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:155
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:611
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool mutt_can_decode ( struct Body a)

Will decoding the attachment produce any output.

Parameters
aBody of email to test
Return values
trueDecoding the attachment will produce output

Definition at line 1707 of file handler.c.

1708 {
1709  if (is_autoview(a))
1710  return true;
1711  else if (a->type == TYPE_TEXT)
1712  return true;
1713  else if (a->type == TYPE_MESSAGE)
1714  return true;
1715  else if (a->type == TYPE_MULTIPART)
1716  {
1717  if (WithCrypto)
1718  {
1719  if ((mutt_str_strcasecmp(a->subtype, "signed") == 0) ||
1720  (mutt_str_strcasecmp(a->subtype, "encrypted") == 0))
1721  {
1722  return true;
1723  }
1724  }
1725 
1726  for (struct Body *b = a->parts; b; b = b->next)
1727  {
1728  if (mutt_can_decode(b))
1729  return true;
1730  }
1731  }
1732  else if ((WithCrypto != 0) && (a->type == TYPE_APPLICATION))
1733  {
1734  if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(a))
1735  return true;
1737  return true;
1738  }
1739 
1740  return false;
1741 }
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition: handler.c:480
struct Body * next
next attachment in the list
Definition: body.h:58
The body of an email.
Definition: body.h:34
char * subtype
content-type subtype
Definition: body.h:37
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:525
Type: &#39;text/*&#39;.
Definition: mime.h:38
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1707
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:584
unsigned int type
content-type primary type
Definition: body.h:70
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
#define WithCrypto
Definition: ncrypt.h:155
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_decode_attachment ( struct Body b,
struct State s 
)

Decode an email's attachment.

Parameters
bBody of the email
sState of text being processed

Definition at line 1748 of file handler.c.

1749 {
1750  int istext = mutt_is_text_part(b);
1751  iconv_t cd = (iconv_t)(-1);
1752 
1753  if (istext && s->flags & MUTT_CHARCONV)
1754  {
1755  char *charset = mutt_param_get(&b->parameter, "charset");
1756  if (!charset && C_AssumedCharset && *C_AssumedCharset)
1757  charset = mutt_ch_get_default_charset();
1758  if (charset && C_Charset)
1760  }
1761  else if (istext && b->charset)
1763 
1764  fseeko(s->fp_in, b->offset, SEEK_SET);
1765  switch (b->encoding)
1766  {
1767  case ENC_QUOTED_PRINTABLE:
1768  decode_quoted(s, b->length,
1769  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1771  cd);
1772  break;
1773  case ENC_BASE64:
1774  mutt_decode_base64(s, b->length,
1775  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1777  cd);
1778  break;
1779  case ENC_UUENCODED:
1780  decode_uuencoded(s, b->length,
1781  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1783  cd);
1784  break;
1785  default:
1786  decode_xbit(s, b->length,
1787  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1789  cd);
1790  break;
1791  }
1792 
1793  if (cd != (iconv_t)(-1))
1794  iconv_close(cd);
1795 }
char * C_AssumedCharset
Config: If a message is missing a character set, assume this character set.
Definition: charset.c:53
static void decode_xbit(struct State *s, long len, bool istext, iconv_t cd)
Decode xbit-encoded text.
Definition: handler.c:167
static void decode_uuencoded(struct State *s, long len, bool istext, iconv_t cd)
Decode uuencoded text.
Definition: handler.c:369
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
static void decode_quoted(struct State *s, long len, bool istext, iconv_t cd)
Decode an attachment encoded with quoted-printable.
Definition: handler.c:305
LOFF_T offset
offset where the actual data begins
Definition: body.h:46
FILE * fp_in
File to read from.
Definition: state.h:46
void mutt_decode_base64(struct State *s, size_t len, bool istext, iconv_t cd)
Decode base64-encoded text.
Definition: handler.c:1460
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
Base-64 encoded text.
Definition: mime.h:52
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:525
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
iconv_t mutt_ch_iconv_open(const char *tocode, const char *fromcode, int flags)
Set up iconv for conversions.
Definition: charset.c:531
char * charset
charset of attached file
Definition: body.h:53
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:427
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
Quoted-printable text.
Definition: mime.h:51
char * mutt_ch_get_default_charset(void)
Get the default character set.
Definition: charset.c:401
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:54
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
Definition: charset.h:81
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:155
UUEncoded text.
Definition: mime.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

bool C_HonorDisposition

Config: Don't display MIME parts inline if they have a disposition of 'attachment'.

Definition at line 64 of file handler.c.

bool C_ImplicitAutoview

Config: Display MIME attachments inline if a 'copiousoutput' mailcap entry exists.

Definition at line 65 of file handler.c.

bool C_IncludeOnlyfirst

Config: Only include the first attachment when replying.

Definition at line 66 of file handler.c.

char* C_PreferredLanguages

Config: Preferred languages for multilingual MIME.

Definition at line 67 of file handler.c.

bool C_ReflowText

Config: Reformat paragraphs of 'format=flowed' text.

Definition at line 68 of file handler.c.

char* C_ShowMultipartAlternative

Config: How to display 'multipart/alternative' MIME parts.

Definition at line 69 of file handler.c.