X-Git-Url: https://git.sommitrealweird.co.uk/eoc.git/blobdiff_plain/747343e09d2930ebc783f9cc657a87877e823fb8..955452c7da93eb4307e37cdfc1dc1c8679e92fcb:/eoc.py?ds=inline diff --git a/eoc.py b/eoc.py index 52621bc..194d040 100644 --- a/eoc.py +++ b/eoc.py @@ -4,7 +4,7 @@ This is a simple mailing list manager that mimicks the ezmlm-idx mail address commands. See manual page for more information. """ -VERSION = "1.2.1" +VERSION = "1.2.5" PLUGIN_INTERFACE_VERSION = "1" import getopt @@ -80,6 +80,34 @@ COMMANDS = SIMPLE_COMMANDS + SUB_COMMANDS + HASH_COMMANDS def md5sum_as_hex(s): return md5.new(s).hexdigest() + +def forkexec(argv, text): + """Run a command (given as argv array) and write text to its stdin""" + (r, w) = os.pipe() + pid = os.fork() + if pid == -1: + raise Exception("fork failed") + elif pid == 0: + os.dup2(r, 0) + os.close(r) + os.close(w) + fd = os.open("/dev/null", os.O_RDWR) + os.dup2(fd, 1) + os.dup2(fd, 2) + os.execvp(argv[0], argv) + sys.exit(1) + else: + os.close(r) + os.write(w, text) + os.close(w) + (pid2, exit) = os.waitpid(pid, 0) + if pid != pid2: + raise Exception("os.waitpid for %d returned for %d" % (pid, pid2)) + if exit != 0: + raise Exception("subprocess failed, exit=0x%x" % exit) + return exit + + environ = None def set_environ(new_environ): @@ -395,22 +423,28 @@ class MailingListManager: "\n ".join(text[:text.find("\n\n")].split("\n")))) if recipients: if self.smtp_server: - smtp = smtplib.SMTP(self.smtp_server) - smtp.sendmail(envelope_sender, recipients, text) - smtp.quit() + try: + smtp = smtplib.SMTP(self.smtp_server) + smtp.sendmail(envelope_sender, recipients, text) + smtp.quit() + except: + error("Error sending SMTP mail, mail probably not sent") + sys.exit(1) elif self.qmqp_server: - q = qmqp.QMQP(self.qmqp_server) - q.sendmail(envelope_sender, recipients, text) - q.quit() + try: + q = qmqp.QMQP(self.qmqp_server) + q.sendmail(envelope_sender, recipients, text) + q.quit() + except: + error("Error sending QMQP mail, mail probably not sent") + sys.exit(1) else: - recipients = string.join(recipients, " ") - f = os.popen("%s -oi -f '%s' %s" % - (self.sendmail, - envelope_sender, - recipients), - "w") - f.write(text) - f.close() + status = forkexec([self.sendmail, "-oi", "-f", + envelope_sender] + recipients, text) + if status: + error("%s returned %s, mail sending probably failed" % + (self.sendmail, status)) + sys.exit((status >> 8) & 0xff) else: debug("send_mail: no recipients, not sending") @@ -463,6 +497,8 @@ class MailingList: def read_stdin(self): data = sys.stdin.read() + # Convert CRLF to plain LF + data = "\n".join(data.split("\r\n")) # Skip Unix mbox "From " mail start indicator if data[:5] == "From ": data = string.split(data, "\n", 1)[1] @@ -515,7 +551,7 @@ class MailingList: return "\n".join(headers) + "\n\n" + body except: - error("Cannot MIME encode header, using original ones, sorry") + info("Cannot MIME encode header, using original ones, sorry") return text def template(self, template_name, dict): @@ -621,7 +657,7 @@ class MailingList: "boundary": self.invent_boundary(), }) else: - self.info_message([recipient], "setlist-sorry", {}) + self.send_info_message([recipient], "setlist-sorry", {}) def parse_setlist_addresses(self, text): body = text.split("\n\n", 1)[1] @@ -892,6 +928,10 @@ class MailingList: return text + self.template("footer", {}) def send_mail_to_subscribers(self, text): + text = self.remove_some_headers(text, ["list-id", "list-help", + "list-unsubscribe", + "list-subscribe", "list-post", + "list-owner", "precedence"]) text = self.headers_to_add() + self.list_headers() + \ self.headers_to_remove(text) text = self.append_footer(text)