Commit c64d697266182f3e85726041aa121c94ea712a68

Authored by Sébastien Larinier
1 parent 5e58cf5a

revert olefile2

oletools/thirdparty/olefile/olefile.py
... ... @@ -1030,10 +1030,11 @@ class OleDirectoryEntry:
1030 1030 #[PL] this method was added to use simple recursion instead of a complex
1031 1031 # algorithm.
1032 1032 # if this is not a storage or a leaf of the tree, nothing to do:
  1033 +
1033 1034 if child_sid == NOSTREAM:
1034 1035 return
1035 1036 # check if child SID is in the proper range:
1036   - if child_sid<0 or child_sid>=len(self.olefile.direntries):
  1037 + if child_sid <= 0 or child_sid >= len(self.olefile.direntries):
1037 1038 self.olefile._raise_defect(DEFECT_INCORRECT, 'OLE DirEntry index out of range')
1038 1039 else:
1039 1040 # get child direntry:
... ...
oletools/thirdparty/olefile/olefile2.py
... ... @@ -209,12 +209,7 @@ __version__ = &#39;0.40py2&#39;
209 209  
210 210 #------------------------------------------------------------------------------
211 211  
212   -import string, struct, array, os.path, sys, datetime
213   -
214   -try:
215   - import StringIO
216   -except:
217   - from _io import StringIO as StringIO
  212 +import string, StringIO, struct, array, os.path, sys, datetime
218 213  
219 214 #[PL] Define explicitly the public API to avoid private objects in pydoc:
220 215 __all__ = ['OleFileIO', 'isOleFile']
... ... @@ -227,7 +222,7 @@ elif array.array(&#39;I&#39;).itemsize == 4:
227 222 # on 64 bits platforms, integers in an array are 32 bits:
228 223 UINT32 = 'I'
229 224 else:
230   - raise(ValueError, 'Need to fix a bug with 32 bit arrays, please contact author...')
  225 + raise ValueError, 'Need to fix a bug with 32 bit arrays, please contact author...'
231 226  
232 227  
233 228 #[PL] These workarounds were inspired from the Path module
... ... @@ -248,7 +243,7 @@ except NameError:
248 243 # is Unicode supported (Python >2.0 or >1.6 ?)
249 244 basestring = (str, unicode)
250 245 except NameError:
251   - basestring = str
  246 + basestring = str
252 247  
253 248 #[PL] Experimental setting: if True, OLE filenames will be kept in Unicode
254 249 # if False (default PIL behaviour), all filenames are converted to Latin-1.
... ... @@ -258,7 +253,7 @@ KEEP_UNICODE_NAMES = False
258 253 # command line to change it.
259 254 DEBUG_MODE = False
260 255 def debug_print(msg):
261   - print(msg)
  256 + print msg
262 257 def debug_pass(msg):
263 258 pass
264 259 debug = debug_pass
... ... @@ -279,15 +274,15 @@ def set_debug_mode(debug_mode):
279 274 MAGIC = '\320\317\021\340\241\261\032\341'
280 275  
281 276 #[PL]: added constants for Sector IDs (from AAF specifications)
282   -MAXREGSECT = 0xFFFFFFFA; # maximum SECT
283   -DIFSECT = 0xFFFFFFFC; # (-4) denotes a DIFAT sector in a FAT
284   -FATSECT = 0xFFFFFFFD; # (-3) denotes a FAT sector in a FAT
285   -ENDOFCHAIN = 0xFFFFFFFE; # (-2) end of a virtual stream chain
286   -FREESECT = 0xFFFFFFFF; # (-1) unallocated sector
  277 +MAXREGSECT = 0xFFFFFFFAL; # maximum SECT
  278 +DIFSECT = 0xFFFFFFFCL; # (-4) denotes a DIFAT sector in a FAT
  279 +FATSECT = 0xFFFFFFFDL; # (-3) denotes a FAT sector in a FAT
  280 +ENDOFCHAIN = 0xFFFFFFFEL; # (-2) end of a virtual stream chain
  281 +FREESECT = 0xFFFFFFFFL; # (-1) unallocated sector
287 282  
288 283 #[PL]: added constants for Directory Entry IDs (from AAF specifications)
289   -MAXREGSID = 0xFFFFFFFA; # maximum directory entry ID
290   -NOSTREAM = 0xFFFFFFFF; # (-1) unallocated directory entry
  284 +MAXREGSID = 0xFFFFFFFAL; # maximum directory entry ID
  285 +NOSTREAM = 0xFFFFFFFFL; # (-1) unallocated directory entry
291 286  
292 287 #[PL] object types in storage (from AAF specifications)
293 288 STGTY_EMPTY = 0 # empty directory entry (according to OpenOffice.org doc)
... ... @@ -397,6 +392,7 @@ def _clsid(clsid):
397 392  
398 393 try:
399 394 # is Unicode supported ?
  395 + unicode
400 396  
401 397 def _unicode(s, errors='replace'):
402 398 """
... ... @@ -418,7 +414,7 @@ try:
418 414 return u.encode('latin_1', errors)
419 415 except:
420 416 # there was an error during Unicode to Latin-1 conversion:
421   - raise(IOError, 'incorrect Unicode name')
  417 + raise IOError, 'incorrect Unicode name'
422 418  
423 419 except NameError:
424 420 def _unicode(s, errors='replace'):
... ... @@ -591,14 +587,14 @@ class OleMetadata:
591 587 """
592 588 Dump all metadata, for debugging purposes.
593 589 """
594   - print('Properties from SummaryInformation stream:')
  590 + print 'Properties from SummaryInformation stream:'
595 591 for prop in self.SUMMARY_ATTRIBS:
596 592 value = getattr(self, prop)
597   - print('- %s: %s' % (prop, repr(value)))
598   - print('Properties from DocumentSummaryInformation stream:')
  593 + print '- %s: %s' % (prop, repr(value))
  594 + print 'Properties from DocumentSummaryInformation stream:'
599 595 for prop in self.DOCSUM_ATTRIBS:
600 596 value = getattr(self, prop)
601   - print('- %s: %s' % (prop, repr(value)))
  597 + print '- %s: %s' % (prop, repr(value))
602 598  
603 599  
604 600 #--- _OleStream ---------------------------------------------------------------
... ... @@ -655,7 +651,7 @@ class _OleStream(StringIO.StringIO):
655 651 # This number should (at least) be less than the total number of
656 652 # sectors in the given FAT:
657 653 if nb_sectors > len(fat):
658   - raise(IOError, 'malformed OLE document, stream too large')
  654 + raise IOError, 'malformed OLE document, stream too large'
659 655 # optimization(?): data is first a list of strings, and join() is called
660 656 # at the end to concatenate all in one string.
661 657 # (this may not be really useful with recent Python versions)
... ... @@ -663,10 +659,10 @@ class _OleStream(StringIO.StringIO):
663 659 # if size is zero, then first sector index should be ENDOFCHAIN:
664 660 if size == 0 and sect != ENDOFCHAIN:
665 661 debug('size == 0 and sect != ENDOFCHAIN:')
666   - raise(IOError, 'incorrect OLE sector index for empty stream')
  662 + raise IOError, 'incorrect OLE sector index for empty stream'
667 663 #[PL] A fixed-length for loop is used instead of an undefined while
668 664 # loop to avoid DoS attacks:
669   - for i in range(nb_sectors):
  665 + for i in xrange(nb_sectors):
670 666 # Sector index may be ENDOFCHAIN, but only if size was unknown
671 667 if sect == ENDOFCHAIN:
672 668 if unknown_size:
... ... @@ -674,7 +670,7 @@ class _OleStream(StringIO.StringIO):
674 670 else:
675 671 # else this means that the stream is smaller than declared:
676 672 debug('sect=ENDOFCHAIN before expected size')
677   - raise(IOError, 'incomplete OLE stream')
  673 + raise IOError, 'incomplete OLE stream'
678 674 # sector index should be within FAT:
679 675 if sect<0 or sect>=len(fat):
680 676 debug('sect=%d (%X) / len(fat)=%d' % (sect, sect, len(fat)))
... ... @@ -684,7 +680,7 @@ class _OleStream(StringIO.StringIO):
684 680 ## f.write(tmp_data)
685 681 ## f.close()
686 682 ## debug('data read so far: %d bytes' % len(tmp_data))
687   - raise(IOError, 'incorrect OLE FAT, sector index out of range')
  683 + raise IOError, 'incorrect OLE FAT, sector index out of range'
688 684 #TODO: merge this code with OleFileIO.getsect() ?
689 685 #TODO: check if this works with 4K sectors:
690 686 try:
... ... @@ -692,7 +688,7 @@ class _OleStream(StringIO.StringIO):
692 688 except:
693 689 debug('sect=%d, seek=%d, filesize=%d' %
694 690 (sect, offset+sectorsize*sect, filesize))
695   - raise(IOError, 'OLE sector index out of range')
  691 + raise IOError, 'OLE sector index out of range'
696 692 sector_data = fp.read(sectorsize)
697 693 # [PL] check if there was enough data:
698 694 # Note: if sector is the last of the file, sometimes it is not a
... ... @@ -702,17 +698,17 @@ class _OleStream(StringIO.StringIO):
702 698 debug('sect=%d / len(fat)=%d, seek=%d / filesize=%d, len read=%d' %
703 699 (sect, len(fat), offset+sectorsize*sect, filesize, len(sector_data)))
704 700 debug('seek+len(read)=%d' % (offset+sectorsize*sect+len(sector_data)))
705   - raise(IOError, 'incomplete OLE sector')
  701 + raise IOError, 'incomplete OLE sector'
706 702 data.append(sector_data)
707 703 # jump to next sector in the FAT:
708 704 try:
709 705 sect = fat[sect]
710 706 except IndexError:
711 707 # [PL] if pointer is out of the FAT an exception is raised
712   - raise(IOError, 'incorrect OLE FAT, sector index out of range')
  708 + raise IOError, 'incorrect OLE FAT, sector index out of range'
713 709 #[PL] Last sector should be a "end of chain" marker:
714 710 if sect != ENDOFCHAIN:
715   - raise(IOError, 'incorrect last sector index in OLE stream')
  711 + raise IOError, 'incorrect last sector index in OLE stream'
716 712 data = string.join(data, "")
717 713 # Data is truncated to the actual stream size:
718 714 if len(data) >= size:
... ... @@ -726,7 +722,7 @@ class _OleStream(StringIO.StringIO):
726 722 else:
727 723 # read data is less than expected:
728 724 debug('len(data)=%d, size=%d' % (len(data), size))
729   - raise (IOError, 'OLE stream size is less than declared')
  725 + raise IOError, 'OLE stream size is less than declared'
730 726 # when all data is read in memory, StringIO constructor is called
731 727 StringIO.StringIO.__init__(self, data)
732 728 # Then the _OleStream object can be used as a read-only file object.
... ... @@ -833,13 +829,13 @@ class _OleDirectoryEntry:
833 829 # sectors, BUT apparently some implementations set it as 0xFFFFFFFFL, 1
834 830 # or some other value so it cannot be raised as a defect in general:
835 831 if olefile.sectorsize == 512:
836   - if sizeHigh != 0 and sizeHigh != 0xFFFFFFFF:
  832 + if sizeHigh != 0 and sizeHigh != 0xFFFFFFFFL:
837 833 debug('sectorsize=%d, sizeLow=%d, sizeHigh=%d (%X)' %
838 834 (olefile.sectorsize, sizeLow, sizeHigh, sizeHigh))
839 835 olefile._raise_defect(DEFECT_UNSURE, 'incorrect OLE stream size')
840 836 self.size = sizeLow
841 837 else:
842   - self.size = sizeLow + (int(sizeHigh)<<32)
  838 + self.size = sizeLow + (long(sizeHigh)<<32)
843 839 debug(' - size: %d (sizeLow=%d, sizeHigh=%d)' % (self.size, sizeLow, sizeHigh))
844 840  
845 841 self.clsid = _clsid(clsid)
... ... @@ -929,7 +925,7 @@ class _OleDirectoryEntry:
929 925  
930 926 def __cmp__(self, other):
931 927 "Compare entries by name"
932   - return __lt__(self.name, other.name)
  928 + return cmp(self.name, other.name)
933 929 #TODO: replace by the same function as MS implementation ?
934 930 # (order by name length first, then case-insensitive order)
935 931  
... ... @@ -938,13 +934,12 @@ class _OleDirectoryEntry:
938 934 "Dump this entry, and all its subentries (for debug purposes only)"
939 935 TYPES = ["(invalid)", "(storage)", "(stream)", "(lockbytes)",
940 936 "(property)", "(root)"]
941   - print(" "*tab + repr(self.name), TYPES[self.entry_type]),
  937 + print " "*tab + repr(self.name), TYPES[self.entry_type],
942 938 if self.entry_type in (STGTY_STREAM, STGTY_ROOT):
943   - print(self.size),\
944   - print("bytes"),
945   - print("\n")
  939 + print self.size, "bytes",
  940 + print
946 941 if self.entry_type in (STGTY_STORAGE, STGTY_ROOT) and self.clsid:
947   - print(" "*tab + "{%s}" % self.clsid)
  942 + print " "*tab + "{%s}" % self.clsid
948 943  
949 944 for kid in self.kids:
950 945 kid.dump(tab + 2)
... ... @@ -1043,7 +1038,7 @@ class OleFileIO:
1043 1038 """
1044 1039 # added by [PL]
1045 1040 if defect_level >= self._raise_defects_level:
1046   - raise(exception_type, message)
  1041 + raise exception_type, message
1047 1042 else:
1048 1043 # just record the issue, no exception raised:
1049 1044 self.parsing_issues.append((exception_type, message))
... ... @@ -1153,7 +1148,7 @@ class OleFileIO:
1153 1148 ) = struct.unpack(fmt_header, header1)
1154 1149 debug( struct.unpack(fmt_header, header1))
1155 1150  
1156   - if self.Sig != b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1':
  1151 + if self.Sig != '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1':
1157 1152 # OLE signature should always be present
1158 1153 self._raise_defect(DEFECT_FATAL, "incorrect OLE signature")
1159 1154 if self.clsid != '\x00'*16:
... ... @@ -1276,10 +1271,10 @@ class OleFileIO:
1276 1271 }
1277 1272 nbsect = len(fat)
1278 1273 nlines = (nbsect+VPL-1)/VPL
1279   - print("index"),
  1274 + print "index",
1280 1275 for i in range(VPL):
1281 1276 print ("%8X" % i),
1282   - print("")
  1277 + print ""
1283 1278 for l in range(nlines):
1284 1279 index = l*VPL
1285 1280 print ("%8X:" % (firstindex+index)),
... ... @@ -1294,8 +1289,8 @@ class OleFileIO:
1294 1289 nom = " --->"
1295 1290 else:
1296 1291 nom = "%8X" % sect
1297   - print(nom)
1298   - print("")
  1292 + print nom,
  1293 + print ""
1299 1294  
1300 1295  
1301 1296 def dumpsect(self, sector, firstindex=0):
... ... @@ -1306,10 +1301,10 @@ class OleFileIO:
1306 1301 tab = array.array(UINT32, sector)
1307 1302 nbsect = len(tab)
1308 1303 nlines = (nbsect+VPL-1)/VPL
1309   - print("index"),
  1304 + print "index",
1310 1305 for i in range(VPL):
1311 1306 print ("%8X" % i),
1312   - print("")
  1307 + print ""
1313 1308 for l in range(nlines):
1314 1309 index = l*VPL
1315 1310 print ("%8X:" % (firstindex+index)),
... ... @@ -1318,8 +1313,8 @@ class OleFileIO:
1318 1313 break
1319 1314 sect = tab[i]
1320 1315 nom = "%8X" % sect
1321   - print(nom),
1322   - print("")
  1316 + print nom,
  1317 + print ""
1323 1318  
1324 1319 def sect2array(self, sect):
1325 1320 """
... ... @@ -1403,9 +1398,9 @@ class OleFileIO:
1403 1398 nb_difat = (self.csectFat-109 + 126)/127
1404 1399 debug( "nb_difat = %d" % nb_difat )
1405 1400 if self.csectDif != nb_difat:
1406   - raise(IOError, 'incorrect DIFAT')
  1401 + raise IOError, 'incorrect DIFAT'
1407 1402 isect_difat = self.sectDifStart
1408   - for i in range(nb_difat):
  1403 + for i in xrange(nb_difat):
1409 1404 debug( "DIFAT block %d, sector %X" % (i, isect_difat) )
1410 1405 #TODO: check if corresponding FAT SID = DIFSECT
1411 1406 sector_difat = self.getsect(isect_difat)
... ... @@ -1418,7 +1413,7 @@ class OleFileIO:
1418 1413 # checks:
1419 1414 if isect_difat not in [ENDOFCHAIN, FREESECT]:
1420 1415 # last DIFAT pointer value must be ENDOFCHAIN or FREESECT
1421   - raise(IOError, 'incorrect end of DIFAT')
  1416 + raise IOError, 'incorrect end of DIFAT'
1422 1417 ## if len(self.fat) != self.num_fat_sectors:
1423 1418 ## # FAT should contain num_fat_sectors blocks
1424 1419 ## print "FAT length: %d instead of %d" % (len(self.fat), self.num_fat_sectors)
... ... @@ -1658,7 +1653,7 @@ class OleFileIO:
1658 1653 if kid.name.lower() == name.lower():
1659 1654 break
1660 1655 else:
1661   - raise(IOError, "file not found")
  1656 + raise IOError, "file not found"
1662 1657 node = kid
1663 1658 return node.sid
1664 1659  
... ... @@ -1678,7 +1673,7 @@ class OleFileIO:
1678 1673 sid = self._find(filename)
1679 1674 entry = self.direntries[sid]
1680 1675 if entry.entry_type != STGTY_STREAM:
1681   - raise(IOError, "this file is not a stream")
  1676 + raise IOError, "this file is not a stream"
1682 1677 return self._open(entry.isectStart, entry.size)
1683 1678  
1684 1679  
... ... @@ -1760,7 +1755,7 @@ class OleFileIO:
1760 1755 entry = self.direntries[sid]
1761 1756 if entry.entry_type != STGTY_STREAM:
1762 1757 #TODO: Should it return zero instead of raising an exception ?
1763   - raise(TypeError, 'object is not an OLE stream')
  1758 + raise TypeError, 'object is not an OLE stream'
1764 1759 return entry.size
1765 1760  
1766 1761  
... ... @@ -1865,12 +1860,12 @@ class OleFileIO:
1865 1860 count = i32(s, offset+4)
1866 1861 value = _unicode(s[offset+8:offset+8+count*2])
1867 1862 elif type == VT_FILETIME:
1868   - value = int(i32(s, offset+4)) + (int(i32(s, offset+8))<<32)
  1863 + value = long(i32(s, offset+4)) + (long(i32(s, offset+8))<<32)
1869 1864 # FILETIME is a 64-bit int: "number of 100ns periods
1870 1865 # since Jan 1,1601".
1871 1866 if convert_time and id not in no_conversion:
1872 1867 debug('Converting property #%d to python datetime, value=%d=%fs'
1873   - %(id, value, float(value)/10000000))
  1868 + %(id, value, float(value)/10000000L))
1874 1869 # convert FILETIME to Python datetime.datetime
1875 1870 # inspired from http://code.activestate.com/recipes/511425-filetime-to-datetime/
1876 1871 _FILETIME_null_date = datetime.datetime(1601, 1, 1, 0, 0, 0)
... ... @@ -1879,7 +1874,7 @@ class OleFileIO:
1879 1874 else:
1880 1875 # legacy code kept for backward compatibility: returns a
1881 1876 # number of seconds since Jan 1,1601
1882   - value = value / 10000000 # seconds
  1877 + value = value / 10000000L # seconds
1883 1878 elif type == VT_UI1: # 1-byte unsigned integer
1884 1879 value = ord(s[offset+4])
1885 1880 elif type == VT_CLSID:
... ... @@ -1944,8 +1939,8 @@ if __name__ == &quot;__main__&quot;:
1944 1939  
1945 1940 # [PL] display quick usage info if launched from command-line
1946 1941 if len(sys.argv) <= 1:
1947   - print(__doc__)
1948   - print("""
  1942 + print __doc__
  1943 + print """
1949 1944 Launched from command line, this script parses OLE files and prints info.
1950 1945  
1951 1946 Usage: olefile2.py [-d] [-c] <file> [file2 ...]
... ... @@ -1953,7 +1948,7 @@ Usage: olefile2.py [-d] [-c] &lt;file&gt; [file2 ...]
1953 1948 Options:
1954 1949 -d : debug mode (display a lot of debug information, for developers only)
1955 1950 -c : check all streams (for debugging purposes)
1956   -""")
  1951 +"""
1957 1952 sys.exit()
1958 1953  
1959 1954 check_streams = False
... ... @@ -1970,13 +1965,13 @@ Options:
1970 1965 continue
1971 1966  
1972 1967 ole = OleFileIO(filename)#, raise_defects=DEFECT_INCORRECT)
1973   - print("-" * 68)
1974   - print(filename)
1975   - print("-" * 68)
  1968 + print "-" * 68
  1969 + print filename
  1970 + print "-" * 68
1976 1971 ole.dumpdirectory()
1977 1972 for streamname in ole.listdir():
1978 1973 if streamname[-1][0] == "\005":
1979   - print( "%s : properties" % streamname)
  1974 + print streamname, ": properties"
1980 1975 props = ole.getproperties(streamname, convert_time=True)
1981 1976 props = props.items()
1982 1977 props.sort()
... ... @@ -1991,22 +1986,22 @@ Options:
1991 1986 if chr(c) in v:
1992 1987 v = '(binary data)'
1993 1988 break
1994   - print(" ", k, v)
  1989 + print " ", k, v
1995 1990  
1996 1991 if check_streams:
1997 1992 # Read all streams to check if there are errors:
1998   - print('\nChecking streams...')
  1993 + print '\nChecking streams...'
1999 1994 for streamname in ole.listdir():
2000 1995 # print name using repr() to convert binary chars to \xNN:
2001   - print('- %s -' % repr('/'.join(streamname)))
  1996 + print '-', repr('/'.join(streamname)),'-',
2002 1997 st_type = ole.get_type(streamname)
2003 1998 if st_type == STGTY_STREAM:
2004   - print('size %d' % ole.get_size(streamname))
  1999 + print 'size %d' % ole.get_size(streamname)
2005 2000 # just try to read stream in memory:
2006 2001 ole.openstream(streamname)
2007 2002 else:
2008   - print('NOT a stream : type=%d' % st_type)
2009   - print('')
  2003 + print 'NOT a stream : type=%d' % st_type
  2004 + print ''
2010 2005  
2011 2006 ## for streamname in ole.listdir():
2012 2007 ## # print name using repr() to convert binary chars to \xNN:
... ... @@ -2014,34 +2009,34 @@ Options:
2014 2009 ## print ole.getmtime(streamname)
2015 2010 ## print ''
2016 2011  
2017   - print('Modification/Creation times of all directory entries:')
  2012 + print 'Modification/Creation times of all directory entries:'
2018 2013 for entry in ole.direntries:
2019 2014 if entry is not None:
2020   - print('- %s: mtime=%s ctime=%s' % (entry.name,
2021   - entry.getmtime(), entry.getctime()))
2022   - print('')
  2015 + print '- %s: mtime=%s ctime=%s' % (entry.name,
  2016 + entry.getmtime(), entry.getctime())
  2017 + print ''
2023 2018  
2024 2019 # parse and display metadata:
2025 2020 meta = ole.get_metadata()
2026 2021 meta.dump()
2027   - print('')
  2022 + print ''
2028 2023 #[PL] Test a few new methods:
2029 2024 root = ole.get_rootentry_name()
2030   - print('Root entry name: "%s"' % root)
  2025 + print 'Root entry name: "%s"' % root
2031 2026 if ole.exists('worddocument'):
2032   - print("This is a Word document.")
2033   - print("type of stream 'WordDocument':", ole.get_type('worddocument'))
2034   - print("size :", ole.get_size('worddocument'))
  2027 + print "This is a Word document."
  2028 + print "type of stream 'WordDocument':", ole.get_type('worddocument')
  2029 + print "size :", ole.get_size('worddocument')
2035 2030 if ole.exists('macros/vba'):
2036   - print("This document may contain VBA macros.")
  2031 + print "This document may contain VBA macros."
2037 2032  
2038 2033 # print parsing issues:
2039   - print('\nNon-fatal issues raised during parsing:')
  2034 + print '\nNon-fatal issues raised during parsing:'
2040 2035 if ole.parsing_issues:
2041 2036 for exctype, msg in ole.parsing_issues:
2042   - print('- %s: %s' % (exctype.__name__, msg))
  2037 + print '- %s: %s' % (exctype.__name__, msg)
2043 2038 else:
2044   - print('None')
  2039 + print 'None'
2045 2040 ## except IOError, v:
2046 2041 ## print "***", "cannot read", file, "-", v
2047 2042  
... ...