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