How safe is this program?

Robert Smart (smart@koel.mel.dit.CSIRO.AU)
Wed, 1 Jun 94 07:40:02 GMT

I'm new to python. I wrote the program below to learn about python
and to solve a problem I've been having with mail messages posted
to multiple mailing lists. I want to throw away messages that I've
already received.

Now the question to all you python gurus is: is their any chance that
the program will exit normally (status 0) in any way other than through
the exit(0) call in the program? Because if that happens I'll lose
a mail message.

Bob Smart

#!/pub/bin/python
#
# dup-mail.py keeps a dbm database of MD5 checksums of incoming mail
# messages. It actually remembers the msgid of files just in case two
# files give the same md5 checksum (?!) this is probably a waste of
# diskspace.
#
# This is meant to be used in an mh .maildelivery file with a line
# such as
# * - | A "/pub/bin/dup-mail.py"
# This will appear (to slocal) to successfully deliver the message if
# the message is already in the database.
#
# You can initialize the database with a command such as
#
# cd ~/Mail
# find . -name '[1-9]*' -exec dup-mail.py '{}' \; -print | tee dup-mail.ls
#
# This also gives a list of files that are duplicates that you might like to
# delete. [The behaviour of -exec seems inverted to me.]

from rfc822 import Message
from sys import stdin, exit, argv
from md5 import md5
from posix import environ
import dbm

if len(argv) == 1: file = stdin
elif len(argv) == 2: file = open( argv[1], 'r')
else: print 'usage: dup-mail.py [file]'; exit(2)

m = Message(file)

d = md5()

msgid = m.getheader('Message-Id')
subj = m.getheader('Subject')

if msgid != None:
d.update( msgid)
else:
msgid = ''
if subj != None:
d.update( subj)

l = file.readline()
while l != '':
d.update(l)
l = file.readline()

md = d.digest()

db = dbm.open( environ['HOME'] + '/Mail/.mail-md5', 'rw', 0600)

try:
if db[md] == msgid: exit(0) # we've already got it: say 'delivered'
except KeyError: pass

db[md] = msgid # remember we got this message
exit(1) # and exit saying we haven't delivered the message yet