summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Vagelpohl <jens@netz.ooo>2006-04-29 10:45:07 +0000
committerJens Vagelpohl <jens@netz.ooo>2006-04-29 10:45:07 +0000
commit3ca476e5ac082d717bd6a3b8abb1334bcbb23894 (patch)
tree61151d4af06edf6e05cab82b2e9b2a6b4fce1e65
parent7c0b03a0e60ce360c365675d09c2da2be2ae8a7c (diff)
downloadMaildropHost-3ca476e5ac082d717bd6a3b8abb1334bcbb23894.zip
MaildropHost-3ca476e5ac082d717bd6a3b8abb1334bcbb23894.tar.gz
- the maildrop daemon used to read in every mail file in the spool
before deciding how many to send (MAILDROP_BATCH setting), which could fill up all memory if the messages are very large and the number of recipients very high. Now we only ever read in files up to the MAILDROP_BATCH setting. (patch by Maik Jablonski)
-rw-r--r--CHANGES.txt6
-rwxr-xr-xmaildrop/maildrop.py75
2 files changed, 47 insertions, 34 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 457ea64..1d8a1d2 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -4,6 +4,12 @@ MaildropHost version and change information
* Bugs fixed
+ - the maildrop daemon used to read in every mail file in the spool
+ before deciding how many to send (MAILDROP_BATCH setting), which
+ could fill up all memory if the messages are very large and the
+ number of recipients very high. Now we only ever read in files up
+ to the MAILDROP_BATCH setting. (patch by Maik Jablonski)
+
- Squashed a deprecation warning in the Email unit tests (patch
by Chris Withers)
diff --git a/maildrop/maildrop.py b/maildrop/maildrop.py
index 56b442d..4b4d86e 100755
--- a/maildrop/maildrop.py
+++ b/maildrop/maildrop.py
@@ -42,35 +42,8 @@ def mainloop():
if not '%s.lck' % x in all_files]
# Remove directories
- clean_files = [x for x in clean_files if not os.path.isdir(x)]
-
- for file_path in clean_files:
-
- # Read in file
- file_handle = open(file_path, 'r')
- file_contents = file_handle.read()
- file_handle.close()
-
- # Is this a real mail turd?
- if not file_contents.startswith('##To:'):
- continue
-
- # Parse and handle content (mail it out)
- mail_dict = {}
- mail_dict['file_path'] = file_path
- file_lines = file_contents.split('\n')
-
- for i in range(len(file_lines)):
- if file_lines[i].startswith('##'):
- header_line = file_lines[i][2:]
- header_key, header_val = header_line.split(':', 1)
- mail_dict[header_key] = header_val
- else:
- mail_dict['body'] = '\n'.join(file_lines[i:])
- break
-
- to_be_sent.append(mail_dict)
-
+ to_be_sent = [x for x in clean_files if not os.path.isdir(x)]
+
if len(to_be_sent) > 0:
# Open the log file
time_stamp = time.strftime('%Y/%m/%d %H:%M:%S')
@@ -105,8 +78,8 @@ def mainloop():
if MAILDROP_TLS > 0:
if (MAILDROP_TLS > 1 and
not smtp_server.has_extn('starttls')):
- # Problem: TLS is required but the server does not offer it
- # We stop processing here.
+ # Problem: TLS is required but the server does not
+ # offer it We stop processing here.
time_stamp = time.strftime('%Y/%m/%d %H:%M:%S')
err_msg = '!!!!! TLS unavailable at %s' % time_stamp
finish_msg = '### Finished at %s' % time_stamp
@@ -152,7 +125,11 @@ def mainloop():
log_file.close()
break
- for mail_dict in to_be_sent[0:batch]:
+ for file_path in to_be_sent[0:batch]:
+ mail_dict = read_mail(file_path)
+ if not mail_dict:
+ continue
+
# Create mail and send it off
h_from = mail_dict.get('From')
h_to = mail_dict.get('To')
@@ -164,12 +141,12 @@ def mainloop():
try:
smtp_server.sendmail(h_from, h_to_list, h_body)
stat = 'OK'
- os.remove(mail_dict.get('file_path'))
+ os.remove(file_path)
except smtplib.SMTPRecipientsRefused, e:
for (addr, error) in e.recipients.items():
stat = 'FATAL: ', str(e)
if str(error[0]) in FATAL_ERROR_CODES:
- os.remove(mail_dict.get('file_path'))
+ os.remove(file_path)
break
except smtplib.SMTPException, e:
stat = 'BAD: ', str(e)
@@ -192,6 +169,36 @@ def mainloop():
time.sleep(MAILDROP_INTERVAL)
+
+def read_mail(file_path):
+ """ Reads in a mail from a file, returns a dictionary with keys
+ for headers and body
+ """
+ # Read in file
+ file_handle = open(file_path, 'r')
+ file_contents = file_handle.read()
+ file_handle.close()
+
+ # Is this a real mail turd?
+ if not file_contents.startswith('##To:'):
+ return
+
+ # Parse and handle content (mail it out)
+ mail_dict = {}
+ file_lines = file_contents.split('\n')
+
+ for i in range(len(file_lines)):
+ if file_lines[i].startswith('##'):
+ header_line = file_lines[i][2:]
+ header_key, header_val = header_line.split(':', 1)
+ mail_dict[header_key] = header_val
+ else:
+ mail_dict['body'] = '\n'.join(file_lines[i:])
+ break
+
+ return mail_dict
+
+
def write_pid(pidfile_path, pid):
""" Write the daemon pid to our pid file """
pid_file = open(pidfile_path, 'w')