1652 |
#define isdelim(c) (isspace (c) || strchr (";<[(", c)) |
#define isdelim(c) (isspace (c) || strchr (";<[(", c)) |
1653 |
#define skipws(ptr) do { while (*ptr && isspace (*ptr)) ptr++; } while (0) |
#define skipws(ptr) do { while (*ptr && isspace (*ptr)) ptr++; } while (0) |
1654 |
|
|
|
/* cmd is: type "/" subtype |
|
|
0*(";" attribute "=" value) |
|
|
[ "(" comment ")" ] |
|
|
[ "<" id ">" ] |
|
|
[ "[" description "]" ] |
|
|
*/ |
|
1655 |
int |
int |
1656 |
parse_type_command (char **pcmd, struct compose_env *env, header_t hdr) |
parse_content_type (struct compose_env *env, |
1657 |
|
struct obstack *stk, char **prest, char **id, char **descr) |
1658 |
{ |
{ |
1659 |
int status = 0, stop = 0; |
int status = 0, stop = 0; |
1660 |
char *sp, c; |
char *rest = *prest; |
1661 |
char *type = NULL; |
char *sp; |
1662 |
char *subtype = NULL; |
char *comment = NULL; |
|
char *comment = NULL, *descr = NULL, *id = NULL; |
|
|
struct obstack stk; |
|
|
char *rest = *pcmd; |
|
|
|
|
|
skipws (rest); |
|
|
for (sp = rest; *sp && !isdelim (*sp); sp++) |
|
|
; |
|
|
c = *sp; |
|
|
*sp = 0; |
|
|
split_content (rest, &type, &subtype); |
|
|
*sp = c; |
|
|
rest = sp; |
|
|
|
|
|
if (!subtype) |
|
|
{ |
|
|
mh_error (_("%s:%lu: missing subtype"), |
|
|
input_file, |
|
|
(unsigned long) mhn_error_loc (env)); |
|
|
return 1; |
|
|
} |
|
|
|
|
|
obstack_init (&stk); |
|
|
obstack_grow (&stk, type, strlen (type)); |
|
|
obstack_1grow (&stk, '/'); |
|
|
obstack_grow (&stk, subtype, strlen (subtype)); |
|
1663 |
|
|
1664 |
while (stop == 0 && status == 0 && *rest) |
while (stop == 0 && status == 0 && *rest) |
1665 |
{ |
{ |
1678 |
break; |
break; |
1679 |
|
|
1680 |
case '[': |
case '[': |
1681 |
if (descr) |
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) |
1691 |
{ |
{ |
1692 |
mh_error (_("%s:%lu: description redefined"), |
mh_error (_("%s:%lu: description redefined"), |
1693 |
input_file, |
input_file, |
1695 |
status = 1; |
status = 1; |
1696 |
break; |
break; |
1697 |
} |
} |
1698 |
status = parse_brace (&descr, &rest, ']', env); |
status = parse_brace (descr, &rest, ']', env); |
1699 |
break; |
break; |
1700 |
|
|
1701 |
case '<': |
case '<': |
1702 |
if (id) |
if (*id) |
1703 |
{ |
{ |
1704 |
mh_error (_("%s:%lu: content id redefined"), |
mh_error (_("%s:%lu: content id redefined"), |
1705 |
input_file, |
input_file, |
1707 |
status = 1; |
status = 1; |
1708 |
break; |
break; |
1709 |
} |
} |
1710 |
status = parse_brace (&id, &rest, '>', env); |
status = parse_brace (id, &rest, '>', env); |
1711 |
break; |
break; |
1712 |
|
|
1713 |
case ';': |
case ';': |
1714 |
obstack_1grow (&stk, ';'); |
obstack_1grow (stk, ';'); |
1715 |
obstack_1grow (&stk, ' '); |
obstack_1grow (stk, ' '); |
1716 |
skipws (rest); |
skipws (rest); |
1717 |
sp = rest; |
sp = rest; |
1718 |
for (; *rest && !isspace (*rest) && *rest != '='; rest++) |
for (; *rest && !isspace (*rest) && *rest != '='; rest++) |
1719 |
obstack_1grow (&stk, *rest); |
obstack_1grow (stk, *rest); |
1720 |
skipws (rest); |
skipws (rest); |
1721 |
if (*rest != '=') |
if (*rest != '=') |
1722 |
{ |
{ |
1727 |
break; |
break; |
1728 |
} |
} |
1729 |
rest++; |
rest++; |
1730 |
obstack_1grow (&stk, '='); |
obstack_1grow (stk, '='); |
1731 |
skipws (rest); |
skipws (rest); |
1732 |
for (; *rest; rest++) |
for (; *rest; rest++) |
1733 |
{ |
{ |
1734 |
if (isdelim (*rest)) |
if (isdelim (*rest)) |
1735 |
break; |
break; |
1736 |
obstack_1grow (&stk, *rest); |
obstack_1grow (stk, *rest); |
1737 |
} |
} |
1738 |
break; |
break; |
1739 |
|
|
1747 |
|
|
1748 |
if (comment) |
if (comment) |
1749 |
{ |
{ |
1750 |
obstack_grow (&stk, " (", 2); |
obstack_grow (stk, " (", 2); |
1751 |
obstack_grow (&stk, comment, strlen (comment)); |
obstack_grow (stk, comment, strlen (comment)); |
1752 |
obstack_1grow (&stk, ')'); |
obstack_1grow (stk, ')'); |
1753 |
free (comment); |
free (comment); |
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 |
|
} |
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); |
1798 |
obstack_1grow (&stk, 0); |
obstack_1grow (&stk, 0); |
1799 |
|
|
1800 |
header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1); |
header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1); |
1801 |
obstack_free (&stk, NULL); |
obstack_free (&stk, NULL); |
1802 |
|
|
1837 |
*msg = NULL; |
*msg = NULL; |
1838 |
} |
} |
1839 |
|
|
1840 |
|
#define EXTCONTENT "message/external-body" |
1841 |
|
|
1842 |
int |
int |
1843 |
edit_extern (char *cmd, struct compose_env *env, message_t *msg, int level) |
edit_extern (char *cmd, struct compose_env *env, message_t *msg, int level) |
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); |
1894 |
return 0; |
return 0; |
1895 |
} |
} |
1896 |
|
|