3 # AttachCheck -- A MTA wrapper to help check outgoing email for
4 # forgotten attachments.
6 # (c) 2005 -- Benjamin Mako Hill <mako@bork.hampshire.edu>
7 # Author/Software Homepage at: http://mako.cc
9 # This software comes with ABSOLUTELY NO WARRANTY.
10 # This is free software and is licensed under the GNU GPL.
12 __copyright__ = "Copyright (c) 2004 Benjamin Mako Hill"
13 __author__ = "Benjamin Mako Hill <mako@debian.org>"
15 ### Configuration Options
16 ###########################################
18 # location of the sendmail binary
19 sendmail = "/usr/sbin/sendmail"
21 # list of mimetype which are, for the sake of this program, not
23 ignored_types = ( "applica/pgp-signat", "application/pgp-signature" )
25 # list of regular expressions which we will view as being indicative
27 attachment_regexes = [ r'\battach(ed|ment|ing)?\b(?im)' ]
30 ### No Edit Below This Line
31 ###########################################
40 mailpipe = os.popen("%s -t" % sendmail, 'w')
41 mailpipe.write( message_string )
42 sys.exit( mailpipe.close() )
44 ## SUB: print error message
47 """(Your message mentions attachments but does not include any.
51 (1) Add an attachment or add \"CONFIRM\" (in ALLCAPS to beginning of
52 the subject of the message and resend. \"CONFIRM\" will be
53 stripped from your message subject befor the message is sent.
56 (2) Add a \"X-AttachCheck-Override: Yes\" header the message.
58 Read the documentation for AttachCheck for more details."""
60 # get the mail from stdin
61 message_string = sys.stdin.read()
62 message = email.message_from_string( message_string )
64 attachment_expected = False
65 attachment_seen = False
68 for part in message.walk():
70 # check to see if this part is a plain text entry
71 if part.get_content_type() == "text/plain":
73 # if this is the second text block, we should interrate
76 attachment_seen = True
77 # otherwise, mark that we've now seen one text field
81 # search for the word "attach" or "attached" or "attachment"
82 # in the body of the message
83 for regex in attachment_regexes:
85 if re.search( regex, part.get_payload() ):
86 attachment_expected = True
88 # check to see if this mime-type is something we can ignore
89 elif ( re.match( r'message/(?m)', part.get_content_type() ) or
90 re.match( r'multipart/(?m)', part.get_content_type() ) or
91 part.get_content_type() in ignored_types ):
94 # if it's not text and it's an ignored type, it's a seen attachment
96 attachment_seen = True
98 # now check to see if we are expecting an attachment
99 if attachment_expected:
101 # if we are expecting an attachment and we've seen one, we should
102 # send the file and be done with things
106 # if we are expected have not seen it, we need to check to see if
107 # the mail has been confirmed
110 # check for the confirmation
112 if re.search( r'Subject: CONFIRM', message_string ):
113 message_string = re.sub( r'(Subject: )(CONFIRM )(.*?)\n',
114 r'\1\3\n', message_string )
117 elif message.get( 'X-AttachCheck-Override' ) == "Yes":
125 # if we are not expecting anything more, we should send the message