Wednesday, January 27, 2010

Project: Building An All-Text Linux Workstation - Part 8

After a long hiatus, we resume work on our all-text workstation.  There are two reasons I waited so long to resume this series: 1. I wanted to devote my full efforts to finishing the book, and 2. I knew this next installment would be hard to write.

The topic for the next two installments is one that should be fairly simple -- email.  Only it's not simple.  In fact, it's rather hellish.

Our Debian system already has a working email system installed and running on it.  In its default form, it allows the users of the machine to send email messages to each other.  This is a traditional Unix idea, since all Unix-like systems (such as Linux) are intrinsically multi-user.

While our small workstation might not seem like a good candidate for such a configuration, it is actually quite useful.  The reason being that you can send email from scripts and other programs.  This is good for programs that run automatically and need to report problems to an operator.  They can just send email.

Before we demonstrate this capability, I need to explain (a little) how email works.

Email systems consist of two (and sometimes three) different components.  The most familiar component is called the Mail User Agent (MUA).  This is a program like Evolution or Thunderbird that is used to read and compose email messages.

The real work of an email system however is performed by another component called a Mail Transport Agent (MTA) which is tasked with moving the email message from one machine to the next and delivering incoming messages into the addressee's mailbox for reading by the MUA.  On some systems a third component, called a Mail Delivery Agent is used by the MTA to perform operations on received email messages before they are delivered to the user's mailbox.  These operations can include things as sorting messages into mail folders and spam filtering.

Our Debian system has an MTA program called exim4 and several MUAs.  The most sophisticated of the default MUAs is a program called mutt.

Let's fire up mutt and send ourselves some email:

me@linuxbox:~$ mutt

As mutt starts up, it prompts you to create a directory called Mail in your home directory:

/home/me/Mail does not exist. Create it? ([yes]/no):

Press the Enter key to select the default (yes).

Next we will see the mutt screen:

The mutt screen has a menu along the top, a message list in the middle, and a status line at the bottom.  We also see an error message at the very bottom of the screen because we don't yet have a mailbox file.  More about that in a minute.

Next, we compose a new mail message.  We do this by pressing the m key.  At the very bottom of the screen we are prompted for the address of the recipient.  Since we are sending it to ourselves, we enter "me".

Next, we are prompted for a message subject.  Let's enter "Test Message" at the prompt.  mutt then brings up the nano text editor so we can compose our message:

We'll type in our message and then type Ctrl-o then Enter to save our message and then Ctrl-x to exit nano.

mutt then displays a summary of the message:

(Ignore the "twin7" in the hostname.  It's an artifact of my network configuration.)

Again, we have a menu at the top of the screen.  We use the "y" selection to actually send the message, so go ahead and type y.

mutt passes the message to exim4 for delivery.  Type "q" to exit mutt.  When the shell prompt returns, we should see a message like this:

You have mail in /var/mail/me

The shell periodically checks for updates to a mailbox file.  The name of this file is stored in the environment variable MAIL and the interval for the update check is set by the shell variable MAILCHECK.

We can easily examine the contents of these variables like this:

me@linuxbox:~$ set | grep MAIL

So we see that our mailbox is a file named /var/mail/me and that the shell checks for updates every 60 seconds.

Since email is always plain text we can look into our mailbox to see what email really looks like:

me@linuxbox:~$ less /var/mail/me

The contents of the mailbox will be something like this:

From me@linuxbox.localdomain Wed Jan 27 11:03:04 2010
Envelope-to: me@linuxbox.localdomain
Delivery-date: Wed, 27 Jan 2010 11:03:04 -0500
Received: from me by linuxbox.localdomain with local (Exim 4.69)
    (envelope-from )
    id 1NaAMC-0000fi-FF
    for me@linuxbox.localdomain; Wed, 27 Jan 2010 11:03:04 -0500
Date: Wed, 27 Jan 2010 11:03:04 -0500
From: Linux User
To: Linux User
Subject: Test Message
Message-ID: <20100127160304.GA2578@linuxbox.localdomain>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.5.18 (2008-05-17)

This is a test message.

As we can see, the message is mostly header followed by the actual message content.

If we launch mutt again, the message will show up in the message list pane of its main screen:

me@linuxbox:~$ mutt

Pressing the Enter key will display the contents of the message.
Pressing either i or q will return you to the message list and q will exit mutt.

mutt is not the only MUA installed by default.  There are some other programs that you can use on the command line to send mail.  mail is one such program.  The mail program is actually a full MUA like mutt but much older.  You can think of it as mutt's stone-age cousin.  It's rarely used as interactive mail reader but it finds a lot of use as command line email sender.  It can accept standard input on the command line to create messages.  Here's an example using mail to send the results of a command to a user:

me@linuxbox:~$ ls -l /usr/bin | mail -s "Listing of /usr/bin" me

This command sends the results of ls to user me.  Using the -s option sets the message subject line.

Running mutt again proves that we now have a second message in our mailbox:

That's all for now.  In the next episode, we'll look at how to deal with email from the outside world.

Further Reading

Here are some Wikipedia articles that provide some background and additional details:
Some documentation on mutt:
Other installments in this series: 1 2 3 4 5 6 7 8 9 10 11 12 13 14