NeoMutt  2025-12-11-980-ge38c27
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 1668 of file handler.c.

1669{
1670 if (!b || !state)
1671 return -1;
1672
1673 bool plaintext = false;
1674 handler_t handler = NULL;
1675 handler_t encrypted_handler = NULL;
1676 int rc = 0;
1677 static unsigned short recurse_level = 0;
1678
1679 const int oflags = state->flags;
1680 const bool is_attachment_display = (oflags & STATE_DISPLAY_ATTACH);
1681
1682 if (recurse_level >= MUTT_MIME_MAX_DEPTH)
1683 {
1684 mutt_debug(LL_DEBUG1, "recurse level too deep. giving up\n");
1685 return 1;
1686 }
1687 recurse_level++;
1688
1689 /* first determine which handler to use to process this part */
1690
1691 if (is_autoview(b))
1692 {
1693 handler = autoview_handler;
1694 state->flags &= ~STATE_CHARCONV;
1695 }
1696 else if (b->type == TYPE_TEXT)
1697 {
1698 if (mutt_istr_equal("plain", b->subtype))
1699 {
1700 const bool c_reflow_text = cs_subset_bool(NeoMutt->sub, "reflow_text");
1701 /* avoid copying this part twice since removing the transfer-encoding is
1702 * the only operation needed. */
1704 {
1705 encrypted_handler = crypt_pgp_application_handler;
1706 handler = encrypted_handler;
1707 }
1708 else if (c_reflow_text &&
1709 mutt_istr_equal("flowed", mutt_param_get(&b->parameter, "format")))
1710 {
1711 handler = rfc3676_handler;
1712 }
1713 else
1714 {
1715 handler = text_plain_handler;
1716 }
1717 }
1718 else if (mutt_istr_equal("enriched", b->subtype))
1719 {
1720 handler = text_enriched_handler;
1721 }
1722 else /* text body type without a handler */
1723 {
1724 plaintext = false;
1725 }
1726 }
1727 else if (b->type == TYPE_MESSAGE)
1728 {
1729 if (mutt_is_message_type(b->type, b->subtype))
1730 handler = message_handler;
1731 else if (mutt_istr_equal("delivery-status", b->subtype))
1732 plaintext = true;
1733 else if (mutt_istr_equal("external-body", b->subtype))
1734 handler = external_body_handler;
1735 }
1736 else if (b->type == TYPE_MULTIPART)
1737 {
1738 const char *const c_show_multipart_alternative = cs_subset_string(NeoMutt->sub, "show_multipart_alternative");
1739 if (!mutt_str_equal("inline", c_show_multipart_alternative) &&
1740 mutt_istr_equal("alternative", b->subtype))
1741 {
1742 handler = alternative_handler;
1743 }
1744 else if (!mutt_str_equal("inline", c_show_multipart_alternative) &&
1745 mutt_istr_equal("multilingual", b->subtype))
1746 {
1747 handler = multilingual_handler;
1748 }
1749 else if ((WithCrypto != 0) && mutt_istr_equal("signed", b->subtype))
1750 {
1751 if (!mutt_param_get(&b->parameter, "protocol"))
1752 mutt_error(_("Error: multipart/signed has no protocol"));
1753 else if (state->flags & STATE_VERIFY)
1754 handler = mutt_signed_handler;
1755 }
1757 {
1758 encrypted_handler = valid_pgp_encrypted_handler;
1759 handler = encrypted_handler;
1760 }
1762 {
1763 encrypted_handler = malformed_pgp_encrypted_handler;
1764 handler = encrypted_handler;
1765 }
1766
1767 if (!handler)
1768 handler = multipart_handler;
1769
1770 if ((b->encoding != ENC_7BIT) && (b->encoding != ENC_8BIT) && (b->encoding != ENC_BINARY))
1771 {
1772 mutt_debug(LL_DEBUG1, "Bad encoding type %d for multipart entity, assuming 7 bit\n",
1773 b->encoding);
1774 b->encoding = ENC_7BIT;
1775 }
1776 }
1777 else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1778 {
1779 if (OptDontHandlePgpKeys && mutt_istr_equal("pgp-keys", b->subtype))
1780 {
1781 /* pass raw part through for key extraction */
1782 plaintext = true;
1783 }
1784 else if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1785 {
1786 encrypted_handler = crypt_pgp_application_handler;
1787 handler = encrypted_handler;
1788 }
1789 else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(b))
1790 {
1791 encrypted_handler = crypt_smime_application_handler;
1792 handler = encrypted_handler;
1793 }
1794 }
1795
1796 if ((plaintext || handler) && (is_attachment_display || !mutt_prefer_as_attachment(b)))
1797 {
1798 /* only respect disposition == attachment if we're not
1799 * displaying from the attachment menu (i.e. pager) */
1800 /* Prevent encrypted attachments from being included in replies
1801 * unless $include_encrypted is set. */
1802 const bool c_include_encrypted = cs_subset_bool(NeoMutt->sub, "include_encrypted");
1803 if ((state->flags & STATE_REPLYING) && (state->flags & STATE_FIRSTDONE) &&
1804 encrypted_handler && !c_include_encrypted)
1805 {
1806 goto cleanup;
1807 }
1808
1809 rc = run_decode_and_handler(b, state, handler, plaintext);
1810 }
1811 else if (state->flags & STATE_DISPLAY)
1812 {
1813 /* print hint to use attachment menu for disposition == attachment
1814 * if we're not already being called from there */
1815 const bool c_honor_disposition = cs_subset_bool(NeoMutt->sub, "honor_disposition");
1816 struct Buffer *msg = buf_pool_get();
1817
1818 if (is_attachment_display)
1819 {
1820 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1821 {
1822 buf_strcpy(msg, _("[-- This is an attachment --]\n"));
1823 }
1824 else
1825 {
1826 /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1827 buf_printf(msg, _("[-- %s/%s is unsupported --]\n"), BODY_TYPE(b), b->subtype);
1828 }
1829 }
1830 else
1831 {
1832 struct Buffer *keystroke = buf_pool_get();
1833 const struct MenuDefinition *md_pager = pager_get_menu_definition();
1834 if (keymap_expand_key(km_find_func(md_pager, OP_VIEW_ATTACHMENTS), keystroke))
1835 {
1836 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1837 {
1838 /* L10N: %s expands to a keystroke/key binding, e.g. 'v'. */
1839 buf_printf(msg, _("[-- This is an attachment (use '%s' to view this part) --]\n"),
1840 buf_string(keystroke));
1841 }
1842 else
1843 {
1844 /* L10N: %s/%s is a MIME type, e.g. "text/plain".
1845 The last %s expands to a keystroke/key binding, e.g. 'v'. */
1846 buf_printf(msg, _("[-- %s/%s is unsupported (use '%s' to view this part) --]\n"),
1847 BODY_TYPE(b), b->subtype, buf_string(keystroke));
1848 }
1849 }
1850 else
1851 {
1852 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1853 {
1854 buf_strcpy(msg, _("[-- This is an attachment (need 'view-attachments' bound to key) --]\n"));
1855 }
1856 else
1857 {
1858 /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1859 buf_printf(msg, _("[-- %s/%s is unsupported (need 'view-attachments' bound to key) --]\n"),
1860 BODY_TYPE(b), b->subtype);
1861 }
1862 }
1863 buf_pool_release(&keystroke);
1864 }
1865 state_mark_attach(state);
1866 state_printf(state, "%s", buf_string(msg));
1867 buf_pool_release(&msg);
1868 }
1869
1870cleanup:
1871 recurse_level--;
1872 state->flags = oflags | (state->flags & STATE_FIRSTDONE);
1873 if (rc != 0)
1874 {
1875 mutt_debug(LL_DEBUG1, "Bailing on attachment of type %s/%s\n", BODY_TYPE(b),
1876 NONULL(b->subtype));
1877 }
1878
1879 return rc;
1880}
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:1620
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:952
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:696
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:543
static int external_body_handler(struct Body *b_email, struct State *state)
Handler for external-body emails - Implements handler_t -.
Definition handler.c:781
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:1533
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:1504
static int message_handler(struct Body *b_email, struct State *state)
Handler for message/rfc822 body parts - Implements handler_t -.
Definition handler.c:723
static int multipart_handler(struct Body *b_email, struct State *state)
Handler for multipart emails - Implements handler_t -.
Definition handler.c:1256
static int multilingual_handler(struct Body *b_email, struct State *state)
Handler for multi-lingual emails - Implements handler_t -.
Definition handler.c:1143
int mutt_signed_handler(struct Body *b_email, struct State *state)
Handler for "multipart/signed" - Implements handler_t -.
Definition crypt.c:1250
#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:493
bool mutt_prefer_as_attachment(struct Body *b)
Do we want this part as an attachment?
Definition handler.c:1887
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:1346
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:93
@ 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:1115
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 1903 of file handler.c.

1904{
1905 if (is_autoview(b))
1906 return true;
1907 if (b->type == TYPE_TEXT)
1908 return true;
1909 if (b->type == TYPE_MESSAGE)
1910 return true;
1911 if (b->type == TYPE_MULTIPART)
1912 {
1913 if (WithCrypto)
1914 {
1915 if (mutt_istr_equal(b->subtype, "signed") || mutt_istr_equal(b->subtype, "encrypted"))
1916 {
1917 return true;
1918 }
1919 }
1920
1921 for (struct Body *part = b->parts; part; part = part->next)
1922 {
1923 if (mutt_can_decode(part))
1924 return true;
1925 }
1926 }
1927 else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1928 {
1930 return true;
1932 return true;
1933 }
1934
1935 return false;
1936}
bool mutt_can_decode(struct Body *b)
Will decoding the attachment produce any output.
Definition handler.c:1903
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 1943 of file handler.c.

1944{
1945 int istext = mutt_is_text_part(b) && (b->disposition == DISP_INLINE);
1946 iconv_t cd = ICONV_T_INVALID;
1947
1948 if (!mutt_file_seek(state->fp_in, b->offset, SEEK_SET))
1949 {
1950 return;
1951 }
1952
1953 if (istext && (b->charset || (state->flags & STATE_CHARCONV)))
1954 {
1955 const char *charset = b->charset;
1956 if (!charset)
1957 {
1958 charset = mutt_param_get(&b->parameter, "charset");
1959 if (!charset && !slist_is_empty(cc_assumed_charset()))
1961 }
1962 if (charset && cc_charset())
1964 }
1965
1966 switch (b->encoding)
1967 {
1969 decode_quoted(state, b->length,
1970 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1972 cd);
1973 break;
1974 case ENC_BASE64:
1975 mutt_decode_base64(state, b->length,
1976 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1978 cd);
1979 break;
1980 case ENC_UUENCODED:
1981 decode_uuencoded(state, b->length,
1982 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1984 cd);
1985 break;
1986 default:
1987 decode_xbit(state, b->length,
1988 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1990 cd);
1991 break;
1992 }
1993}
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:380
void mutt_decode_base64(struct State *state, size_t len, bool istext, iconv_t cd)
Decode base64-encoded text.
Definition handler.c:1568
static void decode_quoted(struct State *state, long len, bool istext, iconv_t cd)
Decode an attachment encoded with quoted-printable.
Definition handler.c:316
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:396
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 1568 of file handler.c.

1569{
1570 char buf[5] = { 0 };
1571 int ch;
1572 int i;
1573 bool cr = false;
1574 char bufi[BUFI_SIZE] = { 0 };
1575 size_t l = 0;
1576
1577 buf[4] = '\0';
1578
1579 if (istext)
1580 state_set_prefix(state);
1581
1582 while (len > 0)
1583 {
1584 for (i = 0; (i < 4) && (len > 0); len--)
1585 {
1586 ch = fgetc(state->fp_in);
1587 if (ch == EOF)
1588 break;
1589 if ((ch >= 0) && (ch < 128) && ((base64val(ch) != -1) || (ch == '=')))
1590 buf[i++] = ch;
1591 }
1592 if (i != 4)
1593 {
1594 /* "i" may be zero if there is trailing whitespace, which is not an error */
1595 if (i != 0)
1596 mutt_debug(LL_DEBUG2, "didn't get a multiple of 4 chars\n");
1597 break;
1598 }
1599
1600 const int c1 = base64val(buf[0]);
1601 const int c2 = base64val(buf[1]);
1602
1603 /* first char */
1604 ch = (c1 << 2) | (c2 >> 4);
1605
1606 if (cr && (ch != '\n'))
1607 bufi[l++] = '\r';
1608
1609 cr = false;
1610
1611 if (istext && (ch == '\r'))
1612 cr = true;
1613 else
1614 bufi[l++] = ch;
1615
1616 /* second char */
1617 if (buf[2] == '=')
1618 break;
1619 const int c3 = base64val(buf[2]);
1620 ch = ((c2 & 0xf) << 4) | (c3 >> 2);
1621
1622 if (cr && (ch != '\n'))
1623 bufi[l++] = '\r';
1624
1625 cr = false;
1626
1627 if (istext && (ch == '\r'))
1628 cr = true;
1629 else
1630 bufi[l++] = ch;
1631
1632 /* third char */
1633 if (buf[3] == '=')
1634 break;
1635 const int c4 = base64val(buf[3]);
1636 ch = ((c3 & 0x3) << 6) | c4;
1637
1638 if (cr && (ch != '\n'))
1639 bufi[l++] = '\r';
1640
1641 cr = false;
1642
1643 if (istext && (ch == '\r'))
1644 cr = true;
1645 else
1646 bufi[l++] = ch;
1647
1648 if ((l + 8) >= sizeof(bufi))
1649 convert_to_state(cd, bufi, &l, state);
1650 }
1651
1652 if (cr)
1653 bufi[l++] = '\r';
1654
1655 convert_to_state(cd, bufi, &l, state);
1656 convert_to_state(cd, 0, 0, state);
1657
1658 state_reset_prefix(state);
1659}
#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 1887 of file handler.c.

1888{
1889 if (!mutt_can_decode(b))
1890 return true;
1891
1892 if (b->disposition != DISP_ATTACH)
1893 return false;
1894
1895 return cs_subset_bool(NeoMutt->sub, "honor_disposition");
1896}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: