NeoMutt  2020-06-26-250-g349c94
Teaching an old dog new tricks
DOXYGEN
handler.h File Reference

Decide how to display email content. More...

#include <stddef.h>
#include <iconv.h>
#include <stdbool.h>
+ Include dependency graph for handler.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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...
 
void mutt_decode_base64 (struct State *s, size_t len, bool istext, iconv_t cd)
 Decode base64-encoded text. 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_IncludeEncrypted
 Config: Whether to include encrypted content when replying. More...
 
bool C_IncludeOnlyfirst
 Config: Only include the first attachment when replying. More...
 
struct SlistC_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.h.

Function Documentation

◆ mutt_body_handler()

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 1593 of file handler.c.

1594 {
1595  if (!b || !s)
1596  return -1;
1597 
1598  bool plaintext = false;
1599  handler_t handler = NULL;
1600  handler_t encrypted_handler = NULL;
1601  int rc = 0;
1602  static unsigned short recurse_level = 0;
1603 
1604  int oflags = s->flags;
1605 
1606  if (recurse_level >= MUTT_MIME_MAX_DEPTH)
1607  {
1608  mutt_debug(LL_DEBUG1, "recurse level too deep. giving up.\n");
1609  return 1;
1610  }
1611  recurse_level++;
1612 
1613  /* first determine which handler to use to process this part */
1614 
1615  if (is_autoview(b))
1616  {
1617  handler = autoview_handler;
1618  s->flags &= ~MUTT_CHARCONV;
1619  }
1620  else if (b->type == TYPE_TEXT)
1621  {
1622  if (mutt_istr_equal("plain", b->subtype))
1623  {
1624  /* avoid copying this part twice since removing the transfer-encoding is
1625  * the only operation needed. */
1626  if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1627  {
1628  encrypted_handler = crypt_pgp_application_handler;
1629  handler = encrypted_handler;
1630  }
1631  else if (C_ReflowText && mutt_istr_equal("flowed", mutt_param_get(&b->parameter, "format")))
1632  {
1633  handler = rfc3676_handler;
1634  }
1635  else
1636  {
1637  handler = text_plain_handler;
1638  }
1639  }
1640  else if (mutt_istr_equal("enriched", b->subtype))
1641  handler = text_enriched_handler;
1642  else /* text body type without a handler */
1643  plaintext = false;
1644  }
1645  else if (b->type == TYPE_MESSAGE)
1646  {
1647  if (mutt_is_message_type(b->type, b->subtype))
1648  handler = message_handler;
1649  else if (mutt_istr_equal("delivery-status", b->subtype))
1650  plaintext = true;
1651  else if (mutt_istr_equal("external-body", b->subtype))
1652  handler = external_body_handler;
1653  }
1654  else if (b->type == TYPE_MULTIPART)
1655  {
1656  if (!mutt_str_equal("inline", C_ShowMultipartAlternative) &&
1657  mutt_istr_equal("alternative", b->subtype))
1658  {
1659  handler = alternative_handler;
1660  }
1661  else if (!mutt_str_equal("inline", C_ShowMultipartAlternative) &&
1662  mutt_istr_equal("multilingual", b->subtype))
1663  {
1664  handler = multilingual_handler;
1665  }
1666  else if ((WithCrypto != 0) && mutt_istr_equal("signed", b->subtype))
1667  {
1668  if (!mutt_param_get(&b->parameter, "protocol"))
1669  mutt_error(_("Error: multipart/signed has no protocol"));
1670  else if (s->flags & MUTT_VERIFY)
1671  handler = mutt_signed_handler;
1672  }
1674  {
1675  encrypted_handler = valid_pgp_encrypted_handler;
1676  handler = encrypted_handler;
1677  }
1679  {
1680  encrypted_handler = malformed_pgp_encrypted_handler;
1681  handler = encrypted_handler;
1682  }
1683 
1684  if (!handler)
1685  handler = multipart_handler;
1686 
1687  if ((b->encoding != ENC_7BIT) && (b->encoding != ENC_8BIT) && (b->encoding != ENC_BINARY))
1688  {
1689  mutt_debug(LL_DEBUG1, "Bad encoding type %d for multipart entity, assuming 7 bit\n",
1690  b->encoding);
1691  b->encoding = ENC_7BIT;
1692  }
1693  }
1694  else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1695  {
1696  if (OptDontHandlePgpKeys && mutt_istr_equal("pgp-keys", b->subtype))
1697  {
1698  /* pass raw part through for key extraction */
1699  plaintext = true;
1700  }
1701  else if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1702  {
1703  encrypted_handler = crypt_pgp_application_handler;
1704  handler = encrypted_handler;
1705  }
1706  else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(b))
1707  {
1708  encrypted_handler = crypt_smime_application_handler;
1709  handler = encrypted_handler;
1710  }
1711  }
1712 
1713  /* only respect disposition == attachment if we're not
1714  * displaying from the attachment menu (i.e. pager) */
1715  if ((!C_HonorDisposition || ((b->disposition != DISP_ATTACH) || OptViewAttach)) &&
1716  (plaintext || handler))
1717  {
1718  /* Prevent encrypted attachments from being included in replies
1719  * unless $include_encrypted is set. */
1720  if ((s->flags & MUTT_REPLYING) && (s->flags & MUTT_FIRSTDONE) &&
1721  encrypted_handler && !C_IncludeEncrypted)
1722  {
1723  goto cleanup;
1724  }
1725 
1726  rc = run_decode_and_handler(b, s, handler, plaintext);
1727  }
1728  /* print hint to use attachment menu for disposition == attachment
1729  * if we're not already being called from there */
1730  else if (s->flags & MUTT_DISPLAY)
1731  {
1732  struct Buffer msg = mutt_buffer_make(256);
1733 
1734  if (!OptViewAttach)
1735  {
1736  char keystroke[128] = { 0 };
1737  if (km_expand_key(keystroke, sizeof(keystroke),
1738  km_find_func(MENU_PAGER, OP_VIEW_ATTACHMENTS)))
1739  {
1741  {
1742  /* L10N: %s expands to a keystroke/key binding, e.g. 'v'. */
1743  mutt_buffer_printf(&msg, _("[-- This is an attachment (use '%s' to view this part) --]\n"),
1744  keystroke);
1745  }
1746  else
1747  {
1748  /* L10N: %s/%s is a MIME type, e.g. "text/plain".
1749  The last %s expands to a keystroke/key binding, e.g. 'v'. */
1750  mutt_buffer_printf(&msg, _("[-- %s/%s is unsupported (use '%s' to view this part) --]\n"),
1751  TYPE(b), b->subtype, keystroke);
1752  }
1753  }
1754  else
1755  {
1757  {
1758  mutt_buffer_strcpy(&msg, _("[-- This is an attachment (need "
1759  "'view-attachments' bound to key) --]\n"));
1760  }
1761  else
1762  {
1763  /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1764  mutt_buffer_printf(&msg, _("[-- %s/%s is unsupported (need 'view-attachments' bound to key) --]\n"),
1765  TYPE(b), b->subtype);
1766  }
1767  }
1768  }
1769  else
1770  {
1772  {
1773  mutt_buffer_strcpy(&msg, _("[-- This is an attachment --]\n"));
1774  }
1775  else
1776  {
1777  /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1778  mutt_buffer_printf(&msg, _("[-- %s/%s is unsupported --]\n"), TYPE(b), b->subtype);
1779  }
1780  }
1781  state_mark_attach(s);
1782  state_printf(s, "%s", mutt_b2s(&msg));
1783  mutt_buffer_dealloc(&msg);
1784  }
1785 
1786 cleanup:
1787  recurse_level--;
1788  s->flags = oflags | (s->flags & MUTT_FIRSTDONE);
1789  if (rc != 0)
1790  {
1791  mutt_debug(LL_DEBUG1, "Bailing on attachment of type %s/%s\n", TYPE(b),
1792  NONULL(b->subtype));
1793  }
1794 
1795  return rc;
1796 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:153
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
#define NONULL(x)
Definition: string2.h:37
#define WithCrypto
Definition: lib.h:123
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1366
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition: handler.c:484
static int alternative_handler(struct Body *a, struct State *s)
Handler for multipart alternative emails - Implements handler_t.
Definition: handler.c:931
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
int(* handler_t)(struct Body *b, struct State *s)
Manage a PGP or S/MIME encrypted MIME part.
Definition: handler.c:87
int crypt_pgp_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:234
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:1111
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:469
#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
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
int crypt_smime_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:444
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:67
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
Pager pager (email viewer)
Definition: keymap.h:79
static int malformed_pgp_encrypted_handler(struct Body *b, struct State *s)
Handler for invalid pgp-encrypted emails - Implements handler_t.
Definition: handler.c:1462
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
Content is attached.
Definition: mime.h:63
WHERE bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:36
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
static int message_handler(struct Body *a, struct State *s)
Handler for message/rfc822 body parts - Implements handler_t.
Definition: handler.c:707
bool C_ReflowText
Config: Reformat paragraphs of &#39;format=flowed&#39; text.
Definition: handler.c:70
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
char * subtype
content-type subtype
Definition: body.h:37
struct Keymap * km_find_func(enum MenuType menu, int func)
Find a function&#39;s mapping in a Menu.
Definition: keymap.c:899
#define mutt_b2s(buf)
Definition: buffer.h:41
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:550
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
#define MUTT_MIME_MAX_DEPTH
Definition: mime.h:69
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:871
#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:1433
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:1293
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:506
static int multilingual_handler(struct Body *a, struct State *s)
Handler for multi-lingual emails - Implements handler_t.
Definition: handler.c:1112
bool C_IncludeEncrypted
Config: Whether to include encrypted content when replying.
Definition: handler.c:67
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:608
void state_mark_attach(struct State *s)
Write a unique marker around content.
Definition: state.c:41
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
bool C_HonorDisposition
Config: Don&#39;t display MIME parts inline if they have a disposition of &#39;attachment&#39;.
Definition: handler.c:65
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
Type: &#39;message/*&#39;.
Definition: mime.h:35
#define TYPE(body)
Definition: mime.h:89
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Log at debug level 1.
Definition: logging.h:40
static int autoview_handler(struct Body *a, struct State *s)
Handler for autoviewable attachments - Implements handler_t.
Definition: handler.c:529
#define mutt_error(...)
Definition: logging.h:84
Binary.
Definition: mime.h:53
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
char * C_ShowMultipartAlternative
Config: How to display &#39;multipart/alternative&#39; MIME parts.
Definition: handler.c:71
#define MUTT_REPLYING
Are we replying?
Definition: state.h:38
static int multipart_handler(struct Body *a, struct State *s)
Handler for multipart emails - Implements handler_t.
Definition: handler.c:1210
WHERE bool OptViewAttach
(pseudo) signals that we are viewing attachments
Definition: options.h:55
#define MUTT_FIRSTDONE
The first attachment has been done.
Definition: state.h:39
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int rfc3676_handler(struct Body *a, struct State *s)
Body handler implementing RFC3676 for format=flowed - Implements handler_t.
Definition: rfc3676.c:316
static int external_body_handler(struct Body *b, struct State *s)
Handler for external-body emails - Implements handler_t.
Definition: handler.c:760
static int text_plain_handler(struct Body *b, struct State *s)
Handler for plain text - Implements handler_t.
Definition: handler.c:681
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_can_decode()

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 1803 of file handler.c.

1804 {
1805  if (is_autoview(a))
1806  return true;
1807  if (a->type == TYPE_TEXT)
1808  return true;
1809  if (a->type == TYPE_MESSAGE)
1810  return true;
1811  if (a->type == TYPE_MULTIPART)
1812  {
1813  if (WithCrypto)
1814  {
1815  if (mutt_istr_equal(a->subtype, "signed") || mutt_istr_equal(a->subtype, "encrypted"))
1816  {
1817  return true;
1818  }
1819  }
1820 
1821  for (struct Body *b = a->parts; b; b = b->next)
1822  {
1823  if (mutt_can_decode(b))
1824  return true;
1825  }
1826  }
1827  else if ((WithCrypto != 0) && (a->type == TYPE_APPLICATION))
1828  {
1829  if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(a))
1830  return true;
1832  return true;
1833  }
1834 
1835  return false;
1836 }
#define WithCrypto
Definition: lib.h:123
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition: handler.c:484
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
char * subtype
content-type subtype
Definition: body.h:37
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:550
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
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:1803
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:608
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Type: &#39;application/*&#39;.
Definition: mime.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_decode_attachment()

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 1843 of file handler.c.

1844 {
1845  int istext = mutt_is_text_part(b) && (b->disposition == DISP_INLINE);
1846  iconv_t cd = (iconv_t)(-1);
1847 
1848  if (istext && (b->charset || (s->flags & MUTT_CHARCONV)))
1849  {
1850  const char *charset = b->charset;
1851  if (!charset)
1852  {
1853  charset = mutt_param_get(&b->parameter, "charset");
1854  if (!charset && C_AssumedCharset)
1855  charset = mutt_ch_get_default_charset();
1856  }
1857  if (charset && C_Charset)
1859  }
1860 
1861  fseeko(s->fp_in, b->offset, SEEK_SET);
1862  switch (b->encoding)
1863  {
1864  case ENC_QUOTED_PRINTABLE:
1865  decode_quoted(s, b->length,
1866  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1868  cd);
1869  break;
1870  case ENC_BASE64:
1871  mutt_decode_base64(s, b->length,
1872  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1874  cd);
1875  break;
1876  case ENC_UUENCODED:
1877  decode_uuencoded(s, b->length,
1878  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1880  cd);
1881  break;
1882  default:
1883  decode_xbit(s, b->length,
1884  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1886  cd);
1887  break;
1888  }
1889 
1890  if (cd != (iconv_t)(-1))
1891  iconv_close(cd);
1892 }
char * C_AssumedCharset
Config: If a message is missing a character set, assume this character set.
Definition: charset.c:52
static void decode_xbit(struct State *s, long len, bool istext, iconv_t cd)
Decode xbit-encoded text.
Definition: handler.c:171
#define WithCrypto
Definition: lib.h:123
static void decode_uuencoded(struct State *s, long len, bool istext, iconv_t cd)
Decode uuencoded text.
Definition: handler.c:372
#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:308
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
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:1494
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:67
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:550
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
iconv_t mutt_ch_iconv_open(const char *tocode, const char *fromcode, int flags)
Set up iconv for conversions.
Definition: charset.c:565
char * charset
Send mode: charset of attached file as stored on disk.
Definition: body.h:49
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:433
Quoted-printable text.
Definition: mime.h:51
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
char * mutt_ch_get_default_charset(void)
Get the default character set.
Definition: charset.c:440
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
Definition: charset.h:72
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
UUEncoded text.
Definition: mime.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_decode_base64()

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 1494 of file handler.c.

1495 {
1496  char buf[5];
1497  int ch, i;
1498  bool cr = false;
1499  char bufi[BUFI_SIZE];
1500  size_t l = 0;
1501 
1502  buf[4] = '\0';
1503 
1504  if (istext)
1505  state_set_prefix(s);
1506 
1507  while (len > 0)
1508  {
1509  for (i = 0; (i < 4) && (len > 0); len--)
1510  {
1511  ch = fgetc(s->fp_in);
1512  if (ch == EOF)
1513  break;
1514  if ((ch >= 0) && (ch < 128) && ((base64val(ch) != -1) || (ch == '=')))
1515  buf[i++] = ch;
1516  }
1517  if (i != 4)
1518  {
1519  /* "i" may be zero if there is trailing whitespace, which is not an error */
1520  if (i != 0)
1521  mutt_debug(LL_DEBUG2, "didn't get a multiple of 4 chars\n");
1522  break;
1523  }
1524 
1525  const int c1 = base64val(buf[0]);
1526  const int c2 = base64val(buf[1]);
1527 
1528  /* first char */
1529  ch = (c1 << 2) | (c2 >> 4);
1530 
1531  if (cr && (ch != '\n'))
1532  bufi[l++] = '\r';
1533 
1534  cr = false;
1535 
1536  if (istext && (ch == '\r'))
1537  cr = true;
1538  else
1539  bufi[l++] = ch;
1540 
1541  /* second char */
1542  if (buf[2] == '=')
1543  break;
1544  const int c3 = base64val(buf[2]);
1545  ch = ((c2 & 0xf) << 4) | (c3 >> 2);
1546 
1547  if (cr && (ch != '\n'))
1548  bufi[l++] = '\r';
1549 
1550  cr = false;
1551 
1552  if (istext && (ch == '\r'))
1553  cr = true;
1554  else
1555  bufi[l++] = ch;
1556 
1557  /* third char */
1558  if (buf[3] == '=')
1559  break;
1560  const int c4 = base64val(buf[3]);
1561  ch = ((c3 & 0x3) << 6) | c4;
1562 
1563  if (cr && (ch != '\n'))
1564  bufi[l++] = '\r';
1565 
1566  cr = false;
1567 
1568  if (istext && (ch == '\r'))
1569  cr = true;
1570  else
1571  bufi[l++] = ch;
1572 
1573  if ((l + 8) >= sizeof(bufi))
1574  convert_to_state(cd, bufi, &l, s);
1575  }
1576 
1577  if (cr)
1578  bufi[l++] = '\r';
1579 
1580  convert_to_state(cd, bufi, &l, s);
1581  convert_to_state(cd, 0, 0, s);
1582 
1583  state_reset_prefix(s);
1584 }
#define state_reset_prefix(state)
Definition: state.h:54
FILE * fp_in
File to read from.
Definition: state.h:46
Log at debug level 2.
Definition: logging.h:41
#define BUFI_SIZE
Definition: handler.c:73
#define state_set_prefix(state)
Definition: state.h:53
#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:122
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_HonorDisposition

bool C_HonorDisposition

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

Definition at line 65 of file handler.c.

◆ C_ImplicitAutoview

bool C_ImplicitAutoview

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

Definition at line 66 of file handler.c.

◆ C_IncludeEncrypted

bool C_IncludeEncrypted

Config: Whether to include encrypted content when replying.

Definition at line 67 of file handler.c.

◆ C_IncludeOnlyfirst

bool C_IncludeOnlyfirst

Config: Only include the first attachment when replying.

Definition at line 68 of file handler.c.

◆ C_PreferredLanguages

struct Slist* C_PreferredLanguages

Config: Preferred languages for multilingual MIME.

Definition at line 69 of file handler.c.

◆ C_ReflowText

bool C_ReflowText

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

Definition at line 70 of file handler.c.

◆ C_ShowMultipartAlternative

char* C_ShowMultipartAlternative

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

Definition at line 71 of file handler.c.