blob: deb8a0218d790dfff1360a79da20e62d1a9dd4a1 [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
Andrew MacIntyrea1e93e82003-07-11 12:16:48 +00005import sys
Skip Montanaro404378f2002-08-02 17:12:15 +00006
7try:
8 import dbm
9 _dbmerror = dbm.error
10except ImportError:
11 dbm = None
12 # just some sort of valid exception which might be raised in the
13 # dbm test
14 _dbmerror = IOError
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000015
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000016def 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:
Guido van Rossume2ae77b2001-10-24 20:42:55 +000031 f = open(filename + os.extsep + "pag", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000032 f.close()
Andrew MacIntyrea1e93e82003-07-11 12:16:48 +000033 # 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()
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000037 return "dbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000038 except IOError:
Skip Montanaro404378f2002-08-02 17:12:15 +000039 # 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
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000053
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +000054 # Check for dumbdbm next -- this has a .dir and a .dat file
Thomas Wouters3027b152000-08-04 08:46:59 +000055 try:
Martin v. Löwis17fb5072003-06-14 08:16:34 +000056 # First check for presence of files
Martin v. Löwis5b8bfdf2003-06-21 13:54:55 +000057 os.stat(filename + os.extsep + "dat")
58 size = os.stat(filename + os.extsep + "dir").st_size
Martin v. Löwis17fb5072003-06-14 08:16:34 +000059 # dumbdbm files with no keys are empty
Martin v. Löwis5b8bfdf2003-06-21 13:54:55 +000060 if size == 0:
Martin v. Löwis17fb5072003-06-14 08:16:34 +000061 return "dumbdbm"
Guido van Rossume2ae77b2001-10-24 20:42:55 +000062 f = open(filename + os.extsep + "dir", "rb")
Moshe Zadka7a4409c2000-07-29 05:31:40 +000063 try:
64 if f.read(1) in ["'", '"']:
65 return "dumbdbm"
66 finally:
67 f.close()
Martin v. Löwis17fb5072003-06-14 08:16:34 +000068 except (OSError, IOError):
Moshe Zadka7a4409c2000-07-29 05:31:40 +000069 pass
70
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000071 # See if the file exists, return None if not
72 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000073 f = open(filename, "rb")
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000074 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000075 return None
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000076
Guido van Rossumcf09a391999-06-08 13:13:16 +000077 # Read the start of the file -- the magic number
78 s16 = f.read(16)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000079 f.close()
Guido van Rossumcf09a391999-06-08 13:13:16 +000080 s = s16[0:4]
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000081
82 # Return "" if not at least 4 bytes
83 if len(s) != 4:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000084 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000085
86 # Convert to 4-byte int in native byte order -- return "" if impossible
87 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000088 (magic,) = struct.unpack("=l", s)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000089 except struct.error:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000090 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000091
92 # Check for GNU dbm
93 if magic == 0x13579ace:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000094 return "gdbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000095
Skip Montanaro02cd3652003-05-06 20:42:10 +000096 # Check for old Berkeley db hash file format v2
Guido van Rossumb86ba121998-04-28 15:41:03 +000097 if magic in (0x00061561, 0x61150600):
Skip Montanaro02cd3652003-05-06 20:42:10 +000098 return "bsddb185"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000099
Skip Montanaro02cd3652003-05-06 20:42:10 +0000100 # Later versions of Berkeley db hash file have a 12-byte pad in
101 # front of the file type
Guido van Rossumcf09a391999-06-08 13:13:16 +0000102 try:
Fred Drake13a2c272000-02-10 17:17:14 +0000103 (magic,) = struct.unpack("=l", s16[-4:])
Guido van Rossumcf09a391999-06-08 13:13:16 +0000104 except struct.error:
105 return ""
106
107 # Check for BSD hash
108 if magic in (0x00061561, 0x61150600):
109 return "dbhash"
110
Guido van Rossum8d12a1b1996-07-30 16:30:15 +0000111 # Unknown
112 return ""