Frank,
First, if you really want to develop mailing list software, why not just
compile and use SmartList? It has many features which you'll probably
wish to add anyway.
But, if for some reason you don't want to use SmartList, then you can
use one of the two suggestions below to add an address to a file.
a. Use "multigram", which is part of the procmail sources (but used only
by SmartList). Multigram will both check to see if an address is in
a file, sort of like grep, and will add it if it is not in the file.
Unfortunately, you'll have to read the multigram code, because there
is no man page. Here's the result of "multigram -h":
Usage: multigram [-cdimr] [-b nnn] [-l nnn] [-w nnn] [-ax address]
[-L domain] file ...
-a address add this address to the list
-b nnn maximum no. of best matches shown
-c display offsets in characters
-d gently delete address from list
-D force delete address from list
-i check for incomplete addresses too
-m display multiple matches per address
-l nnn lower bound metric
-L domain default domain for local addresses
-r rename address on list
-x address exclude this address from the search (max. 2)
-w nnn window width used when matching
See the SmartList sources (in .bin/subscribe) to see how multigram is
used to update a file.
b. Use an "fgrep" recipe in front of an "echo" command, as I do for
the ackmail.cache in "ackmail.rc" (from my procmail library):
# Check the cache for a recent ack (a successful grep "delivers" the
# mail)
LOCKFILE=$ACKS.lock
:0 Wh
| fgrep -i -s "$SENDER $DATE" $ACKS
# Not in the $ACKS file; add it
JUNK=`(fgrep -i -v "$SENDER" $ACKS ; echo "$SENDER $DATE" ) >$ACKS.new ;
rm -f $ACKS ; mv $ACKS.new $ACKS `
The "tricks" here are:
1. The first fgrep detects if an address/date pair is already in the
cache file. If it is, "fgrep" succeeds which causes the mail to
be considered as "delivered" (since this is being done inside a
conditional block--a forked process--dropping the mail at this
point is okay, otherwise duplicate mail would occur).
2. The second fgrep removes any previous record for $SENDER on
another date from the file, and the "echo" appends the new
address/date pair to the end of the cache file.
3. The updates are being done on a "new" file so that if the program
terminates for *any* reason before completing the change, nothing
is lost, except the last update.
4. Setting LOCKFILE is important--it keeps two or more processes from
trying to update the same file at the same time.
Good luck.
Alan
I have tried to wrote a recipe to maintain a mailing list.
Here it is:
:0 Whc: lock
* !^FROM_DAEMON
* !^X-Loop: frank(_at_)netcom(_dot_)com
* ^Subject:.*JOIN LIST
{
:0
{
NAME=`$FORMAIL -xSubject:| sed -e 's/JOIN LIST//'`
EMAIL=`$FORMAIL -xReturn-Path:`
FROM=`$FORMAIL -xFrom:`
:0
| echo $NAME \ ${EMAIL:-$FROM} >> list
}
:0
| ( $FORMAIL -rA"Precedence: junk" \
-A"X-Loop: frank(_at_)netcom(_dot_)com" ; \
echo "Your mail has been received,"; \
echo "and your name will be added to the mailing list soon."; \
| $SENDMAIL -oi -t
}
Is this a healthy recipe? I am missing an important procedure here is
to check if the sender is already on the list. How would I do that?
With sed? Or is there another way? I would really appreciate if
someone could help me.
Thanks a million,
Frank