diff --git a/.editorconfig b/.editorconfig index 9cebe6d6d..cd3315bd8 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ end_of_line = lf insert_final_newline = true # 4 space indentation -[*.{c,h,lua}] +[*.{c,h,lua,py}] indent_style = space indent_size = 4 diff --git a/process/CMakeLists.txt b/process/CMakeLists.txt index 174fae694..0ffb7b4a2 100644 --- a/process/CMakeLists.txt +++ b/process/CMakeLists.txt @@ -1,5 +1,6 @@ install(PROGRAMS create-orders backup-eressea run-turn send-zip-report send-bz2-report compress.py compress.sh epasswd.py orders-process +process-orders.py accept-orders.py checkpasswd.py sendreport.sh sendreports.sh orders-accept DESTINATION bin) install(DIRECTORY cron/ DESTINATION bin USE_SOURCE_PERMISSIONS diff --git a/process/orders-accept.py b/process/orders-accept.py deleted file mode 100755 index 2f8f0bd29..000000000 --- a/process/orders-accept.py +++ /dev/null @@ -1,378 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- - -from email.Utils import parseaddr -from email.Parser import Parser -import os -import os.path -import ConfigParser -from re import compile, IGNORECASE -from stat import ST_MTIME -from string import upper, split, replace -import logging -import sys -from sys import stdin -from time import ctime, sleep, time -from socket import gethostname -from rfc822 import parsedate_tz, mktime_tz - -if 'ERESSEA' in os.environ: - dir = os.environ['ERESSEA'] -elif 'HOME' in os.environ: - dir = os.path.join(os.environ['HOME'], '/eressea') -else: # WTF? No HOME? - dir = "/home/eressea/eressea" -if not os.path.isdir(dir): - print "please set the ERESSEA environment variable to the install path" - sys.exit(1) -rootdir = dir - -game = int(sys.argv[1]) -gamedir = os.path.join(rootdir, "game-%d" % (game, )) -frommail = 'eressea-server@kn-bremen.de' -gamename = 'Eressea' -sender = '%s Server <%s>' % (gamename, frommail) - -inifile = os.path.join(gamedir, 'eressea.ini') -if not os.path.exists(inifile): - print "no such file: " . inifile -else: - config = ConfigParser.ConfigParser() - config.read(inifile) - if config.has_option('game', 'email'): - frommail = config.get('game', 'email') - if config.has_option('game', 'name'): - gamename = config.get('game', 'name') - if config.has_option('game', 'sender'): - sender = config.get('game', 'sender') - else: - sender = "%s Server <%s>" % (gamename, frommail) - config = None -prefix = 'turn-' -hostname = gethostname() -orderbase = "orders.dir" -sendmail = True -# maximum number of reports per sender: -maxfiles = 20 -# write headers to file? -writeheaders = True -# reject all html email? -rejecthtml = True - -def unlock_file(filename): - try: - os.unlink(filename+".lock") - except: - print "could not unlock %s.lock, file not found" % filename - -def lock_file(filename): - i = 0 - wait = 1 - if not os.path.exists(filename): - file=open(filename, "w") - file.close() - while True: - try: - os.symlink(filename, filename+".lock") - return - except: - i = i+1 - if i == 5: unlock_file(filename) - sleep(wait) - wait = wait*2 - -messages = { - "multipart-en" : - "ERROR: The orders you sent contain no plaintext. " \ - "The Eressea server cannot process orders containing HTML " \ - "or invalid attachments, which are the reasons why this " \ - "usually happens. Please change the settings of your mail " \ - "software and re-send the orders.", - - "multipart-de" : - "FEHLER: Die von dir eingeschickte Mail enth�lt keinen " \ - "Text. Evtl. hast Du den Zug als HTML oder als anderweitig " \ - "ung�ltig formatierte Mail ingeschickt. Wir k�nnen ihn " \ - "deshalb nicht ber�cksichtigen. Schicke den Zug nochmals " \ - "als reinen Text ohne Formatierungen ein.", - - "maildate-de": - "Es erreichte uns bereits ein Zug mit einem sp�teren " \ - "Absendedatum (%s > %s). Entweder ist deine " \ - "Systemzeit verstellt, oder ein Zug hat einen anderen Zug von " \ - "dir auf dem Transportweg �berholt. Entscheidend f�r die " \ - "Auswertungsreihenfolge ist das Absendedatum, d.h. der Date:-Header " \ - "deiner Mail.", - - "maildate-en": - "The server already received an order file that was sent at a later " \ - "date (%s > %s). Either your system clock is wrong, or two messages have " \ - "overtaken each other on the way to the server. The order of " \ - "execution on the server is always according to the Date: header in " \ - "your mail.", - - "nodate-en": - "Your message did not contain a valid Date: header in accordance with RFC2822.", - - "nodate-de": - "Deine Nachricht enthielt keinen gueltigen Date: header nach RFC2822.", - - "error-de": - "Fehler", - - "error-en": - "Error", - - "warning-de": - "Warnung", - - "warning-en": - "Warning", - - "subject-de": - "Befehle angekommen", - - "subject-en": - "orders received" -} - -# return 1 if addr is a valid email address -def valid_email(addr): - rfc822_specials = '/()<>@,;:\\"[]' - # First we validate the name portion (name@domain) - c = 0 - while c < len(addr): - if addr[c] == '"' and (not c or addr[c - 1] == '.' or addr[c - 1] == '"'): - c = c + 1 - while c < len(addr): - if addr[c] == '"': break - if addr[c] == '\\' and addr[c + 1] == ' ': - c = c + 2 - continue - if ord(addr[c]) < 32 or ord(addr[c]) >= 127: return 0 - c = c + 1 - else: return 0 - if addr[c] == '@': break - if addr[c] != '.': return 0 - c = c + 1 - continue - if addr[c] == '@': break - if ord(addr[c]) <= 32 or ord(addr[c]) >= 127: return 0 - if addr[c] in rfc822_specials: return 0 - c = c + 1 - if not c or addr[c - 1] == '.': return 0 - - # Next we validate the domain portion (name@domain) - domain = c = c + 1 - if domain >= len(addr): return 0 - count = 0 - while c < len(addr): - if addr[c] == '.': - if c == domain or addr[c - 1] == '.': return 0 - count = count + 1 - if ord(addr[c]) <= 32 or ord(addr[c]) >= 127: return 0 - if addr[c] in rfc822_specials: return 0 - c = c + 1 - return count >= 1 - -# return the replyto or from address in the header -def get_sender(header): - replyto = header.get("Reply-To") - if replyto is None: - replyto = header.get("From") - if replyto is None: return None - x = parseaddr(replyto) - return x[1] - -# return first available filename basename,[0-9]+ -def available_file(dirname, basename): - ver = 0 - maxdate = 0 - filename = "%s/%s,%s,%d" % (dirname, basename, hostname, ver) - while os.path.exists(filename): - maxdate = max(os.stat(filename)[ST_MTIME], maxdate) - ver = ver + 1 - filename = "%s/%s,%s,%d" % (dirname, basename, hostname, ver) - if ver >= maxfiles: - return None, None - return maxdate, filename - -def formatpar(string, l=76, indent=2): - words = split(string) - res = "" - ll = 0 - first = 1 - - for word in words: - if first == 1: - res = word - first = 0 - ll = len(word) - else: - if ll + len(word) > l: - res = res + "\n"+" "*indent+word - ll = len(word) + indent - else: - res = res+" "+word - ll = ll + len(word) + 1 - - return res+"\n" - -def store_message(message, filename): - outfile = open(filename, "w") - outfile.write(message.as_string()) - outfile.close() - return - -def write_part(outfile, part): - charset = part.get_content_charset() - payload = part.get_payload(decode=True) - - if charset is None: - charset = "latin1" - try: - msg = payload.decode(charset, "ignore") - except: - msg = payload - charset = None - try: - utf8 = msg.encode("utf-8", "ignore") - outfile.write(utf8) - except: - outfile.write(msg) - return False - outfile.write("\n"); - return True - -def copy_orders(message, filename, sender): - # print the header first - if writeheaders: - from os.path import split - dirname, basename = split(filename) - dirname = dirname + '/headers' - if not os.path.exists(dirname): os.mkdir(dirname) - outfile = open(dirname + '/' + basename, "w") - for name, value in message.items(): - outfile.write(name + ": " + value + "\n") - outfile.close() - - found = False - outfile = open(filename, "w") - if message.is_multipart(): - for part in message.get_payload(): - content_type = part.get_content_type() - logger.debug("found content type %s for %s" % (content_type, sender)) - if content_type=="text/plain": - if write_part(outfile, part): - found = True - else: - charset = part.get_content_charset() - logger.error("could not write text/plain part (charset=%s) for %s" % (charset, sender)) - - else: - if write_part(outfile, message): - found = True - else: - charset = message.get_content_charset() - logger.error("could not write text/plain message (charset=%s) for %s" % (charset, sender)) - outfile.close() - return found - -# create a file, containing: -# game=0 locale=de file=/path/to/filename email=rcpt@domain.to -def accept(game, locale, stream, extend=None): - global rootdir, orderbase, gamedir, gamename, sender - if extend is not None: - orderbase = orderbase + ".pre-" + extend - savedir = os.path.join(gamedir, orderbase) - # check if it's one of the pre-sent orders. - # create the save-directories if they don't exist - if not os.path.exists(gamedir): os.mkdir(gamedir) - if not os.path.exists(savedir): os.mkdir(savedir) - # parse message - message = Parser().parse(stream) - email = get_sender(message) - logger = logging.getLogger(email) - # write syslog - if email is None or valid_email(email)==0: - logger.warning("invalid email address: " + str(email)) - return -1 - logger.info("received orders from " + email) - # get an available filename - lock_file(gamedir + "/orders.queue") - maxdate, filename = available_file(savedir, prefix + email) - if filename is None: - logger.warning("more than " + str(maxfiles) + " orders from " + email) - return -1 - # copy the orders to the file - text_ok = copy_orders(message, filename, email) - unlock_file(gamedir + "/orders.queue") - - warning, msg, fail = None, "", False - maildate = message.get("Date") - if maildate != None: - turndate = mktime_tz(parsedate_tz(maildate)) - os.utime(filename, (turndate, turndate)) - logger.debug("mail date is '%s' (%d)" % (maildate, turndate)) - if turndate < maxdate: - logger.warning("inconsistent message date " + email) - warning = " (" + messages["warning-" + locale] + ")" - msg = msg + formatpar(messages["maildate-" + locale] % (ctime(maxdate),ctime(turndate)), 76, 2) + "\n" - else: - logger.warning("missing message date " + email) - warning = " (" + messages["warning-" + locale] + ")" - msg = msg + formatpar(messages["nodate-" + locale], 76, 2) + "\n" - - if not text_ok: - warning = " (" + messages["error-" + locale] + ")" - msg = msg + formatpar(messages["multipart-" + locale], 76, 2) + "\n" - logger.warning("rejected - no text/plain in orders from " + email) - os.unlink(filename) - savedir = savedir + "/rejected" - if not os.path.exists(savedir): os.mkdir(savedir) - lock_file(gamedir + "/orders.queue") - maxdate, filename = available_file(savedir, prefix + email) - store_message(message, filename) - unlock_file(gamedir + "/orders.queue") - fail = True - - if sendmail and warning is not None: - subject = gamename + " " + messages["subject-"+locale] + warning - mail = "Subject: %s\nFrom: %s\nTo: %s\n\n" % (subject, sender, email) + msg - from smtplib import SMTP - server = SMTP("localhost") - server.sendmail(sender, email, mail) - server.close() - - if not sendmail: - print text_ok, fail, email - print filename - - if not fail: - lock_file(gamedir + "/orders.queue") - queue = open(gamedir + "/orders.queue", "a") - queue.write("email=%s file=%s locale=%s game=%s\n" % (email, filename, locale, game)) - queue.close() - unlock_file(gamedir + "/orders.queue") - - logger.info("done - accepted orders from " + email) - - return 0 - -# the main body of the script: -try: - os.mkdir(os.path.join(rootdir, 'log')) -except: - pass # already exists? -LOG_FILENAME=os.path.join(rootdir, 'log/orders.log') -logging.basicConfig(level=logging.DEBUG, filename=LOG_FILENAME) -logger = logging -delay=None # TODO: parse the turn delay -locale = sys.argv[2] -infile = stdin -if len(sys.argv)>3: - infile = open(sys.argv[3], "r") -retval = accept(game, locale, infile, delay) -if infile!=stdin: - infile.close() -sys.exit(retval) diff --git a/process/orders-process b/process/orders-process index 79c7b3378..09ca7dc0c 100755 --- a/process/orders-process +++ b/process/orders-process @@ -1,242 +1,3 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- +#!/bin/sh +python process-orders.py "$@" -from os import unlink, symlink, rename, popen, tmpfile -import sys -import os -import os.path -import ConfigParser -from re import compile, IGNORECASE -from string import split, join, upper, strip -from sys import argv, exit -from time import sleep, time, ctime -from syslog import openlog, closelog, syslog - -from epasswd import EPasswd - -def pwd_get_email(faction, pwd, pwdfile=None): - return None - -def split_filename(filename): - return os.path.split(filename) - -def unlock_file(filename): - try: - unlink(filename+".lock") - except: - print "could not unlock %s.lock, file not found" % filename - raise - -def lock_file(filename): - i = 0 - wait = 1 - if not os.path.exists(filename): - file=open(filename, "w") - file.close() - while True: - try: - symlink(filename, filename+".lock") - return - except: - i = i+1 - if i == 5: - raise - sleep(wait) - wait = wait*2 - -messages = { -"subject-de": "Befehle angekommen", -"subject-en": "orders received", - -"validate-en": "Validating", -"validate-de": "Verarbeite", - -"faction-en": "Faction", -"faction-de": "Partei", - -"unknown-de": "WARNUNG: Die Partei ist nicht bekannt, oder das Passwort falsch!", -"unknown-en": "WARNING: This faction is unknown, or the password is incorrect!", - -"warning-de": "Warnung", -"warning-en": "Warning", - -"error-de": "Fehler", -"error-en": "Error", -} - -game = int(sys.argv[1]) -echeck_cmd = "/home/eressea/echeck/echeck.sh" -maxlines = 25 - -# base directory for all your games: -install_dir = "/home/eressea/eressea" -if 'ERESSEA' in os.environ: - install_dir = os.environ['ERESSEA'] -elif 'HOME' in os.environ: - install_dir = os.path.join(os.environ['HOME'], '/eressea') -if not os.path.isdir(install_dir): - print "please set the ERESSEA environment variable to the install path" - sys.exit(1) - -game_dir = os.path.join(install_dir, "game-%d" % (game, )) -frommail = 'eressea-server@kn-bremen.de' -gamename = 'Eressea' -sender = '%s Server <%s>' % (gamename, frommail) - -inifile = os.path.join(game_dir, 'eressea.ini') -if not os.path.exists(inifile): - print "no such file: " . inifile -else: - config = ConfigParser.ConfigParser() - config.read(inifile) - if config.has_option('game', 'email'): - frommail = config.get('game', 'email') - if config.has_option('game', 'name'): - gamename = config.get('game', 'name') - if config.has_option('game', 'sender'): - sender = config.get('game', 'sender') - else: - sender = "%s Server <%s>" % (gamename, frommail) - config = None - -queue_file = os.path.join(game_dir, "orders.queue") -if not os.path.exists(queue_file): - exit(0) - -# regular expression that finds the start of a faction -fact_re = compile("^\s*(eressea|partei|faction)\s+([a-zA-Z0-9]+)\s+\"?([^\"]*)\"?", IGNORECASE) - -def check_pwd(filename, email, pw_data): - results = [] - try: - file = open(filename, "r") - except: - print "could not open file", filename - return results - for line in file.readlines(): - mo = fact_re.search(strip(line)) - if mo != None: - fact_nr = str(mo.group(2)) - fact_pw = str(mo.group(3)) - if pw_data.fac_exists(fact_nr): - if not pw_data.check(fact_nr, fact_pw): - game_email = pw_data.get_email(fact_nr) - results = results + [ (fact_nr, game_email, False, fact_pw) ] - else: - game_email = pw_data.get_email(fact_nr) - results = results + [ (fact_nr, game_email, True, fact_pw) ] - else: - results = results + [ (fact_nr, None, False, fact_pw) ] - return results - -def echeck(filename, locale, rules): - dirname, filename = split_filename(filename) - stream = popen("%s %s %s %s %s" % (echeck_cmd, locale, filename, dirname, rules), 'r') - lines = stream.readlines() - if len(lines)==0: - stream.close() - return None - if len(lines)>maxlines: - mail = join(lines[:maxlines-3] + ["...", "\n"] + lines[-3:], '') - else: - mail = join(lines[:maxlines], '') - stream.close() - return mail - -# parse the queue file - -#print "connecting to SMTP..." -from smtplib import SMTP -try: - server = SMTP("localhost") -except: - print "could not connect to SMTP server" - exit(0) - -#print "reading password file..." -pw_data = EPasswd(os.path.join(game_dir,"passwd")) - -#print "reading orders.queue..." -# move the queue file to a save space while locking it: -try: - lock_file(queue_file) -except: - exit(0) -queuefile = open(queue_file, "r") -lines = queuefile.readlines() -queuefile.close() - -# copy to a temp file - -tname="/tmp/orders.queue.%s" % str(time()) -try: - lock_file(tname) -except: - exit(0) -tmpfile=open(tname, "w") -for line in lines: - tmpfile.write(line) -tmpfile.close() - -openlog("orders") - -unlink(queue_file) -try: - unlock_file(queue_file) -except: - pass - -for line in lines: - tokens = split(line[:-1], ' ') - dict = {} - for token in tokens: - name, value = split(token, '=') - dict[name] = value - - email = dict["email"] - locale = dict["locale"] - game = int(dict["game"]) - infile = dict["file"] - gamename='[E%d]' % game - rules='e%d' % game - warning = "" - failed = True - results = check_pwd(infile, email, pw_data) - logfile = open(os.path.join(game_dir, "zug.log"), "a") - dirname, filename = split_filename(infile) - msg = messages["validate-"+locale] + " " + infile + "\n\n" - for faction, game_email, success, pwd in results: - msg = msg + messages["faction-"+locale] + " " + faction + "\n" - if success: failed = False - else: msg = msg + messages["unknown-"+locale] + "\n" - msg = msg + "\n" - logfile.write("%s:%s:%s:%s:%s:%s\n" % (ctime(time()), email, game_email, faction, pwd, success)) - logfile.close() - - if failed: - warning = " (" + messages["warning-" + locale] + ")" - syslog("failed - no valid password in " + infile) - else: - result = None - if os.path.exists(echeck_cmd): - result = echeck(infile, locale, rules) - if result is None: - # echeck did not finish - msg = msg + "Echeck is broken. Your turn was accepted, but could not be verified.\n" - warning = " (" + messages["warning-" + locale] + ")" - syslog("process - echeck broken, " + infile) - else: - msg = msg + result - syslog("process - checked orders in " + infile) - - subject = gamename + " " + messages["subject-" + locale] + warning - msg = "Subject: %s\nFrom: %s\nTo: %s\nContent-Type: text/plain; charset=utf-8\n\n" % (subject, sender, email) + msg - try: - server.sendmail(sender, email, msg) - except: - syslog("failed - cannot send to " + email) - -server.close() - -closelog() -unlink(tname) -unlock_file(tname) diff --git a/process/process-orders.py b/process/process-orders.py new file mode 100755 index 000000000..8ed5e8625 --- /dev/null +++ b/process/process-orders.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from os import unlink, symlink, rename, popen, tmpfile +import sys +import os +import os.path +import ConfigParser +import subprocess +from re import compile, IGNORECASE +from string import split, join, upper, strip +from sys import argv, exit +from time import sleep, time, ctime +from syslog import openlog, closelog, syslog + +from epasswd import EPasswd + +def pwd_get_email(faction, pwd, pwdfile=None): + return None + +def split_filename(filename): + return os.path.split(filename) + +def unlock_file(filename): + try: + unlink(filename+".lock") + except: + print "could not unlock %s.lock, file not found" % filename + raise + +def lock_file(filename): + i = 0 + wait = 1 + if not os.path.exists(filename): + file=open(filename, "w") + file.close() + while True: + try: + symlink(filename, filename+".lock") + return + except: + i = i+1 + if i == 5: + raise + sleep(wait) + wait = wait*2 + +messages = { +"subject-de": "Befehle angekommen", +"subject-en": "orders received", + +"validate-en": "Validating", +"validate-de": "Verarbeite", + +"faction-en": "Faction", +"faction-de": "Partei", + +"unknown-de": "WARNUNG: Die Partei ist nicht bekannt, oder das Passwort falsch!", +"unknown-en": "WARNING: This faction is unknown, or the password is incorrect!", + +"warning-de": "Warnung", +"warning-en": "Warning", + +"error-de": "Fehler", +"error-en": "Error", +} + +game = int(sys.argv[1]) +echeck_cmd = "/home/eressea/echeck/echeck.sh" +maxlines = 25 + +# base directory for all your games: +install_dir = "/home/eressea/eressea" +if 'ERESSEA' in os.environ: + install_dir = os.environ['ERESSEA'] +elif 'HOME' in os.environ: + install_dir = os.path.join(os.environ['HOME'], 'eressea') +if not os.path.isdir(install_dir): + print "please set the ERESSEA environment variable to the install path" + sys.exit(1) + +game_dir = os.path.join(install_dir, "game-%d" % (game, )) +gamename = 'Eressea' + +inifile = os.path.join(game_dir, 'eressea.ini') +queue_file = os.path.join(game_dir, "orders.queue") +if not os.path.exists(queue_file): + exit(0) + +# regular expression that finds the start of a faction +fact_re = compile("^\s*(eressea|partei|faction)\s+([a-zA-Z0-9]+)\s+\"?([^\"]*)\"?", IGNORECASE) + +def check_pwd(filename, email, pw_data): + results = [] + try: + file = open(filename, "r") + except: + print "could not open file", filename + return results + for line in file.readlines(): + mo = fact_re.search(strip(line)) + if mo != None: + fact_nr = str(mo.group(2)) + fact_pw = str(mo.group(3)) + if pw_data.fac_exists(fact_nr): + if not pw_data.check(fact_nr, fact_pw): + game_email = pw_data.get_email(fact_nr) + results = results + [ (fact_nr, game_email, False, fact_pw) ] + else: + game_email = pw_data.get_email(fact_nr) + results = results + [ (fact_nr, game_email, True, fact_pw) ] + else: + results = results + [ (fact_nr, None, False, fact_pw) ] + return results + +def echeck(filename, locale, rules): + dirname, filename = split_filename(filename) + stream = popen("%s %s %s %s %s" % (echeck_cmd, locale, filename, dirname, rules), 'r') + lines = stream.readlines() + if len(lines)==0: + stream.close() + return None + if len(lines)>maxlines: + mail = join(lines[:maxlines-3] + ["...", "\n"] + lines[-3:], '') + else: + mail = join(lines[:maxlines], '') + stream.close() + return mail + +#print "reading password file..." +pw_data = EPasswd(os.path.join(game_dir,"passwd")) + +#print "reading orders.queue..." +# move the queue file to a save space while locking it: +try: + lock_file(queue_file) +except: + exit(0) +queuefile = open(queue_file, "r") +lines = queuefile.readlines() +queuefile.close() + +# copy to a temp file + +tname="/tmp/orders.queue.%s" % str(time()) +try: + lock_file(tname) +except: + exit(0) +tmpfile=open(tname, "w") +for line in lines: + tmpfile.write(line) +tmpfile.close() + +openlog("orders") + +unlink(queue_file) +try: + unlock_file(queue_file) +except: + pass + +for line in lines: + tokens = split(line[:-1], ' ') + dict = {} + for token in tokens: + name, value = split(token, '=') + dict[name] = value + + email = dict["email"] + locale = dict["locale"] + game = int(dict["game"]) + infile = dict["file"] + gamename='[E%d]' % game + rules='e%d' % game + warning = "" + failed = True + results = check_pwd(infile, email, pw_data) + logfile = open(os.path.join(game_dir, "zug.log"), "a") + dirname, filename = split_filename(infile) + msg = messages["validate-"+locale] + " " + infile + "\n\n" + for faction, game_email, success, pwd in results: + msg = msg + messages["faction-"+locale] + " " + faction + "\n" + if success: failed = False + else: msg = msg + messages["unknown-"+locale] + "\n" + msg = msg + "\n" + logfile.write("%s:%s:%s:%s:%s:%s\n" % (ctime(time()), email, game_email, faction, pwd, success)) + logfile.close() + + if failed: + warning = " (" + messages["warning-" + locale] + ")" + syslog("failed - no valid password in " + infile) + else: + result = None + if os.path.exists(echeck_cmd): + result = echeck(infile, locale, rules) + if result is None: + # echeck did not finish + msg = msg + "Echeck is broken. Your turn was accepted, but could not be verified.\n" + warning = " (" + messages["warning-" + locale] + ")" + syslog("process - echeck broken, " + infile) + else: + msg = msg + result + syslog("process - checked orders in " + infile) + + subject = gamename + " " + messages["subject-" + locale] + warning + try: + sp = subprocess.Popen(['mutt', '-s', subject, email], stdin=subprocess.PIPE) + sp.communicate(msg) + except: + syslog("failed - cannot send to " + email) + +closelog() +unlink(tname) +unlock_file(tname)