blob: 8b31003d9b186d20e941e1df23dfc20a3c815809 [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
4
Guido van Rossum8d12a1b1996-07-30 16:30:15 +00005def whichdb(filename):
6 """Guess which db package to use to open a db file.
7
8 Return values:
9
10 - None if the database file can't be read;
11 - empty string if the file can be read but can't be recognized
12 - the module name (e.g. "dbm" or "gdbm") if recognized.
13
14 Importing the given module may still fail, and opening the
15 database using that module may still fail.
16 """
17
Skip Montanaro58eadba2001-03-01 04:13:51 +000018 import struct
19
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000020 # Check for dbm first -- this has a .pag and a .dir file
21 try:
Guido van Rossume2ae77b2001-10-24 20:42:55 +000022 f = open(filename + os.extsep + "pag", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000023 f.close()
Guido van Rossume2ae77b2001-10-24 20:42:55 +000024 f = open(filename + os.extsep + "dir", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000025 f.close()
26 return "dbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000027 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000028 pass
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000029
Moshe Zadka7a4409c2000-07-29 05:31:40 +000030 # Check for dumbdbm next -- this has a .dir and and a .dat file
Thomas Wouters3027b152000-08-04 08:46:59 +000031 try:
Guido van Rossume2ae77b2001-10-24 20:42:55 +000032 f = open(filename + os.extsep + "dat", "rb")
Moshe Zadka7a4409c2000-07-29 05:31:40 +000033 f.close()
Guido van Rossume2ae77b2001-10-24 20:42:55 +000034 f = open(filename + os.extsep + "dir", "rb")
Moshe Zadka7a4409c2000-07-29 05:31:40 +000035 try:
36 if f.read(1) in ["'", '"']:
37 return "dumbdbm"
38 finally:
39 f.close()
40 except IOError:
41 pass
42
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000043 # See if the file exists, return None if not
44 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000045 f = open(filename, "rb")
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000046 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000047 return None
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000048
Guido van Rossumcf09a391999-06-08 13:13:16 +000049 # Read the start of the file -- the magic number
50 s16 = f.read(16)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000051 f.close()
Guido van Rossumcf09a391999-06-08 13:13:16 +000052 s = s16[0:4]
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000053
54 # Return "" if not at least 4 bytes
55 if len(s) != 4:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000056 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000057
58 # Convert to 4-byte int in native byte order -- return "" if impossible
59 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000060 (magic,) = struct.unpack("=l", s)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000061 except struct.error:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000062 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000063
64 # Check for GNU dbm
65 if magic == 0x13579ace:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000066 return "gdbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000067
68 # Check for BSD hash
Guido van Rossumb86ba121998-04-28 15:41:03 +000069 if magic in (0x00061561, 0x61150600):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000070 return "dbhash"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000071
Guido van Rossumcf09a391999-06-08 13:13:16 +000072 # BSD hash v2 has a 12-byte NULL pad in front of the file type
73 try:
Fred Drake13a2c272000-02-10 17:17:14 +000074 (magic,) = struct.unpack("=l", s16[-4:])
Guido van Rossumcf09a391999-06-08 13:13:16 +000075 except struct.error:
76 return ""
77
78 # Check for BSD hash
79 if magic in (0x00061561, 0x61150600):
80 return "dbhash"
81
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000082 # Unknown
83 return ""