home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / whichdb.py < prev    next >
Text File  |  2003-12-30  |  3KB  |  113 lines

  1. """Guess which db package to use to open a db file."""
  2.  
  3. import os
  4. import struct
  5. import sys
  6.  
  7. try:
  8.     import dbm
  9.     _dbmerror = dbm.error
  10. except ImportError:
  11.     dbm = None
  12.     # just some sort of valid exception which might be raised in the
  13.     # dbm test
  14.     _dbmerror = IOError
  15.  
  16. def whichdb(filename):
  17.     """Guess which db package to use to open a db file.
  18.  
  19.     Return values:
  20.  
  21.     - None if the database file can't be read;
  22.     - empty string if the file can be read but can't be recognized
  23.     - the module name (e.g. "dbm" or "gdbm") if recognized.
  24.  
  25.     Importing the given module may still fail, and opening the
  26.     database using that module may still fail.
  27.     """
  28.  
  29.     # Check for dbm first -- this has a .pag and a .dir file
  30.     try:
  31.         f = open(filename + os.extsep + "pag", "rb")
  32.         f.close()
  33.         # dbm linked with gdbm on OS/2 doesn't have .dir file
  34.         if not (dbm.library == "GNU gdbm" and sys.platform == "os2emx"):
  35.             f = open(filename + os.extsep + "dir", "rb")
  36.             f.close()
  37.         return "dbm"
  38.     except IOError:
  39.         # some dbm emulations based on Berkeley DB generate a .db file
  40.         # some do not, but they should be caught by the dbhash checks
  41.         try:
  42.             f = open(filename + os.extsep + "db", "rb")
  43.             f.close()
  44.             # guarantee we can actually open the file using dbm
  45.             # kind of overkill, but since we are dealing with emulations
  46.             # it seems like a prudent step
  47.             if dbm is not None:
  48.                 d = dbm.open(filename)
  49.                 d.close()
  50.                 return "dbm"
  51.         except (IOError, _dbmerror):
  52.             pass
  53.  
  54.     # Check for dumbdbm next -- this has a .dir and a .dat file
  55.     try:
  56.         # First check for presence of files
  57.         os.stat(filename + os.extsep + "dat")
  58.         size = os.stat(filename + os.extsep + "dir").st_size
  59.         # dumbdbm files with no keys are empty
  60.         if size == 0:
  61.             return "dumbdbm"
  62.         f = open(filename + os.extsep + "dir", "rb")
  63.         try:
  64.             if f.read(1) in ["'", '"']:
  65.                 return "dumbdbm"
  66.         finally:
  67.             f.close()
  68.     except (OSError, IOError):
  69.         pass
  70.  
  71.     # See if the file exists, return None if not
  72.     try:
  73.         f = open(filename, "rb")
  74.     except IOError:
  75.         return None
  76.  
  77.     # Read the start of the file -- the magic number
  78.     s16 = f.read(16)
  79.     f.close()
  80.     s = s16[0:4]
  81.  
  82.     # Return "" if not at least 4 bytes
  83.     if len(s) != 4:
  84.         return ""
  85.  
  86.     # Convert to 4-byte int in native byte order -- return "" if impossible
  87.     try:
  88.         (magic,) = struct.unpack("=l", s)
  89.     except struct.error:
  90.         return ""
  91.  
  92.     # Check for GNU dbm
  93.     if magic == 0x13579ace:
  94.         return "gdbm"
  95.  
  96.     # Check for old Berkeley db hash file format v2
  97.     if magic in (0x00061561, 0x61150600):
  98.         return "bsddb185"
  99.  
  100.     # Later versions of Berkeley db hash file have a 12-byte pad in
  101.     # front of the file type
  102.     try:
  103.         (magic,) = struct.unpack("=l", s16[-4:])
  104.     except struct.error:
  105.         return ""
  106.  
  107.     # Check for BSD hash
  108.     if magic in (0x00061561, 0x61150600):
  109.         return "dbhash"
  110.  
  111.     # Unknown
  112.     return ""
  113.