Re: mutt/2110: decode-copy decode-save create empty parts / messages in case of decoding errors
* Wed Oct 12 2005 Derek Martin <invalid@xxxxxxxxxxxxxx>
> On Tue, Oct 11, 2005 at 02:15:02AM +0200, TAKAHASHI Tamotsu wrote:
> > > Nontheless a message with an empty body is copied/saved.
> >
> > True.
> > While decode-copying, mutt tries to decrypt the message *after*
> > copying the header. So, only the header is left even if aborted.
> > Hmmm...
>
> It strikes me that the "right" behavior is for mutt to attempt the
> decode first, writing the results to a temporary file. If and only if
> this succeeds, mutt should begin to write the new message,
> concatenating the first temporary file with the rest of the message as
> appropriate.
Here is a patch.
But, as usual, more than one bugs per line are expected. ;)
> In cases where there are multiple encrypted parts (unusual but
> possible), I think the right thing to do is attempt to decrypt all of
> the encrypted parts first, and ask the user how to proceed if any of
> them fails.
Sounds good, but beyond my ability.
--
tamo
diff -r 4c45a538cc33 copy.c
--- a/copy.c Tue Oct 11 07:04:24 2005
+++ b/copy.c Fri Oct 14 20:19:28 2005
@@ -766,17 +766,46 @@
char buf[STRING];
MESSAGE *msg;
int r;
+ char tmpfname[_POSIX_PATH_MAX];
+ FILE *tmpfp = NULL;
fseek(fpin, hdr->offset, 0);
if (fgets (buf, sizeof (buf), fpin) == NULL)
return -1;
- if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0
: M_ADD_FROM)) == NULL)
- return -1;
if (dest->magic == M_MBOX || dest->magic == M_MMDF)
chflags |= CH_FROM | CH_FORCE_FROM;
chflags |= (dest->magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE);
- r = _mutt_copy_message (msg->fp, fpin, hdr, body, flags, chflags);
+
+ /* copy to a temporary file because decryption can fail */
+ mutt_mktemp (tmpfname);
+ if ((tmpfp = safe_fopen (tmpfname, "w+")) == NULL)
+ {
+ mutt_perror (tmpfname);
+ return -1;
+ }
+ if ((r = _mutt_copy_message (tmpfp, fpin, hdr, body, flags, chflags)) != 0)
+ {
+ if (tmpfp)
+ {
+ safe_fclose (&tmpfp);
+ mutt_unlink (tmpfname);
+ }
+ return r;
+ }
+ fflush (tmpfp);
+
+ /* actually copy to the dest */
+ if ((msg = mx_open_new_message (dest, hdr, is_from (buf, NULL, 0, NULL) ? 0
: M_ADD_FROM)) == NULL)
+ return -1;
+ rewind (tmpfp);
+ if (mutt_copy_stream (tmpfp, msg->fp))
+ r=-1;
+ if (tmpfp)
+ {
+ safe_fclose (&tmpfp);
+ mutt_unlink (tmpfname);
+ }
if (mx_commit_message (msg, dest) != 0)
r = -1;