diff options
| author | bwarsaw | 2001-12-06 07:04:15 +0000 |
|---|---|---|
| committer | bwarsaw | 2001-12-06 07:04:15 +0000 |
| commit | 694264b28d23a1b956732e28c9a1c3643929b27f (patch) | |
| tree | 4bd6235e0674cd2f42a7f3729695ac00336fabe6 | |
| parent | 9a39c279caad4cd291726eefbbbeb9ddd0b5670e (diff) | |
| download | mailman-694264b28d23a1b956732e28c9a1c3643929b27f.tar.gz mailman-694264b28d23a1b956732e28c9a1c3643929b27f.tar.zst mailman-694264b28d23a1b956732e28c9a1c3643929b27f.zip | |
| -rw-r--r-- | Mailman/MTA/Postfix.py | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/Mailman/MTA/Postfix.py b/Mailman/MTA/Postfix.py index b22917f41..da201bf37 100644 --- a/Mailman/MTA/Postfix.py +++ b/Mailman/MTA/Postfix.py @@ -46,13 +46,13 @@ VDBFILE = VTEXTFILE + '.db' # Here's the deal with locking. In order to assure that Postfix doesn't read # the file while we're writing updates, we should drop an exclusive advisory -# lock on the file. Ideally, we'd specify the `l' flag to dbhash.open() which -# translates to passing the O_EXLOCK flag to the underlying bsddb open call -- -# on systems that support O_EXLOCK. +# lock on the file. Ideally, we'd specify the `l' flag to bsddb.hashopen() +# which translates to passing the O_EXLOCK flag to the underlying open call, +# for systems that support O_EXLOCK. # # Unfortunately, Linux is one of those systems that don't support O_EXLOCK. # To make matters worse, the default bsddb module in Python gives us no access -# to the file descriptor of the database file, so we cannot dbhash.open(), dig +# to the file descriptor of the database file, so we cannot hashopen(), dig # out the fd, then use fcntl.flock() to acquire the lock. Bummer. :( # # Another approach would be to do a file dance to assure exclusivity. @@ -69,25 +69,30 @@ VDBFILE = VTEXTFILE + '.db' # of the aliases.db file. # # The best solution I can come up with involves opening the aliases.db file -# with built-in open(), do the fd digout and flock(), then use dbhash.open() -# to re-open the file through bsddb. Blech. If anybody has a better, -# portable, solution, I'm all ears. +# with bsddb.hashopen() first, then do a built-in open(), digout the fd from +# the file object and flock() it. We have to open with bsddb.hashopen() first +# in case the file doesn't exist yet, but we can't write to it until we get +# the lock. Blech. If anybody has a better, portable, solution, I'm all +# ears. def makelock(): return LockFile.LockFile(LOCKFILE) def _zapfile(filename): - # Truncate the file w/o messing with the file permissions - fp = open(filename, 'w') - fp.close() + # Truncate the file w/o messing with the file permissions, but only if it + # already exists. + if os.path.exists(filename): + fp = open(filename, 'w') + fp.close() def _zapdb(filename): - db = bsddb.hashopen(filename, 'c') - for k in db.keys(): - del db[k] - db.close() + if os.path.exists(filename): + db = bsddb.hashopen(filename, 'c') + for k in db.keys(): + del db[k] + db.close() def clear(): @@ -99,8 +104,6 @@ def clear(): def addlist(mlist, db, fp): - listname = mlist.internal_name() - fieldsz = len(listname) + len('-request') # Set up the mailman-loop address loopaddr = Utils.ParseEmail(Utils.get_site_email(extra='loop'))[0] loopmbox = os.path.join(mm_cfg.DATA_DIR, 'owner-bounces.mbox') @@ -117,6 +120,18 @@ def addlist(mlist, db, fp): print >> fp, '# The ultimate loop stopper address' print >> fp, '%s: %s' % (loopaddr, loopmbox) print >> fp + # Always update YP_LAST_MODIFIED + db['YP_LAST_MODIFIED'] = '%010d' % time.time() + # Add a YP_MASTER_NAME only if there isn't one already + if not db.has_key('YP_MASTER_NAME'): + db['YP_MASTER_NAME'] = socket.getfqdn() + # Bootstrapping. bin/genaliases must be run before any lists are created, + # but if no lists exist yet then mlist is None. The whole point of the + # exercise is to get the minimal aliases.db file into existance. + if mlist is None: + return + listname = mlist.internal_name() + fieldsz = len(listname) + len('-request') # The text file entries get a little extra info print >> fp, '# STANZA START:', listname print >> fp, '# CREATED:', time.ctime(time.time()) @@ -130,11 +145,6 @@ def addlist(mlist, db, fp): db[k + '\0'] = v + '\0' # Format the text file nicely print >> fp, k + ':', ((fieldsz - len(k) + 1) * ' '), v - # Always update YP_LAST_MODIFIED - db['YP_LAST_MODIFIED'] = '%010d' % time.time() - # Add a YP_MASTER_NAME only if there isn't one already - if not db.has_key('YP_MASTER_NAME'): - db['YP_MASTER_NAME'] = socket.getfqdn() # Finish the text file stanza print >> fp, '# STANZA END:', listname print >> fp @@ -224,9 +234,9 @@ def do_create(mlist, dbfile, textfile, func): # First, open the dbhash file using built-in open so we can acquire an # exclusive lock on it. See the discussion above for why we do it # this way instead of specifying the `l' option to dbhash.open() + db = bsddb.hashopen(dbfile, 'c') lockfp = open(dbfile) fcntl.flock(lockfp.fileno(), fcntl.LOCK_EX) - db = bsddb.hashopen(dbfile, 'c') # Crack open the plain text file try: fp = open(textfile, 'r+') @@ -260,7 +270,7 @@ def create(mlist, cgi=0, nolock=0): # Do the aliases file, which need to be done in any case try: do_create(mlist, DBFILE, TEXTFILE, addlist) - if mlist.host_name in mm_cfg.POSTFIX_STYLE_VIRTUAL_DOMAINS: + if mlist and mlist.host_name in mm_cfg.POSTFIX_STYLE_VIRTUAL_DOMAINS: do_create(mlist, VDBFILE, VTEXTFILE, addvirtual) finally: if lock: |
