return $lnum;
}
+# unparse_mail(&attachments, eol, boundary)
+# Convert an array of attachments into MIME format, and return them as an
+# array of lines.
+sub unparse_mail
+{
+local ($attach, $eol, $bound) = @_;
+local @rv;
+foreach my $a (@$attach) {
+ push(@rv, $eol);
+ push(@rv, "--".$bound.$eol);
+ local $enc;
+ foreach my $h (@{$a->{'headers'}}) {
+ push(@rv, $h->[0].": ".$h->[1].$eol);
+ $enc = $h->[1]
+ if (lc($h->[0]) eq 'content-transfer-encoding');
+ }
+ push(@rv, $eol);
+ if (lc($enc) eq 'base64') {
+ local $enc = &encode_base64($a->{'data'});
+ $enc =~ s/\r//g;
+ foreach my $l (split(/\n/, $enc)) {
+ push(@rv, $l.$eol);
+ }
+ }
+ else {
+ $a->{'data'} =~ s/\r//g;
+ $a->{'data'} =~ s/\n\.\n/\n\. \n/g;
+ foreach my $l (split(/\n/, $a->{'data'})) {
+ push(@rv, $l.$eol);
+ }
+ }
+ }
+push(@rv, $eol);
+push(@rv, "--".$bound."--".$eol);
+push(@rv, $eol);
+return @rv;
+}
+
# mail_size(&mail, [textonly])
# Returns the size of an email message in bytes
sub mail_size
$bodyattach = $attach[0];
if ($in{'html_edit'}) {
- # Add the plain-text body
- local $mt = "text/plain";
+ # Create an attachment which contains both the HTML and plain
+ # bodies as alternatives
+ local @alts = ( $attach[0] );
+ local $mt = "text/plain; charset=$charset";
if ($plainbody =~ /[\177-\377]/) {
- unshift(@attach,
+ push(@alts,
{ 'headers' => [ [ 'Content-Type', $mt ],
[ 'Content-Transfer-Encoding',
'quoted-printable' ] ],
'data' => quoted_encode($plainbody) });
}
else {
- unshift(@attach,
+ push(@alts,
{ 'headers' => [ [ 'Content-Type', $mt ],
[ 'Content-Transfer-Encoding',
'7bit' ] ],
# Set content type to multipart/alternative, to tell mail
# clients about the optional body
- push(@{$mail->{'headers'}}, [ 'Content-Type',
- 'multipart/alternative' ]);
+ local $bound = "altsbound".time();
+ $attach[0] = {
+ 'headers' => [ [ 'Content-Type',
+ 'multipart/alternative; '.
+ 'boundary="'.$bound.'"' ],
+ [ 'Content-Transfer-Encoding',
+ '7bit' ] ],
+ 'data' => join("", &unparse_mail(\@alts, "\n", $bound))
+ };
}
}
$attachsize = 0;