Sending attached file through SMTP



The following snenario shows how to send an attached file through SMTP:

First, connect to the outgoing SMTP server and send the requested commands:

Figure 1

telnet smtp.tiscali.fr 25
Trying 213.36.80.74...
Connected to mail-tiscali.libertysurf.net.
Escape character is '^]'.
220 mail.libertysurf.net ESMTP Service (6.5.026) ready
EHLO fr.tiscali.com
250-mail.libertysurf.net
250-DSN
250-8BITMIME
250-PIPELINING
250-HELP
250-AUTH
250-DELIVERBY 300
250 SIZE 5120000
MAIL FROM:<denis.beurive@fr.tiscali.com>
250 MAIL FROM:<denis.beurive@fr.tiscali.com> OK
RCPT TO:<denis_beurive@yahoo.com>
250 RCPT TO:<denis_beurive@yahoo.com> OK
DATA
354 Start mail input; end with <CRLF>.<CRLF>

Then send the, well formated, data part. Please note that the file to send (which name is "to_send") is encoded using base 64 (you can use the Perl module MIME::Base64).

Notes:

  • The text in black represents the header part of the data.
  • The text in blue represents the body part of the data (see the next perl script - figure 4).

Figure 2

Message-ID: <3F3377BA.9A669F60@yahoo.com>
Date: Fri, 08 Aug 2003 12:13:14 +0200
From: Tiscali user <denis.beurive@fr.tiscali.com>
Reply-To: denis_beurive@yahoo.com
To: denis_beurive@yahoo.com
Subject: attached file
Content-Type: multipart/mixed; boundary="====1060343816====";


--====1060343816====
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

This is the attached file
--====1060343816====
Content-Type: application/octet-stream; name="to_send"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="to_send"

dXNlIGxpYiAiL2V4cG9ydC9jb21tb24tcGVybC1saWIvbXlfcGFja2FnZXMvIjsKdXNlIHN0cmlj
dDsKdXNlIGZpbGVyOwoKCm15ICRyYzsKbXkgJGVycjsKbXkgJGhvc3Q7Cm15ICRwb3J0OwpteSAk
bG9naW47Cm15ICRwYXNzOwpteSAkcGF0aDsKbXkgJG5hbWU7Cm15ICRjaGVja19wZXJpb2Q7Cm15
ICR2YWxpZF9hZ2U7Cm15ICRtYXhfcmVjb25uZWN0OwpteSAkd2FpdF9yZWNvbm5lY3Q7CgojIC0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIENoZWNr
IGNvbW1hbmQgbGluZQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLQoKaWYgKGludCBAQVJHViAhPSAxMCkKewogIHByaW50ICJVc2FnZTogcGVybCBm
dHAucGwgPGhvc3Q+IDxwb3J0PiA8bG9naW4+IDxwYXNzd29yZD4gPGZpbGUgcGF0aD4gPGZpbGUg
bmFtZT4gIiAuCiAgICAgICAgIjxjaGVjayBwZXJpb2Q+IDx2YWxpZCBhZ2U+IDxtYXggcmVjb25u
ZWN0PiA8d2FpdCByZWNvbm5lY3Q+XG5cbiI7CiAgZXhpdCAxOwp9CgokaG9zdCAgICAgICAgICAg
PSAkQVJHVlswXTsKJHBvcnQgICAgICAgICAgID0gJEFSR1ZbMV07CiRsb2dpbiAgICAgICAgICA9
ICRBUkdWWzJdOwokcGFzcyAgICAgICAgICAgPSAkQVJHVlszXTsKJHBhdGggICAgICAgICAgID0g
JEFSR1ZbNF07CiRuYW1lICAgICAgICAgICA9ICRBUkdWWzVdOwokY2hlY2tfcGVyaW9kICAgPSAk
QVJHVls2XTsKJHZhbGlkX2FnZSAgICAgID0gJEFSR1ZbN107CiRtYXhfcmVjb25uZWN0ICA9ICRB
UkdWWzhdOwokd2FpdF9yZWNvbm5lY3QgPSAkQVJHVls5XTsKCiMgLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgV2FpdCBmb3IgdGhlIGZpbGUgdG8g
YmVjb21lIGF2YWlsYWJsZQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLQoKJHJjID0gd2FpdF9mb3JfZmlsZV9mdHAgKAogICAgICAgICAgICAgICAg
ICAgICAgICAgICRob3N0LAogICAgICAgICAgICAgICAgICAgICAgICAgICRwb3J0LAogICAgICAg
ICAgICAgICAgICAgICAgICAgICRsb2dpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAkcGFz
cywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgJHBhdGgsCiAgICAgICAgICAgICAgICAgICAg
ICAgICAgJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJGNoZWNrX3BlcmlvZCwKICAg
ICAgICAgICAgICAgICAgICAgICAgICAkdmFsaWRfYWdlLAogICAgICAgICAgICAgICAgICAgICAg
ICAgICRtYXhfcmVjb25uZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICR3YWl0X3JlY29u
bmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBcJGVyciwgCiAgICAgICAgICAgICAgICAg
ICAgICAgICAgMQogICAgICAgICAgICAgICAgICAgICAgICApOwoKaWYgKCRyYyA9PSAtMSkKewog
IHByaW50ICJFcnJvciB3aGlsZSB3YWl0aW5nIGZvciBmaWxlICckcGF0aCcgLT4gJyRuYW1lJyB0
byBiZSBhdmFpbGFibGU6ICRlcnJcblxuIjsKICBleGl0IDE7Cn0KCnByaW50ICJGaWxlICckcGF0
aCcgLT4gJyRuYW1lJyBpcyBhdmFpbGFibGVcblxuIjsKCgoKZXhpdCAwOwo=

--====1060343816====--

Send the sequence <CRLF>.<CRLF> in order to tell the server: " This is the end of the data part"

Figure 3


.
250 <3F2516280022428F> Mail accepted
QUIT
221 mail.libertysurf.net QUIT
Connection closed by foreign host.

The following Perl script generates the body part of the email's data (exclusion of the header). See figure 2, the text in blue.

Figure 4

use strict;
use MIME::Base64;
use MIME::QuotedPrint;

my $file;
my $boundary;
my $message;
my $mail_from;
my $mail_to;
my $mail_subject;
my $mail_body;
my $content_type;

$file         = "to_send";
$boundary     = "====" . time() . "====";
$message      = encode_qp( "This is the attached file" );
$mail_from    = 'denis_beurive@yahoo.com';
$mail_to      = 'denis_beurive@yahoo.com';
$mail_subject = 'test attached file';
$content_type = "multipart/mixed; boundary=\"$boundary\"";



unless (open (ATTACHEMENT, "<$file"))
{
  print STDERR "[FATAL] Can not open attachement file '$file' - $!\n";
  exit 1;
}

binmode ATTACHEMENT;
undef $/;
$mail_body = encode_base64(<ATTACHEMENT>);

close ATTACHEMENT;

$boundary = '--'.$boundary;
$mail_body = <<END_OF_BODY;

$boundary
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

$message
$boundary
Content-Type: application/octet-stream; name="$file"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="$file"

$mail_body
$boundary--
END_OF_BODY

print "To send as mail body:\n\n";
print "[" . $mail_body . "]";
print "\n\n";