mirror of
https://github.com/python/cpython.git
synced 2024-12-01 11:15:56 +01:00
cf09a3924f
I guess in 1.5.2 a new module, whichdb, was added that attempts to divine the nature of a database file. This module doesn't know anything about Berkeley DB v2 files. In v2, Sleepycat added a 12-byte null pad in front of the old magic numbers (at least for hash and btree files). I've been using v2 for awhile and upgrading to 1.5.2 broke all my anydbm.open calls. I believe the following patch corrects the problem.
69 lines
1.6 KiB
Python
69 lines
1.6 KiB
Python
"""Guess which db package to use to open a db file."""
|
|
|
|
import struct
|
|
|
|
def whichdb(filename):
|
|
"""Guess which db package to use to open a db file.
|
|
|
|
Return values:
|
|
|
|
- None if the database file can't be read;
|
|
- empty string if the file can be read but can't be recognized
|
|
- the module name (e.g. "dbm" or "gdbm") if recognized.
|
|
|
|
Importing the given module may still fail, and opening the
|
|
database using that module may still fail.
|
|
"""
|
|
|
|
# Check for dbm first -- this has a .pag and a .dir file
|
|
try:
|
|
f = open(filename + ".pag", "rb")
|
|
f.close()
|
|
f = open(filename + ".dir", "rb")
|
|
f.close()
|
|
return "dbm"
|
|
except IOError:
|
|
pass
|
|
|
|
# See if the file exists, return None if not
|
|
try:
|
|
f = open(filename, "rb")
|
|
except IOError:
|
|
return None
|
|
|
|
# Read the start of the file -- the magic number
|
|
s16 = f.read(16)
|
|
f.close()
|
|
s = s16[0:4]
|
|
|
|
# Return "" if not at least 4 bytes
|
|
if len(s) != 4:
|
|
return ""
|
|
|
|
# Convert to 4-byte int in native byte order -- return "" if impossible
|
|
try:
|
|
(magic,) = struct.unpack("=l", s)
|
|
except struct.error:
|
|
return ""
|
|
|
|
# Check for GNU dbm
|
|
if magic == 0x13579ace:
|
|
return "gdbm"
|
|
|
|
# Check for BSD hash
|
|
if magic in (0x00061561, 0x61150600):
|
|
return "dbhash"
|
|
|
|
# BSD hash v2 has a 12-byte NULL pad in front of the file type
|
|
try:
|
|
(magic,) = struct.unpack("=l", s16[-4:])
|
|
except struct.error:
|
|
return ""
|
|
|
|
# Check for BSD hash
|
|
if magic in (0x00061561, 0x61150600):
|
|
return "dbhash"
|
|
|
|
# Unknown
|
|
return ""
|