diff options
Diffstat (limited to 'Tools')
-rwxr-xr-x | Tools/scripts/mailerdaemon.py | 178 |
1 files changed, 136 insertions, 42 deletions
diff --git a/Tools/scripts/mailerdaemon.py b/Tools/scripts/mailerdaemon.py index 245f670..f2e8ac4 100755 --- a/Tools/scripts/mailerdaemon.py +++ b/Tools/scripts/mailerdaemon.py @@ -2,6 +2,7 @@ import string import rfc822 +import calendar import regex import os import sys @@ -17,21 +18,22 @@ class ErrorMessage(rfc822.Message): if not sub: return 0 sub = string.lower(sub) - if sub == 'waiting mail': return 1 + if sub[:12] == 'waiting mail': return 1 if string.find(sub, 'warning') >= 0: return 1 + self.sub = sub return 0 def get_errors(self): for p in EMPARSERS: self.rewindbody() try: - return p(self.fp) + return p(self.fp, self.sub) except Unparseable: pass raise Unparseable sendmail_pattern = regex.compile('[0-9][0-9][0-9] ') -def emparse_sendmail(fp): +def emparse_sendmail(fp, sub): while 1: line = fp.readline() if not line: @@ -60,7 +62,6 @@ def emparse_sendmail(fp): line = line[:-1] if not line: continue - found_a_line = 1 if sendmail_pattern.match(line) == 4: # Yes, an error/warning line. Ignore 4, remember 5, stop on rest if line[0] == '5': @@ -72,12 +73,23 @@ def emparse_sendmail(fp): line = string.split(line) if line and line[0][:3] == '---': break + found_a_line = 1 + # special case for CWI sendmail + if len(line) > 1 and line[1] == 'Undelivered': + while 1: + line = fp.readline() + if not line: + break + line = string.strip(line) + if not line: + break + errors.append(line + ': ' + sub) # Empty transcripts are ok, others without an error are not. if found_a_line and not (errors or warnings): raise Unparseable return errors -def emparse_cts(fp): +def emparse_cts(fp, sub): while 1: line = fp.readline() if not line: @@ -106,7 +118,7 @@ def emparse_cts(fp): errors.append(line) return errors -def emparse_aol(fp): +def emparse_aol(fp, sub): while 1: line = fp.readline() if not line: @@ -132,7 +144,7 @@ def emparse_aol(fp): raise Unparseable return errors -def emparse_compuserve(fp): +def emparse_compuserve(fp, sub): while 1: line = fp.readline() if not line: @@ -157,8 +169,7 @@ def emparse_compuserve(fp): return errors prov_pattern = regex.compile('.* | \(.*\)') - -def emparse_providence(fp): +def emparse_providence(fp, sub): while 1: line = fp.readline() if not line: @@ -189,58 +200,141 @@ def emparse_providence(fp): raise Unparseable return errors +def emparse_x400(fp, sub): + exp = 'This report relates to your message:' + while 1: + line = fp.readline() + if not line: + raise Unparseable + line = line[:-1] + + # Check that we're not in the returned message yet + if string.lower(line)[:5] == 'from:': + raise Unparseable + if line[:len(exp)] == exp: + break + + errors = [] + exp = 'Your message was not delivered to' + while 1: + line = fp.readline() + if not line: + break + line = line[:-1] + if not line: + continue + if line[:len(exp)] == exp: + error = string.strip(line[len(exp):]) + sep = ': ' + while 1: + line = fp.readline() + if not line: + break + line = line[:-1] + if not line: + break + if line[0] == ' ' and line[-1] != ':': + error = error + sep + string.strip(line) + sep = '; ' + errors.append(error) + return errors + raise Unparseable + +def emparse_passau(fp, sub): + exp = 'Unable to deliver message because' + while 1: + line = fp.readline() + if not line: + raise Unparseable + if string.lower(line)[:5] == 'from:': + raise Unparseable + if line[:len(exp)] == exp: + break + + errors = [] + exp = 'Returned Text follows' + while 1: + line = fp.readline() + if not line: + raise Unparseable + line = line[:-1] + # Check that we're not in the returned message yet + if string.lower(line)[:5] == 'from:': + raise Unparseable + if not line: + continue + if line[:len(exp)] == exp: + return errors + errors.append(string.strip(line)) + EMPARSERS = [emparse_sendmail, emparse_aol, emparse_cts, emparse_compuserve, - emparse_providence] + emparse_providence, emparse_x400, emparse_passau] + +def sort_numeric(a, b): + a = string.atoi(a) + b = string.atoi(b) + if a < b: return -1 + elif a > b: return 1 + else: return 0 def parsedir(dir, modify): os.chdir(dir) - files = os.listdir('.') pat = regex.compile('^[0-9]*$') errordict = {} + errorfirst = {} errorlast = {} nok = nwarn = nbad = 0 + + # find all numeric file names and sort them + files = filter(lambda fn, pat=pat: pat.match(fn) > 0, os.listdir('.')) + files.sort(sort_numeric) for fn in files: - if pat.match(fn) > 0: - # Ok, so it's a numeric filename. Lets try to parse it. - fp = open(fn) - m = ErrorMessage(fp) - sender = m.getaddr('From') - print '%s\t%-40s\t'%(fn, sender[1]), - - if m.is_warning(): - print 'warning only' - nwarn = nwarn + 1 - if modify: - os.unlink(fn) - continue - - try: - errors = m.get_errors() - except Unparseable: - print '** Not parseable' - nbad = nbad + 1 - continue - print len(errors), 'errors' - - # Remember them - for e in errors: - if not errordict.has_key(e): - errordict[e] = 1 - else: - errordict[e] = errordict[e] + 1 - errorlast[e] = fn + # Lets try to parse the file. + fp = open(fn) + m = ErrorMessage(fp) + sender = m.getaddr('From') + print '%s\t%-40s\t'%(fn, sender[1]), - nok = nok + 1 + if m.is_warning(): + print 'warning only' + nwarn = nwarn + 1 if modify: os.unlink(fn) + continue + + try: + errors = m.get_errors() + except Unparseable: + print '** Not parseable' + nbad = nbad + 1 + continue + print len(errors), 'errors' + + # Remember them + for e in errors: + try: + mm, dd = m.getdate('date')[1:1+2] + date = '%s %02d' % (calendar.month_abbr[mm], dd) + except: + date = '??????' + if not errordict.has_key(e): + errordict[e] = 1 + errorfirst[e] = '%s (%s)' % (fn, date) + else: + errordict[e] = errordict[e] + 1 + errorlast[e] = '%s (%s)' % (fn, date) + + nok = nok + 1 + if modify: + os.unlink(fn) print '--------------' print nok, 'files parsed,',nwarn,'files warning-only,', print nbad,'files unparseable' print '--------------' for e in errordict.keys(): - print errordict[e], '\t', errorlast[e], '\t', e + print errordict[e], errorfirst[e], '-', errorlast[e], '\t', e def main(): modify = 0 |