blob: 8687b719b21a62075e8644f3977f53dc95646e87 [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
5if os.sep==".":
6 endsep = "/"
7else:
8 endsep = "."
Tim Peters30edd232001-03-16 08:29:48 +00009
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000010def whichdb(filename):
11 """Guess which db package to use to open a db file.
12
13 Return values:
14
15 - None if the database file can't be read;
16 - empty string if the file can be read but can't be recognized
17 - the module name (e.g. "dbm" or "gdbm") if recognized.
18
19 Importing the given module may still fail, and opening the
20 database using that module may still fail.
21 """
22
Skip Montanaro58eadba2001-03-01 04:13:51 +000023 import struct
24
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000025 # Check for dbm first -- this has a .pag and a .dir file
26 try:
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000027 f = open(filename + endsep + "pag", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000028 f.close()
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000029 f = open(filename + endsep + "dir", "rb")
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000030 f.close()
31 return "dbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000032 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000033 pass
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000034
Moshe Zadka7a4409c2000-07-29 05:31:40 +000035 # Check for dumbdbm next -- this has a .dir and and a .dat file
Thomas Wouters3027b152000-08-04 08:46:59 +000036 try:
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000037 f = open(filename + endsep + "dat", "rb")
Moshe Zadka7a4409c2000-07-29 05:31:40 +000038 f.close()
Guido van Rossumd74fb6b2001-03-02 06:43:49 +000039 f = open(filename + endsep + "dir", "rb")
Moshe Zadka7a4409c2000-07-29 05:31:40 +000040 try:
41 if f.read(1) in ["'", '"']:
42 return "dumbdbm"
43 finally:
44 f.close()
45 except IOError:
46 pass
47
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000048 # See if the file exists, return None if not
49 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000050 f = open(filename, "rb")
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000051 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000052 return None
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000053
Guido van Rossumcf09a391999-06-08 13:13:16 +000054 # Read the start of the file -- the magic number
55 s16 = f.read(16)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000056 f.close()
Guido van Rossumcf09a391999-06-08 13:13:16 +000057 s = s16[0:4]
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000058
59 # Return "" if not at least 4 bytes
60 if len(s) != 4:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000061 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000062
63 # Convert to 4-byte int in native byte order -- return "" if impossible
64 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000065 (magic,) = struct.unpack("=l", s)
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000066 except struct.error:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000067 return ""
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000068
69 # Check for GNU dbm
70 if magic == 0x13579ace:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000071 return "gdbm"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000072
73 # Check for BSD hash
Guido van Rossumb86ba121998-04-28 15:41:03 +000074 if magic in (0x00061561, 0x61150600):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000075 return "dbhash"
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000076
Guido van Rossumcf09a391999-06-08 13:13:16 +000077 # BSD hash v2 has a 12-byte NULL pad in front of the file type
78 try:
Fred Drake13a2c272000-02-10 17:17:14 +000079 (magic,) = struct.unpack("=l", s16[-4:])
Guido van Rossumcf09a391999-06-08 13:13:16 +000080 except struct.error:
81 return ""
82
83 # Check for BSD hash
84 if magic in (0x00061561, 0x61150600):
85 return "dbhash"
86
Guido van Rossum8d12a1b1996-07-30 16:30:15 +000087 # Unknown
88 return ""