# Path: Milter/plock.py
# class PLock(object):
#   "A simple /etc/passwd style lock,update,rename protocol for updating files."
#   def __init__(self,basename):
#     self.basename = basename
#     self.fp = None
# 
#   def lock(self,lockname=None,mode=0o660,strict_perms=False):
#     "Start an update transaction.  Return FILE to write new version."
#     self.unlock()
#     if not lockname:
#       lockname = self.basename + '.lock'
#     self.lockname = lockname
#     try:
#       st = os.stat(self.basename)
#       mode |= st.st_mode
#     except OSError: pass
#     u = os.umask(0o2)
#     try:
#       fd = os.open(lockname,os.O_WRONLY+os.O_CREAT+os.O_EXCL,mode)
#     finally:
#       os.umask(u)
#     self.fp = os.fdopen(fd,'w')
#     try:
#       os.chown(self.lockname,-1,st.st_gid)
#     except:
#       if strict_perms:
#         self.unlock()
#         raise
#     return self.fp
# 
#   def wlock(self,lockname=None):
#     "Wait until lock is free, then start an update transaction."
#     while True:
#       try:
#         return self.lock(lockname)
#       except OSError:
#         sleep(2)
# 
#   def commit(self,backname=None):
#     "Commit update transaction with optional backup file."
#     if not self.fp:
#       raise IOError("File not locked")
#     self.fp.close()
#     self.fp = None
#     if backname:
#       try:
#         os.remove(backname)
#       except OSError: pass
#       os.link(self.basename,backname)
#     os.rename(self.lockname,self.basename)
# 
#   def unlock(self):
#     "Cancel update transaction."
#     if self.fp:
#       try:
#         self.fp.close()
#       except: pass
#       self.fp = None
#       os.remove(self.lockname)


import time
from Milter.plock import PLock
# Purge old entries in auto_whitelist and send_dsn logs.
#
# Revision 1.4  2007/01/11 04:31:26  customdesigned
# Negative feedback for bad headers.  Purge cache logs on startup.
#
# Revision 1.3  2007/01/08 23:20:54  customdesigned
# Get user feedback.
#
# Revision 1.2  2007/01/05 23:33:55  customdesigned
# Make blacklist an AddrCache
#
# Revision 1.1  2007/01/05 21:25:40  customdesigned
# Move AddrCache to Milter package.
#

# Author: Stuart D. Gathman <stuart@bmsi.com>
# Copyright 2001,2002,2003,2004,2005 Business Management Systems, Inc.
# This code is under the GNU General Public License.  See COPYING for details.

from __future__ import print_function

class AddrCache(object):
  time_format = '%Y%b%d %H:%M:%S %Z'

  def __init__(self,renew=7,fname=None):
    self.age = renew
    self.cache = {}
    self.fname = fname

  def load(self,fname,age=0):

# Path: Milter/plock.py
# class PLock(object):
#   "A simple /etc/passwd style lock,update,rename protocol for updating files."
#   def __init__(self,basename):
#     self.basename = basename
#     self.fp = None
# 
#   def lock(self,lockname=None,mode=0o660,strict_perms=False):
#     "Start an update transaction.  Return FILE to write new version."
#     self.unlock()
#     if not lockname:
#       lockname = self.basename + '.lock'
#     self.lockname = lockname
#     try:
#       st = os.stat(self.basename)
#       mode |= st.st_mode
#     except OSError: pass
#     u = os.umask(0o2)
#     try:
#       fd = os.open(lockname,os.O_WRONLY+os.O_CREAT+os.O_EXCL,mode)
#     finally:
#       os.umask(u)
#     self.fp = os.fdopen(fd,'w')
#     try:
#       os.chown(self.lockname,-1,st.st_gid)
#     except:
#       if strict_perms:
#         self.unlock()
#         raise
#     return self.fp
# 
#   def wlock(self,lockname=None):
#     "Wait until lock is free, then start an update transaction."
#     while True:
#       try:
#         return self.lock(lockname)
#       except OSError:
#         sleep(2)
# 
#   def commit(self,backname=None):
#     "Commit update transaction with optional backup file."
#     if not self.fp:
#       raise IOError("File not locked")
#     self.fp.close()
#     self.fp = None
#     if backname:
#       try:
#         os.remove(backname)
#       except OSError: pass
#       os.link(self.basename,backname)
#     os.rename(self.lockname,self.basename)
# 
#   def unlock(self):
#     "Cancel update transaction."
#     if self.fp:
#       try:
#         self.fp.close()
#       except: pass
#       self.fp = None
#       os.remove(self.lockname)


# Path: Milter/cache.py
import time
from Milter.plock import PLock

# Purge old entries in auto_whitelist and send_dsn logs.
#
# Revision 1.4  2007/01/11 04:31:26  customdesigned
# Negative feedback for bad headers.  Purge cache logs on startup.
#
# Revision 1.3  2007/01/08 23:20:54  customdesigned
# Get user feedback.
#
# Revision 1.2  2007/01/05 23:33:55  customdesigned
# Make blacklist an AddrCache
#
# Revision 1.1  2007/01/05 21:25:40  customdesigned
# Move AddrCache to Milter package.
#

# Author: Stuart D. Gathman <stuart@bmsi.com>
# Copyright 2001,2002,2003,2004,2005 Business Management Systems, Inc.
# This code is under the GNU General Public License.  See COPYING for details.

from __future__ import print_function

class AddrCache(object):
  time_format = '%Y%b%d %H:%M:%S %Z'

  def __init__(self,renew=7,fname=None):
    self.age = renew
    self.cache = {}
    self.fname = fname

  def load(self,fname,age=0):

    "Load address cache from persistent store."