Lloyd Zusman <[EMAIL PROTECTED]> writes:
> [ ... ] it occurs to me that a more general capability might be
> useful: to be able to specify an action on the command line of
> tmda-filter, which will cause the message on stdin to have that action
> unconditionally performed on it.
>
> For example:
>
> tmda-filter --action=hold
>
> put the stdin-based message into the pending queue
>
> tmda-filter --action=ok
>
> deliver the message normally (for example, in case the
> message would be handled otherwise by the user's TMDA
> rules)
>
> tmda-filter '--action=deliver=~/mbox.spam'
>
> send the message to the spam mailbox
>
> ... etc. ...
>
> [ ... ]
Well, I couldn't wait any more, and so I wrote the patch that will
enable this functionality. :)
It turns out that the only file that I needed to change was
tmda-rfilter. This is based on the latest CVS version.
What do you folks think?
*** tmda-rfilter.orig Sun Oct 24 00:39:25 2004
--- tmda-rfilter Sun Oct 24 00:39:32 2004
***************
*** 40,45 ****
--- 40,50 ----
--discard
Discard message if address is invalid instead of bouncing it.
+ -a <action>
+ --action <action>
+ Unconditionally perform <action> on the incoming message. No rules
+ are checked.
+
-p
--print
Print the message to stdout. This option is useful when TMDA is run
***************
*** 102,107 ****
--- 107,113 ----
filter_match = None
discard = None
act_as_filter = 0
+ unconditional_action = None
program = sys.argv[0]
def usage(code, msg=''):
***************
*** 134,148 ****
try:
opts, args = getopt.getopt(sys.argv[1:],
! 'c:dpt:I:M:S:Vh', ['config-file=',
! 'discard',
! 'print',
! 'template-dir=',
! 'filter-incoming-file=',
! 'filter-match=',
! 'vhome-script=',
! 'version',
! 'help'])
except getopt.error, msg:
usage(1, msg)
--- 140,155 ----
try:
opts, args = getopt.getopt(sys.argv[1:],
! 'a:c:dpt:I:M:S:Vh', ['config-file=',
! 'discard',
! 'print',
! 'action=',
! 'template-dir=',
! 'filter-incoming-file=',
! 'filter-match=',
! 'vhome-script=',
! 'version',
! 'help'])
except getopt.error, msg:
usage(1, msg)
***************
*** 163,168 ****
--- 170,177 ----
os.environ['TMDA_TEMPLATE_DIR'] = arg
elif opt in ('-d', '--discard'):
discard = 1
+ elif opt in ('-a', '--action'):
+ unconditional_action = arg
elif opt in ('-p', '--print'):
act_as_filter = 1
elif opt in ('-c', '--config-file'):
***************
*** 791,807 ****
verify_confirm_cookie(confirm_done_hdr, 'done')
if (cookie_type in Defaults.TAGS_CONFIRM) and cookie_value:
verify_confirm_cookie(cookie_value, 'accept')
! # Parse the incoming filter file.
! infilter = FilterParser.FilterParser(Defaults.DB_CONNECTION)
! infilter.read(Defaults.FILTER_INCOMING)
! (actions, matching_line) = infilter.firstmatch(recipient_address,
! sender_list,
! orig_msgin_body_as_raw_string,
! orig_msgin_headers_as_raw_string,
! orig_msgin_size)
! (action, option) = actions.get('incoming', (None, None))
! # Dispose of the message now if there was a filter file match.
! # Log the action along with and the matching line in the filter
# file that caused it.
if action in ('bounce','reject'):
if Defaults.FILTER_BOUNCE_CC:
--- 800,824 ----
verify_confirm_cookie(confirm_done_hdr, 'done')
if (cookie_type in Defaults.TAGS_CONFIRM) and cookie_value:
verify_confirm_cookie(cookie_value, 'accept')
!
! if unconditional_action is None:
! # Parse the incoming filter file.
! infilter = FilterParser.FilterParser(Defaults.DB_CONNECTION)
! infilter.read(Defaults.FILTER_INCOMING)
! (actions, matching_line) = infilter.firstmatch(recipient_address,
! sender_list,
! orig_msgin_body_as_raw_string,
! orig_msgin_headers_as_raw_string,
! orig_msgin_size)
! (action, option) = actions.get('incoming', (None, None))
! else:
! # Use the action "as is" from the command line.
! (action, option) = FilterParser.splitaction(unconditional_action)
! matching_line = 'unconditional ' + action
!
! # Dispose of the message now if there was a filter file match
! # or if an unconditional action was given on the command line.
! # Log the action along with the matching line in the filter
# file that caused it.
if action in ('bounce','reject'):
if Defaults.FILTER_BOUNCE_CC:
***************
*** 834,859 ****
elif action == 'hold':
logit('HOLD', '(%s)' % matching_line)
bouncegen('hold')
! # The message didn't match the filter file, so check if it was
! # sent to a 'tagged' address.
! # Dated tag?
! if (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_DATED)) \
! and cookie_value:
! verify_dated_cookie(cookie_value)
! # Sender tag?
! elif (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_SENDER)) \
! and cookie_value:
! sender_address = globals().get('envelope_sender')
! verify_sender_cookie(sender_address, cookie_value)
! # Keyword tag?
! elif (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_KEYWORD)) \
! and cookie_value:
! verify_keyword_cookie(cookie_value)
! # If the message gets this far (i.e, was not sent to a tagged
! # address and it didn't match the filter file), then we consult
! # Defaults.ACTION_INCOMING.
! do_default_action(Defaults.ACTION_INCOMING.lower(), 'action_incoming',
! 'bounce_incoming.txt')
# This is the end my friend.
if __name__ == '__main__':
--- 851,881 ----
elif action == 'hold':
logit('HOLD', '(%s)' % matching_line)
bouncegen('hold')
! elif unconditional_action is not None:
! # Illegal unconditional action specified on command line.
! raise NameError, 'Invalid unconditional action : ' + action
!
! if unconditional_action is None:
! # The message didn't match the filter file, so check if it was
! # sent to a 'tagged' address.
! # Dated tag?
! if (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_DATED)) \
! and cookie_value:
! verify_dated_cookie(cookie_value)
! # Sender tag?
! elif (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_SENDER)) \
! and cookie_value:
! sender_address = globals().get('envelope_sender')
! verify_sender_cookie(sender_address, cookie_value)
! # Keyword tag?
! elif (cookie_type in map(lambda s: s.lower(), Defaults.TAGS_KEYWORD)) \
! and cookie_value:
! verify_keyword_cookie(cookie_value)
! # If the message gets this far (i.e, was not sent to a tagged
! # address and it didn't match the filter file), then we consult
! # Defaults.ACTION_INCOMING.
! do_default_action(Defaults.ACTION_INCOMING.lower(), 'action_incoming',
! 'bounce_incoming.txt')
# This is the end my friend.
if __name__ == '__main__':
--
Lloyd Zusman
[EMAIL PROTECTED]
God bless you.
_________________________________________________
tmda-workers mailing list ([EMAIL PROTECTED])
http://tmda.net/lists/listinfo/tmda-workers