DB_* extentions to the _APEND variable

David Grimberg <[email protected]> Wed, 03 Oct 2007 06:50:33 -0700
Newsgroups gmane.mail.spam.tmda.devel
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------060707070803090400050705
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi everyone,

I figured it was about time I submitted these patches to the community 
at large since my system administrator recently updated TMDA to the 
latest and greatest necessitating my revisitation of the modifications 
that I'd been maintaining on our local install for the last couple of 
years.  The first patch tmda-1.1.12-db.diff adds database support for 
the PENDING_*_APPEND variables by adding the following default variables:

   DB_PENDING_BLACKLIST_APPEND
   DB_PENDING_DELETE_APPEND
   DB_PENDING_RELEASE_APPEND
   DB_PENDING_WHITELIST_APPEND

And then properly handling them in the Pending.py module.  These new 
variables operate just like the currently existing DB_*_APPEND 
variables, just extending the concept to cover what I felt was some 
missing functionality.  I've personally been using these since 2005.

The second patch tmda-1.1.12-stdin.diff modifies Pending.py to not close 
and reopen stdin when tmda-pending is being run non interactively.  When 
the close and reopen change was applied to Pending.py it broke my 
current cron job (see chkpending.txt) that rewrites the mailto links 
with the TMDA-CGI urls to release messages.  When Pending.py tries to 
reopen stdin in a non interactive session it fails with the following 
error (see tmda-pending-cron-error.txt for complete error text):

   IOError: [Errno 6] No such device or address: '/dev/tty'

Finally since I'm submitting two patches at the same time I've included 
diffs for each patch separately and one diff for both patches combined.

--------------060707070803090400050705
Content-Type: text/plain;
 name="tmda-pending-cron-error.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="tmda-pending-cron-error.txt"

Traceback (most recent call last):
  File "/usr/bin/tmda-pending", line 333, in ?
    main()
  File "/usr/bin/tmda-pending", line 324, in main
    pretend = opts.pretend
  File "/usr/lib/python2.4/site-packages/TMDA/Pending.py", line 94, in initQueue
    sys.stdin = open('/dev/tty', 'r')
IOError: [Errno 6] No such device or address: '/dev/tty'

--------------060707070803090400050705
Content-Type: text/plain;
 name="chkpending.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="chkpending.txt"

#!/bin/bash
URL=`grep ^CGI_URL /etc/tmdarc | cut -d = -f 2 | cut -d \" -f 2`
HOSTNAME=`grep ^HOSTNAME /etc/tmdarc | cut -d = -f 2 | cut -d \" -f 2`
TMPFILE=`mktemp` && {
  #echo Using URL from /etc/tmdarc: $URL
  #echo Using HOSTNAME from /etc/tmdarc: $HOSTNAME 
  #echo Using TMPFILE: $TMPFILE

/usr/bin/tmda-pending -c ~/.tmda/config2 -TCbO 2d| grep -v "\*\{10\}"| awk '{print $1}'| \
/usr/bin/tmda-pending -bs - | sed -e 's|^<mailto:\(.*\)-confirm-\(.*\)@'$HOSTNAME'>|'$URL'\?'`/usr/bin/id -u`'.\2|g' > $TMPFILE
CNT=`cat $TMPFILE|wc -c`
if (($CNT>0)); then
  cat $TMPFILE | mail -s 'TMDA pending summary' `whoami`;
fi
rm -f $TMPFILE
}



--------------060707070803090400050705
Content-Type: text/plain;
 name="tmda-1.1.12-db.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="tmda-1.1.12-db.diff"

diff -ur tmda-1.1.12/TMDA/ChangeLog tmda-1.1.12-db/TMDA/ChangeLog
--- tmda-1.1.12/TMDA/ChangeLog	2007-04-26 13:29:55.000000000 -0700
+++ tmda-1.1.12-db/TMDA/ChangeLog	2007-10-02 06:32:44.000000000 -0700
@@ -1,3 +1,16 @@
+2005-10-07  David Grimberg  <[email protected]>
+
+	* Defaults.py (DB_PENDING_BLACKLIST_APPEND): New Variable.
+	(DB_PENDING_DELETE_APPEND): Ditto.
+	(DB_PENDING_RELEASE_APPEND): Ditto.
+	(DB_PENDING_WHITELIST_APPEND): Ditto.
+
+	* Pending.py: Modified to use new DB_PENDING_* variables.
+	Also added code to check if operating in interactive or
+	non interactive mode.  If not interactive, don't reset
+	sys.stdin since the reset was causing issues with some
+	scripted operations.
+
 2007-04-26  Jason R. Mastaler  <[email protected]>
 
 	* pythonlib/email: Sync up with email 4.0.2.
diff -ur tmda-1.1.12/TMDA/Defaults.py tmda-1.1.12-db/TMDA/Defaults.py
--- tmda-1.1.12/TMDA/Defaults.py	2007-02-23 12:20:10.000000000 -0800
+++ tmda-1.1.12-db/TMDA/Defaults.py	2007-10-02 06:30:06.000000000 -0700
@@ -1155,6 +1155,35 @@
 if not vars().has_key('PENDING_BLACKLIST_APPEND'):
     PENDING_BLACKLIST_APPEND = None
 
+# DB_PENDING_BLACKLIST_APPEND
+# SQL INSERT statement to be used to insert blacklisted sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_BLACKLIST_APPEND = """
+#  INSERT INTO blacklist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_BLACKLIST_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'drop'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_BLACKLIST_APPEND'):
+    DB_PENDING_BLACKLIST_APPEND = None
+
 # PENDING_DELETE_APPEND
 # Filename to which a sender's e-mail address should be automatically
 # appended when a message is "deleted" by tmda-pending.  tmda-filter's
@@ -1170,6 +1199,35 @@
 if not vars().has_key('PENDING_DELETE_APPEND'):
     PENDING_DELETE_APPEND = None
 
+# DB_PENDING_DELETE_APPEND
+# SQL INSERT statement to be used to insert deleted sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_DELETE_APPEND = """
+#  INSERT INTO blacklist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_DELETE_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'confirm'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_DELETE_APPEND'):
+    DB_PENDING_DELETE_APPEND = None
+
 # PENDING_RELEASE_APPEND
 # Filename to which a sender's e-mail address should be automatically
 # appended when a message is "released" by tmda-pending.
@@ -1183,6 +1241,35 @@
 if not vars().has_key('PENDING_RELEASE_APPEND'):
     PENDING_RELEASE_APPEND = None
 
+# DB_PENDING_RELEASE_APPEND
+# SQL INSERT statement to be used to insert released sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_RELEASE_APPEND = """
+#  INSERT INTO whitelist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_RELEASE_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'accept'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_RELEASE_APPEND'):
+    DB_PENDING_RELEASE_APPEND = None
+
 # PENDING_WHITELIST_APPEND
 # Filename to which a sender's e-mail address should be appended
 # when a message is "whitelisted" by tmda-pending.
@@ -1196,6 +1283,35 @@
 if not vars().has_key('PENDING_WHITELIST_APPEND'):
     PENDING_WHITELIST_APPEND = None
 
+# DB_PENDING_WHITELIST_APPEND
+# SQL INSERT statement to be used to insert whitelisted sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_WHITELIST_APPEND = """
+#  INSERT INTO whitelist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_WHITELIST_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'accept'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_WHITELIST_APPEND'):
+    DB_PENDING_WHITELIST_APPEND = None
+
 # PENDING_WHITELIST_RELEASE
 # An option detailing the action taken when 'Whitelist' is the 
 # current action in tmda-pending or tmda-cgi
diff -ur tmda-1.1.12/TMDA/Pending.py tmda-1.1.12-db/TMDA/Pending.py
--- tmda-1.1.12/TMDA/Pending.py	2007-01-17 13:49:44.000000000 -0800
+++ tmda-1.1.12-db/TMDA/Pending.py	2007-10-01 07:15:40.000000000 -0700
@@ -32,6 +32,7 @@
 
 import Defaults
 import Errors
+import FilterParser
 import Util
 from TMDA.Queue.Queue import Queue
 
@@ -306,9 +307,11 @@
         """Get the user input."""
         try:
             message = '([p]ass / [s]how / [r]el / [d]el'
-            if Defaults.PENDING_WHITELIST_APPEND:
+            if Defaults.PENDING_WHITELIST_APPEND or \
+               (Defaults.DB_PENDING_WHITELIST_APPEND and Defaults.DB_CONNECTION):
                 message = message + ' / [w]hite'
-            if Defaults.PENDING_BLACKLIST_APPEND:
+            if Defaults.PENDING_BLACKLIST_APPEND or \
+               (Defaults.DB_PENDING_BLACKLIST_APPEND and Defaults.DB_CONNECTION):
                 message = message + ' / [b]lack'
             message = message + ' / [q]uit) [%s]: '
             inp = raw_input(message % self.dispose_def)
@@ -371,6 +374,16 @@
         if Defaults.PENDING_RELEASE_APPEND:
             Util.append_to_file(self.append_address,
                                 Defaults.PENDING_RELEASE_APPEND)
+        if Defaults.DB_PENDING_RELEASE_APPEND and Defaults.DB_CONNECTION:
+            _username = Defaults.USERNAME.lower()
+            _hostname = Defaults.HOSTNAME.lower()
+            _recipient = _username + '@' + _hostname
+            params = FilterParser.create_sql_params(
+                recipient=_recipient, username=_username,
+                hostname=_hostname, sender=self.append_address)
+            Util.db_insert(Defaults.DB_CONNECTION,
+                           Defaults.DB_PENDING_RELEASE_APPEND,
+                           params)
         timestamp, pid = self.msgid.split('.')
         # Remove Return-Path: to avoid duplicates.
         del self.msgobj['return-path']
@@ -403,27 +416,61 @@
         if Defaults.PENDING_DELETE_APPEND:
             Util.append_to_file(self.append_address,
                                 Defaults.PENDING_DELETE_APPEND)
+        if Defaults.DB_PENDING_DELETE_APPEND and Defaults.DB_CONNECTION:
+            _username = Defaults.USERNAME.lower()
+            _hostname = Defaults.HOSTNAME.lower()
+            _recipient = _username + '@' + _hostname
+            params = FilterParser.create_sql_params(
+                recipient=_recipient, username=_username,
+                hostname=_hostname, sender=self.append_address)
+            Util.db_insert(Defaults.DB_CONNECTION,
+                           Defaults.DB_PENDING_DELETE_APPEND,
+                           params)
 	Q.delete_message(self.msgid)
 
     def whitelist(self):
         """Whitelist the message sender."""
-        if Defaults.PENDING_WHITELIST_APPEND:
-            Util.append_to_file(self.append_address,
+        if Defaults.PENDING_WHITELIST_APPEND or \
+           (Defaults.DB_PENDING_WHITELIST_APPEND and Defaults.DB_CONNECTION):
+            if Defaults.PENDING_WHITELIST_APPEND:
+                Util.append_to_file(self.append_address,
                                 Defaults.PENDING_WHITELIST_APPEND)
+            if Defaults.DB_PENDING_WHITELIST_APPEND and Defaults.DB_CONNECTION:
+                _username = Defaults.USERNAME.lower()
+                _hostname = Defaults.HOSTNAME.lower()
+                _recipient = _username + '@' + _hostname
+                params = FilterParser.create_sql_params(
+                    recipient=_recipient, username=_username,
+                    hostname=_hostname, sender=self.append_address)
+                Util.db_insert(Defaults.DB_CONNECTION,
+                               Defaults.DB_PENDING_WHITELIST_APPEND,
+                               params)
             if Defaults.PENDING_WHITELIST_RELEASE == 1:
                 self.release()
         else:
             raise Errors.ConfigError, \
-                  'PENDING_WHITELIST_APPEND not defined!'
+                  '[DB_]PENDING_WHITELIST_APPEND not defined!'
 
     def blacklist(self):
         """Blacklist the message sender."""
-        if Defaults.PENDING_BLACKLIST_APPEND:
-            Util.append_to_file(self.append_address,
+        if Defaults.PENDING_BLACKLIST_APPEND or \
+           (Defaults.DB_PENDING_BLACKLIST_APPEND and Defaults.DB_CONNECTION):
+            if Defaults.PENDING_BLACKLIST_APPEND:
+                Util.append_to_file(self.append_address,
                                 Defaults.PENDING_BLACKLIST_APPEND)
+            if Defaults.DB_PENDING_BLACKLIST_APPEND and Defaults.DB_CONNECTION:
+                _username = Defaults.USERNAME.lower()
+                _hostname = Defaults.HOSTNAME.lower()
+                _recipient = _username + '@' + _hostname
+                params = FilterParser.create_sql_params(
+                    recipient=_recipient, username=_username,
+                    hostname=_hostname, sender=self.append_address)
+                Util.db_insert(Defaults.DB_CONNECTION,
+                               Defaults.DB_PENDING_BLACKLIST_APPEND,
+                               params)
         else:
             raise Errors.ConfigError, \
-                  'PENDING_BLACKLIST_APPEND not defined!'
+                  '[DB_]PENDING_BLACKLIST_APPEND not defined!'
 
     def pager(self):
         Util.pager(self.show())

--------------060707070803090400050705
Content-Type: text/plain;
 name="tmda-1.1.12-db-stdin.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="tmda-1.1.12-db-stdin.diff"

diff -ur tmda-1.1.12/TMDA/ChangeLog tmda-1.1.12.a/TMDA/ChangeLog
--- tmda-1.1.12/TMDA/ChangeLog	2007-04-26 13:29:55.000000000 -0700
+++ tmda-1.1.12.a/TMDA/ChangeLog	2007-09-17 06:52:01.000000000 -0700
@@ -1,3 +1,16 @@
+2005-10-07  David Grimberg  <[email protected]>
+
+	* Defaults.py (DB_PENDING_BLACKLIST_APPEND): New Variable.
+	(DB_PENDING_DELETE_APPEND): Ditto.
+	(DB_PENDING_RELEASE_APPEND): Ditto.
+	(DB_PENDING_WHITELIST_APPEND): Ditto.
+
+	* Pending.py: Modified to use new DB_PENDING_* variables.
+	Also added code to check if operating in interactive or
+	non interactive mode.  If not interactive, don't reset
+	sys.stdin since the reset was causing issues with some
+	scripted operations.
+
 2007-04-26  Jason R. Mastaler  <[email protected]>
 
 	* pythonlib/email: Sync up with email 4.0.2.
diff -ur tmda-1.1.12/TMDA/Defaults.py tmda-1.1.12.a/TMDA/Defaults.py
--- tmda-1.1.12/TMDA/Defaults.py	2007-02-23 12:20:10.000000000 -0800
+++ tmda-1.1.12.a/TMDA/Defaults.py	2007-09-17 06:40:02.000000000 -0700
@@ -1155,6 +1155,35 @@
 if not vars().has_key('PENDING_BLACKLIST_APPEND'):
     PENDING_BLACKLIST_APPEND = None
 
+# DB_PENDING_BLACKLIST_APPEND
+# SQL INSERT statement to be used to insert blacklisted sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_BLACKLIST_APPEND = """
+#  INSERT INTO blacklist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_BLACKLIST_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'drop'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_BLACKLIST_APPEND'):
+    DB_PENDING_BLACKLIST_APPEND = None
+
 # PENDING_DELETE_APPEND
 # Filename to which a sender's e-mail address should be automatically
 # appended when a message is "deleted" by tmda-pending.  tmda-filter's
@@ -1170,6 +1199,35 @@
 if not vars().has_key('PENDING_DELETE_APPEND'):
     PENDING_DELETE_APPEND = None
 
+# DB_PENDING_DELETE_APPEND
+# SQL INSERT statement to be used to insert deleted sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_DELETE_APPEND = """
+#  INSERT INTO blacklist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_DELETE_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'confirm'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_DELETE_APPEND'):
+    DB_PENDING_DELETE_APPEND = None
+
 # PENDING_RELEASE_APPEND
 # Filename to which a sender's e-mail address should be automatically
 # appended when a message is "released" by tmda-pending.
@@ -1183,6 +1241,35 @@
 if not vars().has_key('PENDING_RELEASE_APPEND'):
     PENDING_RELEASE_APPEND = None
 
+# DB_PENDING_RELEASE_APPEND
+# SQL INSERT statement to be used to insert released sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_RELEASE_APPEND = """
+#  INSERT INTO whitelist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_RELEASE_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'accept'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_RELEASE_APPEND'):
+    DB_PENDING_RELEASE_APPEND = None
+
 # PENDING_WHITELIST_APPEND
 # Filename to which a sender's e-mail address should be appended
 # when a message is "whitelisted" by tmda-pending.
@@ -1196,6 +1283,35 @@
 if not vars().has_key('PENDING_WHITELIST_APPEND'):
     PENDING_WHITELIST_APPEND = None
 
+# DB_PENDING_WHITELIST_APPEND
+# SQL INSERT statement to be used to insert whitelisted sender addresses
+# into a SQL database. The Python DB API will take care of properly
+# quoting parameters that are strings.
+# Requires a valid DB_CONNECTION object.
+#
+# Available substition parameters are:
+#
+# %(recipient)s  - USERNAME@HOSTNAME
+# %(username)s   - USERNAME
+# %(hostname)s   - HOSTNAME
+# %(sender)s     - sender's address (envelope sender or X-Primary-Address)
+#
+# Examples:
+#
+# DB_PENDING_WHITELIST_APPEND = """
+#  INSERT INTO whitelist (user_email, address)
+#       VALUES (%(recipient)s, %(sender)s)"""
+#
+# DB_PENDING_WHITELIST_APPEND = """
+#  INSERT INTO wildcard_list (uid, address, action)
+#       SELECT uid, %(sender)s, 'accept'
+#         FROM users
+#        WHERE users.email = %(recipient)s"""
+#
+# Default is None
+if not vars().has_key('DB_PENDING_WHITELIST_APPEND'):
+    DB_PENDING_WHITELIST_APPEND = None
+
 # PENDING_WHITELIST_RELEASE
 # An option detailing the action taken when 'Whitelist' is the 
 # current action in tmda-pending or tmda-cgi
diff -ur tmda-1.1.12/TMDA/Pending.py tmda-1.1.12.a/TMDA/Pending.py
--- tmda-1.1.12/TMDA/Pending.py	2007-01-17 13:49:44.000000000 -0800
+++ tmda-1.1.12.a/TMDA/Pending.py	2007-09-27 07:07:00.000000000 -0700
@@ -32,6 +32,7 @@
 
 import Defaults
 import Errors
+import FilterParser
 import Util
 from TMDA.Queue.Queue import Queue
 
@@ -70,6 +71,7 @@
         self.younger = younger
         self.pretend = pretend
 
+        self.interactive = 0
         self.stdout = sys.stdout
 
 
@@ -90,8 +92,9 @@
                     self.msgs.extend(line.strip().split())
                 self.msgs.remove('-')
                 # re-open stdin on the tty
-                sys.stdin.close()
-                sys.stdin = open('/dev/tty', 'r')
+                if self.interactive:
+                  sys.stdin.close()
+                  sys.stdin = open('/dev/tty', 'r')
 
         if not self.msgs and not wantedstdin:
             self.msgs = Q.fetch_ids()
@@ -282,6 +285,8 @@
                        younger,
                        pretend)
 
+        self.interactive = 1
+
 
     def initQueue(self):
         """Additionally initialize the interactive queue."""
@@ -306,9 +311,11 @@
         """Get the user input."""
         try:
             message = '([p]ass / [s]how / [r]el / [d]el'
-            if Defaults.PENDING_WHITELIST_APPEND:
+            if Defaults.PENDING_WHITELIST_APPEND or \
+               (Defaults.DB_PENDING_WHITELIST_APPEND and Defaults.DB_CONNECTION):
                 message = message + ' / [w]hite'
-            if Defaults.PENDING_BLACKLIST_APPEND:
+            if Defaults.PENDING_BLACKLIST_APPEND or \
+               (Defaults.DB_PENDING_BLACKLIST_APPEND and Defaults.DB_CONNECTION):
                 message = message + ' / [b]lack'
             message = message + ' / [q]uit) [%s]: '
             inp = raw_input(message % self.dispose_def)
@@ -371,6 +378,16 @@
         if Defaults.PENDING_RELEASE_APPEND:
             Util.append_to_file(self.append_address,
                                 Defaults.PENDING_RELEASE_APPEND)
+        if Defaults.DB_PENDING_RELEASE_APPEND and Defaults.DB_CONNECTION:
+            _username = Defaults.USERNAME.lower()
+            _hostname = Defaults.HOSTNAME.lower()
+            _recipient = _username + '@' + _hostname
+            params = FilterParser.create_sql_params(
+                recipient=_recipient, username=_username,
+                hostname=_hostname, sender=self.append_address)
+            Util.db_insert(Defaults.DB_CONNECTION,
+                           Defaults.DB_PENDING_RELEASE_APPEND,
+                           params)
         timestamp, pid = self.msgid.split('.')
         # Remove Return-Path: to avoid duplicates.
         del self.msgobj['return-path']
@@ -403,27 +420,61 @@
         if Defaults.PENDING_DELETE_APPEND:
             Util.append_to_file(self.append_address,
                                 Defaults.PENDING_DELETE_APPEND)
+        if Defaults.DB_PENDING_DELETE_APPEND and Defaults.DB_CONNECTION:
+            _username = Defaults.USERNAME.lower()
+            _hostname = Defaults.HOSTNAME.lower()
+            _recipient = _username + '@' + _hostname
+            params = FilterParser.create_sql_params(
+                recipient=_recipient, username=_username,
+                hostname=_hostname, sender=self.append_address)
+            Util.db_insert(Defaults.DB_CONNECTION,
+                           Defaults.DB_PENDING_DELETE_APPEND,
+                           params)
 	Q.delete_message(self.msgid)
 
     def whitelist(self):
         """Whitelist the message sender."""
-        if Defaults.PENDING_WHITELIST_APPEND:
-            Util.append_to_file(self.append_address,
+        if Defaults.PENDING_WHITELIST_APPEND or \
+           (Defaults.DB_PENDING_WHITELIST_APPEND and Defaults.DB_CONNECTION):
+            if Defaults.PENDING_WHITELIST_APPEND:
+                Util.append_to_file(self.append_address,
                                 Defaults.PENDING_WHITELIST_APPEND)
+            if Defaults.DB_PENDING_WHITELIST_APPEND and Defaults.DB_CONNECTION:
+                _username = Defaults.USERNAME.lower()
+                _hostname = Defaults.HOSTNAME.lower()
+                _recipient = _username + '@' + _hostname
+                params = FilterParser.create_sql_params(
+                    recipient=_recipient, username=_username,
+                    hostname=_hostname, sender=self.append_address)
+                Util.db_insert(Defaults.DB_CONNECTION,
+                               Defaults.DB_PENDING_WHITELIST_APPEND,
+                               params)
             if Defaults.PENDING_WHITELIST_RELEASE == 1:
                 self.release()
         else:
             raise Errors.ConfigError, \
-                  'PENDING_WHITELIST_APPEND not defined!'
+                  '[DB_]PENDING_WHITELIST_APPEND not defined!'
 
     def blacklist(self):
         """Blacklist the message sender."""
-        if Defaults.PENDING_BLACKLIST_APPEND:
-            Util.append_to_file(self.append_address,
+        if Defaults.PENDING_BLACKLIST_APPEND or \
+           (Defaults.DB_PENDING_BLACKLIST_APPEND and Defaults.DB_CONNECTION):
+            if Defaults.PENDING_BLACKLIST_APPEND:
+                Util.append_to_file(self.append_address,
                                 Defaults.PENDING_BLACKLIST_APPEND)
+            if Defaults.DB_PENDING_BLACKLIST_APPEND and Defaults.DB_CONNECTION:
+                _username = Defaults.USERNAME.lower()
+                _hostname = Defaults.HOSTNAME.lower()
+                _recipient = _username + '@' + _hostname
+                params = FilterParser.create_sql_params(
+                    recipient=_recipient, username=_username,
+                    hostname=_hostname, sender=self.append_address)
+                Util.db_insert(Defaults.DB_CONNECTION,
+                               Defaults.DB_PENDING_BLACKLIST_APPEND,
+                               params)
         else:
             raise Errors.ConfigError, \
-                  'PENDING_BLACKLIST_APPEND not defined!'
+                  '[DB_]PENDING_BLACKLIST_APPEND not defined!'
 
     def pager(self):
         Util.pager(self.show())

--------------060707070803090400050705
Content-Type: text/plain;
 name="tmda-1.1.12-stdin.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="tmda-1.1.12-stdin.diff"

diff -ur tmda-1.1.12/TMDA/Pending.py tmda-1.1.12.a/TMDA/Pending.py
--- tmda-1.1.12/TMDA/Pending.py	2007-01-17 13:49:44.000000000 -0800
+++ tmda-1.1.12.a/TMDA/Pending.py	2007-10-01 06:54:12.000000000 -0700
@@ -70,6 +70,7 @@
         self.younger = younger
         self.pretend = pretend
 
+        self.interactive = 0
         self.stdout = sys.stdout
 
 
@@ -90,8 +91,9 @@
                     self.msgs.extend(line.strip().split())
                 self.msgs.remove('-')
                 # re-open stdin on the tty
-                sys.stdin.close()
-                sys.stdin = open('/dev/tty', 'r')
+                if self.interactive:
+                  sys.stdin.close()
+                  sys.stdin = open('/dev/tty', 'r')
 
         if not self.msgs and not wantedstdin:
             self.msgs = Q.fetch_ids()
@@ -282,6 +284,8 @@
                        younger,
                        pretend)
 
+        self.interactive = 1
+
 
     def initQueue(self):
         """Additionally initialize the interactive queue."""

--------------060707070803090400050705
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline