Implemented external-body.
Showing
1 changed file
with
120 additions
and
47 deletions
... | @@ -1652,44 +1652,14 @@ parse_brace (char **pval, char **cmd, int c, struct compose_env *env) | ... | @@ -1652,44 +1652,14 @@ parse_brace (char **pval, char **cmd, int c, struct compose_env *env) |
1652 | #define isdelim(c) (isspace (c) || strchr (";<[(", c)) | 1652 | #define isdelim(c) (isspace (c) || strchr (";<[(", c)) |
1653 | #define skipws(ptr) do { while (*ptr && isspace (*ptr)) ptr++; } while (0) | 1653 | #define skipws(ptr) do { while (*ptr && isspace (*ptr)) ptr++; } while (0) |
1654 | 1654 | ||
1655 | /* cmd is: type "/" subtype | ||
1656 | 0*(";" attribute "=" value) | ||
1657 | [ "(" comment ")" ] | ||
1658 | [ "<" id ">" ] | ||
1659 | [ "[" description "]" ] | ||
1660 | */ | ||
1661 | int | 1655 | int |
1662 | parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | 1656 | parse_content_type (struct compose_env *env, |
1657 | struct obstack *stk, char **prest, char **id, char **descr) | ||
1663 | { | 1658 | { |
1664 | int status = 0, stop = 0; | 1659 | int status = 0, stop = 0; |
1665 | char *sp, c; | 1660 | char *rest = *prest; |
1666 | char *type = NULL; | 1661 | char *sp; |
1667 | char *subtype = NULL; | 1662 | char *comment = NULL; |
1668 | char *comment = NULL, *descr = NULL, *id = NULL; | ||
1669 | struct obstack stk; | ||
1670 | char *rest = *pcmd; | ||
1671 | |||
1672 | skipws (rest); | ||
1673 | for (sp = rest; *sp && !isdelim (*sp); sp++) | ||
1674 | ; | ||
1675 | c = *sp; | ||
1676 | *sp = 0; | ||
1677 | split_content (rest, &type, &subtype); | ||
1678 | *sp = c; | ||
1679 | rest = sp; | ||
1680 | |||
1681 | if (!subtype) | ||
1682 | { | ||
1683 | mh_error (_("%s:%lu: missing subtype"), | ||
1684 | input_file, | ||
1685 | (unsigned long) mhn_error_loc (env)); | ||
1686 | return 1; | ||
1687 | } | ||
1688 | |||
1689 | obstack_init (&stk); | ||
1690 | obstack_grow (&stk, type, strlen (type)); | ||
1691 | obstack_1grow (&stk, '/'); | ||
1692 | obstack_grow (&stk, subtype, strlen (subtype)); | ||
1693 | 1663 | ||
1694 | while (stop == 0 && status == 0 && *rest) | 1664 | while (stop == 0 && status == 0 && *rest) |
1695 | { | 1665 | { |
... | @@ -1708,7 +1678,16 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | ... | @@ -1708,7 +1678,16 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) |
1708 | break; | 1678 | break; |
1709 | 1679 | ||
1710 | case '[': | 1680 | case '[': |
1711 | if (descr) | 1681 | if (!descr) |
1682 | { | ||
1683 | mh_error (_("%s:%lu: syntax error"), | ||
1684 | input_file, | ||
1685 | (unsigned long) mhn_error_loc (env)); | ||
1686 | status = 1; | ||
1687 | break; | ||
1688 | } | ||
1689 | |||
1690 | if (*descr) | ||
1712 | { | 1691 | { |
1713 | mh_error (_("%s:%lu: description redefined"), | 1692 | mh_error (_("%s:%lu: description redefined"), |
1714 | input_file, | 1693 | input_file, |
... | @@ -1716,11 +1695,11 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | ... | @@ -1716,11 +1695,11 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) |
1716 | status = 1; | 1695 | status = 1; |
1717 | break; | 1696 | break; |
1718 | } | 1697 | } |
1719 | status = parse_brace (&descr, &rest, ']', env); | 1698 | status = parse_brace (descr, &rest, ']', env); |
1720 | break; | 1699 | break; |
1721 | 1700 | ||
1722 | case '<': | 1701 | case '<': |
1723 | if (id) | 1702 | if (*id) |
1724 | { | 1703 | { |
1725 | mh_error (_("%s:%lu: content id redefined"), | 1704 | mh_error (_("%s:%lu: content id redefined"), |
1726 | input_file, | 1705 | input_file, |
... | @@ -1728,16 +1707,16 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | ... | @@ -1728,16 +1707,16 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) |
1728 | status = 1; | 1707 | status = 1; |
1729 | break; | 1708 | break; |
1730 | } | 1709 | } |
1731 | status = parse_brace (&id, &rest, '>', env); | 1710 | status = parse_brace (id, &rest, '>', env); |
1732 | break; | 1711 | break; |
1733 | 1712 | ||
1734 | case ';': | 1713 | case ';': |
1735 | obstack_1grow (&stk, ';'); | 1714 | obstack_1grow (stk, ';'); |
1736 | obstack_1grow (&stk, ' '); | 1715 | obstack_1grow (stk, ' '); |
1737 | skipws (rest); | 1716 | skipws (rest); |
1738 | sp = rest; | 1717 | sp = rest; |
1739 | for (; *rest && !isspace (*rest) && *rest != '='; rest++) | 1718 | for (; *rest && !isspace (*rest) && *rest != '='; rest++) |
1740 | obstack_1grow (&stk, *rest); | 1719 | obstack_1grow (stk, *rest); |
1741 | skipws (rest); | 1720 | skipws (rest); |
1742 | if (*rest != '=') | 1721 | if (*rest != '=') |
1743 | { | 1722 | { |
... | @@ -1748,13 +1727,13 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | ... | @@ -1748,13 +1727,13 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) |
1748 | break; | 1727 | break; |
1749 | } | 1728 | } |
1750 | rest++; | 1729 | rest++; |
1751 | obstack_1grow (&stk, '='); | 1730 | obstack_1grow (stk, '='); |
1752 | skipws (rest); | 1731 | skipws (rest); |
1753 | for (; *rest; rest++) | 1732 | for (; *rest; rest++) |
1754 | { | 1733 | { |
1755 | if (isdelim (*rest)) | 1734 | if (isdelim (*rest)) |
1756 | break; | 1735 | break; |
1757 | obstack_1grow (&stk, *rest); | 1736 | obstack_1grow (stk, *rest); |
1758 | } | 1737 | } |
1759 | break; | 1738 | break; |
1760 | 1739 | ||
... | @@ -1768,13 +1747,56 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | ... | @@ -1768,13 +1747,56 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) |
1768 | 1747 | ||
1769 | if (comment) | 1748 | if (comment) |
1770 | { | 1749 | { |
1771 | obstack_grow (&stk, " (", 2); | 1750 | obstack_grow (stk, " (", 2); |
1772 | obstack_grow (&stk, comment, strlen (comment)); | 1751 | obstack_grow (stk, comment, strlen (comment)); |
1773 | obstack_1grow (&stk, ')'); | 1752 | obstack_1grow (stk, ')'); |
1774 | free (comment); | 1753 | free (comment); |
1775 | } | 1754 | } |
1755 | *prest = rest; | ||
1756 | return status; | ||
1757 | } | ||
1758 | |||
1759 | /* cmd is: type "/" subtype | ||
1760 | 0*(";" attribute "=" value) | ||
1761 | [ "(" comment ")" ] | ||
1762 | [ "<" id ">" ] | ||
1763 | [ "[" description "]" ] | ||
1764 | */ | ||
1765 | int | ||
1766 | parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) | ||
1767 | { | ||
1768 | int status = 0; | ||
1769 | char *sp, c; | ||
1770 | char *type = NULL; | ||
1771 | char *subtype = NULL; | ||
1772 | char *descr = NULL, *id = NULL; | ||
1773 | struct obstack stk; | ||
1774 | char *rest = *pcmd; | ||
1775 | |||
1776 | skipws (rest); | ||
1777 | for (sp = rest; *sp && !isdelim (*sp); sp++) | ||
1778 | ; | ||
1779 | c = *sp; | ||
1780 | *sp = 0; | ||
1781 | split_content (rest, &type, &subtype); | ||
1782 | *sp = c; | ||
1783 | rest = sp; | ||
1784 | |||
1785 | if (!subtype) | ||
1786 | { | ||
1787 | mh_error (_("%s:%lu: missing subtype"), | ||
1788 | input_file, | ||
1789 | (unsigned long) mhn_error_loc (env)); | ||
1790 | return 1; | ||
1791 | } | ||
1776 | 1792 | ||
1793 | obstack_init (&stk); | ||
1794 | obstack_grow (&stk, type, strlen (type)); | ||
1795 | obstack_1grow (&stk, '/'); | ||
1796 | obstack_grow (&stk, subtype, strlen (subtype)); | ||
1797 | status = parse_content_type (env, &stk, &rest, &id, &descr); | ||
1777 | obstack_1grow (&stk, 0); | 1798 | obstack_1grow (&stk, 0); |
1799 | |||
1778 | header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1); | 1800 | header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1); |
1779 | obstack_free (&stk, NULL); | 1801 | obstack_free (&stk, NULL); |
1780 | 1802 | ||
... | @@ -1815,9 +1837,60 @@ finish_msg (struct compose_env *env, message_t *msg) | ... | @@ -1815,9 +1837,60 @@ finish_msg (struct compose_env *env, message_t *msg) |
1815 | *msg = NULL; | 1837 | *msg = NULL; |
1816 | } | 1838 | } |
1817 | 1839 | ||
1840 | #define EXTCONTENT "message/external-body" | ||
1841 | |||
1818 | int | 1842 | int |
1819 | edit_extern (char *cmd, struct compose_env *env, message_t *msg, int level) | 1843 | edit_extern (char *cmd, struct compose_env *env, message_t *msg, int level) |
1820 | { | 1844 | { |
1845 | int rc; | ||
1846 | char *rest; | ||
1847 | char *id = NULL; | ||
1848 | header_t hdr, hdr2; | ||
1849 | body_t body; | ||
1850 | stream_t in, out = NULL; | ||
1851 | struct obstack stk; | ||
1852 | |||
1853 | if (!*msg) | ||
1854 | message_create (msg, NULL); | ||
1855 | |||
1856 | if ((rc = header_create (&hdr2, NULL, 0, NULL)) != 0) | ||
1857 | { | ||
1858 | mh_error (_("cannot create header: %s"), | ||
1859 | mu_strerror (rc)); | ||
1860 | return 1; | ||
1861 | } | ||
1862 | |||
1863 | rest = cmd; | ||
1864 | rc = parse_type_command (&rest, env, hdr2); | ||
1865 | |||
1866 | message_get_header (*msg, &hdr); | ||
1867 | |||
1868 | obstack_init (&stk); | ||
1869 | obstack_grow (&stk, EXTCONTENT, sizeof (EXTCONTENT) - 1); | ||
1870 | *--rest = ';'; /* FIXME */ | ||
1871 | rc = parse_content_type (env, &stk, &rest, &id, NULL); | ||
1872 | obstack_1grow (&stk, 0); | ||
1873 | header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1); | ||
1874 | obstack_free (&stk, NULL); | ||
1875 | if (rc) | ||
1876 | return 1; | ||
1877 | |||
1878 | message_get_body (*msg, &body); | ||
1879 | body_get_stream (body, &out); | ||
1880 | stream_seek (out, 0, SEEK_SET); | ||
1881 | |||
1882 | if (!id) | ||
1883 | id = mh_create_message_id (env->subpart); | ||
1884 | header_set_value (hdr2, MU_HEADER_CONTENT_ID, id, 1); | ||
1885 | free (id); | ||
1886 | |||
1887 | header_get_stream (hdr2, &in); | ||
1888 | stream_seek (in, 0, SEEK_SET); | ||
1889 | cat_message (out, in); | ||
1890 | stream_close (out); | ||
1891 | header_destroy (&hdr2, header_get_owner (hdr2)); | ||
1892 | |||
1893 | finish_msg (env, msg); | ||
1821 | return 0; | 1894 | return 0; |
1822 | } | 1895 | } |
1823 | 1896 | ... | ... |
-
Please register or sign in to post a comment