24.3 Write a Delivery Agent Script
The program that is driven by the
#!/usr/local/bin/perl
When this appears as the first line of a script,
the
In writing a program for mail delivery using the 24.3.1 Duplicates discardedWhen sendmail gathers its list of recipients, it views a program to run as just another recipient. Before performing any delivery, it sorts the list of recipients and discards any duplicates. Ordinarily, this is just the behavior that is desired, but discarding duplicate programs from the aliases (5) file [7] can cause some users to lose mail. To illustrate, consider a program that notifies the system administrator that mail has arrived for a retired user:
#!/bin/sh /usr/ucb/mail -s gone postmaster
This script reads everything (the mail message) from its standard
input and feeds what it reads to the
/usr/ucb/mail
program.
The command-line arguments to
mail
are
a subject line of
george: "|/usr/local/bin/gone" ben: "|/usr/local/bin/gone"
When mail is sent to both To avoid this problem (which is most common in user ~/.forward files), design all delivery programs to require at least one unique argument. For example, the above program should be rewritten to require the user's name as an argument:
#!/bin/sh if [ ${#} -ne 2 ]; then echo $0 needs a user name. exit fi /usr/ucb/mail -s "$1 gone" postmaster By requiring a username as an argument, the once-faulty aliases are made unique:
george: "|/usr/local/bin/gone george" ben: "|/usr/local/bin/gone ben" Although the program paths are still the same, the addresses (name and arguments together) are different, and neither is discarded. 24.3.2 Correct exit(2) values
The
sendmail
program expects its
554 Unknown status val
Here,
#!/bin/sh EX_OK=0 # From <sysexits.h> EX_USAGE=64 # From <sysexits.h> if [ ${#} -ne 2 ]; then echo $0 needs a user name. exit $EX_USAGE fi /usr/ucb/mail -s "$1 gone" postmaster exit $EX_OK Here, if the argument count is wrong, we exit with the value EX_USAGE, thus producing a clearer (two-line) error message:
/usr/local/bin/gone needs a user name. /usr/local/bin/gone... Bad usage. If all goes well, we then exit with EX_OK so that sendmail knows that the mail was successfully delivered. 24.3.3 Is It Really EX_OK?
When
sendmail
sees that the
(void)fclose(fp);
If the file that is being written to is remotely mounted, the written
data may be cached locally. All the preceding write statements
will have succeeded, but if the remote host crashes after
the last write (but before the close), some of the data can
be lost. The
fclose
(3) fails, but the Even in writing small shell scripts, it is important to include error checking. The following rewrite of our gone program includes error checking but does not handle signals. We leave that as an exercise for the reader:
#!/bin/sh EX_OK=0 # From <sysexits.h> EX_USAGE=64 # From <sysexits.h> EX_SOFTWARE=70 # From <sysexits.h> if [ ${#} -ne 2 ]; then echo $0 needs a user name. exit $EX_USAGE fi if /usr/ucb/mail -s "$1 gone" postmaster >/dev/null 2>&1 then exit $EX_OK fi exit $EX_SOFTWARE |
|