summaryrefslogtreecommitdiff
path: root/mh/mhn.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2003-03-23 22:47:20 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2003-03-23 22:47:20 +0000
commitfcadaeef1c45828497e7a3a77fc1cd48dbe467d3 (patch)
tree17ea134ed2cadf37b7caf3629686360c593cd789 /mh/mhn.c
parent45ce2c0941ff716b1d8e3b16bf9eff4aac4f1a87 (diff)
downloadmailutils-fcadaeef1c45828497e7a3a77fc1cd48dbe467d3.tar.gz
mailutils-fcadaeef1c45828497e7a3a77fc1cd48dbe467d3.tar.bz2
Implemented external-body.
Diffstat (limited to 'mh/mhn.c')
-rw-r--r--mh/mhn.c169
1 files changed, 121 insertions, 48 deletions
diff --git a/mh/mhn.c b/mh/mhn.c
index d7bd25218..6903871e2 100644
--- a/mh/mhn.c
+++ b/mh/mhn.c
@@ -1652,44 +1652,14 @@ parse_brace (char **pval, char **cmd, int c, struct compose_env *env)
#define isdelim(c) (isspace (c) || strchr (";<[(", c))
#define skipws(ptr) do { while (*ptr && isspace (*ptr)) ptr++; } while (0)
-/* cmd is: type "/" subtype
- 0*(";" attribute "=" value)
- [ "(" comment ")" ]
- [ "<" id ">" ]
- [ "[" description "]" ]
-*/
int
-parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
+parse_content_type (struct compose_env *env,
+ struct obstack *stk, char **prest, char **id, char **descr)
{
int status = 0, stop = 0;
- char *sp, c;
- char *type = NULL;
- char *subtype = 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));
+ char *rest = *prest;
+ char *sp;
+ char *comment = NULL;
while (stop == 0 && status == 0 && *rest)
{
@@ -1708,7 +1678,16 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
break;
case '[':
- if (descr)
+ if (!descr)
+ {
+ mh_error (_("%s:%lu: syntax error"),
+ input_file,
+ (unsigned long) mhn_error_loc (env));
+ status = 1;
+ break;
+ }
+
+ if (*descr)
{
mh_error (_("%s:%lu: description redefined"),
input_file,
@@ -1716,11 +1695,11 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
status = 1;
break;
}
- status = parse_brace (&descr, &rest, ']', env);
+ status = parse_brace (descr, &rest, ']', env);
break;
case '<':
- if (id)
+ if (*id)
{
mh_error (_("%s:%lu: content id redefined"),
input_file,
@@ -1728,16 +1707,16 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
status = 1;
break;
}
- status = parse_brace (&id, &rest, '>', env);
+ status = parse_brace (id, &rest, '>', env);
break;
case ';':
- obstack_1grow (&stk, ';');
- obstack_1grow (&stk, ' ');
+ obstack_1grow (stk, ';');
+ obstack_1grow (stk, ' ');
skipws (rest);
sp = rest;
for (; *rest && !isspace (*rest) && *rest != '='; rest++)
- obstack_1grow (&stk, *rest);
+ obstack_1grow (stk, *rest);
skipws (rest);
if (*rest != '=')
{
@@ -1748,13 +1727,13 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
break;
}
rest++;
- obstack_1grow (&stk, '=');
+ obstack_1grow (stk, '=');
skipws (rest);
for (; *rest; rest++)
{
if (isdelim (*rest))
break;
- obstack_1grow (&stk, *rest);
+ obstack_1grow (stk, *rest);
}
break;
@@ -1768,13 +1747,56 @@ parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
if (comment)
{
- obstack_grow (&stk, " (", 2);
- obstack_grow (&stk, comment, strlen (comment));
- obstack_1grow (&stk, ')');
+ obstack_grow (stk, " (", 2);
+ obstack_grow (stk, comment, strlen (comment));
+ obstack_1grow (stk, ')');
free (comment);
}
-
+ *prest = rest;
+ return status;
+}
+
+/* cmd is: type "/" subtype
+ 0*(";" attribute "=" value)
+ [ "(" comment ")" ]
+ [ "<" id ">" ]
+ [ "[" description "]" ]
+*/
+int
+parse_type_command (char **pcmd, struct compose_env *env, header_t hdr)
+{
+ int status = 0;
+ char *sp, c;
+ char *type = NULL;
+ char *subtype = NULL;
+ char *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));
+ status = parse_content_type (env, &stk, &rest, &id, &descr);
obstack_1grow (&stk, 0);
+
header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1);
obstack_free (&stk, NULL);
@@ -1815,9 +1837,60 @@ finish_msg (struct compose_env *env, message_t *msg)
*msg = NULL;
}
+#define EXTCONTENT "message/external-body"
+
int
edit_extern (char *cmd, struct compose_env *env, message_t *msg, int level)
{
+ int rc;
+ char *rest;
+ char *id = NULL;
+ header_t hdr, hdr2;
+ body_t body;
+ stream_t in, out = NULL;
+ struct obstack stk;
+
+ if (!*msg)
+ message_create (msg, NULL);
+
+ if ((rc = header_create (&hdr2, NULL, 0, NULL)) != 0)
+ {
+ mh_error (_("cannot create header: %s"),
+ mu_strerror (rc));
+ return 1;
+ }
+
+ rest = cmd;
+ rc = parse_type_command (&rest, env, hdr2);
+
+ message_get_header (*msg, &hdr);
+
+ obstack_init (&stk);
+ obstack_grow (&stk, EXTCONTENT, sizeof (EXTCONTENT) - 1);
+ *--rest = ';'; /* FIXME */
+ rc = parse_content_type (env, &stk, &rest, &id, NULL);
+ obstack_1grow (&stk, 0);
+ header_set_value (hdr, MU_HEADER_CONTENT_TYPE, obstack_finish (&stk), 1);
+ obstack_free (&stk, NULL);
+ if (rc)
+ return 1;
+
+ message_get_body (*msg, &body);
+ body_get_stream (body, &out);
+ stream_seek (out, 0, SEEK_SET);
+
+ if (!id)
+ id = mh_create_message_id (env->subpart);
+ header_set_value (hdr2, MU_HEADER_CONTENT_ID, id, 1);
+ free (id);
+
+ header_get_stream (hdr2, &in);
+ stream_seek (in, 0, SEEK_SET);
+ cat_message (out, in);
+ stream_close (out);
+ header_destroy (&hdr2, header_get_owner (hdr2));
+
+ finish_msg (env, msg);
return 0;
}

Return to:

Send suggestions and report system problems to the System administrator.