summaryrefslogtreecommitdiff
path: root/src/mailman/mta/postfix.py
diff options
context:
space:
mode:
authorBarry Warsaw2009-11-28 18:51:13 -0500
committerBarry Warsaw2009-11-28 18:51:13 -0500
commitebb3ead38ca35fc053f6b4df3919499c266636ed (patch)
treeac308c19163fe6a1e7a39434c8ae5e43a8ab9296 /src/mailman/mta/postfix.py
parent5f799a91a16e54f8d7f6333b49a7674b92cc204a (diff)
downloadmailman-ebb3ead38ca35fc053f6b4df3919499c266636ed.tar.gz
mailman-ebb3ead38ca35fc053f6b4df3919499c266636ed.tar.zst
mailman-ebb3ead38ca35fc053f6b4df3919499c266636ed.zip
Diffstat (limited to 'src/mailman/mta/postfix.py')
-rw-r--r--src/mailman/mta/postfix.py93
1 files changed, 53 insertions, 40 deletions
diff --git a/src/mailman/mta/postfix.py b/src/mailman/mta/postfix.py
index ca327dd1c..56ede5b45 100644
--- a/src/mailman/mta/postfix.py
+++ b/src/mailman/mta/postfix.py
@@ -60,32 +60,56 @@ class LMTP:
def create(self, mlist):
"""See `IMailTransportAgentAliases`."""
- # Acquire a lock file to prevent other processes from racing us here.
- with Lock(LOCKFILE):
- # We can ignore the mlist argument because for LMTP delivery, we
- # just generate the entire file every time.
- self._do_write_file()
+ # We can ignore the mlist argument because for LMTP delivery, we just
+ # generate the entire file every time.
+ self.regenerate()
delete = create
- def regenerate(self):
+ def regenerate(self, output=None):
"""See `IMailTransportAgentAliases`."""
# Acquire a lock file to prevent other processes from racing us here.
with Lock(LOCKFILE):
- self._do_write_file()
+ # If output is a filename, open up a backing file and write the
+ # output there, then do the atomic rename dance. First though, if
+ # it's None, we use a calculated path.
+ if output is None:
+ path = os.path.join(config.DATA_DIR, 'postfix_lmtp')
+ path_new = path + '.new'
+ elif isinstance(output, basestring):
+ path = output
+ path_new = output + '.new'
+ else:
+ path = path_new = None
+ if path_new is None:
+ self._do_write_file(output)
+ # There's nothing to rename, and we can't generate the .db
+ # file, so we're done.
+ return
+ # Write the file.
+ with open(path_new, 'w') as fp:
+ self._do_write_file(fp)
+ # Atomically rename to the intended path.
+ os.rename(path + '.new', path)
+ # Now that the new file is in place, we must tell Postfix to
+ # generate a new .db file.
+ command = config.mta.postfix_map_cmd + ' ' + path
+ status = (os.system(command) >> 8) & 0xff
+ if status:
+ msg = 'command failure: %s, %s, %s'
+ errstr = os.strerror(status)
+ log.error(msg, command, status, errstr)
+ raise RuntimeError(msg % (command, status, errstr))
- def _do_write_file(self):
+ def _do_write_file(self, fp):
"""Do the actual file writes for list creation."""
- # Open up the new alias text file.
- path = os.path.join(config.DATA_DIR, 'postfix_lmtp')
# Sort all existing mailing list names first by domain, then my local
# part. For postfix we need a dummy entry for the domain.
by_domain = {}
for mailing_list in getUtility(IListManager).mailing_lists:
by_domain.setdefault(mailing_list.host_name, []).append(
mailing_list.list_name)
- with open(path + '.new', 'w') as fp:
- print >> fp, """\
+ print >> fp, """\
# AUTOMATICALLY GENERATED BY MAILMAN ON {0}
#
# This file is generated by Mailman, and is kept in sync with the binary hash
@@ -93,33 +117,22 @@ class LMTP:
# doing, and can keep the two files properly in sync. If you screw it up,
# you're on your own.
""".format(datetime.datetime.now().replace(microsecond=0))
- for domain in sorted(by_domain):
- print >> fp, """\
+ for domain in sorted(by_domain):
+ print >> fp, """\
# Aliases which are visible only in the @{0} domain.
""".format(domain)
- for list_name in by_domain[domain]:
- # Calculate the field width of the longest alias. 10 ==
- # len('-subscribe') + '@'.
- longest = len(list_name + domain) + 10
- print >> fp, """\
-{0}@{1:{3}}lmtp:inet:{2.mta.lmtp_host}:{2.mta.lmtp_port}""".format(
- list_name, domain, config,
- # Add 1 because the bare list name has no dash.
- longest + 1)
- for destination in SUBDESTINATIONS:
- print >> fp, """\
-{0}-{1}@{2:{4}}lmtp:inet:{3.mta.lmtp_host}:{3.mta.lmtp_port}""".format(
- list_name, destination, domain, config,
- longest - len(destination))
- print >> fp
- # Move the temporary file into place, then generate the new .db file.
- os.rename(path + '.new', path)
- # Now that the new aliases file has been written, we must tell Postfix
- # to generate a new .db file.
- command = config.mta.postfix_map_cmd + ' ' + path
- status = (os.system(command) >> 8) & 0xff
- if status:
- msg = 'command failure: %s, %s, %s'
- errstr = os.strerror(status)
- log.error(msg, command, status, errstr)
- raise RuntimeError(msg % (command, status, errstr))
+ for list_name in by_domain[domain]:
+ # Calculate the field width of the longest alias. 10 ==
+ # len('-subscribe') + '@'.
+ longest = len(list_name + domain) + 10
+ print >> fp, """\
+{0}@{1:{3}}lmtp:{2.mta.lmtp_host}:{2.mta.lmtp_port}""".format(
+ list_name, domain, config,
+ # Add 1 because the bare list name has no dash.
+ longest + 1)
+ for destination in SUBDESTINATIONS:
+ print >> fp, """\
+{0}-{1}@{2:{4}}lmtp:{3.mta.lmtp_host}:{3.mta.lmtp_port}""".format(
+ list_name, destination, domain, config,
+ longest - len(destination))
+ print >> fp