home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / zipfile.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  30.8 KB  |  1,036 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import struct
  5. import os
  6. import time
  7. import sys
  8. import shutil
  9. import binascii
  10. import cStringIO
  11. import stat
  12.  
  13. try:
  14.     import zlib
  15.     crc32 = zlib.crc32
  16. except ImportError:
  17.     zlib = None
  18.     crc32 = binascii.crc32
  19.  
  20. __all__ = [
  21.     'BadZipfile',
  22.     'error',
  23.     'ZIP_STORED',
  24.     'ZIP_DEFLATED',
  25.     'is_zipfile',
  26.     'ZipInfo',
  27.     'ZipFile',
  28.     'PyZipFile',
  29.     'LargeZipFile']
  30.  
  31. class BadZipfile(Exception):
  32.     pass
  33.  
  34.  
  35. class LargeZipFile(Exception):
  36.     pass
  37.  
  38. error = BadZipfile
  39. ZIP64_LIMIT = (1 << 31) - 1
  40. ZIP_FILECOUNT_LIMIT = 1 << 16
  41. ZIP_MAX_COMMENT = (1 << 16) - 1
  42. ZIP_STORED = 0
  43. ZIP_DEFLATED = 8
  44. structEndArchive = '<4s4H2LH'
  45. stringEndArchive = 'PK\x05\x06'
  46. sizeEndCentDir = struct.calcsize(structEndArchive)
  47. _ECD_SIGNATURE = 0
  48. _ECD_DISK_NUMBER = 1
  49. _ECD_DISK_START = 2
  50. _ECD_ENTRIES_THIS_DISK = 3
  51. _ECD_ENTRIES_TOTAL = 4
  52. _ECD_SIZE = 5
  53. _ECD_OFFSET = 6
  54. _ECD_COMMENT_SIZE = 7
  55. _ECD_COMMENT = 8
  56. _ECD_LOCATION = 9
  57. structCentralDir = '<4s4B4HL2L5H2L'
  58. stringCentralDir = 'PK\x01\x02'
  59. sizeCentralDir = struct.calcsize(structCentralDir)
  60. _CD_SIGNATURE = 0
  61. _CD_CREATE_VERSION = 1
  62. _CD_CREATE_SYSTEM = 2
  63. _CD_EXTRACT_VERSION = 3
  64. _CD_EXTRACT_SYSTEM = 4
  65. _CD_FLAG_BITS = 5
  66. _CD_COMPRESS_TYPE = 6
  67. _CD_TIME = 7
  68. _CD_DATE = 8
  69. _CD_CRC = 9
  70. _CD_COMPRESSED_SIZE = 10
  71. _CD_UNCOMPRESSED_SIZE = 11
  72. _CD_FILENAME_LENGTH = 12
  73. _CD_EXTRA_FIELD_LENGTH = 13
  74. _CD_COMMENT_LENGTH = 14
  75. _CD_DISK_NUMBER_START = 15
  76. _CD_INTERNAL_FILE_ATTRIBUTES = 16
  77. _CD_EXTERNAL_FILE_ATTRIBUTES = 17
  78. _CD_LOCAL_HEADER_OFFSET = 18
  79. structFileHeader = '<4s2B4HL2L2H'
  80. stringFileHeader = 'PK\x03\x04'
  81. sizeFileHeader = struct.calcsize(structFileHeader)
  82. _FH_SIGNATURE = 0
  83. _FH_EXTRACT_VERSION = 1
  84. _FH_EXTRACT_SYSTEM = 2
  85. _FH_GENERAL_PURPOSE_FLAG_BITS = 3
  86. _FH_COMPRESSION_METHOD = 4
  87. _FH_LAST_MOD_TIME = 5
  88. _FH_LAST_MOD_DATE = 6
  89. _FH_CRC = 7
  90. _FH_COMPRESSED_SIZE = 8
  91. _FH_UNCOMPRESSED_SIZE = 9
  92. _FH_FILENAME_LENGTH = 10
  93. _FH_EXTRA_FIELD_LENGTH = 11
  94. structEndArchive64Locator = '<4sLQL'
  95. stringEndArchive64Locator = 'PK\x06\x07'
  96. sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator)
  97. structEndArchive64 = '<4sQ2H2L4Q'
  98. stringEndArchive64 = 'PK\x06\x06'
  99. sizeEndCentDir64 = struct.calcsize(structEndArchive64)
  100. _CD64_SIGNATURE = 0
  101. _CD64_DIRECTORY_RECSIZE = 1
  102. _CD64_CREATE_VERSION = 2
  103. _CD64_EXTRACT_VERSION = 3
  104. _CD64_DISK_NUMBER = 4
  105. _CD64_DISK_NUMBER_START = 5
  106. _CD64_NUMBER_ENTRIES_THIS_DISK = 6
  107. _CD64_NUMBER_ENTRIES_TOTAL = 7
  108. _CD64_DIRECTORY_SIZE = 8
  109. _CD64_OFFSET_START_CENTDIR = 9
  110.  
  111. def is_zipfile(filename):
  112.     
  113.     try:
  114.         fpin = open(filename, 'rb')
  115.         endrec = _EndRecData(fpin)
  116.         fpin.close()
  117.         if endrec:
  118.             return True
  119.     except IOError:
  120.         pass
  121.  
  122.     return False
  123.  
  124.  
  125. def _EndRecData64(fpin, offset, endrec):
  126.     fpin.seek(offset - sizeEndCentDir64Locator, 2)
  127.     data = fpin.read(sizeEndCentDir64Locator)
  128.     (sig, diskno, reloff, disks) = struct.unpack(structEndArchive64Locator, data)
  129.     if sig != stringEndArchive64Locator:
  130.         return endrec
  131.     if diskno != 0 or disks != 1:
  132.         raise BadZipfile('zipfiles that span multiple disks are not supported')
  133.     disks != 1
  134.     fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2)
  135.     data = fpin.read(sizeEndCentDir64)
  136.     (sig, sz, create_version, read_version, disk_num, disk_dir, dircount, dircount2, dirsize, diroffset) = struct.unpack(structEndArchive64, data)
  137.     if sig != stringEndArchive64:
  138.         return endrec
  139.     endrec[_ECD_SIGNATURE] = sig
  140.     endrec[_ECD_DISK_NUMBER] = disk_num
  141.     endrec[_ECD_DISK_START] = disk_dir
  142.     endrec[_ECD_ENTRIES_THIS_DISK] = dircount
  143.     endrec[_ECD_ENTRIES_TOTAL] = dircount2
  144.     endrec[_ECD_SIZE] = dirsize
  145.     endrec[_ECD_OFFSET] = diroffset
  146.     return endrec
  147.  
  148.  
  149. def _EndRecData(fpin):
  150.     fpin.seek(0, 2)
  151.     filesize = fpin.tell()
  152.     fpin.seek(-sizeEndCentDir, 2)
  153.     data = fpin.read()
  154.     if data[0:4] == stringEndArchive and data[-2:] == '\x00\x00':
  155.         endrec = struct.unpack(structEndArchive, data)
  156.         endrec = list(endrec)
  157.         endrec.append('')
  158.         endrec.append(filesize - sizeEndCentDir)
  159.         return _EndRecData64(fpin, -sizeEndCentDir, endrec)
  160.     maxCommentStart = max(filesize - 65536 - sizeEndCentDir, 0)
  161.     fpin.seek(maxCommentStart, 0)
  162.     data = fpin.read()
  163.     start = data.rfind(stringEndArchive)
  164.  
  165.  
  166. class ZipInfo(object):
  167.     __slots__ = ('orig_filename', 'filename', 'date_time', 'compress_type', 'comment', 'extra', 'create_system', 'create_version', 'extract_version', 'reserved', 'flag_bits', 'volume', 'internal_attr', 'external_attr', 'header_offset', 'CRC', 'compress_size', 'file_size', '_raw_time')
  168.     
  169.     def __init__(self, filename = 'NoName', date_time = (1980, 1, 1, 0, 0, 0)):
  170.         self.orig_filename = filename
  171.         null_byte = filename.find(chr(0))
  172.         if null_byte >= 0:
  173.             filename = filename[0:null_byte]
  174.         
  175.         if os.sep != '/' and os.sep in filename:
  176.             filename = filename.replace(os.sep, '/')
  177.         
  178.         self.filename = filename
  179.         self.date_time = date_time
  180.         self.compress_type = ZIP_STORED
  181.         self.comment = ''
  182.         self.extra = ''
  183.         if sys.platform == 'win32':
  184.             self.create_system = 0
  185.         else:
  186.             self.create_system = 3
  187.         self.create_version = 20
  188.         self.extract_version = 20
  189.         self.reserved = 0
  190.         self.flag_bits = 0
  191.         self.volume = 0
  192.         self.internal_attr = 0
  193.         self.external_attr = 0
  194.  
  195.     
  196.     def FileHeader(self):
  197.         dt = self.date_time
  198.         dosdate = dt[0] - 1980 << 9 | dt[1] << 5 | dt[2]
  199.         dostime = dt[3] << 11 | dt[4] << 5 | dt[5] // 2
  200.         if self.flag_bits & 8:
  201.             CRC = compress_size = file_size = 0
  202.         else:
  203.             CRC = self.CRC
  204.             compress_size = self.compress_size
  205.             file_size = self.file_size
  206.         extra = self.extra
  207.         if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
  208.             fmt = '<HHQQ'
  209.             extra = extra + struct.pack(fmt, 1, struct.calcsize(fmt) - 4, file_size, compress_size)
  210.             file_size = 0xFFFFFFFFL
  211.             compress_size = 0xFFFFFFFFL
  212.             self.extract_version = max(45, self.extract_version)
  213.             self.create_version = max(45, self.extract_version)
  214.         
  215.         (filename, flag_bits) = self._encodeFilenameFlags()
  216.         header = struct.pack(structFileHeader, stringFileHeader, self.extract_version, self.reserved, flag_bits, self.compress_type, dostime, dosdate, CRC, compress_size, file_size, len(filename), len(extra))
  217.         return header + filename + extra
  218.  
  219.     
  220.     def _encodeFilenameFlags(self):
  221.         if isinstance(self.filename, unicode):
  222.             
  223.             try:
  224.                 return (self.filename.encode('ascii'), self.flag_bits)
  225.             except UnicodeEncodeError:
  226.                 return (self.filename.encode('utf-8'), self.flag_bits | 2048)
  227.             
  228.  
  229.         None<EXCEPTION MATCH>UnicodeEncodeError
  230.         return (self.filename, self.flag_bits)
  231.  
  232.     
  233.     def _decodeFilename(self):
  234.         if self.flag_bits & 2048:
  235.             return self.filename.decode('utf-8')
  236.         return self.filename
  237.  
  238.     
  239.     def _decodeExtra(self):
  240.         extra = self.extra
  241.         unpack = struct.unpack
  242.         while extra:
  243.             (tp, ln) = unpack('<HH', extra[:4])
  244.             if tp == 1:
  245.                 if ln >= 24:
  246.                     counts = unpack('<QQQ', extra[4:28])
  247.                 elif ln == 16:
  248.                     counts = unpack('<QQ', extra[4:20])
  249.                 elif ln == 8:
  250.                     counts = unpack('<Q', extra[4:12])
  251.                 elif ln == 0:
  252.                     counts = ()
  253.                 else:
  254.                     raise RuntimeError, 'Corrupt extra field %s' % (ln,)
  255.                 idx = ln >= 24
  256.                 if self.file_size in (0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFL):
  257.                     self.file_size = counts[idx]
  258.                     idx += 1
  259.                 
  260.                 if self.compress_size == 0xFFFFFFFFL:
  261.                     self.compress_size = counts[idx]
  262.                     idx += 1
  263.                 
  264.                 if self.header_offset == 0xFFFFFFFFL:
  265.                     old = self.header_offset
  266.                     self.header_offset = counts[idx]
  267.                     idx += 1
  268.                 
  269.             
  270.             extra = extra[ln + 4:]
  271.  
  272.  
  273.  
  274. class _ZipDecrypter:
  275.     
  276.     def _GenerateCRCTable():
  277.         poly = 0xEDB88320L
  278.         table = [
  279.             0] * 256
  280.         for i in range(256):
  281.             crc = i
  282.             for j in range(8):
  283.                 if crc & 1:
  284.                     crc = crc >> 1 & 2147483647 ^ poly
  285.                     continue
  286.                 crc = crc >> 1 & 2147483647
  287.             
  288.             table[i] = crc
  289.         
  290.         return table
  291.  
  292.     crctable = _GenerateCRCTable()
  293.     
  294.     def _crc32(self, ch, crc):
  295.         return crc >> 8 & 16777215 ^ self.crctable[(crc ^ ord(ch)) & 255]
  296.  
  297.     
  298.     def __init__(self, pwd):
  299.         self.key0 = 305419896
  300.         self.key1 = 591751049
  301.         self.key2 = 878082192
  302.         for p in pwd:
  303.             self._UpdateKeys(p)
  304.         
  305.  
  306.     
  307.     def _UpdateKeys(self, c):
  308.         self.key0 = self._crc32(c, self.key0)
  309.         self.key1 = self.key1 + (self.key0 & 255) & 0xFFFFFFFFL
  310.         self.key1 = self.key1 * 134775813 + 1 & 0xFFFFFFFFL
  311.         self.key2 = self._crc32(chr(self.key1 >> 24 & 255), self.key2)
  312.  
  313.     
  314.     def __call__(self, c):
  315.         c = ord(c)
  316.         k = self.key2 | 2
  317.         c = c ^ k * (k ^ 1) >> 8 & 255
  318.         c = chr(c)
  319.         self._UpdateKeys(c)
  320.         return c
  321.  
  322.  
  323.  
  324. class ZipExtFile:
  325.     
  326.     def __init__(self, fileobj, zipinfo, decrypt = None):
  327.         self.fileobj = fileobj
  328.         self.decrypter = decrypt
  329.         self.bytes_read = 0x0L
  330.         self.rawbuffer = ''
  331.         self.readbuffer = ''
  332.         self.linebuffer = ''
  333.         self.eof = False
  334.         self.univ_newlines = False
  335.         self.nlSeps = ('\n',)
  336.         self.lastdiscard = ''
  337.         self.compress_type = zipinfo.compress_type
  338.         self.compress_size = zipinfo.compress_size
  339.         self.closed = False
  340.         self.mode = 'r'
  341.         self.name = zipinfo.filename
  342.         self.compreadsize = 65536
  343.         if self.compress_type == ZIP_DEFLATED:
  344.             self.dc = zlib.decompressobj(-15)
  345.         
  346.  
  347.     
  348.     def set_univ_newlines(self, univ_newlines):
  349.         self.univ_newlines = univ_newlines
  350.         self.nlSeps = ('\n',)
  351.         if self.univ_newlines:
  352.             self.nlSeps = ('\r\n', '\r', '\n')
  353.         
  354.  
  355.     
  356.     def __iter__(self):
  357.         return self
  358.  
  359.     
  360.     def next(self):
  361.         nextline = self.readline()
  362.         if not nextline:
  363.             raise StopIteration()
  364.         nextline
  365.         return nextline
  366.  
  367.     
  368.     def close(self):
  369.         self.closed = True
  370.  
  371.     
  372.     def _checkfornewline(self):
  373.         (nl, nllen) = (-1, -1)
  374.         if self.linebuffer:
  375.             if (self.lastdiscard, self.linebuffer[0]) == ('\r', '\n'):
  376.                 self.linebuffer = self.linebuffer[1:]
  377.             
  378.             for sep in self.nlSeps:
  379.                 nl = self.linebuffer.find(sep)
  380.                 if nl >= 0:
  381.                     nllen = len(sep)
  382.                     return (nl, nllen)
  383.             
  384.         
  385.         return (nl, nllen)
  386.  
  387.     
  388.     def readline(self, size = -1):
  389.         if size < 0:
  390.             size = sys.maxint
  391.         elif size == 0:
  392.             return ''
  393.         (nl, nllen) = self._checkfornewline()
  394.         buf = self.linebuffer[:nl]
  395.         self.lastdiscard = self.linebuffer[nl:nl + nllen]
  396.         self.linebuffer = self.linebuffer[nl + nllen:]
  397.         return buf + '\n'
  398.  
  399.     
  400.     def readlines(self, sizehint = -1):
  401.         result = []
  402.         while True:
  403.             line = self.readline()
  404.             if not line:
  405.                 break
  406.             
  407.             result.append(line)
  408.         return result
  409.  
  410.     
  411.     def read(self, size = None):
  412.         if size == 0:
  413.             return ''
  414.         bytesToRead = self.compress_size - self.bytes_read
  415.         if self.decrypter is not None:
  416.             bytesToRead -= 12
  417.         
  418.         if size is not None and size >= 0:
  419.             if self.compress_type == ZIP_STORED:
  420.                 lr = len(self.readbuffer)
  421.                 bytesToRead = min(bytesToRead, size - lr)
  422.             elif self.compress_type == ZIP_DEFLATED:
  423.                 if len(self.readbuffer) > size:
  424.                     bytesToRead = 0
  425.                 else:
  426.                     lr = len(self.rawbuffer)
  427.                     bytesToRead = min(bytesToRead, self.compreadsize - lr)
  428.             
  429.         
  430.         if bytesToRead + self.bytes_read > self.compress_size:
  431.             bytesToRead = self.compress_size - self.bytes_read
  432.         
  433.         if size is None or len(self.readbuffer) <= size:
  434.             bytes = self.readbuffer
  435.             self.readbuffer = ''
  436.         else:
  437.             bytes = self.readbuffer[:size]
  438.             self.readbuffer = self.readbuffer[size:]
  439.         return bytes
  440.  
  441.  
  442.  
  443. class ZipFile:
  444.     fp = None
  445.     
  446.     def __init__(self, file, mode = 'r', compression = ZIP_STORED, allowZip64 = False):
  447.         if mode not in ('r', 'w', 'a'):
  448.             raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
  449.         mode not in ('r', 'w', 'a')
  450.         if compression == ZIP_STORED:
  451.             pass
  452.         elif compression == ZIP_DEFLATED:
  453.             if not zlib:
  454.                 raise RuntimeError, 'Compression requires the (missing) zlib module'
  455.             zlib
  456.         else:
  457.             raise RuntimeError, 'That compression method is not supported'
  458.         self._allowZip64 = compression == ZIP_STORED
  459.         self._didModify = False
  460.         self.debug = 0
  461.         self.NameToInfo = { }
  462.         self.filelist = []
  463.         self.compression = compression
  464.         self.mode = key = mode.replace('b', '')[0]
  465.         self.pwd = None
  466.         self.comment = ''
  467.         if isinstance(file, basestring):
  468.             self._filePassed = 0
  469.             self.filename = file
  470.             modeDict = {
  471.                 'r': 'rb',
  472.                 'w': 'wb',
  473.                 'a': 'r+b' }
  474.             
  475.             try:
  476.                 self.fp = open(file, modeDict[mode])
  477.             except IOError:
  478.                 if mode == 'a':
  479.                     mode = key = 'w'
  480.                     self.fp = open(file, modeDict[mode])
  481.                 else:
  482.                     raise 
  483.                 mode == 'a'
  484.             
  485.  
  486.         None<EXCEPTION MATCH>IOError
  487.         self._filePassed = 1
  488.         self.fp = file
  489.         self.filename = getattr(file, 'name', None)
  490.         if key == 'r':
  491.             self._GetContents()
  492.         elif key == 'w':
  493.             pass
  494.         elif key == 'a':
  495.             
  496.             try:
  497.                 self._RealGetContents()
  498.                 self.fp.seek(self.start_dir, 0)
  499.             except BadZipfile:
  500.                 self.fp.seek(0, 2)
  501.             except:
  502.                 None<EXCEPTION MATCH>BadZipfile
  503.             
  504.  
  505.         None<EXCEPTION MATCH>BadZipfile
  506.         if not self._filePassed:
  507.             self.fp.close()
  508.             self.fp = None
  509.         
  510.         raise RuntimeError, 'Mode must be "r", "w" or "a"'
  511.  
  512.     
  513.     def _GetContents(self):
  514.         
  515.         try:
  516.             self._RealGetContents()
  517.         except BadZipfile:
  518.             if not self._filePassed:
  519.                 self.fp.close()
  520.                 self.fp = None
  521.             
  522.             raise 
  523.  
  524.  
  525.     
  526.     def _RealGetContents(self):
  527.         fp = self.fp
  528.         endrec = _EndRecData(fp)
  529.         if not endrec:
  530.             raise BadZipfile, 'File is not a zip file'
  531.         endrec
  532.         if self.debug > 1:
  533.             print endrec
  534.         
  535.         size_cd = endrec[_ECD_SIZE]
  536.         offset_cd = endrec[_ECD_OFFSET]
  537.         self.comment = endrec[_ECD_COMMENT]
  538.         concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
  539.         if endrec[_ECD_SIGNATURE] == stringEndArchive64:
  540.             concat -= sizeEndCentDir64 + sizeEndCentDir64Locator
  541.         
  542.         if self.debug > 2:
  543.             inferred = concat + offset_cd
  544.             print 'given, inferred, offset', offset_cd, inferred, concat
  545.         
  546.         self.start_dir = offset_cd + concat
  547.         fp.seek(self.start_dir, 0)
  548.         data = fp.read(size_cd)
  549.         fp = cStringIO.StringIO(data)
  550.         total = 0
  551.         while total < size_cd:
  552.             centdir = fp.read(sizeCentralDir)
  553.             if centdir[0:4] != stringCentralDir:
  554.                 raise BadZipfile, 'Bad magic number for central directory'
  555.             centdir[0:4] != stringCentralDir
  556.             centdir = struct.unpack(structCentralDir, centdir)
  557.             if self.debug > 2:
  558.                 print centdir
  559.             
  560.             filename = fp.read(centdir[_CD_FILENAME_LENGTH])
  561.             x = ZipInfo(filename)
  562.             x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
  563.             x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
  564.             x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
  565.             (x.create_version, x.create_system, x.extract_version, x.reserved, x.flag_bits, x.compress_type, t, d, x.CRC, x.compress_size, x.file_size) = centdir[1:12]
  566.             (x.volume, x.internal_attr, x.external_attr) = centdir[15:18]
  567.             x._raw_time = t
  568.             x.date_time = ((d >> 9) + 1980, d >> 5 & 15, d & 31, t >> 11, t >> 5 & 63, (t & 31) * 2)
  569.             x._decodeExtra()
  570.             x.header_offset = x.header_offset + concat
  571.             x.filename = x._decodeFilename()
  572.             self.filelist.append(x)
  573.             self.NameToInfo[x.filename] = x
  574.             total = total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] + centdir[_CD_EXTRA_FIELD_LENGTH] + centdir[_CD_COMMENT_LENGTH]
  575.             if self.debug > 2:
  576.                 print 'total', total
  577.                 continue
  578.  
  579.     
  580.     def namelist(self):
  581.         l = []
  582.         for data in self.filelist:
  583.             l.append(data.filename)
  584.         
  585.         return l
  586.  
  587.     
  588.     def infolist(self):
  589.         return self.filelist
  590.  
  591.     
  592.     def printdir(self):
  593.         print '%-46s %19s %12s' % ('File Name', 'Modified    ', 'Size')
  594.         for zinfo in self.filelist:
  595.             date = '%d-%02d-%02d %02d:%02d:%02d' % zinfo.date_time[:6]
  596.             print '%-46s %s %12d' % (zinfo.filename, date, zinfo.file_size)
  597.         
  598.  
  599.     
  600.     def testzip(self):
  601.         chunk_size = 1048576
  602.         for zinfo in self.filelist:
  603.             
  604.             try:
  605.                 f = self.open(zinfo.filename, 'r')
  606.                 while f.read(chunk_size):
  607.                     pass
  608.             continue
  609.             except BadZipfile:
  610.                 return zinfo.filename
  611.             
  612.  
  613.         
  614.  
  615.     
  616.     def getinfo(self, name):
  617.         info = self.NameToInfo.get(name)
  618.         if info is None:
  619.             raise KeyError('There is no item named %r in the archive' % name)
  620.         info is None
  621.         return info
  622.  
  623.     
  624.     def setpassword(self, pwd):
  625.         self.pwd = pwd
  626.  
  627.     
  628.     def read(self, name, pwd = None):
  629.         return self.open(name, 'r', pwd).read()
  630.  
  631.     
  632.     def open(self, name, mode = 'r', pwd = None):
  633.         if mode not in ('r', 'U', 'rU'):
  634.             raise RuntimeError, 'open() requires mode "r", "U", or "rU"'
  635.         mode not in ('r', 'U', 'rU')
  636.         if not self.fp:
  637.             raise RuntimeError, 'Attempt to read ZIP archive that was already closed'
  638.         self.fp
  639.         if self._filePassed:
  640.             zef_file = self.fp
  641.         else:
  642.             zef_file = open(self.filename, 'rb')
  643.         if isinstance(name, ZipInfo):
  644.             zinfo = name
  645.         else:
  646.             zinfo = self.getinfo(name)
  647.         zef_file.seek(zinfo.header_offset, 0)
  648.         fheader = zef_file.read(sizeFileHeader)
  649.         if fheader[0:4] != stringFileHeader:
  650.             raise BadZipfile, 'Bad magic number for file header'
  651.         fheader[0:4] != stringFileHeader
  652.         fheader = struct.unpack(structFileHeader, fheader)
  653.         fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
  654.         if fheader[_FH_EXTRA_FIELD_LENGTH]:
  655.             zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
  656.         
  657.         if fname != zinfo.orig_filename:
  658.             raise BadZipfile, 'File name in directory "%s" and header "%s" differ.' % (zinfo.orig_filename, fname)
  659.         fname != zinfo.orig_filename
  660.         is_encrypted = zinfo.flag_bits & 1
  661.         zd = None
  662.         if is_encrypted:
  663.             if not pwd:
  664.                 pwd = self.pwd
  665.             
  666.             if not pwd:
  667.                 raise RuntimeError, 'File %s is encrypted, password required for extraction' % name
  668.             pwd
  669.             zd = _ZipDecrypter(pwd)
  670.             bytes = zef_file.read(12)
  671.             h = map(zd, bytes[0:12])
  672.             if zinfo.flag_bits & 8:
  673.                 check_byte = zinfo._raw_time >> 8 & 255
  674.             else:
  675.                 check_byte = zinfo.CRC >> 24 & 255
  676.             if ord(h[11]) != check_byte:
  677.                 raise RuntimeError('Bad password for file', name)
  678.             ord(h[11]) != check_byte
  679.         
  680.         if zd is None:
  681.             zef = ZipExtFile(zef_file, zinfo)
  682.         else:
  683.             zef = ZipExtFile(zef_file, zinfo, zd)
  684.         if 'U' in mode:
  685.             zef.set_univ_newlines(True)
  686.         
  687.         return zef
  688.  
  689.     
  690.     def extract(self, member, path = None, pwd = None):
  691.         if not isinstance(member, ZipInfo):
  692.             member = self.getinfo(member)
  693.         
  694.         if path is None:
  695.             path = os.getcwd()
  696.         
  697.         return self._extract_member(member, path, pwd)
  698.  
  699.     
  700.     def extractall(self, path = None, members = None, pwd = None):
  701.         if members is None:
  702.             members = self.namelist()
  703.         
  704.         for zipinfo in members:
  705.             self.extract(zipinfo, path, pwd)
  706.         
  707.  
  708.     
  709.     def _extract_member(self, member, targetpath, pwd):
  710.         if targetpath[-1:] in (os.path.sep, os.path.altsep) and len(os.path.splitdrive(targetpath)[1]) > 1:
  711.             targetpath = targetpath[:-1]
  712.         
  713.         if member.filename[0] == '/':
  714.             targetpath = os.path.join(targetpath, member.filename[1:])
  715.         else:
  716.             targetpath = os.path.join(targetpath, member.filename)
  717.         targetpath = os.path.normpath(targetpath)
  718.         upperdirs = os.path.dirname(targetpath)
  719.         if upperdirs and not os.path.exists(upperdirs):
  720.             os.makedirs(upperdirs)
  721.         
  722.         if member.filename[-1] == '/':
  723.             os.mkdir(targetpath)
  724.             return targetpath
  725.         source = self.open(member, pwd = pwd)
  726.         target = file(targetpath, 'wb')
  727.         shutil.copyfileobj(source, target)
  728.         source.close()
  729.         target.close()
  730.         return targetpath
  731.  
  732.     
  733.     def _writecheck(self, zinfo):
  734.         if zinfo.filename in self.NameToInfo:
  735.             if self.debug:
  736.                 print 'Duplicate name:', zinfo.filename
  737.             
  738.         
  739.         if self.mode not in ('w', 'a'):
  740.             raise RuntimeError, 'write() requires mode "w" or "a"'
  741.         self.mode not in ('w', 'a')
  742.         if not self.fp:
  743.             raise RuntimeError, 'Attempt to write ZIP archive that was already closed'
  744.         self.fp
  745.         if zinfo.compress_type == ZIP_DEFLATED and not zlib:
  746.             raise RuntimeError, 'Compression requires the (missing) zlib module'
  747.         not zlib
  748.         if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED):
  749.             raise RuntimeError, 'That compression method is not supported'
  750.         zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED)
  751.         if zinfo.file_size > ZIP64_LIMIT:
  752.             if not self._allowZip64:
  753.                 raise LargeZipFile('Filesize would require ZIP64 extensions')
  754.             self._allowZip64
  755.         
  756.         if zinfo.header_offset > ZIP64_LIMIT:
  757.             if not self._allowZip64:
  758.                 raise LargeZipFile('Zipfile size would require ZIP64 extensions')
  759.             self._allowZip64
  760.         
  761.  
  762.     
  763.     def write(self, filename, arcname = None, compress_type = None):
  764.         if not self.fp:
  765.             raise RuntimeError('Attempt to write to ZIP archive that was already closed')
  766.         self.fp
  767.         st = os.stat(filename)
  768.         isdir = stat.S_ISDIR(st.st_mode)
  769.         mtime = time.localtime(st.st_mtime)
  770.         date_time = mtime[0:6]
  771.         if arcname is None:
  772.             arcname = filename
  773.         
  774.         arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
  775.         while arcname[0] in (os.sep, os.altsep):
  776.             arcname = arcname[1:]
  777.         if isdir:
  778.             arcname += '/'
  779.         
  780.         zinfo = ZipInfo(arcname, date_time)
  781.         zinfo.external_attr = (st[0] & 65535) << 0x10L
  782.         if compress_type is None:
  783.             zinfo.compress_type = self.compression
  784.         else:
  785.             zinfo.compress_type = compress_type
  786.         zinfo.file_size = st.st_size
  787.         zinfo.flag_bits = 0
  788.         zinfo.header_offset = self.fp.tell()
  789.         self._writecheck(zinfo)
  790.         self._didModify = True
  791.         if isdir:
  792.             zinfo.file_size = 0
  793.             zinfo.compress_size = 0
  794.             zinfo.CRC = 0
  795.             self.filelist.append(zinfo)
  796.             self.NameToInfo[zinfo.filename] = zinfo
  797.             self.fp.write(zinfo.FileHeader())
  798.             return None
  799.         fp = open(filename, 'rb')
  800.         self.fp.write(zinfo.FileHeader())
  801.         while None:
  802.             buf = fp.read(8192)
  803.             file_size = file_size + len(buf)
  804.             CRC = crc32(buf, CRC) & 0xFFFFFFFFL
  805.             if cmpr:
  806.                 buf = cmpr.compress(buf)
  807.                 compress_size = compress_size + len(buf)
  808.             
  809.             continue
  810.             fp.close()
  811.             if cmpr:
  812.                 buf = cmpr.flush()
  813.                 compress_size = compress_size + len(buf)
  814.                 self.fp.write(buf)
  815.                 zinfo.compress_size = compress_size
  816.             else:
  817.                 zinfo.compress_size = file_size
  818.         zinfo.CRC = CRC
  819.         zinfo.file_size = file_size
  820.         position = self.fp.tell()
  821.         self.fp.seek(zinfo.header_offset + 14, 0)
  822.         self.fp.write(struct.pack('<LLL', zinfo.CRC, zinfo.compress_size, zinfo.file_size))
  823.         self.fp.seek(position, 0)
  824.         self.filelist.append(zinfo)
  825.         self.NameToInfo[zinfo.filename] = zinfo
  826.  
  827.     
  828.     def writestr(self, zinfo_or_arcname, bytes):
  829.         if not isinstance(zinfo_or_arcname, ZipInfo):
  830.             zinfo = ZipInfo(filename = zinfo_or_arcname, date_time = time.localtime(time.time())[:6])
  831.             zinfo.compress_type = self.compression
  832.             zinfo.external_attr = 25165824
  833.         else:
  834.             zinfo = zinfo_or_arcname
  835.         if not self.fp:
  836.             raise RuntimeError('Attempt to write to ZIP archive that was already closed')
  837.         self.fp
  838.         zinfo.file_size = len(bytes)
  839.         zinfo.header_offset = self.fp.tell()
  840.         self._writecheck(zinfo)
  841.         self._didModify = True
  842.         zinfo.CRC = crc32(bytes) & 0xFFFFFFFFL
  843.         if zinfo.compress_type == ZIP_DEFLATED:
  844.             co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -15)
  845.             bytes = co.compress(bytes) + co.flush()
  846.             zinfo.compress_size = len(bytes)
  847.         else:
  848.             zinfo.compress_size = zinfo.file_size
  849.         zinfo.header_offset = self.fp.tell()
  850.         self.fp.write(zinfo.FileHeader())
  851.         self.fp.write(bytes)
  852.         self.fp.flush()
  853.         if zinfo.flag_bits & 8:
  854.             self.fp.write(struct.pack('<lLL', zinfo.CRC, zinfo.compress_size, zinfo.file_size))
  855.         
  856.         self.filelist.append(zinfo)
  857.         self.NameToInfo[zinfo.filename] = zinfo
  858.  
  859.     
  860.     def __del__(self):
  861.         self.close()
  862.  
  863.     
  864.     def close(self):
  865.         if self.fp is None:
  866.             return None
  867.         if not self._filePassed:
  868.             self.fp.close()
  869.         
  870.         self.fp = None
  871.  
  872.  
  873.  
  874. class PyZipFile(ZipFile):
  875.     
  876.     def writepy(self, pathname, basename = ''):
  877.         (dir, name) = os.path.split(pathname)
  878.         if os.path.isdir(pathname):
  879.             initname = os.path.join(pathname, '__init__.py')
  880.             if os.path.isfile(initname):
  881.                 if basename:
  882.                     basename = '%s/%s' % (basename, name)
  883.                 else:
  884.                     basename = name
  885.                 if self.debug:
  886.                     print 'Adding package in', pathname, 'as', basename
  887.                 
  888.                 (fname, arcname) = self._get_codename(initname[0:-3], basename)
  889.                 if self.debug:
  890.                     print 'Adding', arcname
  891.                 
  892.                 self.write(fname, arcname)
  893.                 dirlist = os.listdir(pathname)
  894.                 dirlist.remove('__init__.py')
  895.                 for filename in dirlist:
  896.                     path = os.path.join(pathname, filename)
  897.                     (root, ext) = os.path.splitext(filename)
  898.                     if os.path.isdir(path):
  899.                         if os.path.isfile(os.path.join(path, '__init__.py')):
  900.                             self.writepy(path, basename)
  901.                         
  902.                     os.path.isfile(os.path.join(path, '__init__.py'))
  903.                     if ext == '.py':
  904.                         (fname, arcname) = self._get_codename(path[0:-3], basename)
  905.                         if self.debug:
  906.                             print 'Adding', arcname
  907.                         
  908.                         self.write(fname, arcname)
  909.                         continue
  910.                 
  911.             elif self.debug:
  912.                 print 'Adding files from directory', pathname
  913.             
  914.             for filename in os.listdir(pathname):
  915.                 path = os.path.join(pathname, filename)
  916.                 (root, ext) = os.path.splitext(filename)
  917.                 if ext == '.py':
  918.                     (fname, arcname) = self._get_codename(path[0:-3], basename)
  919.                     if self.debug:
  920.                         print 'Adding', arcname
  921.                     
  922.                     self.write(fname, arcname)
  923.                     continue
  924.             
  925.         elif pathname[-3:] != '.py':
  926.             raise RuntimeError, 'Files added with writepy() must end with ".py"'
  927.         
  928.         (fname, arcname) = self._get_codename(pathname[0:-3], basename)
  929.         if self.debug:
  930.             print 'Adding file', arcname
  931.         
  932.         self.write(fname, arcname)
  933.  
  934.     
  935.     def _get_codename(self, pathname, basename):
  936.         file_py = pathname + '.py'
  937.         file_pyc = pathname + '.pyc'
  938.         file_pyo = pathname + '.pyo'
  939.         if os.path.isfile(file_pyo) and os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime:
  940.             fname = file_pyo
  941.         elif not os.path.isfile(file_pyc) or os.stat(file_pyc).st_mtime < os.stat(file_py).st_mtime:
  942.             import py_compile
  943.             if self.debug:
  944.                 print 'Compiling', file_py
  945.             
  946.             
  947.             try:
  948.                 py_compile.compile(file_py, file_pyc, None, True)
  949.             except py_compile.PyCompileError:
  950.                 err = None
  951.                 print err.msg
  952.  
  953.             fname = file_pyc
  954.         else:
  955.             fname = file_pyc
  956.         archivename = os.path.split(fname)[1]
  957.         if basename:
  958.             archivename = '%s/%s' % (basename, archivename)
  959.         
  960.         return (fname, archivename)
  961.  
  962.  
  963.  
  964. def main(args = None):
  965.     import textwrap
  966.     USAGE = textwrap.dedent('        Usage:\n            zipfile.py -l zipfile.zip        # Show listing of a zipfile\n            zipfile.py -t zipfile.zip        # Test if a zipfile is valid\n            zipfile.py -e zipfile.zip target # Extract zipfile into target dir\n            zipfile.py -c zipfile.zip src ... # Create zipfile from sources\n        ')
  967.     if args is None:
  968.         args = sys.argv[1:]
  969.     
  970.     if not args or args[0] not in ('-l', '-c', '-e', '-t'):
  971.         print USAGE
  972.         sys.exit(1)
  973.     
  974.     if args[0] == '-l':
  975.         if len(args) != 2:
  976.             print USAGE
  977.             sys.exit(1)
  978.         
  979.         zf = ZipFile(args[1], 'r')
  980.         zf.printdir()
  981.         zf.close()
  982.     elif args[0] == '-t':
  983.         if len(args) != 2:
  984.             print USAGE
  985.             sys.exit(1)
  986.         
  987.         zf = ZipFile(args[1], 'r')
  988.         zf.testzip()
  989.         print 'Done testing'
  990.     elif args[0] == '-e':
  991.         if len(args) != 3:
  992.             print USAGE
  993.             sys.exit(1)
  994.         
  995.         zf = ZipFile(args[1], 'r')
  996.         out = args[2]
  997.         for path in zf.namelist():
  998.             if path.startswith('./'):
  999.                 tgt = os.path.join(out, path[2:])
  1000.             else:
  1001.                 tgt = os.path.join(out, path)
  1002.             tgtdir = os.path.dirname(tgt)
  1003.             if not os.path.exists(tgtdir):
  1004.                 os.makedirs(tgtdir)
  1005.             
  1006.             fp = open(tgt, 'wb')
  1007.             fp.write(zf.read(path))
  1008.             fp.close()
  1009.         
  1010.         zf.close()
  1011.     elif args[0] == '-c':
  1012.         if len(args) < 3:
  1013.             print USAGE
  1014.             sys.exit(1)
  1015.         
  1016.         
  1017.         def addToZip(zf, path, zippath):
  1018.             if os.path.isfile(path):
  1019.                 zf.write(path, zippath, ZIP_DEFLATED)
  1020.             elif os.path.isdir(path):
  1021.                 for nm in os.listdir(path):
  1022.                     addToZip(zf, os.path.join(path, nm), os.path.join(zippath, nm))
  1023.                 
  1024.             
  1025.  
  1026.         zf = ZipFile(args[1], 'w', allowZip64 = True)
  1027.         for src in args[2:]:
  1028.             addToZip(zf, src, os.path.basename(src))
  1029.         
  1030.         zf.close()
  1031.     
  1032.  
  1033. if __name__ == '__main__':
  1034.     main()
  1035.  
  1036.