blob: 92996367ee429b50a681f59106fdbbe8ebd41216 [file] [log] [blame]
Guido van Rossum8d12a1b1996-07-30 16:30:15 +00001"""Guess which db package to use to open a db file."""
2
Guido van Rossumd74fb6b2001-03-02 06:43:49 +00003import os
Skip Montanaro404378f2002-08-02 17:12:15 +00004import struct
5
6try:
7 import dbm
8 _dbmerror = dbm.error
9except ImportError:
10 dbm = None
11 # just some sort of valid exception which might be raised in the
12 # dbm test
13 _dbmerror = IOError
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000014
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000015def whichdb(filename):
16 """Guess which db package to use to open a db file.
17
18 Return values:
19
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.
23
24 Importing the given module may still fail, and opening the
25 database using that module may still fail.
26 """
27
28 # Check for dbm first -- this has a .pag and a .dir file
29 try:
Guido van Rossume2ae77b2001-10-24 20:42:55 +000030 f = open(filename + os.extsep + "pag", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000031 f.close()
Guido van Rossume2ae77b2001-10-24 20:42:55 +000032 f = open(filename + os.extsep + "dir", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000033 f.close()
34 return "dbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000035 except IOError:
Skip Montanaro404378f2002-08-02 17:12:15 +000036 # 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
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000050
Moshe Zadka7a4409c2000-07-29 05:31:40 +000051 # Check for dumbdbm next -- this has a .dir and and a .dat file
Thomas Wouters3027b152000-08-04 08:46:59 +000052 try:
Martin v. Löwis17fb5072003-06-14 08:16:34 +000053 # First check for presence of files
54 sizes = os.stat(filename + os.extsep + "dat").st_size, \
55 os.stat(filename + os.extsep + "dir").st_size
56 # dumbdbm files with no keys are empty
57 if sizes == (0, 0):
58 return "dumbdbm"
Guido van Rossume2ae77b2001-10-24 20:42:55 +000059 f = open(filename + os.extsep + "dir", "rb")
Moshe Zadka7a4409c2000-07-29 05:31:40 +000060 try:
61 if f.read(1) in ["'", '"']:
62 return "dumbdbm"
63 finally:
64 f.close()
Martin v. Löwis17fb5072003-06-14 08:16:34 +000065 except (OSError, IOError):
Moshe Zadka7a4409c2000-07-29 05:31:40 +000066 pass
67
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000068 # See if the file exists, return None if not
69 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000070 f = open(filename, "rb")
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000071 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000072 return None
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000073
Guido van Rossumcf09a391999-06-08 13:13:16 +000074 # Read the start of the file -- the magic number
75 s16 = f.read(16)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000076 f.close()
Guido van Rossumcf09a391999-06-08 13:13:16 +000077 s = s16[0:4]
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000078
79 # Return "" if not at least 4 bytes
80 if len(s) != 4:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000082
83 # Convert to 4-byte int in native byte order -- return "" if impossible
84 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000085 (magic,) = struct.unpack("=l", s)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000086 except struct.error:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000088
89 # Check for GNU dbm
90 if magic == 0x13579ace:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000091 return "gdbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000092
Skip Montanaro02cd3652003-05-06 20:42:10 +000093 # Check for old Berkeley db hash file format v2
Guido van Rossumb86ba121998-04-28 15:41:03 +000094 if magic in (0x00061561, 0x61150600):
Skip Montanaro02cd3652003-05-06 20:42:10 +000095 return "bsddb185"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000096
Skip Montanaro02cd3652003-05-06 20:42:10 +000097 # Later versions of Berkeley db hash file have a 12-byte pad in
98 # front of the file type
Guido van Rossumcf09a391999-06-08 13:13:16 +000099 try:
Fred Drake13a2c272000-02-10 17:17:14 +0000100 (magic,) = struct.unpack("=l", s16[-4:])
Guido van Rossumcf09a391999-06-08 13:13:16 +0000101 except struct.error:
102 return ""
103
104 # Check for BSD hash
105 if magic in (0x00061561, 0x61150600):
106 return "dbhash"
107
Guido van Rossum8d12a1b1996-07-30 16:30:15 +0000108 # Unknown
109 return ""