Some systems with MH can't use the mhook utilities because the MTA doesn't support them, because the MTA runs on another computer, and so on. You may want your mail processed in batches, late at night -- instead of one by one, with .maildelivery.
Besides, the .maildelivery file and mhook programs can't do everything:
How to Set Up
If your system uses the popular sendmail or smail MTAs, you can probably start your own mail-handling program by putting its pathname in your .forward file. For example, this line in my .forward file will start the program /u/jerry/bin/inmail:
"| /u/jerry/bin/inmail"If your system handles executable files that start with #! (see the Section How Does Your System Execute Files?), you can probably execute shell scripts that way by just giving the script's name. Otherwise, start scripts by giving the pathname to the interpreter -- for example:
"| /bin/sh /u/jerry/bin/inmail"The MTA will start the program and feed the incoming message to the program's standard input. When the program finishes and returns a zero exit status, the message will have been delivered.
Gotchas: UID, GID, Permissions...
If your mail handler is run directly by the system MTA, you can run into some tough problems making it work correctly. On our Sun with SunOS 4.1, for instance, the sendmail MTA will run a private mail handler in several ways:
Example: Mail handler for debugging
#! /bin/sh exec > /tmp/inmail$$.log 2>&1 # Send all output to log file set -xv # Make shell show debugging output /bin/id # On BSD systems, use "whoami" and "groups" instead /bin/env # On BSD systems, use "printenv" instead /bin/cat > /tmp/inmail$$.stdin # Grab incoming message exit 0 # Important to set a zero status if handler succeeds
\jerry, "| /usr/ucb/vacation jerry"If you just want to acknowledge incoming mail or send a standard reply, vacation can be a good way to do it. The details about the format of the reply, as well as who will get replies and how often, should be in your online vacation(1) manual page.
To feed all of your mail to your handler, put a entry in your .maildelivery file like one of the three below. Use the first entry if your handler can be executed directly. The second entry runs awk; the third runs a Bourne shell:
* - ^ A /u/jerry/bin/inmail * - ^ A "/usr/bin/awk -f /u/jerry/bin/inmail" * - | A ". /u/jerry/bin/inmail"Of course, you can use fields besides * to control what messages are passed to your handler -- and results besides A to control what other entries in .maildelivery are executed.
The exit status that your handler returns is important. If your handler returns a nonzero status, .maildelivery will act as if that the handler failed. Try to make your handler set a zero status when it succeeds. (The section Using Exit Status explains. The exit 0 command sets a zero status in Bourne shell scripts.)
Printing Incoming Mail
You can print incoming mail from .maildelivery. For instance, the following entry would print all messages sent to the company-standards address. As always, the R means that messages won't be marked "delivered" when they're printed:
to company-standards ^ R "/usr/ucb/lpr -Plaser"The print job may come out with a banner page that says it was printed by daemon or some other user you wouldn't expect. (See the Section on Gotchas.)
If you don't need a pop-up window, you might look at the script anyway. It uses a technique for running programs from .maildelivery that's good to know.
The script should probably be run only for important mail. It opens a red xterm (X terminal emulator) window in the top-right corner of an X display. The title bar will say (depending on your window manager):
Important mail. Press q to quit.There'll be a copy of the mail message inside the window, shown by a pager program like less or pg. (Note that, to keep the window from closing too soon, the pager program can't exit until you select the window and type a command like q. The more pager quits at the end of the file, so it won't do.)
The script is simple on purpose: to make it easy to customize for your window system, and to make it easy to understand. The environment inside your .maildelivery file has almost no information about where you're logged on. So, I hard-coded most of the information into the script. If you need help understanding the script, see the Chapter Introduction to UNIX Programming with MH. To run it, put an entry like the one below in your .maildelivery file. (If your system can directly execute files that start with #!, you can omit the /bin/sh.)
From root | R "/bin/cat >/tmp/m$$; /bin/sh /x/y/rcvxterm /tmp/m$$ &"The script reads a file named on its command line. It could read its standard input, the message from the .maildelivery file. But actions in .maildelivery that don't finish after a reasonable amount of time are killed automatically. To be sure your window stays there, and to avoid blocking other actions in .maildelivery, run rcvxterm in the background as shown above. Use cat to copy the message into a temporary file. (Note that, during .maildelivery, your umask is set at 077. That keeps other users from reading the temporary file.)
The script is below. If you haven't installed a shell script before, there's help in the Section Writing Shell Scripts for MH.
NOTE: If you leave this simple-minded demonstration script running while the display is unattended for long periods, it can overload your system with too many processes and/or open windows. You might hack the script to count the number of rcvxterm processes -- with ps and grep -c, for instance -- and quit without opening an xterm if there are too many running already.
#! /bin/sh # $Id: rcvxterm,v 18.104.22.168 92/08/02 18:19:27 jerry book2 $ ### rcvxterm - HACK script to notify you about new mail ### Usage in .maildelivery: "/bin/cat >/tmp/m$$; /x/y/rcvxterm /tmp/m$$ &" trap '/bin/rm -f $1' 0 1 2 15 # REMOVE TEMP FILE BEFORE EXITING # USE less BECAUSE IT DOESN'T QUIT UNTIL YOU TYPE q. pg WORKS, TOO. # USE FULL PATHS; REMEMBER THAT .maildelivery ENVIRONMENT IS LIMITED. /usr/bin/X11/xterm -display hostname:0.0 \ -geometry 80x24-0+0 -bg red -fg white \ -title "important mail. Press q to quit" \ -ut -e /usr/local/bin/less $1
A handler can read your system mailbox file directly, usually with inc. I think it's easier to do that, splitting your messages into a folder -- then have my handler run MH programs like scan and pick to handle the messages.
Most handlers are probably shell or perl scripts. A script can be run by hand when you type its name at a shell prompt, or your computer can run it automatically with at or cron. One automatic handler is the autoinc shell script.
After you write a script like autoinc, add an entry to your personal crontab file or start an at job to run your script whenever you want. It's probably a good idea to run it late at night, if you can. The load on the system might be less then. Also, and more important, there's less chance of the handler being executed while you're logged on and might be reading mail -- it could change your current folder and current message while you weren't expecting it. (You can avoid that by making the handler use a different MH profile, context, and sequences file. The rmmer script uses most of those tricks.) If you haven't used crontab or at before, there are examples. Also, be sure to check the exit status of commands like inc to see if something has gone wrong -- the Section Using Exit Status has tips.
[Table of Contents] [Index] [Previous: Storing in Mailbox Files: rcvpack] [Next: Practical Tips]
This file is from the third edition of the book MH & xmh: Email for Users & Programmers, ISBN 1-56592-093-7, by Jerry Peek. Copyright © 1991, 1992, 1995 by O'Reilly & Associates, Inc. This file is freely-available; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. For more information, see the file copying.htm.
Suggestions are welcome: Jerry Peek <email@example.com>