Send Mail
Extend
assignment 3 to
actually send a mail message after logging in to the server.
The host and login creds are specified in the same way as assignment 3,
and the message data is given in standard input. I have an input
file
tmsg1.txt that looks like this:
recip=bennet@mc.edu
subj=This here is a genuine test message
You see, I was feeling kind of testy, so I
decided to send this message.
.This line starts with a period.
This line does not.
Here's what mine looks like:
tom@desktop$ ./smlog2 smtp.gmail.com @gmailsmlog1 < tmsg1.txt
S: 220 smtp.gmail.com ESMTP x7-20020a056830114700b006e49669e1f1sm1251293otq.10 - gsmtp
C: EHLO 192.168.1.136
S: 250-smtp.gmail.com at your service, [76.107.18.246]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-STARTTLS
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
C: EHLO 192.168.1.136
S: 250-smtp.gmail.com at your service, [76.107.18.246]
S: 250-SIZE 35882577
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
S: 250-ENHANCEDSTATUSCODES
S: 250-PIPELINING
S: 250-CHUNKING
S: 250 SMTPUTF8
C: AUTH PLAIN AGJvZ3VzAG5vbnBhc3N3b3Jk
S: 235 2.7.0 Accepted
C: MAIL FROM:<tomstestacct700@gmail.com>
S: 250 2.1.0 OK x7-20020a056830114700b006e49669e1f1sm1251293otq.10 - gsmtp
C: RCPT TO:<bennet@mc.edu>
S: 250 2.1.5 OK x7-20020a056830114700b006e49669e1f1sm1251293otq.10 - gsmtp
C: DATA
S: 354 Go ahead x7-20020a056830114700b006e49669e1f1sm1251293otq.10 - gsmtp
C: Date: Sat, 02 Mar 2024 23:38:20 -0600
C: From: tomstestacct700@gmail.com
C: Subject: This here is a genuine test message
C: To: bennet@mc.edu
C:
C: You see, I was feeling kind of testy, so I
C: decided to send this message.
C:
C: ..This line starts with a period.
C: This line does not.
C: .
S: 250 2.0.0 OK 1709444300 x7-20020a056830114700b006e49669e1f1sm1251293otq.10 - gsmtp
C: QUIT
S: 221 2.0.0 closing connection x7-20020a056830114700b006e49669e1f1sm1251293otq.10 - gsmtp
tom@desktop$
And the message is delivered to my campus email account, just as
specified.
I put my input in a file and sent it on the command line using the <
symbol. You can also just type it
at the console, in case you just need
a quick way to send short email messages from the command line.
Input File Format
The file starts with settings lines, each with a key name and a value.
These parts are separated by =, and the value is everything on
the line after the =. As you can see, it specifies the email
recipient and the subject of the email. The program also allows the sender
to be set, but that's usually computed from the login (see below).
After the settings come the lines of the message. This is a simple
text message, sent without the use of MIME.
The program reads and stores the input before contacting the
server. I stored the settings in a C++ map, and pushed the lines
of the message into vector of strings.
Default Sender
The sender is usually not set in the input file. Instead,
the account name from the login credentials
is used. If it contains a @ (and so looks
like an email address), that is used directly.
If there's no @, the top two domain components of the server name are
appended, with an @.
For gmail, the user is just the account name. My test
account is tomstestacct700, and the server name is
smtp.gmail.com, so the program takes the last two components
of the server name and forms tomstestacct700@gmail.com
as the sender. If the
login contains @, it is used unchanged as the sender address.
Those rules should work for most servers, but if not, the
input file may specify a sender setting to be used instead.
Additional Protocol Steps
You will need to add a few things to your assignment 3 solution.
These operations are fully described in
RFC 5321,
but you see most of what
you need in the example above.
- After completing login, you initiate sending mail with a MAIL FROM
command giving the sender address, in the format shown above. There should
not be a space after the colon. The server may send a failure response
if it doesn't like your sender address.
- Specify the recipient by generating RCPT TO as you see above.
In general, multiple recipients can be specified, but the assignment
assumes just one.
- To send the message itself, issue the DATA command. If
the server gives you a positive response, it expects the whole message content,
headers and body separated by a blank line. Generate your message with
at least the headers shown.
- The message ends with a line containing just a period.
The server will not respond until it sees this mark, so it won't
inform you of any problems it has with the message until it receives the
whole thing.
- If any line of the message starts with a period, add an extra on
the front. The server discards the leading period on any line that
has one, other than the terminator. This allows the message to contain
lines of just one or two periods without ambiguity.
Setting the Date
As an old dog, I created the date header value using the plain C
time,
localtime and
strftime.
Feel free to explore the newer C++ time facilities if you prefer.
The standard for the date format is
here,
but you can see it pretty well above. Day and 24-hour time, with
the last bit representing the time
zone relative to Greenwich, hours and minutes.
Submission
When your program is working, nicely commented and properly indented,
submit it using the form
here