MH & nmh: Email for Users & Programmers

May, 2006

Sending Files

You can use comp to send mail interactively. Fill in the message header and leave the message body blank (just use CTRL-D). Then, at the What now? prompt, go into an editor like vi and use the file-reading command (in vi, it's :read filename) to read in the file. You can edit the draft before you exit the editor and send. Or use directives and filenames as the Section Example Drafts with Directives shows.

MH also comes with a command called mhmail. Instead of having a components file, mhmail has options called -subject, -cc, and so on. If you have a text file that you want to send in a mail message, there are a few ways to do it. (The file should have just text -- usually, that's letters, digits, and punctuation -- unless you're using a multimedia mail standard like MIME. You shouldn't mail nontext files without special processing such as uuencode(1).) You can send any file, text or non-text, with viamail, the MIME file-sending script explained later in this section. Finally, the append script works at the What now? prompt.

Send Non-MIME Files: mhmail

The mhmail command will read text from its standard input, such as a pipe from another program (|) or a left angle bracket (<) from a file. It also has a -body switch. Here are four examples:

    % mhmail joe avax\!lynn -cc al -subject "My report" < report
    % mhmail alice -body "See you at noon for lunch" -from Hungry
    % myprg | mhmail teacher -cc ehuser -subject "My program output" &
    % mhmail `ali -list gurus` joe jane -subject 'Help\!' < problem
The first command line mails a file named report to joe and avax!lynn; it also sends a cc: to al. (You can put spaces or commas between the addresses.) Be sure to use a left angle bracket (<) before the filename, not a right angle bracket (>)! The To: address(es) always come first. (This was only really necessary for older versions of mhmail that were implemented as a shell script.)

Unless you understand how your shell handles characters such as parentheses and the ampersand sign (&), it's safest to put single or double quotes (' or ") around the subject. If you use the C shell (which displays a percent sign (%) prompt), you should also put backslashes (\) before any exclamation points (!), as I did here.

The second command line sends a short message about lunch to alice. The -from switch makes the message From: Hungry, but the mail system will add your real email address, too, in a Sender: field. Again, you should use quotes around the body.

The third command line runs your program called myprg (although you could use most any UNIX program instead). The output is piped into mhmail, which collects all the output while the program is running and then sends the output to your teacher with a copy to you. The ampersand (&) on the end runs the commands in the background, so you can do something else while they work.

The fourth command line runs the MH ali command with its -list switch to get the addresses from the MH mail alias called gurus. This uses backquoting. Besides the addresses from the alias, this fourth message also goes to joe and jane.

The Section Mailing Non-interactively: mhmail has more mhmail techniques.

Send Files with MIME: viamail

If both you and the recipient have MIME-capable MH systems, you can use viamail (with MH and nmh before version 0.27) or sendfiles (with nmh-0.27 and above). viamail is explained at the end of the mhn(1) manual page, and sendfiles has its own manual page. These programs package one or more files with the tar(1) and compress(1) commands. Files are sent as an application/octet-stream content with base64 encoding. The encoded message will have the Content-type: parameters type=tar and x-conversions=compress, as well as the comment (extract with uncompress | tar xvpf -). If needed, the data will be split into several message/partial messages.

You probably shouldn't use viamail or sendfiles unless you're sure that the recipient can handle the message. Unfortunately, a lot of MIME user agents can't handle partial messages. The recipient can reassemble the parts by hand, but it's tedious; a program like one of the newer versions of shar will make life a lot easier for the recipient. But viamail and sendfiles do use the robust, reliable MIME standard -- so it may be worth the work for the recipient.

For some reason, viamail is in the MH library directory, and sendfiles is in the nmh library directory. (More confusingly, under nmh-0.27 and above, viamail still exists -- in the nmh bin directory with the other MH utilities -- and you can invoke it directly!) So, to use viamail under MH or sendfiles under nmh, unless the library directory is in your shell's search path, you need to type the absolute pathname of the library directory.

The first argument (except for the option -- see below) is the address you want to send the files to. You can use more than one address, separated by commas and inside quotes (see below). Next comes the subject, which is required; you should quote it. Finally, give the filename(s) you want to send.

Here's an example of sending the files ch01 and ch02 to fred and The message subject is Chapters 1 and 2:

    % /usr/local/mh/lib/viamail "fred," "Chapters 1 and 2" ch01 ch02
    mailpath = fred,
    subject-string = Chapters 1 and 2
    files = ch01 ch02
    a ch01 44 blocks
    a ch02 37 blocks
After it repeats the addresses, subject and filenames, viamail and sendfiles run tar(1) with its v (verbose) flag; you'll see the output as tar archives the files.

The message will be sent From: you unless the undocumented PERSON environment variable has been set to a different address. The message parts are sent right away unless you add an option (which has to be first, before the addresses!) that tells viamail and sendfiles how many seconds to pause between the parts. For instance, to send the mail from and pause one minute (60 seconds) between the parts:

    % setenv PERSON ''
    % /usr/local/mh/lib/viamail -60 "fred," "Chapters 1 and 2" ch01 ch02
The PERSON address can't be a complete RFC 822 address such as "G. Vidal" <>. It has to be a plain address in the format username or username@host.domain.

Add Files to Your Drafts: append

To add the contents of a file to your draft message, you can always go into an editor such as vi and use its read file (:r) command. But that's not very efficient, especially for attaching several files.

The paper "MH.5: How to Process 200 Messages a Day and Still Get Some Real Work Done," by Marshall T. Rose and John L. Romine, has a shell script called append. (There's also a version, with work by Bob Desinger, in the miscellany/scripts directory of the MH distribution. It comes with an online manual page.)

This book's online archive has a version of append that lets you type more than one filename; it also allows wildcards, environment variables, and abbreviated filenames. You call it as an editor at the What now? prompt. For example, to append a copy of your file, report to your draft message:

    What now? edit append report
After it appends the file(s), you get another What now? prompt. If you want to separate the files you append with blank lines, rows of dashes, or whatever, an easy way to do so is to make a little file named something like separator with that separator in it:
    % cat separator
This next example shows how to append all the files from the $HOME/proj directory whose names end with .out, then your separator file, and then a file in the current directory named .signature:
    What now? e append $HOME/proj/*.out sep .signature
The sep above is an abbreviation for the separator file's full filename. See the explanation of append.

The Section Add Text to Drafts: mysend shows a way to add files automatically: a sendproc script. The Section Automatic Signature on End of Messages has a simpler way to add text (like a signature) every time you send a message: by changing your draft message template files. mhn can add files, too, in MIME format, with the # directive -- see the Section Composing and Sending MIME Messages.

One last note: append doesn't make MIME attachments; it just appends files. But that would be trivial to change: hack the script to make it add the MIME # directive before each file it attaches.