NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
handler.h File Reference

Decide how to display email content. More...

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

Handler for the Body of an email.

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

Definition at line 1619 of file handler.c.

1620{
1621 if (!b || !state)
1622 return -1;
1623
1624 bool plaintext = false;
1625 handler_t handler = NULL;
1626 handler_t encrypted_handler = NULL;
1627 int rc = 0;
1628 static unsigned short recurse_level = 0;
1629
1630 const int oflags = state->flags;
1631 const bool is_attachment_display = (oflags & STATE_DISPLAY_ATTACH);
1632
1633 if (recurse_level >= MUTT_MIME_MAX_DEPTH)
1634 {
1635 mutt_debug(LL_DEBUG1, "recurse level too deep. giving up.\n");
1636 return 1;
1637 }
1638 recurse_level++;
1639
1640 /* first determine which handler to use to process this part */
1641
1642 if (is_autoview(b))
1643 {
1644 handler = autoview_handler;
1645 state->flags &= ~STATE_CHARCONV;
1646 }
1647 else if (b->type == TYPE_TEXT)
1648 {
1649 if (mutt_istr_equal("plain", b->subtype))
1650 {
1651 const bool c_reflow_text = cs_subset_bool(NeoMutt->sub, "reflow_text");
1652 /* avoid copying this part twice since removing the transfer-encoding is
1653 * the only operation needed. */
1655 {
1656 encrypted_handler = crypt_pgp_application_handler;
1657 handler = encrypted_handler;
1658 }
1659 else if (c_reflow_text &&
1660 mutt_istr_equal("flowed", mutt_param_get(&b->parameter, "format")))
1661 {
1662 handler = rfc3676_handler;
1663 }
1664 else
1665 {
1666 handler = text_plain_handler;
1667 }
1668 }
1669 else if (mutt_istr_equal("enriched", b->subtype))
1670 handler = text_enriched_handler;
1671 else /* text body type without a handler */
1672 plaintext = false;
1673 }
1674 else if (b->type == TYPE_MESSAGE)
1675 {
1676 if (mutt_is_message_type(b->type, b->subtype))
1677 handler = message_handler;
1678 else if (mutt_istr_equal("delivery-status", b->subtype))
1679 plaintext = true;
1680 else if (mutt_istr_equal("external-body", b->subtype))
1681 handler = external_body_handler;
1682 }
1683 else if (b->type == TYPE_MULTIPART)
1684 {
1685 const char *const c_show_multipart_alternative = cs_subset_string(NeoMutt->sub, "show_multipart_alternative");
1686 if (!mutt_str_equal("inline", c_show_multipart_alternative) &&
1687 mutt_istr_equal("alternative", b->subtype))
1688 {
1689 handler = alternative_handler;
1690 }
1691 else if (!mutt_str_equal("inline", c_show_multipart_alternative) &&
1692 mutt_istr_equal("multilingual", b->subtype))
1693 {
1694 handler = multilingual_handler;
1695 }
1696 else if ((WithCrypto != 0) && mutt_istr_equal("signed", b->subtype))
1697 {
1698 if (!mutt_param_get(&b->parameter, "protocol"))
1699 mutt_error(_("Error: multipart/signed has no protocol"));
1700 else if (state->flags & STATE_VERIFY)
1701 handler = mutt_signed_handler;
1702 }
1704 {
1705 encrypted_handler = valid_pgp_encrypted_handler;
1706 handler = encrypted_handler;
1707 }
1709 {
1710 encrypted_handler = malformed_pgp_encrypted_handler;
1711 handler = encrypted_handler;
1712 }
1713
1714 if (!handler)
1715 handler = multipart_handler;
1716
1717 if ((b->encoding != ENC_7BIT) && (b->encoding != ENC_8BIT) && (b->encoding != ENC_BINARY))
1718 {
1719 mutt_debug(LL_DEBUG1, "Bad encoding type %d for multipart entity, assuming 7 bit\n",
1720 b->encoding);
1721 b->encoding = ENC_7BIT;
1722 }
1723 }
1724 else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1725 {
1726 if (OptDontHandlePgpKeys && mutt_istr_equal("pgp-keys", b->subtype))
1727 {
1728 /* pass raw part through for key extraction */
1729 plaintext = true;
1730 }
1731 else if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(b))
1732 {
1733 encrypted_handler = crypt_pgp_application_handler;
1734 handler = encrypted_handler;
1735 }
1736 else if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(b))
1737 {
1738 encrypted_handler = crypt_smime_application_handler;
1739 handler = encrypted_handler;
1740 }
1741 }
1742
1743 /* only respect disposition == attachment if we're not
1744 * displaying from the attachment menu (i.e. pager) */
1745 if ((plaintext || handler) && (is_attachment_display || !mutt_prefer_as_attachment(b)))
1746 {
1747 /* Prevent encrypted attachments from being included in replies
1748 * unless $include_encrypted is set. */
1749 const bool c_include_encrypted = cs_subset_bool(NeoMutt->sub, "include_encrypted");
1750 if ((state->flags & STATE_REPLYING) && (state->flags & STATE_FIRSTDONE) &&
1751 encrypted_handler && !c_include_encrypted)
1752 {
1753 goto cleanup;
1754 }
1755
1756 rc = run_decode_and_handler(b, state, handler, plaintext);
1757 }
1758 /* print hint to use attachment menu for disposition == attachment
1759 * if we're not already being called from there */
1760 else if (state->flags & STATE_DISPLAY)
1761 {
1762 const bool c_honor_disposition = cs_subset_bool(NeoMutt->sub, "honor_disposition");
1763 struct Buffer msg = mutt_buffer_make(256);
1764
1765 if (!is_attachment_display)
1766 {
1767 char keystroke[128] = { 0 };
1768 if (km_expand_key(keystroke, sizeof(keystroke),
1769 km_find_func(MENU_PAGER, OP_VIEW_ATTACHMENTS)))
1770 {
1771 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1772 {
1773 /* L10N: %s expands to a keystroke/key binding, e.g. 'v'. */
1774 mutt_buffer_printf(&msg, _("[-- This is an attachment (use '%s' to view this part) --]\n"),
1775 keystroke);
1776 }
1777 else
1778 {
1779 /* L10N: %s/%s is a MIME type, e.g. "text/plain".
1780 The last %s expands to a keystroke/key binding, e.g. 'v'. */
1781 mutt_buffer_printf(&msg, _("[-- %s/%s is unsupported (use '%s' to view this part) --]\n"),
1782 TYPE(b), b->subtype, keystroke);
1783 }
1784 }
1785 else
1786 {
1787 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1788 {
1789 mutt_buffer_strcpy(&msg, _("[-- This is an attachment (need 'view-attachments' bound to key) --]\n"));
1790 }
1791 else
1792 {
1793 /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1794 mutt_buffer_printf(&msg, _("[-- %s/%s is unsupported (need 'view-attachments' bound to key) --]\n"),
1795 TYPE(b), b->subtype);
1796 }
1797 }
1798 }
1799 else
1800 {
1801 if (c_honor_disposition && (b->disposition == DISP_ATTACH))
1802 {
1803 mutt_buffer_strcpy(&msg, _("[-- This is an attachment --]\n"));
1804 }
1805 else
1806 {
1807 /* L10N: %s/%s is a MIME type, e.g. "text/plain". */
1808 mutt_buffer_printf(&msg, _("[-- %s/%s is unsupported --]\n"), TYPE(b), b->subtype);
1809 }
1810 }
1811 state_mark_attach(state);
1812 state_printf(state, "%s", mutt_buffer_string(&msg));
1813 mutt_buffer_dealloc(&msg);
1814 }
1815
1816cleanup:
1817 recurse_level--;
1818 state->flags = oflags | (state->flags & STATE_FIRSTDONE);
1819 if (rc != 0)
1820 {
1821 mutt_debug(LL_DEBUG1, "Bailing on attachment of type %s/%s\n", TYPE(b),
1822 NONULL(b->subtype));
1823 }
1824
1825 return rc;
1826}
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:365
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:347
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
SecurityFlags mutt_is_application_pgp(struct Body *b)
Does the message use PGP?
Definition: crypt.c:541
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:598
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:460
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:497
bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: globals.c:69
static int alternative_handler(struct Body *a, struct State *state)
Handler for multipart alternative emails - Implements handler_t -.
Definition: handler.c:936
int crypt_pgp_application_handler(struct Body *b, struct State *state)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition: cryptglue.c:237
int crypt_smime_application_handler(struct Body *b, struct State *state)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition: cryptglue.c:444
static int multipart_handler(struct Body *a, struct State *state)
Handler for multipart emails - Implements handler_t -.
Definition: handler.c:1228
static int text_plain_handler(struct Body *b, struct State *state)
Handler for plain text - Implements handler_t -.
Definition: handler.c:679
static int external_body_handler(struct Body *b, struct State *state)
Handler for external-body emails - Implements handler_t -.
Definition: handler.c:764
static int multilingual_handler(struct Body *a, struct State *state)
Handler for multi-lingual emails - Implements handler_t -.
Definition: handler.c:1122
static int message_handler(struct Body *a, struct State *state)
Handler for message/rfc822 body parts - Implements handler_t -.
Definition: handler.c:706
int mutt_signed_handler(struct Body *b, struct State *state)
Verify a "multipart/signed" body - Implements handler_t -.
Definition: crypt.c:1126
static int malformed_pgp_encrypted_handler(struct Body *b, struct State *state)
Handler for invalid pgp-encrypted emails - Implements handler_t -.
Definition: handler.c:1488
static int autoview_handler(struct Body *a, struct State *state)
Handler for autoviewable attachments - Implements handler_t -.
Definition: handler.c:524
static int valid_pgp_encrypted_handler(struct Body *b, struct State *state)
Handler for valid pgp-encrypted emails - Implements handler_t -.
Definition: handler.c:1459
int rfc3676_handler(struct Body *a, struct State *state)
Body handler implementing RFC3676 for format=flowed - Implements handler_t -.
Definition: rfc3676.c:320
int text_enriched_handler(struct Body *a, struct State *state)
Handler for enriched text - Implements handler_t -.
Definition: enriched.c:465
#define mutt_error(...)
Definition: logging.h:87
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
static bool is_autoview(struct Body *b)
Should email body be filtered by mailcap.
Definition: handler.c:478
bool mutt_prefer_as_attachment(struct Body *b)
Do we want this part as an attachment?
Definition: handler.c:1833
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:1314
int(* handler_t)(struct Body *b, struct State *state)
Definition: handler.c:78
struct Keymap * km_find_func(enum MenuType mtype, int func)
Find a function's mapping in a Menu.
Definition: keymap.c:960
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:932
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
@ 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
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
@ DISP_ATTACH
Content is attached.
Definition: mime.h:63
#define TYPE(body)
Definition: mime.h:89
#define _(a)
Definition: message.h:28
void state_mark_attach(struct State *state)
Write a unique marker around content.
Definition: state.c:71
int state_printf(struct State *state, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:185
#define STATE_DISPLAY
Output is displayed to the user.
Definition: state.h:32
#define STATE_DISPLAY_ATTACH
We are displaying an attachment.
Definition: state.h:40
#define STATE_FIRSTDONE
The first attachment has been done.
Definition: state.h:39
#define STATE_REPLYING
Are we replying?
Definition: state.h:38
#define STATE_VERIFY
Perform signature verification.
Definition: state.h:33
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define WithCrypto
Definition: lib.h:116
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1450
#define NONULL(x)
Definition: string2.h:37
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:62
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:42
char * subtype
content-type subtype
Definition: body.h:60
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:34
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
StateFlags flags
Flags, e.g. STATE_DISPLAY.
Definition: state.h:51
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
+ 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 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 1849 of file handler.c.

1850{
1851 if (is_autoview(b))
1852 return true;
1853 if (b->type == TYPE_TEXT)
1854 return true;
1855 if (b->type == TYPE_MESSAGE)
1856 return true;
1857 if (b->type == TYPE_MULTIPART)
1858 {
1859 if (WithCrypto)
1860 {
1861 if (mutt_istr_equal(b->subtype, "signed") || mutt_istr_equal(b->subtype, "encrypted"))
1862 {
1863 return true;
1864 }
1865 }
1866
1867 for (struct Body *part = b->parts; part; part = part->next)
1868 {
1869 if (mutt_can_decode(part))
1870 return true;
1871 }
1872 }
1873 else if ((WithCrypto != 0) && (b->type == TYPE_APPLICATION))
1874 {
1876 return true;
1878 return true;
1879 }
1880
1881 return false;
1882}
bool mutt_can_decode(struct Body *b)
Will decoding the attachment produce any output.
Definition: handler.c:1849
The body of an email.
Definition: body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
struct Body * next
next attachment in the list
Definition: body.h:71
+ 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 state 
)

Decode an email's attachment.

Parameters
bBody of the email
stateState of text being processed

Definition at line 1889 of file handler.c.

1890{
1891 int istext = mutt_is_text_part(b) && (b->disposition == DISP_INLINE);
1892 iconv_t cd = (iconv_t) (-1);
1893
1894 if (!mutt_file_seek(state->fp_in, b->offset, SEEK_SET))
1895 {
1896 return;
1897 }
1898
1899 if (istext && (b->charset || (state->flags & STATE_CHARCONV)))
1900 {
1901 const char *charset = b->charset;
1902 if (!charset)
1903 {
1904 const struct Slist *const c_assumed_charset = cs_subset_slist(NeoMutt->sub, "assumed_charset");
1905 charset = mutt_param_get(&b->parameter, "charset");
1906 if (!charset && c_assumed_charset)
1907 charset = mutt_ch_get_default_charset(c_assumed_charset);
1908 }
1909 const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
1910 if (charset && c_charset)
1911 cd = mutt_ch_iconv_open(c_charset, charset, MUTT_ICONV_HOOK_FROM);
1912 }
1913
1914 switch (b->encoding)
1915 {
1917 decode_quoted(state, b->length,
1918 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1920 cd);
1921 break;
1922 case ENC_BASE64:
1923 mutt_decode_base64(state, b->length,
1924 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1926 cd);
1927 break;
1928 case ENC_UUENCODED:
1929 decode_uuencoded(state, b->length,
1930 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1932 cd);
1933 break;
1934 default:
1935 decode_xbit(state, b->length,
1936 istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
1938 cd);
1939 break;
1940 }
1941
1942 if (cd != (iconv_t) (-1))
1943 iconv_close(cd);
1944}
const struct Slist * cs_subset_slist(const struct ConfigSubset *sub, const char *name)
Get a string-list config item by name.
Definition: helpers.c:268
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:708
static void decode_uuencoded(struct State *state, long len, bool istext, iconv_t cd)
Decode uuencoded text.
Definition: handler.c:365
void mutt_decode_base64(struct State *state, size_t len, bool istext, iconv_t cd)
Decode base64-encoded text.
Definition: handler.c:1520
static void decode_quoted(struct State *state, long len, bool istext, iconv_t cd)
Decode an attachment encoded with quoted-printable.
Definition: handler.c:301
static void decode_xbit(struct State *state, long len, bool istext, iconv_t cd)
Decode xbit-encoded text.
Definition: handler.c:162
@ 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:563
const char * mutt_ch_get_default_charset(const struct Slist *const assumed_charset)
Get the default character set.
Definition: charset.c:439
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
Definition: charset.h:72
#define STATE_CHARCONV
Do character set conversions.
Definition: state.h:36
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:436
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:78
String list.
Definition: slist.h:47
FILE * fp_in
File to read from.
Definition: state.h:48
+ 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 1520 of file handler.c.

1521{
1522 char buf[5] = { 0 };
1523 int ch, i;
1524 bool cr = false;
1525 char bufi[BUFI_SIZE] = { 0 };
1526 size_t l = 0;
1527
1528 buf[4] = '\0';
1529
1530 if (istext)
1531 state_set_prefix(state);
1532
1533 while (len > 0)
1534 {
1535 for (i = 0; (i < 4) && (len > 0); len--)
1536 {
1537 ch = fgetc(state->fp_in);
1538 if (ch == EOF)
1539 break;
1540 if ((ch >= 0) && (ch < 128) && ((base64val(ch) != -1) || (ch == '=')))
1541 buf[i++] = ch;
1542 }
1543 if (i != 4)
1544 {
1545 /* "i" may be zero if there is trailing whitespace, which is not an error */
1546 if (i != 0)
1547 mutt_debug(LL_DEBUG2, "didn't get a multiple of 4 chars\n");
1548 break;
1549 }
1550
1551 const int c1 = base64val(buf[0]);
1552 const int c2 = base64val(buf[1]);
1553
1554 /* first char */
1555 ch = (c1 << 2) | (c2 >> 4);
1556
1557 if (cr && (ch != '\n'))
1558 bufi[l++] = '\r';
1559
1560 cr = false;
1561
1562 if (istext && (ch == '\r'))
1563 cr = true;
1564 else
1565 bufi[l++] = ch;
1566
1567 /* second char */
1568 if (buf[2] == '=')
1569 break;
1570 const int c3 = base64val(buf[2]);
1571 ch = ((c2 & 0xf) << 4) | (c3 >> 2);
1572
1573 if (cr && (ch != '\n'))
1574 bufi[l++] = '\r';
1575
1576 cr = false;
1577
1578 if (istext && (ch == '\r'))
1579 cr = true;
1580 else
1581 bufi[l++] = ch;
1582
1583 /* third char */
1584 if (buf[3] == '=')
1585 break;
1586 const int c4 = base64val(buf[3]);
1587 ch = ((c3 & 0x3) << 6) | c4;
1588
1589 if (cr && (ch != '\n'))
1590 bufi[l++] = '\r';
1591
1592 cr = false;
1593
1594 if (istext && (ch == '\r'))
1595 cr = true;
1596 else
1597 bufi[l++] = ch;
1598
1599 if ((l + 8) >= sizeof(bufi))
1600 convert_to_state(cd, bufi, &l, state);
1601 }
1602
1603 if (cr)
1604 bufi[l++] = '\r';
1605
1606 convert_to_state(cd, bufi, &l, state);
1607 convert_to_state(cd, 0, 0, state);
1608
1609 state_reset_prefix(state);
1610}
#define base64val(ch)
Definition: base64.h:30
#define BUFI_SIZE
Definition: handler.c:61
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:113
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
#define state_set_prefix(state)
Definition: state.h:55
#define state_reset_prefix(state)
Definition: state.h:56
+ 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 1833 of file handler.c.

1834{
1835 if (!mutt_can_decode(b))
1836 return true;
1837
1838 if (b->disposition != DISP_ATTACH)
1839 return false;
1840
1841 return cs_subset_bool(NeoMutt->sub, "honor_disposition");
1842}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: