NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
handler.h File Reference

Decide how to display email content. More...

#include <iconv.h>
#include <stdbool.h>
#include <stddef.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 *state)
 Handler for the Body of an email.
bool mutt_can_decode (struct Body *b)
 Will decoding the attachment produce any output.
void mutt_decode_attachment (const struct Body *b, struct State *state)
 Decode an email's attachment.
void mutt_decode_base64 (struct State *state, size_t len, bool istext, iconv_t cd)
 Decode base64-encoded text.
bool mutt_prefer_as_attachment (struct Body *b)
 Do we want this part as an attachment?

Detailed Description

Decide how to display email content.

Authors
  • Richard Russon
  • Pietro Cerutti

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

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

Definition in file handler.h.

Function Documentation

◆ mutt_body_handler()

int mutt_body_handler ( struct Body * b,
struct State * state )

Handler for the Body of an email.

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

Definition at line 1675 of file handler.c.

1676{
1677 if (!b || !state)
1678 return -1;
1679
1680 bool plaintext = false;
1681 handler_t handler = NULL;
1682 handler_t encrypted_handler = NULL;
1683 int rc = 0;
1684 static unsigned short recurse_level = 0;
1685
1686 const int oflags = state->flags;
1687 const bool is_attachment_display = (oflags & STATE_DISPLAY_ATTACH);
1688
1689 if (recurse_level >= MUTT_MIME_MAX_DEPTH)
1690 {
1691 mutt_debug(LL_DEBUG1, "recurse level too deep. giving up\n");
1692 return 1;
1693 }
1694 recurse_level++;
1695
1696 /* first determine which handler to use to process this part */
1697
1698 if (is_autoview(b))
1699 {
1700 handler = autoview_handler;
1701 state->flags &= ~STATE_CHARCONV;
1702 }
1703 else if (b->type == TYPE_TEXT)
1704 {
1705 if (mutt_istr_equal("plain", b->subtype))
1706 {
1707 const bool c_reflow_text = cs_subset_bool(NeoMutt->sub, "reflow_text");
1708 /* avoid copying this part twice since removing the transfer-encoding is
1709 * the only operation needed. */
1711 {
1712 encrypted_handler = crypt_pgp_application_handler;
1713 handler = encrypted_handler;
1714 }
1715 else if (c_reflow_text &&
1716 mutt_istr_equal("flowed", mutt_param_get(&b->parameter, "format")))
1717 {
1718 handler = rfc3676_handler;
1719 }
1720 else
1721 {
1722 handler = text_plain_handler;
1723 }
1724 }
1725 else if (mutt_istr_equal("enriched", b->subtype))
1726 {
1727 handler = text_enriched_handler;
1728 }
1729 else /* text body type without a handler */
1730 {
1731 plaintext = false;
1732 }
1733 }
1734 else if (b->type == TYPE_MESSAGE)
1735 {
1736 if (mutt_is_message_type(b->type, b->subtype))
1737 handler = message_handler;
1738 else if (mutt_istr_equal("delivery-status", b->subtype))
1739 plaintext = true;
1740 else if (mutt_istr_equal("external-body", b->subtype))
1741 handler = external_body_handler;
1742 }
1743 else if (b->type == TYPE_MULTIPART)
1744 {
1745 const char *const c_show_multipart_alternative = cs_subset_string(NeoMutt->sub, "show_multipart_alternative");
1746 if (!mutt_str_equal("inline", c_show_multipart_alternative) &&
1747 mutt_istr_equal("alternative", b->subtype))
1748 {
1749 handler = alternative_handler;
1750 }
1751 else if (!mutt_str_equal("inline", c_show_multipart_alternative) &&
1752 mutt_istr_equal("multilingual", b->subtype))
1753 {
1754 handler = multilingual_handler;
1755 }
1756 else if ((WithCrypto != 0) && mutt_istr_equal("signed", b->subtype))
1757 {
1758 if (!mutt_param_get(&b->parameter, "protocol"))
1759 mutt_error(_("Error: multipart/signed has no protocol"));
1760 else if (state->flags & STATE_VERIFY)
1761 handler = mutt_signed_handler;
1762 }
1764 {
1765 encrypted_handler = valid_pgp_encrypted_handler;
1766 handler = encrypted_handler;
1767 }
1769 {
1770 encrypted_handler = malformed_pgp_encrypted_handler;
1771 handler = encrypted_handler;
1772 }
1773
1774 if (!handler)
1775 handler = multipart_handler;
1776
1777 if ((b->encoding != ENC_7BIT) && (b->encoding != ENC_8BIT) && (b->encoding != ENC_BINARY))
1778 {
1779 mutt_debug(LL_DEBUG1, "Bad encoding type %d for multipart entity, assuming 7 bit\n",
1780 b->encoding);
1781 b->encoding = ENC_7BIT;
1782 }
1783 }
1784 else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1785 {
1786 if (OptDontHandlePgpKeys && mutt_istr_equal("pgp-keys", b->subtype))
1787 {
1788 /* pass raw part through for key extraction */
1789 plaintext = true;
1790 }
1791 else if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1792 {
1793 encrypted_handler = crypt_pgp_application_handler;
1794 handler = encrypted_handler;
1795 }
1796 else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(b))
1797 {
1798 encrypted_handler = crypt_smime_application_handler;
1799 handler = encrypted_handler;
1800 }
1801 }
1802
1803 if ((plaintext || handler) && (is_attachment_display || !mutt_prefer_as_attachment(b)))
1804 {
1805 /* only respect disposition == attachment if we're not
1806 * displaying from the attachment menu (i.e. pager) */
1807 /* Prevent encrypted attachments from being included in replies
1808 * unless $include_encrypted is set. */
1809 const bool c_include_encrypted = cs_subset_bool(NeoMutt->sub, "include_encrypted");
1810 if ((state->flags & STATE_REPLYING) && (state->flags & STATE_FIRSTDONE) &&
1811 encrypted_handler && !c_include_encrypted)
1812 {
1813 goto cleanup;
1814 }
1815
1816 rc = run_decode_and_handler(b, state, handler, plaintext);
1817 }
1818 else if (state->flags & STATE_DISPLAY)
1819 {
1820 /* print hint to use attachment menu for disposition == attachment
1821 * if we're not already being called from there */
1822 const bool c_honor_disposition = cs_subset_bool(NeoMutt->sub, "honor_disposition");
1823 struct Buffer *msg = buf_pool_get();
1824
1825 if (is_attachment_display)
1826 {
1827 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1828 {
1829 buf_strcpy(msg, _("[-- This is an attachment --]\n"));
1830 }
1831 else
1832 {
1833 /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1834 buf_printf(msg, _("[-- %s/%s is unsupported --]\n"), BODY_TYPE(b), b->subtype);
1835 }
1836 }
1837 else
1838 {
1839 struct Buffer *keystroke = buf_pool_get();
1840 const struct MenuDefinition *md_pager = pager_get_menu_definition();
1841 if (keymap_expand_key(km_find_func(md_pager, OP_VIEW_ATTACHMENTS), keystroke))
1842 {
1843 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1844 {
1845 /* L10N: %s expands to a keystroke/key binding, e.g. 'v'. */
1846 buf_printf(msg, _("[-- This is an attachment (use '%s' to view this part) --]\n"),
1847 buf_string(keystroke));
1848 }
1849 else
1850 {
1851 /* L10N: %s/%s is a MIME type, e.g. "text/plain".
1852 The last %s expands to a keystroke/key binding, e.g. 'v'. */
1853 buf_printf(msg, _("[-- %s/%s is unsupported (use '%s' to view this part) --]\n"),
1854 BODY_TYPE(b), b->subtype, buf_string(keystroke));
1855 }
1856 }
1857 else
1858 {
1859 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1860 {
1861 buf_strcpy(msg, _("[-- This is an attachment (need 'view-attachments' bound to key) --]\n"));
1862 }
1863 else
1864 {
1865 /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1866 buf_printf(msg, _("[-- %s/%s is unsupported (need 'view-attachments' bound to key) --]\n"),
1867 BODY_TYPE(b), b->subtype);
1868 }
1869 }
1870 buf_pool_release(&keystroke);
1871 }
1872 state_mark_attach(state);
1873 state_printf(state, "%s", buf_string(msg));
1874 buf_pool_release(&msg);
1875 }
1876
1877cleanup:
1878 recurse_level--;
1879 state->flags = oflags | (state->flags & STATE_FIRSTDONE);
1880 if (rc != 0)
1881 {
1882 mutt_debug(LL_DEBUG1, "Bailing on attachment of type %s/%s\n", BODY_TYPE(b),
1883 NONULL(b->subtype));
1884 }
1885
1886 return rc;
1887}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition crypt.c:610
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition crypt.c:468
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition crypt.c:505
SecurityFlags mutt_is_application_pgp(const struct Body *b)
Does the message use PGP?
Definition crypt.c:549
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition parse.c:1653
bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition globals.c:46
int crypt_pgp_application_handler(struct Body *b_email, struct State *state)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition cryptglue.c:266
static int alternative_handler(struct Body *b_email, struct State *state)
Handler for multipart alternative emails - Implements handler_t -.
Definition handler.c:955
int text_enriched_handler(struct Body *b_email, struct State *state)
Handler for enriched text - Implements handler_t -.
Definition enriched.c:474
static int text_plain_handler(struct Body *b_email, struct State *state)
Handler for plain text - Implements handler_t -.
Definition handler.c:699
int crypt_smime_application_handler(struct Body *b_email, struct State *state)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition cryptglue.c:524
static int autoview_handler(struct Body *b_email, struct State *state)
Handler for autoviewable attachments - Implements handler_t -.
Definition handler.c:545
static int external_body_handler(struct Body *b_email, struct State *state)
Handler for external-body emails - Implements handler_t -.
Definition handler.c:784
int rfc3676_handler(struct Body *b_email, struct State *state)
Handler for format=flowed - Implements handler_t -.
Definition rfc3676.c:329
static int malformed_pgp_encrypted_handler(struct Body *b_email, struct State *state)
Handler for invalid pgp-encrypted emails - Implements handler_t -.
Definition handler.c:1536
static int valid_pgp_encrypted_handler(struct Body *b_email, struct State *state)
Handler for valid pgp-encrypted emails - Implements handler_t -.
Definition handler.c:1507
static int message_handler(struct Body *b_email, struct State *state)
Handler for message/rfc822 body parts - Implements handler_t -.
Definition handler.c:726
static int multipart_handler(struct Body *b_email, struct State *state)
Handler for multipart emails - Implements handler_t -.
Definition handler.c:1259
static int multilingual_handler(struct Body *b_email, struct State *state)
Handler for multi-lingual emails - Implements handler_t -.
Definition handler.c:1146
int mutt_signed_handler(struct Body *b_email, struct State *state)
Handler for "multipart/signed" - Implements handler_t -.
Definition crypt.c:1251
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition handler.c:495
bool mutt_prefer_as_attachment(struct Body *b)
Do we want this part as an attachment?
Definition handler.c:1894
int(* handler_t)(struct Body *b_email, struct State *state)
Definition handler.c:89
static int run_decode_and_handler(struct Body *b, struct State *state, handler_t handler, bool plaintext)
Run an appropriate decoder for an email.
Definition handler.c:1349
bool keymap_expand_key(struct Keymap *km, struct Buffer *buf)
Get the key string bound to a Keymap.
Definition keymap.c:247
struct Keymap * km_find_func(const struct MenuDefinition *md, int func)
Find a function's mapping in a Menu.
Definition menu.c:141
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
@ ENC_7BIT
7-bit text
Definition mime.h:49
@ ENC_BINARY
Binary.
Definition mime.h:53
@ ENC_8BIT
8-bit text
Definition mime.h:50
#define MUTT_MIME_MAX_DEPTH
Maximum nesting depth for MIME parts to prevent stack overflow.
Definition mime.h:69
@ TYPE_MESSAGE
Type: 'message/*'.
Definition mime.h:35
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
@ TYPE_APPLICATION
Type: 'application/*'.
Definition mime.h:33
@ TYPE_TEXT
Type: 'text/*'.
Definition mime.h:38
#define BODY_TYPE(body)
Get the type name of a body part.
Definition mime.h:92
@ DISP_ATTACH
Content is attached.
Definition mime.h:63
#define _(a)
Definition message.h:28
void state_mark_attach(struct State *state)
Write a unique marker around content.
Definition state.c:73
int state_printf(struct State *state, const char *fmt,...)
Write a formatted string to the State.
Definition state.c:190
@ STATE_CHARCONV
Do character set conversions.
Definition state.h:41
@ STATE_FIRSTDONE
The first attachment has been done.
Definition state.h:44
@ STATE_REPLYING
Are we replying?
Definition state.h:43
@ STATE_VERIFY
Perform signature verification.
Definition state.h:38
@ STATE_DISPLAY_ATTACH
We are displaying an attachment.
Definition state.h:45
@ STATE_DISPLAY
Output is displayed to the user.
Definition state.h:37
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:106
#define PGP_ENCRYPT
Email is PGP encrypted.
Definition lib.h:112
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:107
#define WithCrypto
Definition lib.h:132
struct MenuDefinition * pager_get_menu_definition(void)
Get the Pager Menu Definition.
Definition functions.c:1116
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition parameter.c:85
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define NONULL(x)
Definition string2.h:44
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
unsigned int disposition
content-disposition, ContentDisposition
Definition body.h:42
char * subtype
content-type subtype
Definition body.h:61
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
unsigned int type
content-type primary type, ContentType
Definition body.h:40
String manipulation buffer.
Definition buffer.h:36
Functions for a Dialog or Window.
Definition menudef.h:44
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
StateFlags flags
Flags, e.g. STATE_DISPLAY.
Definition state.h:58

◆ mutt_can_decode()

bool mutt_can_decode ( struct Body * b)

Will decoding the attachment produce any output.

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

Definition at line 1910 of file handler.c.

1911{
1912 if (is_autoview(b))
1913 return true;
1914 if (b->type == TYPE_TEXT)
1915 return true;
1916 if (b->type == TYPE_MESSAGE)
1917 return true;
1918 if (b->type == TYPE_MULTIPART)
1919 {
1920 if (WithCrypto)
1921 {
1922 if (mutt_istr_equal(b->subtype, "signed") || mutt_istr_equal(b->subtype, "encrypted"))
1923 {
1924 return true;
1925 }
1926 }
1927
1928 for (struct Body *part = b->parts; part; part = part->next)
1929 {
1930 if (mutt_can_decode(part))
1931 return true;
1932 }
1933 }
1934 else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1935 {
1937 return true;
1939 return true;
1940 }
1941
1942 return false;
1943}
bool mutt_can_decode(struct Body *b)
Will decoding the attachment produce any output.
Definition handler.c:1910
The body of an email.
Definition body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
struct Body * next
next attachment in the list
Definition body.h:72
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutt_decode_attachment()

void mutt_decode_attachment ( const struct Body * b,
struct State * state )

Decode an email's attachment.

Parameters
bBody of the email
stateState of text being processed

Definition at line 1950 of file handler.c.

1951{
1952 int istext = mutt_is_text_part(b) && (b->disposition == DISP_INLINE);
1953 iconv_t cd = ICONV_T_INVALID;
1954
1955 if (!mutt_file_seek(state->fp_in, b->offset, SEEK_SET))
1956 {
1957 return;
1958 }
1959
1960 if (istext && (b->charset || (state->flags & STATE_CHARCONV)))
1961 {
1962 const char *charset = b->charset;
1963 if (!charset)
1964 {
1965 charset = mutt_param_get(&b->parameter, "charset");
1966 if (!charset && !slist_is_empty(cc_assumed_charset()))
1968 }
1969 if (charset && cc_charset())
1971 }
1972
1973 switch (b->encoding)
1974 {
1976 decode_quoted(state, b->length,
1977 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1979 cd);
1980 break;
1981 case ENC_BASE64:
1982 mutt_decode_base64(state, b->length,
1983 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1985 cd);
1986 break;
1987 case ENC_UUENCODED:
1988 decode_uuencoded(state, b->length,
1989 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1991 cd);
1992 break;
1993 default:
1994 decode_xbit(state, b->length,
1995 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1997 cd);
1998 break;
1999 }
2000}
const char * cc_charset(void)
Get the cached value of $charset.
const struct Slist * cc_assumed_charset(void)
Get the cached value of $assumed_charset.
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
static void decode_uuencoded(struct State *state, long len, bool istext, iconv_t cd)
Decode uuencoded text.
Definition handler.c:382
void mutt_decode_base64(struct State *state, size_t len, bool istext, iconv_t cd)
Decode base64-encoded text.
Definition handler.c:1571
static void decode_quoted(struct State *state, long len, bool istext, iconv_t cd)
Decode an attachment encoded with quoted-printable.
Definition handler.c:318
static void decode_xbit(struct State *state, long len, bool istext, iconv_t cd)
Decode xbit-encoded text.
Definition handler.c:176
@ ENC_UUENCODED
UUEncoded text.
Definition mime.h:54
@ ENC_BASE64
Base-64 encoded text.
Definition mime.h:52
@ ENC_QUOTED_PRINTABLE
Quoted-printable text.
Definition mime.h:51
@ DISP_INLINE
Content is inline.
Definition mime.h:62
iconv_t mutt_ch_iconv_open(const char *tocode, const char *fromcode, uint8_t flags)
Set up iconv for conversions.
Definition charset.c:581
const char * mutt_ch_get_default_charset(const struct Slist *const assumed_charset)
Get the default character set.
Definition charset.c:452
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
Definition charset.h:67
#define ICONV_T_INVALID
Error value for iconv functions.
Definition charset.h:111
bool slist_is_empty(const struct Slist *list)
Is the slist empty?
Definition slist.c:140
bool mutt_is_text_part(const struct Body *b)
Is this part of an email in plain text?
Definition muttlib.c:399
LOFF_T offset
offset where the actual data begins
Definition body.h:52
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
char * charset
Send mode: charset of attached file as stored on disk.
Definition body.h:79
FILE * fp_in
File to read from.
Definition state.h:55
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 * state,
size_t len,
bool istext,
iconv_t cd )

Decode base64-encoded text.

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

Definition at line 1571 of file handler.c.

1572{
1573 char buf[5] = { 0 };
1574 int ch;
1575 int i;
1576 bool cr = false;
1577 char bufi[BUFI_SIZE] = { 0 };
1578 size_t l = 0;
1579
1580 buf[4] = '\0';
1581
1582 if (istext)
1583 state_set_prefix(state);
1584
1585 while (len > 0)
1586 {
1587 for (i = 0; (i < 4) && (len > 0); len--)
1588 {
1589 ch = fgetc(state->fp_in);
1590 if (ch == EOF)
1591 break;
1592 if ((ch >= 0) && (ch < 128) && ((base64val(ch) != -1) || (ch == '=')))
1593 buf[i++] = ch;
1594 }
1595 if (i != 4)
1596 {
1597 /* "i" may be zero if there is trailing whitespace, which is not an error */
1598 if (i != 0)
1599 mutt_debug(LL_DEBUG2, "didn't get a multiple of 4 chars\n");
1600 break;
1601 }
1602
1603 const int c1 = base64val(buf[0]);
1604 if (c1 == -1) /* '=' (or any non-base64 char) at slot 0: stop */
1605 break;
1606 const int c2 = base64val(buf[1]);
1607 if (c2 == -1) /* '=' at slot 1: invalid padding, stop */
1608 break;
1609
1610 /* first char */
1611 ch = (c1 << 2) | (c2 >> 4);
1612
1613 if (cr && (ch != '\n'))
1614 bufi[l++] = '\r';
1615
1616 cr = false;
1617
1618 if (istext && (ch == '\r'))
1619 cr = true;
1620 else
1621 bufi[l++] = ch;
1622
1623 /* second char */
1624 if (buf[2] == '=')
1625 break;
1626 const int c3 = base64val(buf[2]);
1627 ch = ((c2 & 0xf) << 4) | (c3 >> 2);
1628
1629 if (cr && (ch != '\n'))
1630 bufi[l++] = '\r';
1631
1632 cr = false;
1633
1634 if (istext && (ch == '\r'))
1635 cr = true;
1636 else
1637 bufi[l++] = ch;
1638
1639 /* third char */
1640 if (buf[3] == '=')
1641 break;
1642 const int c4 = base64val(buf[3]);
1643 ch = ((c3 & 0x3) << 6) | c4;
1644
1645 if (cr && (ch != '\n'))
1646 bufi[l++] = '\r';
1647
1648 cr = false;
1649
1650 if (istext && (ch == '\r'))
1651 cr = true;
1652 else
1653 bufi[l++] = ch;
1654
1655 if ((l + 8) >= sizeof(bufi))
1656 convert_to_state(cd, bufi, &l, state);
1657 }
1658
1659 if (cr)
1660 bufi[l++] = '\r';
1661
1662 convert_to_state(cd, bufi, &l, state);
1663 convert_to_state(cd, 0, 0, state);
1664
1665 state_reset_prefix(state);
1666}
#define base64val(ch)
Convert base64 character to its numeric value.
Definition base64.h:33
#define BUFI_SIZE
Input buffer size for handler operations.
Definition handler.c:72
static void convert_to_state(iconv_t cd, char *bufi, size_t *l, struct State *state)
Convert text and write it to a file.
Definition handler.c:126
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
#define state_set_prefix(state)
Definition state.h:62
#define state_reset_prefix(state)
Definition state.h:63
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mutt_prefer_as_attachment()

bool mutt_prefer_as_attachment ( struct Body * b)

Do we want this part as an attachment?

Parameters
bBody of email to test
Return values
trueWe want this part as an attachment

Definition at line 1894 of file handler.c.

1895{
1896 if (!mutt_can_decode(b))
1897 return true;
1898
1899 if (b->disposition != DISP_ATTACH)
1900 return false;
1901
1902 return cs_subset_bool(NeoMutt->sub, "honor_disposition");
1903}
Here is the call graph for this function:
Here is the caller graph for this function: