2 """Guess which db package to use to open a db file."""
13 # just some sort of valid exception which might be raised in the
17 def whichdb(filename
):
18 """Guess which db package to use to open a db file.
22 - None if the database file can't be read;
23 - empty string if the file can be read but can't be recognized
24 - the module name (e.g. "dbm" or "gdbm") if recognized.
26 Importing the given module may still fail, and opening the
27 database using that module may still fail.
30 # Check for dbm first -- this has a .pag and a .dir file
32 f
= open(filename
+ os
.extsep
+ "pag", "rb")
34 # dbm linked with gdbm on OS/2 doesn't have .dir file
35 if not (dbm
.library
== "GNU gdbm" and sys
.platform
== "os2emx"):
36 f
= open(filename
+ os
.extsep
+ "dir", "rb")
40 # some dbm emulations based on Berkeley DB generate a .db file
41 # some do not, but they should be caught by the dbhash checks
43 f
= open(filename
+ os
.extsep
+ "db", "rb")
45 # guarantee we can actually open the file using dbm
46 # kind of overkill, but since we are dealing with emulations
47 # it seems like a prudent step
49 d
= dbm
.open(filename
)
52 except (IOError, _dbmerror
):
55 # Check for dumbdbm next -- this has a .dir and a .dat file
57 # First check for presence of files
58 os
.stat(filename
+ os
.extsep
+ "dat")
59 size
= os
.stat(filename
+ os
.extsep
+ "dir").st_size
60 # dumbdbm files with no keys are empty
63 f
= open(filename
+ os
.extsep
+ "dir", "rb")
65 if f
.read(1) in ("'", '"'):
69 except (OSError, IOError):
72 # See if the file exists, return None if not
74 f
= open(filename
, "rb")
78 # Read the start of the file -- the magic number
83 # Return "" if not at least 4 bytes
87 # Convert to 4-byte int in native byte order -- return "" if impossible
89 (magic
,) = struct
.unpack("=l", s
)
94 if magic
== 0x13579ace:
97 # Check for old Berkeley db hash file format v2
98 if magic
in (0x00061561, 0x61150600):
101 # Later versions of Berkeley db hash file have a 12-byte pad in
102 # front of the file type
104 (magic
,) = struct
.unpack("=l", s16
[-4:])
109 if magic
in (0x00061561, 0x61150600):
115 if __name__
== "__main__":
116 for filename
in sys
.argv
[1:]:
117 print whichdb(filename
) or "UNKNOWN", filename