| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | """Guess which db package to use to open a db file.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-03-02 06:43:49 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2002-08-02 17:12:15 +00:00
										 |  |  | import struct | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     import dbm | 
					
						
							|  |  |  |     _dbmerror = dbm.error | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     dbm = None | 
					
						
							|  |  |  |     # just some sort of valid exception which might be raised in the | 
					
						
							|  |  |  |     # dbm test | 
					
						
							|  |  |  |     _dbmerror = IOError | 
					
						
							| 
									
										
										
										
											2001-03-02 06:43:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 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: | 
					
						
							| 
									
										
										
										
											2001-10-24 20:42:55 +00:00
										 |  |  |         f = open(filename + os.extsep + "pag", "rb") | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         f.close() | 
					
						
							| 
									
										
										
										
											2001-10-24 20:42:55 +00:00
										 |  |  |         f = open(filename + os.extsep + "dir", "rb") | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         f.close() | 
					
						
							|  |  |  |         return "dbm" | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  |     except IOError: | 
					
						
							| 
									
										
										
										
											2002-08-02 17:12:15 +00:00
										 |  |  |         # some dbm emulations based on Berkeley DB generate a .db file | 
					
						
							|  |  |  |         # some do not, but they should be caught by the dbhash checks | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             f = open(filename + os.extsep + "db", "rb") | 
					
						
							|  |  |  |             f.close() | 
					
						
							|  |  |  |             # guarantee we can actually open the file using dbm | 
					
						
							|  |  |  |             # kind of overkill, but since we are dealing with emulations | 
					
						
							|  |  |  |             # it seems like a prudent step | 
					
						
							|  |  |  |             if dbm is not None: | 
					
						
							|  |  |  |                 d = dbm.open(filename) | 
					
						
							|  |  |  |                 d.close() | 
					
						
							|  |  |  |                 return "dbm" | 
					
						
							|  |  |  |         except (IOError, _dbmerror): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-29 05:31:40 +00:00
										 |  |  |     # Check for dumbdbm next -- this has a .dir and and a .dat file | 
					
						
							| 
									
										
										
										
											2000-08-04 08:46:59 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2001-10-24 20:42:55 +00:00
										 |  |  |         f = open(filename + os.extsep + "dat", "rb") | 
					
						
							| 
									
										
										
										
											2000-07-29 05:31:40 +00:00
										 |  |  |         f.close() | 
					
						
							| 
									
										
										
										
											2001-10-24 20:42:55 +00:00
										 |  |  |         f = open(filename + os.extsep + "dir", "rb") | 
					
						
							| 
									
										
										
										
											2000-07-29 05:31:40 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             if f.read(1) in ["'", '"']: | 
					
						
							|  |  |  |                 return "dumbdbm" | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             f.close() | 
					
						
							|  |  |  |     except IOError: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  |     # See if the file exists, return None if not | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         f = open(filename, "rb") | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  |     except IOError: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-06-08 13:13:16 +00:00
										 |  |  |     # Read the start of the file -- the magic number | 
					
						
							|  |  |  |     s16 = f.read(16) | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  |     f.close() | 
					
						
							| 
									
										
										
										
											1999-06-08 13:13:16 +00:00
										 |  |  |     s = s16[0:4] | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Return "" if not at least 4 bytes | 
					
						
							|  |  |  |     if len(s) != 4: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return "" | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Convert to 4-byte int in native byte order -- return "" if impossible | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         (magic,) = struct.unpack("=l", s) | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  |     except struct.error: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return "" | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Check for GNU dbm | 
					
						
							|  |  |  |     if magic == 0x13579ace: | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return "gdbm" | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Check for BSD hash | 
					
						
							| 
									
										
										
										
											1998-04-28 15:41:03 +00:00
										 |  |  |     if magic in (0x00061561, 0x61150600): | 
					
						
							| 
									
										
										
										
											1998-03-26 21:13:24 +00:00
										 |  |  |         return "dbhash" | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-06-08 13:13:16 +00:00
										 |  |  |     # BSD hash v2 has a 12-byte NULL pad in front of the file type | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2000-02-10 17:17:14 +00:00
										 |  |  |         (magic,) = struct.unpack("=l", s16[-4:]) | 
					
						
							| 
									
										
										
										
											1999-06-08 13:13:16 +00:00
										 |  |  |     except struct.error: | 
					
						
							|  |  |  |         return "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check for BSD hash | 
					
						
							|  |  |  |     if magic in (0x00061561, 0x61150600): | 
					
						
							|  |  |  |         return "dbhash" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-07-30 16:30:15 +00:00
										 |  |  |     # Unknown | 
					
						
							|  |  |  |     return "" |