Bladeren bron

separate filters for each mailgroup

Pi 1 jaar geleden
bovenliggende
commit
ae94c92f06
6 gewijzigde bestanden met toevoegingen van 230 en 136 verwijderingen
  1. 2 1
      cropswap-debug.sh
  2. 12 2
      cropswap-sendmail.sh
  3. 41 0
      filters/cropswap-members@shandan.one
  4. 58 0
      filters/cropswap@shandan.one
  5. 61 0
      filters/postmaster@localhost
  6. 56 133
      maildroprc

+ 2 - 1
cropswap-debug.sh

@@ -3,7 +3,8 @@ set -euo pipefail
 MAIL="$(cat -)"
 cat <<EOF | /usr/sbin/sendmail -f maildrop pi
 ${MAIL}
+
 ERROR ${1:-unknown}
+
 $(env)
 EOF
-exit 1

+ 12 - 2
cropswap-sendmail.sh

@@ -6,6 +6,12 @@ cleanup (){
 }
 trap cleanup EXIT
 
+DELIVERED=false
+SENDMAIL="/usr/sbin/sendmail"
+if (($DEBUG != 0)); then
+	SENDMAIL="$DEBUGMAIL"
+fi
+
 cat - | formail -kb \
 	-X "MIME-Version:" \
 	-X "Content-Type:" \
@@ -54,6 +60,10 @@ for email in "${!SUBSCRIBED[@]}"; do
 		continue
 	fi
 	echo "Forwarding mail to: ${SUBSCRIBED["$email"]} <${email}>"
-	/usr/sbin/sendmail -F "${FROM}" -f "${MAILGROUP}" "${SUBSCRIBED["$email"]} <${email}>" < "${WD}/mail"
+	"$SENDMAIL" -F "${FROM}" -f "${MAILGROUP}" "${SUBSCRIBED["$email"]} <${email}>" < "${WD}/mail"
+	DELIVERED=true
 done
-#TODO: report errors properly
+if ! $DELIVERED; then
+	"$DEBUGMAIL" undelivered
+	exit "$UNHANDLED"
+fi

+ 41 - 0
filters/cropswap-members@shandan.one

@@ -0,0 +1,41 @@
+if ($FORWARD)
+{
+   FROM=$ALIAS
+   gdbmopen($MLIST, "R")
+   TO=gdbmfetch($TOALIAS)
+   gdbmclose
+   to "!"
+}
+if (!$CONTINUE)
+{
+   flock $STAGE {
+      if (gdbmopen($STAGE, "W"))
+      {
+         cc "|$DEBUGMAIL progress-$MEMBERGROUP-fail"
+         EXITCODE=$FATAL
+         exit
+      }
+      foreach /^(To|Cc):\s+(.*)\s+\<$MEMBERGROUPREGEX\>$/
+      {
+         gdbmstore("TOALIAS", "$MATCH2")
+      }
+      gdbmstore("CONTINUE", "YES")
+      gdbmstore("TOMEMBER", "YES")
+      gdbmstore("MAILGROUP", "$MEMBERGROUP")
+      gdbmstore("SUBJECT", "Crop Swap Member")
+      gdbmclose
+   }
+}
+elsif ($CONTINUE)
+{
+   gdbmopen($MLIST, "R")
+   ALIAS=gdbmfetch(tolower($FROM))
+   if ($ALIAS eq "")
+   {
+      gdbmclose
+      EXITCODE=$UNREGISTERED
+      exit
+   }
+   gdbmclose
+}
+

+ 58 - 0
filters/cropswap@shandan.one

@@ -0,0 +1,58 @@
+if($FORWARD)
+{
+   MLIST="$LISTDIR/alist"
+   gdbmopen($MLIST, "R")
+   ORGANIZER=gdbmfetch(tolower($FROM))
+   gdbmclose
+
+   if ($ORGANIZER eq "")
+   {
+      SLIST="$LISTDIR/alist"
+      to "!"
+   }
+
+   #
+   # ORGANIZERS ONLY
+   #
+   FROM=$ORGANIZER
+   MLIST="$LISTDIR/mlist"
+   gdbmopen($MLIST, "R")
+   TO=gdbmfetch($TOALIAS)
+   gdbmclose
+   to "!"
+}
+if (!$CONTINUE)
+{
+   flock $STAGE {
+      if (gdbmopen($STAGE, "W"))
+      {
+         cc "|$DEBUGMAIL progress-$ORGANIZERGROUP-fail"
+         EXITCODE=$FATAL
+         exit
+      }
+         foreach /^(To|Cc):\s+(.*)\s+\<$ORGANIZERGROUPREGEX\>$/
+      {
+         gdbmstore("TOALIAS", "$MATCH2")
+      }
+      gdbmstore("CONTINUE", "YES")
+      gdbmstore("TOORGANIZER", "YES")
+      gdbmstore("MAILGROUP", "$ORGANIZERGROUP")
+      gdbmstore("SUBJECT", "Crop Swap Notice")
+      gdbmclose
+   }
+}
+elsif($CONTINUE)
+{
+   gdbmopen($MLIST, "R")
+   ALIAS=gdbmfetch(tolower($FROM))
+   if ($ALIAS eq "")
+   {
+       gdbmclose
+       #
+       # TODO: test this works at all
+       FROM=$FROM
+       SLIST="$LISTDIR/alist"
+       to "!"
+   }
+   gdbmclose
+}

+ 61 - 0
filters/postmaster@localhost

@@ -0,0 +1,61 @@
+if (!$CONTINUE)
+{
+   flock $STAGE {
+      if (gdbmopen($STAGE, "W"))
+      {
+         cc "|$DEBUGMAIL progress-$POSTMASTER-fail"
+         EXITCODE=$FATAL
+         exit
+      }
+       if (/^X\-GROUP:\s*$ORGANIZERGROUPREGEX\s*$/)
+      {
+         gdbmstore("TOORGANIZER", "YES")
+      }
+      if (/^X\-GROUP:\s*$MEMBERGROUPREGEX\s*$/)
+      {
+         gdbmstore("TOMEMBER", "YES")
+      }
+      gdbmstore("TOPOSTMASTER", "YES")
+      gdbmstore("CONTINUE", "YES")
+      gdbmclose
+   }
+}
+elsif ($CONTINUE)
+{
+   if (/^Subject:\s*\[SIGNUP\]\s*$/)
+   {
+      if (/^X-MEMBER-ALIAS:\s*(.*)\s*$/)
+      {
+         gdbmopen($MLIST, "W")
+         SUFFIX=0
+         ALIAS=$MATCH1
+         KEY=$ALIAS
+         EXISTS=gdbmfetch($KEY)
+         while ($EXISTS ne "" && $EXISTS ne tolower($FROM))
+         {
+            SUFFIX=($SUFFIX + 1)
+            KEY="$ALIAS $SUFFIX"
+            EXISTS=gdbmfetch($KEY)
+         }
+         if (gdbmstore(tolower($FROM), $KEY) == 0 && gdbmstore($KEY, tolower($FROM)) == 0)
+         {
+            gdbmclose
+            to "|$MAILBOT -N -t $SIGNUPRESP -A 'From: $MAILGROUP' -f$FROM /usr/bin/sendmail $FROM"
+         }
+         else
+         {
+            gdbmclose
+            cc "|$DEBUGMAIL"
+            EXITCODE=$FATAL
+            exit
+         }
+      }
+      EXITCODE=$BADREQUEST
+      # No response to unregistered users
+      exit
+   }
+   #cc "|$DEBUGMAIL"
+   EXITCODE=$UNHANDLED
+   # No response to unregistered users
+   exit
+}

+ 56 - 133
maildroprc

@@ -10,12 +10,12 @@ DEBUGMAIL="/opt/cropswap/debug.sh"
 MAILBOT="/usr/bin/mailbot"
 SIGNUPRESP="/opt/cropswap/signup.eml"
 SUBSCRIBERESP="/opt/cropswap/subunsub.eml"
-
-#
-# Uncomment to debug
-#SENDMAIL="/opt/cropswap/debug.sh"
-#MAILBOT="/opt/cropswap/debug.sh"
-#
+FILTERDIR="/opt/cropswap/filters"
+DEBUG=0
+if ($DEBUG)
+{
+   MAILBOT="/opt/cropswap/debug.sh"
+}
 
 POSTMASTER="postmaster@localhost"
 POSTMASTERREGEX=escape($POSTMASTER)
@@ -31,15 +31,11 @@ MEMBERGROUPREGEX=escape($MEMBERGROUP)
 ORGANIZERGROUP="cropswap@shandan.one"
 ORGANIZERGROUPREGEX=escape($ORGANIZERGROUP)
 
-SUFFIX=0
+ANYGROUPREGEX="$MEMBERGROUPREGEX|$ORGANIZERGROUPREGEX"
+HANDLEDREGEX="($POSTMASTERREGEX|$ANYGROUPREGEX)"
 
 FORWARD=0
 SUBSCRIBE=""
-CONTINUE=0
-TOPOSTMASTER=0
-TOORGANIZER=0
-TOMEMBER=0
-TO=""
 
 UNHANDLED=5
 BADREQUEST=4
@@ -47,71 +43,69 @@ UNREGISTERED=3
 UNSUBSCRIBED=2
 FATAL=1
 
+STAGE="/var/mail/maildrop/stage"
+flock $STAGE {
+   if (gdbmopen($STAGE, "C"))
+   {
+      cc "|$DEBUGMAIL init-stages-fail"
+      EXITCODE=$FATAL
+      exit
+   }
+   gdbmstore("CONTINUE", "NO")
+   gdbmstore("TOMEMBER", "NO")
+   gdbmstore("TOORGANIZER", "NO")
+   gdbmstore("TOPOSTMASTER", "NO")
+   gdbmstore("MAILGROUP", "")
+   CONTINUE=(gdbmfetch("CONTINUE") eq "YES")
+   gdbmclose
+}
+
 foreach /^(To|Cc):.*/
 {
    ADDR=getaddr($MATCH)
-   foreach (tolower $ADDR) =~ /^$POSTMASTER$/
-   {
-      if (/^X\-GROUP:\s*$ORGANIZERGROUPREGEX\s*$/)
-      {
-         TOORGANIZER=1
-      }
-      if (/^X\-GROUP:\s*$MEMBERGROUPREGEX\s*$/)
-      {
-         TOORGANIZER=1
-      }
-      CONTINUE=1
-      TOPOSTMASTER=1
-   }
-   foreach (tolower $ADDR) =~ /^$ORGANIZERGROUPREGEX$/
+   foreach (tolower $ADDR) =~ /^$HANDLEDREGEX$/
    {
-      TOORGANIZER=1
-      CONTINUE=1
-   }
-   foreach (tolower $ADDR) =~ /^$MEMBERGROUPREGEX$/
-   {
-      TOMEMBER=1
-      CONTINUE=1
-   }
-   foreach /^(To|Cc):\s+(.*)\s+\<$ORGANIZERGROUPREGEX\>$/
-   {
-      TOALIAS=$MATCH2
-   }
-   foreach /^(To|Cc):\s+(.*)\s+\<$MEMBERGROUPREGEX\>$/
-   {
-      TOALIAS=$MATCH2
+      cc "|$DEBUGMAIL include match $MATCH"
+      include "$FILTERDIR/$MATCH"
    }
 }
 
+if (gdbmopen($STAGE, "R"))
+{
+   cc "|$DEBUGMAIL progress-stages-fail"
+   EXITCODE=$FATAL
+   exit
+}
+CONTINUE=(gdbmfetch("CONTINUE") eq "YES")
+TOPOSTMASTER=(gdbmfetch("TOPOSTMASTER") eq "YES")
+TOMEMBER=(gdbmfetch("TOMEMBER") eq "YES")
+TOORGANIZER=(gdbmfetch("TOORGANIZER") eq "YES")
+MAILGROUP=gdbmfetch("MAILGROUP")
+SUBJECT=gdbmfetch("SUBJECT")
+TOALIAS=gdbmfetch("TOALIAS")
+gdbmclose
+
 if (!$CONTINUE)
 {
+   cc "|$DEBUGMAIL no-continue"
    EXITCODE=$UNHANDLED
    exit
 }
 
 if ($TOMEMBER && $TOORGANIZER)
 {
-   cc "|$DEBUGMAIL multiplemembergroupset"
+   cc "|$DEBUGMAIL multiple-mail-group-set"
    EXITCODE=$BADREQUEST
    exit
 }
 
-if ($TOMEMBER)
-{
-   MAILGROUP=$MEMBERGROUP
-   SUBJECT="Crop Swap Member"
-}
-elsif ($TOORGANIZER)
-{
-   MAILGROUP=$ORGANIZERGROUP
-   SUBJECT="Crop Swap Notice"
-}
-else
+if ($MAILGROUP eq "")
 {
-   cc "|$DEBUGMAIL nomembergroupset"
-   EXITCODE=$FATAL
+   cc "|$DEBUGMAIL no-mail-group-set"
+   EXITCODE=$BADREQUEST
    exit
 }
+
 LISTDIR="/var/mail/maildrop/$MAILGROUP"
 MLIST="$LISTDIR/mlist"
 SLIST="$LISTDIR/slist"
@@ -119,59 +113,12 @@ SLIST="$LISTDIR/slist"
 
 if ($TOPOSTMASTER)
 {
-   if (/^Subject:\s*\[SIGNUP\]\s*$/)
-   {
-      if (/^X-MEMBER-ALIAS:\s*(.*)\s*$/)
-      {
-         gdbmopen($MLIST, "W")
-         ALIAS=$MATCH1
-         KEY=$ALIAS
-         EXISTS=gdbmfetch($KEY)
-         while ($EXISTS ne "" && $EXISTS ne tolower($FROM))
-         {
-            SUFFIX=($SUFFIX + 1)
-            KEY="$ALIAS $SUFFIX"
-            EXISTS=gdbmfetch($KEY)
-         }
-         if (gdbmstore(tolower($FROM), $KEY) == 0 && gdbmstore($KEY, tolower($FROM)) == 0)
-         {
-            gdbmclose
-            to "|$MAILBOT -N -t $SIGNUPRESP -A 'From: $MAILGROUP' -f$FROM /usr/bin/sendmail $FROM"
-         }
-         else
-         {
-            gdbmclose
-            EXITCODE=$FATAL
-            exit
-         }
-      }
-      EXITCODE=$BADREQUEST
-      # No response to unregistered users
-      exit
-   }
-   EXITCODE=$UNHANDLED
-   # No response to unregistered users
-   exit
+   include "$FILTERDIR/$POSTMASTER"
 }
-
-gdbmopen($MLIST, "R")
-ALIAS=gdbmfetch(tolower($FROM))
-if ($ALIAS eq "")
+else
 {
-    gdbmclose
-    if ($TOORGANIZER)
-    {
-       #
-       # TODO: test this works at all
-       FROM=$FROM
-       REPLYTO=$FROM
-       SLIST="$LISTDIR/alist"
-       to "!"
-    }
-    EXITCODE=$UNREGISTERED
-    exit
+   include "$FILTERDIR/$MAILGROUP"
 }
-gdbmclose
 
 
 #
@@ -215,32 +162,8 @@ if (!$FORWARD)
 # SUBSCRIBED USERS
 #
 NOFORWARD=$FROM
-if ($TOMEMBER)
-{
-   FROM=$ALIAS
-   gdbmopen($MLIST, "R")
-   TO=gdbmfetch($TOALIAS)
-   gdbmclose
-   to "!"
-}
+include "$FILTERDIR/$MAILGROUP"
 
-MLIST="$LISTDIR/alist"
-gdbmopen($MLIST, "R")
-ORGANIZER=gdbmfetch(tolower($FROM))
-gdbmclose
-
-if ($ORGANIZER eq "")
-{
-   SLIST="$LISTDIR/alist"
-   to "!"
-}
-
-#
-# ORGANIZERS ONLY
-#
-FROM=$ORGANIZER
-MLIST="$LISTDIR/mlist"
-gdbmopen($MLIST, "R")
-TO=gdbmfetch($TOALIAS)
-gdbmclose
-to "!"
+cc "|$DEBUGMAIL unhandled"
+EXITCODE=$UNHANDLED
+exit