procmail
[Top] [All Lists]

Re: Mailling List Question -- How to avoid reduplication

1996-03-18 10:20:02
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


<Prev in Thread] Current Thread [Next in Thread>
  • Re: Mailling List Question -- How to avoid reduplication, Alan Stebbens <=