Commit 1485ab7d 1485ab7d2666042b20b0caa64beb3ddfeb4577fe by Sergey Poznyakoff

mhn: fixes in compose mode.

* mh/mhn.c (edit_forw): Accept directives without explicit folder
spec.
Fix creation of individual mime parts; set Content-Type: message/rfc822
for each of them.
(mhn_edit): Fix some coredumps.
(main): Use -file argument, if it is given.
* mh/tests/atlocal.in (mimeflt): New function.
* mh/tests/mhn.at: Add tests for compose mode.
1 parent 3260bd74
......@@ -2223,15 +2223,14 @@ edit_extern (char *cmd, struct compose_env *env, mu_message_t *msg, int level)
int
edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
{
char *sp, *id = NULL, *descr = NULL;
char *id = NULL, *descr = NULL;
int stop = 0, status = 0;
size_t i;
size_t i, npart;
struct mu_wordsplit ws;
mu_header_t hdr;
mu_mime_t mime;
mu_message_t msg;
const char *val;
char *newval;
skipws (cmd);
while (stop == 0 && status == 0 && *cmd)
......@@ -2282,11 +2281,23 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
}
mu_mime_create (&mime, NULL, 0);
if (ws.ws_wordv[0][0] == '+')
{
mbox = mh_open_folder (ws.ws_wordv[0], 0);
i = 1;
}
else
{
mbox = mh_open_folder (mh_current_folder (), 0);
i = 0;
}
mbox = mh_open_folder (ws.ws_wordv[0], 0);
for (i = 1; i < ws.ws_wordc; i++)
for (npart = 1; i < ws.ws_wordc; i++, npart++)
{
mu_message_t input_msg;
mu_message_t input_msg, newmsg;
mu_body_t body;
mu_stream_t input_str, bstr;
char *endp;
size_t n = strtoul (ws.ws_wordv[i], &endp, 10);
......@@ -2308,9 +2319,47 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
return 1;
}
if ((status = mu_message_create_copy (&msg, input_msg)))
break;
mu_mime_add_part (mime, msg);
status = mu_message_get_streamref (input_msg, &input_str);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_streamref", NULL,
status);
exit (1);
}
status = mu_message_create (&newmsg, NULL);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_message_create", NULL, status);
exit (1);
}
status = mu_message_get_body (newmsg, &body);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_body", NULL,
status);
exit (1);
}
status = mu_body_get_streamref (body, &bstr);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_body_get_streamref", NULL,
status);
exit (1);
}
status = mu_stream_copy (bstr, input_str, 0, NULL);
if (status)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_copy", NULL,
status);
exit (1);
}
mu_stream_unref (bstr);
mu_stream_unref (input_str);
mu_message_get_header (newmsg, &hdr);
mu_header_set_value (hdr, MU_HEADER_CONTENT_TYPE, "message/rfc822", 1);
mu_mime_add_part (mime, newmsg);
}
mu_wordsplit_free (&ws);
......@@ -2319,16 +2368,23 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
mu_message_unref (*pmsg);
*pmsg = NULL;
}
mu_mime_get_message (mime, &msg);
mu_message_get_header (msg, &hdr);
mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &val);
sp = strchr (val, ';');
if (!sp)
abort ();
mu_asprintf (&newval, "multipart/digest%s", sp);
mu_header_set_value (hdr, MU_HEADER_CONTENT_TYPE, newval, 1);
free (newval);
if (npart > 2)
{
char *newval, *sp;
mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &val);
sp = strchr (val, ';');
if (sp)
{
mu_asprintf (&newval, "multipart/digest%s", sp);
mu_header_set_value (hdr, MU_HEADER_CONTENT_TYPE, newval, 1);
free (newval);
}
}
if (!id)
id = mh_create_message_id (env->subpart);
......@@ -2463,7 +2519,6 @@ mhn_edit (struct compose_env *env, int level)
int status = 0;
char *buf = NULL;
size_t bufsize = 0, n;
mu_body_t body;
mu_stream_t output = NULL;
mu_message_t msg = NULL;
size_t line_count = 0;
......@@ -2483,6 +2538,11 @@ mhn_edit (struct compose_env *env, int level)
/* Create new message */
mu_message_create (&msg, NULL);
mu_message_get_header (msg, &hdr);
}
if (!output)
{
mu_body_t body;
mu_message_get_body (msg, &body);
mu_body_get_streamref (body, &output);
line_count = 0;
......@@ -2841,7 +2901,7 @@ main (int argc, char **argv)
argv += index;
signal (SIGPIPE, SIG_IGN);
if (input_file)
{
if (argc)
......@@ -2849,9 +2909,9 @@ main (int argc, char **argv)
mu_error (_("extra arguments"));
return 1;
}
input_file = mh_expand_name (mu_folder_directory (),
argc == 1 ? argv[0] : "draft", 0);
message = mh_file_to_message (NULL, input_file);
message = mh_file_to_message (NULL,
mu_tilde_expansion (input_file,
"/", NULL));
if (!message)
return 1;
}
......
......@@ -6,3 +6,34 @@ PATH=@abs_builddir@:@abs_top_builddir@/mh:$top_srcdir:$srcdir:$PATH
remove_curdir() {
sed "s|$curdir/*||;s| *$||" $*
}
# mimeflt [FILE]
# Filter out all variable information from a MIME message in FILE.
# If FILE is not given, filter stdin.
# "Variable information" means part boundary and Content-ID header values.
# These elements are likely to change between invocations of mhn -build.
mimeflt() {
awk '
/^Content-Type:/ {
if (match($0, /boundary=".*"/)) {
s=substr($0,RSTART+10,RLENGTH-11)
boundary[++boundary_num] = s
sub(/boundary=".*"/,"boundary=\"BOUNDARY-" boundary_num "\"")
}
}
/^X-IMAPbase:/ { next }
/^Content-ID:/ {
content_id[$2]++
print "Content-ID:", ++content_id_num
next
}
{
if ($0 == ("--" boundary[boundary_num])) {
print "--BOUNDARY-" boundary_num
} else if ($0 == ("--" boundary[boundary_num] "--")) {
print "--BOUNDARY-" boundary_num "--"
boundary_num--
} else
print
}
' $*
}
......
......@@ -412,6 +412,615 @@ part 2 application/x-tar 13835
-rw-r--r-- gray/staff 937 2010-11-29 13:58 Jabberwocky
])
dnl -------------------------------------------------------------------
dnl 4. Compose mode
dnl -------------------------------------------------------------------
MH_CHECK([mhn-compose: adjacent plain text],
[mhn17 mhn-compose mhn-compose-01],[
AT_DATA([input],
[From: gray@example.net
Subject: Adjacent plain text contexts
------
this is the first content
#
and this is the second
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Adjacent plain text contexts
Content-Type: multipart/mixed; boundary="BOUNDARY-1"
MIME-Version: 1.0
--BOUNDARY-1
Content-ID: 1
Content-Type: text/plain
this is the first content
--BOUNDARY-1
Content-ID: 2
Content-Type: text/plain
and this is the second
--BOUNDARY-1--
])
MH_CHECK([mhn-compose: plain text content types],
[mhn18 mhn-compose mhn-compose-02],[
AT_DATA([input],
[From: gray@example.net
Subject: Plaintext content types
------
#<text/enriched [First part]
this content will be tagged as text/enriched
#
and this content will be tagged as text/plain
#
#<application/x-patch [this is a patch]
and this content will be tagged as application/x-patch
])
mhn -build -file ./input||exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Plaintext content types
Content-Type: multipart/mixed; boundary="BOUNDARY-1"
MIME-Version: 1.0
--BOUNDARY-1
Content-Description: First part
Content-ID: 1
Content-Type: text/enriched
this content will be tagged as text/enriched
--BOUNDARY-1
Content-ID: 2
Content-Type: text/plain
and this content will be tagged as text/plain
--BOUNDARY-1
Content-Description: this is a patch
Content-ID: 3
Content-Type: application/x-patch
and this content will be tagged as application/x-patch
--BOUNDARY-1--
])
MH_CHECK([mhn-compose: sharp at the beginning of a line],
[mhn19 mhn-compose mhn-compose-03],[
AT_DATA([input],
[From: gray@example.net
Subject: Sharp at the beginning of a line
------
##when sent, this line will start with only one #
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Sharp at the beginning of a line
Content-Type: text/plain
MIME-Version: 1.0
#when sent, this line will start with only one #
])
MH_CHECK([mhn-compose: charset],
[mhn20 mhn-compose mhn-compose-04],[
AT_DATA([input],
[From: gray@example.net
Subject: Charset
------
#<text/plain; charset=utf-8
Cześć
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Charset
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=utf-8
MIME-Version: 1.0
Cze=C5=9B=C4=87
])
MH_CHECK([mhn-compose: forward],
[mhn21 mhn-compose mhn-compose-05],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
AT_DATA([input],
[From: gray@example.net
Subject: Forwards
------
#forw [forwarded messages] +inbox 1 2 5
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Forwards
Content-Description: forwarded messages
Content-Type: multipart/digest; boundary="BOUNDARY-1"
MIME-Version: 1.0
--BOUNDARY-1
Content-Type: message/rfc822
Received: (from foobar@nonexistent.net)
by nonexistent.net id fBSKI8N04906
for bar@dontmailme.org; Fri, 28 Dec 2001 22:18:08 +0200
Date: Fri, 28 Dec 2001 22:18:08 +0200
From: Foo Bar <foobar@nonexistent.net>
Message-Id: <200112282018.fBSKI8N04906@nonexistent.net>
To: Bar <bar@dontmailme.org>
Subject: Jabberwocky
X-Envelope-Date: Fri Dec 28 22:18:09 2001
X-Envelope-Sender: foobar@nonexistent.net
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
`Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jujub bird, and shun
The frumious Bandersnatch!'
He took his vorpal sword in hand:
Long time the manxome foe he sought --
So rested he by the Tumtum gree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wook,
And burbled as it came!
One, two! One, two! And through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
`And has thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Calloh! Callay!
He chortled in his joy.
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
--BOUNDARY-1
Content-Type: message/rfc822
Received: (from bar@dontmailme.org)
by dontmailme.org id fERKR9N16790
for foobar@nonexistent.net; Fri, 28 Dec 2001 22:18:08 +0200
Date: Fri, 28 Dec 2001 23:28:08 +0200
From: Bar <bar@dontmailme.org>
To: Foo Bar <foobar@nonexistent.net>
Message-Id: <200112232808.fERKR9N16790@dontmailme.org>
Subject: Re: Jabberwocky
X-Envelope-Date: Fri Dec 28 23:28:09 2001
X-Envelope-Sender: bar@dontmailme.org
It seems very pretty, but it's *rather* hard to understand!'
Somehow it seems to fill my head with ideas -- only I don't
exactly know what they are! However, SOMEBODY killed SOMETHING:
that's clear, at any rate...
--BOUNDARY-1
Content-Type: message/rfc822
Organization: Mailutils-tests
Received: from example.net (localhost [[127.0.0.1]])
by example.net with ESMTP id g6CLhIb05086
for <gray@example.net>; Sat, 13 Jul 2002 00:43:18 +0300
Message-Id: <200207122143.g6CLhIb05086@example.net>
To: Foo Bar <foobar@nonexistent.net>
Subject: Empty MIME Parts
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY-2"
Content-ID: 1
Date: Sat, 13 Jul 2002 00:43:18 +0300
From: Sergey Poznyakoff <gray@example.net>
X-Envelope-Date: Sat Jul 13 00:43:18 2002
X-Envelope-Sender: gray@example.net
--BOUNDARY-2
Content-Type: text/plain; name="empty"; charset="us-ascii"
Content-ID: 2
Content-Description: Empty part
--BOUNDARY-2
Content-Type: text/plain; name="single.line"; charset="us-ascii"
Content-ID: 3
Content-Description: Single line part
--BOUNDARY-2--
--BOUNDARY-1--
])
MH_CHECK([mhn-compose: forward (current folder)],
[mhn22 mhn-compose mhn-compose-06],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
echo "Current-Folder: inbox" > Mail/context
AT_DATA([input],
[From: gray@example.net
Subject: Forwards
------
#forw [forwarded messages] 1 2 5
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Forwards
Content-Description: forwarded messages
Content-Type: multipart/digest; boundary="BOUNDARY-1"
MIME-Version: 1.0
--BOUNDARY-1
Content-Type: message/rfc822
Received: (from foobar@nonexistent.net)
by nonexistent.net id fBSKI8N04906
for bar@dontmailme.org; Fri, 28 Dec 2001 22:18:08 +0200
Date: Fri, 28 Dec 2001 22:18:08 +0200
From: Foo Bar <foobar@nonexistent.net>
Message-Id: <200112282018.fBSKI8N04906@nonexistent.net>
To: Bar <bar@dontmailme.org>
Subject: Jabberwocky
X-Envelope-Date: Fri Dec 28 22:18:09 2001
X-Envelope-Sender: foobar@nonexistent.net
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
`Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jujub bird, and shun
The frumious Bandersnatch!'
He took his vorpal sword in hand:
Long time the manxome foe he sought --
So rested he by the Tumtum gree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wook,
And burbled as it came!
One, two! One, two! And through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
`And has thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Calloh! Callay!
He chortled in his joy.
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
--BOUNDARY-1
Content-Type: message/rfc822
Received: (from bar@dontmailme.org)
by dontmailme.org id fERKR9N16790
for foobar@nonexistent.net; Fri, 28 Dec 2001 22:18:08 +0200
Date: Fri, 28 Dec 2001 23:28:08 +0200
From: Bar <bar@dontmailme.org>
To: Foo Bar <foobar@nonexistent.net>
Message-Id: <200112232808.fERKR9N16790@dontmailme.org>
Subject: Re: Jabberwocky
X-Envelope-Date: Fri Dec 28 23:28:09 2001
X-Envelope-Sender: bar@dontmailme.org
It seems very pretty, but it's *rather* hard to understand!'
Somehow it seems to fill my head with ideas -- only I don't
exactly know what they are! However, SOMEBODY killed SOMETHING:
that's clear, at any rate...
--BOUNDARY-1
Content-Type: message/rfc822
Organization: Mailutils-tests
Received: from example.net (localhost [[127.0.0.1]])
by example.net with ESMTP id g6CLhIb05086
for <gray@example.net>; Sat, 13 Jul 2002 00:43:18 +0300
Message-Id: <200207122143.g6CLhIb05086@example.net>
To: Foo Bar <foobar@nonexistent.net>
Subject: Empty MIME Parts
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY-2"
Content-ID: 1
Date: Sat, 13 Jul 2002 00:43:18 +0300
From: Sergey Poznyakoff <gray@example.net>
X-Envelope-Date: Sat Jul 13 00:43:18 2002
X-Envelope-Sender: gray@example.net
--BOUNDARY-2
Content-Type: text/plain; name="empty"; charset="us-ascii"
Content-ID: 2
Content-Description: Empty part
--BOUNDARY-2
Content-Type: text/plain; name="single.line"; charset="us-ascii"
Content-ID: 3
Content-Description: Single line part
--BOUNDARY-2--
--BOUNDARY-1--
])
MH_CHECK([mhn-compose: forward (single message)],
[mhn23 mhn-compose mhn-compose-07],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
AT_DATA([input],
[From: gray@example.net
Subject: Forwards
------
#forw [forwarded messages] +inbox 1
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Forwards
Content-Description: forwarded messages
Content-Type: message/rfc822
MIME-Version: 1.0
Received: (from foobar@nonexistent.net)
by nonexistent.net id fBSKI8N04906
for bar@dontmailme.org; Fri, 28 Dec 2001 22:18:08 +0200
Date: Fri, 28 Dec 2001 22:18:08 +0200
From: Foo Bar <foobar@nonexistent.net>
Message-Id: <200112282018.fBSKI8N04906@nonexistent.net>
To: Bar <bar@dontmailme.org>
Subject: Jabberwocky
X-Envelope-Date: Fri Dec 28 22:18:09 2001
X-Envelope-Sender: foobar@nonexistent.net
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
`Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jujub bird, and shun
The frumious Bandersnatch!'
He took his vorpal sword in hand:
Long time the manxome foe he sought --
So rested he by the Tumtum gree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wook,
And burbled as it came!
One, two! One, two! And through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
`And has thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Calloh! Callay!
He chortled in his joy.
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
])
MH_CHECK([mhn-compose: external data],
[mhn24 mhn-compose mhn-compose-08],[
AT_DATA([input],
[From: gray@example.net
Subject: External data
------
#@application/octet-stream; \
type=tar; \
conversions=compress \
[[GNU Mailutils distribution]] \
name="mailutils-3.0.tar.gz"; \
directory="/gnu/mailutils"; \
site="ftp.gnu.org"; \
access-type=anon-ftp; \
mode="image"
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: External data
Content-Type: message/external-body; name="mailutils-3.0.tar.gz"; directory="/gnu/mailutils"; site="ftp.gnu.org"; access-type=anon-ftp; mode="image"
MIME-Version: 1.0
Content-Description: GNU Mailutils distribution
Content-ID: 1
Content-Type: application/octet-stream; type=tar; conversions=compress
])
MH_CHECK([mhn-compose: multipart],
[mhn25 mhn-compose mhn-compose-09],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail])
AT_DATA([foo.tar],
[Not a tarball, really
])
AT_DATA([input],
[From: gray@example.net
Subject: Multipart
------
Initial text part.
#begin [Multipart message] mixed
#forw [forwarded message] +mbox1 1
Plain text 1
#<text/x-special
Plain text 2
#application/octet-stream; type=tar [Tar archive] ./foo.tar
#end
])
mhn -build ./input || exit $?
mimeflt input
],
[0],
[From: gray@example.net
Subject: Multipart
Content-Type: multipart/mixed; boundary="BOUNDARY-1"
MIME-Version: 1.0
--BOUNDARY-1
Content-ID: 1
Content-Type: text/plain
Initial text part.
--BOUNDARY-1
Content-Type: multipart/mixed; boundary="BOUNDARY-2"
MIME-Version: 1.0
--BOUNDARY-2
Content-Description: forwarded message
Content-ID: 2
Content-Type: message/rfc822
MIME-Version: 1.0
Received: (from foobar@nonexistent.net)
by nonexistent.net id fBSKI8N04906
for bar@dontmailme.org; Fri, 28 Dec 2001 22:18:08 +0200
Date: Fri, 28 Dec 2001 22:18:08 +0200
From: Foo Bar <foobar@nonexistent.net>
Message-Id: <200112282018.fBSKI8N04906@nonexistent.net>
To: Bar <bar@dontmailme.org>
Subject: Jabberwocky
X-Envelope-Date: Fri Dec 28 22:18:09 2001
X-Envelope-Sender: foobar@nonexistent.net
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
`Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jujub bird, and shun
The frumious Bandersnatch!'
He took his vorpal sword in hand:
Long time the manxome foe he sought --
So rested he by the Tumtum gree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wook,
And burbled as it came!
One, two! One, two! And through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
`And has thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Calloh! Callay!
He chortled in his joy.
`Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
--BOUNDARY-2
Content-ID: 3
Content-Type: text/plain
Plain text 1
--BOUNDARY-2
Content-ID: 4
Content-Type: text/x-special
Plain text 2
--BOUNDARY-2
Content-Transfer-Encoding: base64
Content-Description: Tar archive
Content-ID: 5
Content-Type: application/octet-stream; type=tar
Tm90IGEgdGFyYmFsbCwgcmVhbGx5Cg==
--BOUNDARY-2--
--BOUNDARY-1--
])
m4_popdef[MH_KEYWORDS])
# End of mhn.at
# Local Variables:
# coding: utf-8
# End:
......