|
#! /usr/bin/python2 |
|
|
|
import os |
|
import sys |
|
import paths |
|
import getopt |
|
import errno |
|
import time |
|
|
|
from Mailman import mm_cfg |
|
#from Mailman import MailList |
|
from Mailman import MailList |
|
from Mailman import Utils |
|
from Mailman import i18n |
|
from Mailman import Errors |
|
from Mailman.MTA.Utils import makealiases |
|
|
|
_ = i18n._ |
|
C_ = i18n.C_ |
|
|
|
VIRTFILE = os.path.join(mm_cfg.DATA_DIR, 'virtual-mailman') |
|
|
|
def usage(code, msg=''): |
|
if code: |
|
fd = sys.stderr |
|
else: |
|
fd = sys.stdout |
|
print >> fd, C_(__doc__) |
|
if msg: |
|
print >> fd, msg |
|
sys.exit(code) |
|
|
|
def _isvirtual(mlist): |
|
return (mlist and mlist.host_name.lower() in |
|
[d.lower() for d in mm_cfg.POSTFIX_STYLE_VIRTUAL_DOMAINS]) |
|
|
|
def _addvirtual(mlist, fp): |
|
listname = mlist.internal_name() |
|
fieldsz = len(listname) + len('-unsubscribe') |
|
hostname = mlist.host_name |
|
# Set up the mailman-loop address |
|
loopaddr = Utils.get_site_email(mlist.host_name, extra='loop') |
|
loopdest = Utils.ParseEmail(loopaddr)[0] |
|
# And the site list posting address. |
|
siteaddr = Utils.get_site_email(mlist.host_name) |
|
sitedest = Utils.ParseEmail(siteaddr)[0] |
|
if mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN: |
|
loopdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN |
|
sitedest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN |
|
# If the site list's host_name is a virtual domain, adding it to the |
|
# SITE ADDRESSES will duplicate the list posting entry, so comment it. |
|
if _isvirtual(MailList.MailList(mm_cfg.MAILMAN_SITE_LIST, lock=False)): |
|
siteaddr = '#' + siteaddr |
|
# Seek to the end of the text file, but if it's empty write the standard |
|
# disclaimer, and the loop catch address and site address. |
|
fp.seek(0, 2) |
|
if not fp.tell(): |
|
print >> fp, """\ |
|
# This file is generated by Mailman, and is kept in sync with the binary hash |
|
# file virtual-mailman.db. YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you |
|
# know what you're doing, and can keep the two files properly in sync. If you |
|
# screw it up, you're on your own. |
|
# |
|
# Note that you should already have this virtual domain set up properly in |
|
# your Postfix installation. See README.POSTFIX for details. |
|
|
|
# LOOP ADDRESSES START |
|
%s\t%s |
|
# LOOP ADDRESSES END |
|
|
|
# We also add the site list address in each virtual domain as that address |
|
# is exposed on admin and listinfo overviews. |
|
# SITE ADDRESSES START |
|
%s\t%s |
|
# SITE ADDRESSES END |
|
""" % (loopaddr, loopdest, siteaddr, sitedest) |
|
# The text file entries get a little extra info |
|
print >> fp, '# STANZA START:', listname |
|
print >> fp, '# CREATED:', time.ctime(time.time()) |
|
# Now add all the standard alias entries |
|
for k, v in makealiases(listname): |
|
fqdnaddr = '%s@%s' % (k, hostname) |
|
if mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN: |
|
localaddr = '%s@%s' % (k, mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN) |
|
else: |
|
localaddr = k |
|
# Format the text file nicely |
|
print >> fp, fqdnaddr, ((fieldsz - len(k)) * ' '), localaddr |
|
# Finish the text file stanza |
|
print >> fp, '# STANZA END:', listname |
|
print >> fp |
|
|
|
def _do_create(mlist, textfile, func): |
|
# Crack open the plain text file |
|
try: |
|
fp = open(textfile, 'r+') |
|
except IOError, e: |
|
if e.errno <> errno.ENOENT: raise |
|
omask = os.umask(007) |
|
try: |
|
fp = open(textfile, 'w+') |
|
finally: |
|
os.umask(omask) |
|
try: |
|
func(mlist, fp) |
|
finally: |
|
fp.close() |
|
|
|
def main(): |
|
try: |
|
opts, args = getopt.getopt( |
|
sys.argv[1:], 'a', |
|
['all']) |
|
except getopt.error, msg: |
|
usage(1, msg) |
|
|
|
listnames = {} |
|
|
|
for opt, arg in opts: |
|
if opt in ('-h', '--help'): |
|
usage(0) |
|
elif opt in ('-a', '--all'): |
|
for name in Utils.list_names(): |
|
listnames[name] = 1; |
|
|
|
if not listnames: |
|
if args and args[0]: |
|
listnames[args[0]] = 1 |
|
else: |
|
print >> sys.stderr, C_('Nothing to do.') |
|
sys.exit(0) |
|
|
|
for listname in listnames.keys(): |
|
try: |
|
mlist = MailList.MailList(listname, lock=0) |
|
except Errors.MMListError: |
|
usage(1, C_('No such list: %(listname)s')) |
|
|
|
_do_create(mlist, VIRTFILE, _addvirtual) |
|
print listname |
|
|
|
|
|
if __name__ == '__main__': |
|
main() |