home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Freeware 31 / FreelogHS31.iso / Texte / scribus / scribus-1.3.3.9-win32-install.exe / lib / tarfile.py < prev    next >
Text File  |  2005-09-12  |  70KB  |  1,973 lines

  1. #!/usr/bin/env python
  2. # -*- coding: iso-8859-1 -*-
  3. #-------------------------------------------------------------------
  4. # tarfile.py
  5. #-------------------------------------------------------------------
  6. # Copyright (C) 2002 Lars GustΣbel <lars@gustaebel.de>
  7. # All rights reserved.
  8. #
  9. # Permission  is  hereby granted,  free  of charge,  to  any person
  10. # obtaining a  copy of  this software  and associated documentation
  11. # files  (the  "Software"),  to   deal  in  the  Software   without
  12. # restriction,  including  without limitation  the  rights to  use,
  13. # copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. # copies  of  the  Software,  and to  permit  persons  to  whom the
  15. # Software  is  furnished  to  do  so,  subject  to  the  following
  16. # conditions:
  17. #
  18. # The above copyright  notice and this  permission notice shall  be
  19. # included in all copies or substantial portions of the Software.
  20. #
  21. # THE SOFTWARE IS PROVIDED "AS  IS", WITHOUT WARRANTY OF ANY  KIND,
  22. # EXPRESS OR IMPLIED, INCLUDING  BUT NOT LIMITED TO  THE WARRANTIES
  23. # OF  MERCHANTABILITY,  FITNESS   FOR  A  PARTICULAR   PURPOSE  AND
  24. # NONINFRINGEMENT.  IN  NO  EVENT SHALL  THE  AUTHORS  OR COPYRIGHT
  25. # HOLDERS  BE LIABLE  FOR ANY  CLAIM, DAMAGES  OR OTHER  LIABILITY,
  26. # WHETHER  IN AN  ACTION OF  CONTRACT, TORT  OR OTHERWISE,  ARISING
  27. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  28. # OTHER DEALINGS IN THE SOFTWARE.
  29. #
  30. """Read from and write to tar format archives.
  31. """
  32.  
  33. __version__ = "$Revision: 1.21.2.5 $"
  34. # $Source: /cvsroot/python/python/dist/src/Lib/tarfile.py,v $
  35.  
  36. version     = "0.6.4"
  37. __author__  = "Lars GustΣbel (lars@gustaebel.de)"
  38. __date__    = "$Date: 2005/08/27 10:08:21 $"
  39. __cvsid__   = "$Id: tarfile.py,v 1.21.2.5 2005/08/27 10:08:21 loewis Exp $"
  40. __credits__ = "Gustavo Niemeyer, Niels GustΣbel, Richard Townsend."
  41.  
  42. #---------
  43. # Imports
  44. #---------
  45. import sys
  46. import os
  47. import shutil
  48. import stat
  49. import errno
  50. import time
  51. import struct
  52.  
  53. if sys.platform == 'mac':
  54.     # This module needs work for MacOS9, especially in the area of pathname
  55.     # handling. In many places it is assumed a simple substitution of / by the
  56.     # local os.path.sep is good enough to convert pathnames, but this does not
  57.     # work with the mac rooted:path:name versus :nonrooted:path:name syntax
  58.     raise ImportError, "tarfile does not work for platform==mac"
  59.  
  60. try:
  61.     import grp, pwd
  62. except ImportError:
  63.     grp = pwd = None
  64.  
  65. # from tarfile import *
  66. __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
  67.  
  68. #---------------------------------------------------------
  69. # tar constants
  70. #---------------------------------------------------------
  71. NUL        = "\0"               # the null character
  72. BLOCKSIZE  = 512                # length of processing blocks
  73. RECORDSIZE = BLOCKSIZE * 20     # length of records
  74. MAGIC      = "ustar"            # magic tar string
  75. VERSION    = "00"               # version number
  76.  
  77. LENGTH_NAME    = 100            # maximum length of a filename
  78. LENGTH_LINK    = 100            # maximum length of a linkname
  79. LENGTH_PREFIX  = 155            # maximum length of the prefix field
  80. MAXSIZE_MEMBER = 077777777777L  # maximum size of a file (11 octal digits)
  81.  
  82. REGTYPE  = "0"                  # regular file
  83. AREGTYPE = "\0"                 # regular file
  84. LNKTYPE  = "1"                  # link (inside tarfile)
  85. SYMTYPE  = "2"                  # symbolic link
  86. CHRTYPE  = "3"                  # character special device
  87. BLKTYPE  = "4"                  # block special device
  88. DIRTYPE  = "5"                  # directory
  89. FIFOTYPE = "6"                  # fifo special device
  90. CONTTYPE = "7"                  # contiguous file
  91.  
  92. GNUTYPE_LONGNAME = "L"          # GNU tar extension for longnames
  93. GNUTYPE_LONGLINK = "K"          # GNU tar extension for longlink
  94. GNUTYPE_SPARSE   = "S"          # GNU tar extension for sparse file
  95.  
  96. #---------------------------------------------------------
  97. # tarfile constants
  98. #---------------------------------------------------------
  99. SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,  # file types that tarfile
  100.                    SYMTYPE, DIRTYPE, FIFOTYPE,  # can cope with.
  101.                    CONTTYPE, CHRTYPE, BLKTYPE,
  102.                    GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
  103.                    GNUTYPE_SPARSE)
  104.  
  105. REGULAR_TYPES = (REGTYPE, AREGTYPE,             # file types that somehow
  106.                  CONTTYPE, GNUTYPE_SPARSE)      # represent regular files
  107.  
  108. #---------------------------------------------------------
  109. # Bits used in the mode field, values in octal.
  110. #---------------------------------------------------------
  111. S_IFLNK = 0120000        # symbolic link
  112. S_IFREG = 0100000        # regular file
  113. S_IFBLK = 0060000        # block device
  114. S_IFDIR = 0040000        # directory
  115. S_IFCHR = 0020000        # character device
  116. S_IFIFO = 0010000        # fifo
  117.  
  118. TSUID   = 04000          # set UID on execution
  119. TSGID   = 02000          # set GID on execution
  120. TSVTX   = 01000          # reserved
  121.  
  122. TUREAD  = 0400           # read by owner
  123. TUWRITE = 0200           # write by owner
  124. TUEXEC  = 0100           # execute/search by owner
  125. TGREAD  = 0040           # read by group
  126. TGWRITE = 0020           # write by group
  127. TGEXEC  = 0010           # execute/search by group
  128. TOREAD  = 0004           # read by other
  129. TOWRITE = 0002           # write by other
  130. TOEXEC  = 0001           # execute/search by other
  131.  
  132. #---------------------------------------------------------
  133. # Some useful functions
  134. #---------------------------------------------------------
  135. def nts(s):
  136.     """Convert a null-terminated string buffer to a python string.
  137.     """
  138.     return s.rstrip(NUL)
  139.  
  140. def calc_chksum(buf):
  141.     """Calculate the checksum for a member's header. It's a simple addition
  142.        of all bytes, treating the chksum field as if filled with spaces.
  143.        buf is a 512 byte long string buffer which holds the header.
  144.     """
  145.     chk = 256                           # chksum field is treated as blanks,
  146.                                         # so the initial value is 8 * ord(" ")
  147.     for c in buf[:148]: chk += ord(c)   # sum up all bytes before chksum
  148.     for c in buf[156:]: chk += ord(c)   # sum up all bytes after chksum
  149.     return chk
  150.  
  151. def copyfileobj(src, dst, length=None):
  152.     """Copy length bytes from fileobj src to fileobj dst.
  153.        If length is None, copy the entire content.
  154.     """
  155.     if length == 0:
  156.         return
  157.     if length is None:
  158.         shutil.copyfileobj(src, dst)
  159.         return
  160.  
  161.     BUFSIZE = 16 * 1024
  162.     blocks, remainder = divmod(length, BUFSIZE)
  163.     for b in xrange(blocks):
  164.         buf = src.read(BUFSIZE)
  165.         if len(buf) < BUFSIZE:
  166.             raise IOError, "end of file reached"
  167.         dst.write(buf)
  168.  
  169.     if remainder != 0:
  170.         buf = src.read(remainder)
  171.         if len(buf) < remainder:
  172.             raise IOError, "end of file reached"
  173.         dst.write(buf)
  174.     return
  175.  
  176. filemode_table = (
  177.     ((S_IFLNK,      "l"),
  178.      (S_IFREG,      "-"),
  179.      (S_IFBLK,      "b"),
  180.      (S_IFDIR,      "d"),
  181.      (S_IFCHR,      "c"),
  182.      (S_IFIFO,      "p")),
  183.  
  184.     ((TUREAD,       "r"),),
  185.     ((TUWRITE,      "w"),),
  186.     ((TUEXEC|TSUID, "s"),
  187.      (TSUID,        "S"),
  188.      (TUEXEC,       "x")),
  189.  
  190.     ((TGREAD,       "r"),),
  191.     ((TGWRITE,      "w"),),
  192.     ((TGEXEC|TSGID, "s"),
  193.      (TSGID,        "S"),
  194.      (TGEXEC,       "x")),
  195.  
  196.     ((TOREAD,       "r"),),
  197.     ((TOWRITE,      "w"),),
  198.     ((TOEXEC|TSVTX, "t"),
  199.      (TSVTX,        "T"),
  200.      (TOEXEC,       "x"))
  201. )
  202.  
  203. def filemode(mode):
  204.     """Convert a file's mode to a string of the form
  205.        -rwxrwxrwx.
  206.        Used by TarFile.list()
  207.     """
  208.     perm = []
  209.     for table in filemode_table:
  210.         for bit, char in table:
  211.             if mode & bit == bit:
  212.                 perm.append(char)
  213.                 break
  214.         else:
  215.             perm.append("-")
  216.     return "".join(perm)
  217.  
  218. if os.sep != "/":
  219.     normpath = lambda path: os.path.normpath(path).replace(os.sep, "/")
  220. else:
  221.     normpath = os.path.normpath
  222.  
  223. class TarError(Exception):
  224.     """Base exception."""
  225.     pass
  226. class ExtractError(TarError):
  227.     """General exception for extract errors."""
  228.     pass
  229. class ReadError(TarError):
  230.     """Exception for unreadble tar archives."""
  231.     pass
  232. class CompressionError(TarError):
  233.     """Exception for unavailable compression methods."""
  234.     pass
  235. class StreamError(TarError):
  236.     """Exception for unsupported operations on stream-like TarFiles."""
  237.     pass
  238.  
  239. #---------------------------
  240. # internal stream interface
  241. #---------------------------
  242. class _LowLevelFile:
  243.     """Low-level file object. Supports reading and writing.
  244.        It is used instead of a regular file object for streaming
  245.        access.
  246.     """
  247.  
  248.     def __init__(self, name, mode):
  249.         mode = {
  250.             "r": os.O_RDONLY,
  251.             "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
  252.         }[mode]
  253.         if hasattr(os, "O_BINARY"):
  254.             mode |= os.O_BINARY
  255.         self.fd = os.open(name, mode)
  256.  
  257.     def close(self):
  258.         os.close(self.fd)
  259.  
  260.     def read(self, size):
  261.         return os.read(self.fd, size)
  262.  
  263.     def write(self, s):
  264.         os.write(self.fd, s)
  265.  
  266. class _Stream:
  267.     """Class that serves as an adapter between TarFile and
  268.        a stream-like object.  The stream-like object only
  269.        needs to have a read() or write() method and is accessed
  270.        blockwise.  Use of gzip or bzip2 compression is possible.
  271.        A stream-like object could be for example: sys.stdin,
  272.        sys.stdout, a socket, a tape device etc.
  273.  
  274.        _Stream is intended to be used only internally.
  275.     """
  276.  
  277.     def __init__(self, name, mode, type, fileobj, bufsize):
  278.         """Construct a _Stream object.
  279.         """
  280.         self._extfileobj = True
  281.         if fileobj is None:
  282.             fileobj = _LowLevelFile(name, mode)
  283.             self._extfileobj = False
  284.  
  285.         self.name    = name or ""
  286.         self.mode    = mode
  287.         self.type    = type
  288.         self.fileobj = fileobj
  289.         self.bufsize = bufsize
  290.         self.buf     = ""
  291.         self.pos     = 0L
  292.         self.closed  = False
  293.  
  294.         if type == "gz":
  295.             try:
  296.                 import zlib
  297.             except ImportError:
  298.                 raise CompressionError, "zlib module is not available"
  299.             self.zlib = zlib
  300.             self.crc = zlib.crc32("")
  301.             if mode == "r":
  302.                 self._init_read_gz()
  303.             else:
  304.                 self._init_write_gz()
  305.  
  306.         if type == "bz2":
  307.             try:
  308.                 import bz2
  309.             except ImportError:
  310.                 raise CompressionError, "bz2 module is not available"
  311.             if mode == "r":
  312.                 self.dbuf = ""
  313.                 self.cmp = bz2.BZ2Decompressor()
  314.             else:
  315.                 self.cmp = bz2.BZ2Compressor()
  316.  
  317.     def __del__(self):
  318.         if not self.closed:
  319.             self.close()
  320.  
  321.     def _init_write_gz(self):
  322.         """Initialize for writing with gzip compression.
  323.         """
  324.         self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
  325.                                             -self.zlib.MAX_WBITS,
  326.                                             self.zlib.DEF_MEM_LEVEL,
  327.                                             0)
  328.         timestamp = struct.pack("<L", long(time.time()))
  329.         self.__write("\037\213\010\010%s\002\377" % timestamp)
  330.         if self.name.endswith(".gz"):
  331.             self.name = self.name[:-3]
  332.         self.__write(self.name + NUL)
  333.  
  334.     def write(self, s):
  335.         """Write string s to the stream.
  336.         """
  337.         if self.type == "gz":
  338.             self.crc = self.zlib.crc32(s, self.crc)
  339.         self.pos += len(s)
  340.         if self.type != "tar":
  341.             s = self.cmp.compress(s)
  342.         self.__write(s)
  343.  
  344.     def __write(self, s):
  345.         """Write string s to the stream if a whole new block
  346.            is ready to be written.
  347.         """
  348.         self.buf += s
  349.         while len(self.buf) > self.bufsize:
  350.             self.fileobj.write(self.buf[:self.bufsize])
  351.             self.buf = self.buf[self.bufsize:]
  352.  
  353.     def close(self):
  354.         """Close the _Stream object. No operation should be
  355.            done on it afterwards.
  356.         """
  357.         if self.closed:
  358.             return
  359.  
  360.         if self.mode == "w" and self.type != "tar":
  361.             self.buf += self.cmp.flush()
  362.         if self.mode == "w" and self.buf:
  363.             self.fileobj.write(self.buf)
  364.             self.buf = ""
  365.             if self.type == "gz":
  366.                 self.fileobj.write(struct.pack("<l", self.crc))
  367.                 self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFFL))
  368.  
  369.         if not self._extfileobj:
  370.             self.fileobj.close()
  371.  
  372.         self.closed = True
  373.  
  374.     def _init_read_gz(self):
  375.         """Initialize for reading a gzip compressed fileobj.
  376.         """
  377.         self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
  378.         self.dbuf = ""
  379.  
  380.         # taken from gzip.GzipFile with some alterations
  381.         if self.__read(2) != "\037\213":
  382.             raise ReadError, "not a gzip file"
  383.         if self.__read(1) != "\010":
  384.             raise CompressionError, "unsupported compression method"
  385.  
  386.         flag = ord(self.__read(1))
  387.         self.__read(6)
  388.  
  389.         if flag & 4:
  390.             xlen = ord(self.__read(1)) + 256 * ord(self.__read(1))
  391.             self.read(xlen)
  392.         if flag & 8:
  393.             while True:
  394.                 s = self.__read(1)
  395.                 if not s or s == NUL:
  396.                     break
  397.         if flag & 16:
  398.             while True:
  399.                 s = self.__read(1)
  400.                 if not s or s == NUL:
  401.                     break
  402.         if flag & 2:
  403.             self.__read(2)
  404.  
  405.     def tell(self):
  406.         """Return the stream's file pointer position.
  407.         """
  408.         return self.pos
  409.  
  410.     def seek(self, pos=0):
  411.         """Set the stream's file pointer to pos. Negative seeking
  412.            is forbidden.
  413.         """
  414.         if pos - self.pos >= 0:
  415.             blocks, remainder = divmod(pos - self.pos, self.bufsize)
  416.             for i in xrange(blocks):
  417.                 self.read(self.bufsize)
  418.             self.read(remainder)
  419.         else:
  420.             raise StreamError, "seeking backwards is not allowed"
  421.         return self.pos
  422.  
  423.     def read(self, size=None):
  424.         """Return the next size number of bytes from the stream.
  425.            If size is not defined, return all bytes of the stream
  426.            up to EOF.
  427.         """
  428.         if size is None:
  429.             t = []
  430.             while True:
  431.                 buf = self._read(self.bufsize)
  432.                 if not buf:
  433.                     break
  434.                 t.append(buf)
  435.             buf = "".join(t)
  436.         else:
  437.             buf = self._read(size)
  438.         self.pos += len(buf)
  439.         return buf
  440.  
  441.     def _read(self, size):
  442.         """Return size bytes from the stream.
  443.         """
  444.         if self.type == "tar":
  445.             return self.__read(size)
  446.  
  447.         c = len(self.dbuf)
  448.         t = [self.dbuf]
  449.         while c < size:
  450.             buf = self.__read(self.bufsize)
  451.             if not buf:
  452.                 break
  453.             buf = self.cmp.decompress(buf)
  454.             t.append(buf)
  455.             c += len(buf)
  456.         t = "".join(t)
  457.         self.dbuf = t[size:]
  458.         return t[:size]
  459.  
  460.     def __read(self, size):
  461.         """Return size bytes from stream. If internal buffer is empty,
  462.            read another block from the stream.
  463.         """
  464.         c = len(self.buf)
  465.         t = [self.buf]
  466.         while c < size:
  467.             buf = self.fileobj.read(self.bufsize)
  468.             if not buf:
  469.                 break
  470.             t.append(buf)
  471.             c += len(buf)
  472.         t = "".join(t)
  473.         self.buf = t[size:]
  474.         return t[:size]
  475. # class _Stream
  476.  
  477. #------------------------
  478. # Extraction file object
  479. #------------------------
  480. class ExFileObject(object):
  481.     """File-like object for reading an archive member.
  482.        Is returned by TarFile.extractfile(). Support for
  483.        sparse files included.
  484.     """
  485.  
  486.     def __init__(self, tarfile, tarinfo):
  487.         self.fileobj = tarfile.fileobj
  488.         self.name    = tarinfo.name
  489.         self.mode    = "r"
  490.         self.closed  = False
  491.         self.offset  = tarinfo.offset_data
  492.         self.size    = tarinfo.size
  493.         self.pos     = 0L
  494.         self.linebuffer = ""
  495.         if tarinfo.issparse():
  496.             self.sparse = tarinfo.sparse
  497.             self.read = self._readsparse
  498.         else:
  499.             self.read = self._readnormal
  500.  
  501.     def __read(self, size):
  502.         """Overloadable read method.
  503.         """
  504.         return self.fileobj.read(size)
  505.  
  506.     def readline(self, size=-1):
  507.         """Read a line with approx. size. If size is negative,
  508.            read a whole line. readline() and read() must not
  509.            be mixed up (!).
  510.         """
  511.         if size < 0:
  512.             size = sys.maxint
  513.  
  514.         nl = self.linebuffer.find("\n")
  515.         if nl >= 0:
  516.             nl = min(nl, size)
  517.         else:
  518.             size -= len(self.linebuffer)
  519.             while (nl < 0 and size > 0):
  520.                 buf = self.read(min(size, 100))
  521.                 if not buf:
  522.                     break
  523.                 self.linebuffer += buf
  524.                 size -= len(buf)
  525.                 nl = self.linebuffer.find("\n")
  526.             if nl == -1:
  527.                 s = self.linebuffer
  528.                 self.linebuffer = ""
  529.                 return s
  530.         buf = self.linebuffer[:nl]
  531.         self.linebuffer = self.linebuffer[nl + 1:]
  532.         while buf[-1:] == "\r":
  533.             buf = buf[:-1]
  534.         return buf + "\n"
  535.  
  536.     def readlines(self):
  537.         """Return a list with all (following) lines.
  538.         """
  539.         result = []
  540.         while True:
  541.             line = self.readline()
  542.             if not line: break
  543.             result.append(line)
  544.         return result
  545.  
  546.     def _readnormal(self, size=None):
  547.         """Read operation for regular files.
  548.         """
  549.         if self.closed:
  550.             raise ValueError, "file is closed"
  551.         self.fileobj.seek(self.offset + self.pos)
  552.         bytesleft = self.size - self.pos
  553.         if size is None:
  554.             bytestoread = bytesleft
  555.         else:
  556.             bytestoread = min(size, bytesleft)
  557.         self.pos += bytestoread
  558.         return self.__read(bytestoread)
  559.  
  560.     def _readsparse(self, size=None):
  561.         """Read operation for sparse files.
  562.         """
  563.         if self.closed:
  564.             raise ValueError, "file is closed"
  565.  
  566.         if size is None:
  567.             size = self.size - self.pos
  568.  
  569.         data = []
  570.         while size > 0:
  571.             buf = self._readsparsesection(size)
  572.             if not buf:
  573.                 break
  574.             size -= len(buf)
  575.             data.append(buf)
  576.         return "".join(data)
  577.  
  578.     def _readsparsesection(self, size):
  579.         """Read a single section of a sparse file.
  580.         """
  581.         section = self.sparse.find(self.pos)
  582.  
  583.         if section is None:
  584.             return ""
  585.  
  586.         toread = min(size, section.offset + section.size - self.pos)
  587.         if isinstance(section, _data):
  588.             realpos = section.realpos + self.pos - section.offset
  589.             self.pos += toread
  590.             self.fileobj.seek(self.offset + realpos)
  591.             return self.__read(toread)
  592.         else:
  593.             self.pos += toread
  594.             return NUL * toread
  595.  
  596.     def tell(self):
  597.         """Return the current file position.
  598.         """
  599.         return self.pos
  600.  
  601.     def seek(self, pos, whence=0):
  602.         """Seek to a position in the file.
  603.         """
  604.         self.linebuffer = ""
  605.         if whence == 0:
  606.             self.pos = min(max(pos, 0), self.size)
  607.         if whence == 1:
  608.             if pos < 0:
  609.                 self.pos = max(self.pos + pos, 0)
  610.             else:
  611.                 self.pos = min(self.pos + pos, self.size)
  612.         if whence == 2:
  613.             self.pos = max(min(self.size + pos, self.size), 0)
  614.  
  615.     def close(self):
  616.         """Close the file object.
  617.         """
  618.         self.closed = True
  619. #class ExFileObject
  620.  
  621. #------------------
  622. # Exported Classes
  623. #------------------
  624. class TarInfo(object):
  625.     """Informational class which holds the details about an
  626.        archive member given by a tar header block.
  627.        TarInfo objects are returned by TarFile.getmember(),
  628.        TarFile.getmembers() and TarFile.gettarinfo() and are
  629.        usually created internally.
  630.     """
  631.  
  632.     def __init__(self, name=""):
  633.         """Construct a TarInfo object. name is the optional name
  634.            of the member.
  635.         """
  636.  
  637.         self.name     = name       # member name (dirnames must end with '/')
  638.         self.mode     = 0666       # file permissions
  639.         self.uid      = 0          # user id
  640.         self.gid      = 0          # group id
  641.         self.size     = 0          # file size
  642.         self.mtime    = 0          # modification time
  643.         self.chksum   = 0          # header checksum
  644.         self.type     = REGTYPE    # member type
  645.         self.linkname = ""         # link name
  646.         self.uname    = "user"     # user name
  647.         self.gname    = "group"    # group name
  648.         self.devmajor = 0          #-
  649.         self.devminor = 0          #-for use with CHRTYPE and BLKTYPE
  650.         self.prefix   = ""         # prefix to filename or holding information
  651.                                    # about sparse files
  652.  
  653.         self.offset   = 0          # the tar header starts here
  654.         self.offset_data = 0       # the file's data starts here
  655.  
  656.     def __repr__(self):
  657.         return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
  658.  
  659.     def frombuf(cls, buf):
  660.         """Construct a TarInfo object from a 512 byte string buffer.
  661.         """
  662.         tarinfo = cls()
  663.         tarinfo.name   = nts(buf[0:100])
  664.         tarinfo.mode   = int(buf[100:108], 8)
  665.         tarinfo.uid    = int(buf[108:116],8)
  666.         tarinfo.gid    = int(buf[116:124],8)
  667.  
  668.         # There are two possible codings for the size field we
  669.         # have to discriminate, see comment in tobuf() below.
  670.         if buf[124] != chr(0200):
  671.             tarinfo.size = long(buf[124:136], 8)
  672.         else:
  673.             tarinfo.size = 0L
  674.             for i in range(11):
  675.                 tarinfo.size <<= 8
  676.                 tarinfo.size += ord(buf[125 + i])
  677.  
  678.         tarinfo.mtime  = long(buf[136:148], 8)
  679.         tarinfo.chksum = int(buf[148:156], 8)
  680.         tarinfo.type   = buf[156:157]
  681.         tarinfo.linkname = nts(buf[157:257])
  682.         tarinfo.uname  = nts(buf[265:297])
  683.         tarinfo.gname  = nts(buf[297:329])
  684.         try:
  685.             tarinfo.devmajor = int(buf[329:337], 8)
  686.             tarinfo.devminor = int(buf[337:345], 8)
  687.         except ValueError:
  688.             tarinfo.devmajor = tarinfo.devmajor = 0
  689.         tarinfo.prefix = buf[345:500]
  690.  
  691.         # The prefix field is used for filenames > 100 in
  692.         # the POSIX standard.
  693.         # name = prefix + '/' + name
  694.         if tarinfo.type != GNUTYPE_SPARSE:
  695.             tarinfo.name = normpath(os.path.join(nts(tarinfo.prefix), tarinfo.name))
  696.  
  697.         # Directory names should have a '/' at the end.
  698.         if tarinfo.isdir() and tarinfo.name[-1:] != "/":
  699.             tarinfo.name += "/"
  700.         return tarinfo
  701.  
  702.     frombuf = classmethod(frombuf)
  703.  
  704.     def tobuf(self):
  705.         """Return a tar header block as a 512 byte string.
  706.         """
  707.         # Prefer the size to be encoded as 11 octal ascii digits
  708.         # which is the most portable. If the size exceeds this
  709.         # limit (>= 8 GB), encode it as an 88-bit value which is
  710.         # a GNU tar feature.
  711.         if self.size <= MAXSIZE_MEMBER:
  712.             size = "%011o" % self.size
  713.         else:
  714.             s = self.size
  715.             size = ""
  716.             for i in range(11):
  717.                 size = chr(s & 0377) + size
  718.                 s >>= 8
  719.             size = chr(0200) + size
  720.  
  721.         # The following code was contributed by Detlef Lannert.
  722.         parts = []
  723.         for value, fieldsize in (
  724.                 (self.name, 100),
  725.                 ("%07o" % (self.mode & 07777), 8),
  726.                 ("%07o" % self.uid, 8),
  727.                 ("%07o" % self.gid, 8),
  728.                 (size, 12),
  729.                 ("%011o" % self.mtime, 12),
  730.                 ("        ", 8),
  731.                 (self.type, 1),
  732.                 (self.linkname, 100),
  733.                 (MAGIC, 6),
  734.                 (VERSION, 2),
  735.                 (self.uname, 32),
  736.                 (self.gname, 32),
  737.                 ("%07o" % self.devmajor, 8),
  738.                 ("%07o" % self.devminor, 8),
  739.                 (self.prefix, 155)
  740.             ):
  741.             l = len(value)
  742.             parts.append(value[:fieldsize] + (fieldsize - l) * NUL)
  743.  
  744.         buf = "".join(parts)
  745.         chksum = calc_chksum(buf)
  746.         buf = buf[:148] + "%06o\0" % chksum + buf[155:]
  747.         buf += (BLOCKSIZE - len(buf)) * NUL
  748.         self.buf = buf
  749.         return buf
  750.  
  751.     def isreg(self):
  752.         return self.type in REGULAR_TYPES
  753.     def isfile(self):
  754.         return self.isreg()
  755.     def isdir(self):
  756.         return self.type == DIRTYPE
  757.     def issym(self):
  758.         return self.type == SYMTYPE
  759.     def islnk(self):
  760.         return self.type == LNKTYPE
  761.     def ischr(self):
  762.         return self.type == CHRTYPE
  763.     def isblk(self):
  764.         return self.type == BLKTYPE
  765.     def isfifo(self):
  766.         return self.type == FIFOTYPE
  767.     def issparse(self):
  768.         return self.type == GNUTYPE_SPARSE
  769.     def isdev(self):
  770.         return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE)
  771. # class TarInfo
  772.  
  773. class TarFile(object):
  774.     """The TarFile Class provides an interface to tar archives.
  775.     """
  776.  
  777.     debug = 0                   # May be set from 0 (no msgs) to 3 (all msgs)
  778.  
  779.     dereference = False         # If true, add content of linked file to the
  780.                                 # tar file, else the link.
  781.  
  782.     ignore_zeros = False        # If true, skips empty or invalid blocks and
  783.                                 # continues processing.
  784.  
  785.     errorlevel = 0              # If 0, fatal errors only appear in debug
  786.                                 # messages (if debug >= 0). If > 0, errors
  787.                                 # are passed to the caller as exceptions.
  788.  
  789.     posix = False               # If True, generates POSIX.1-1990-compliant
  790.                                 # archives (no GNU extensions!)
  791.  
  792.     fileobject = ExFileObject
  793.  
  794.     def __init__(self, name=None, mode="r", fileobj=None):
  795.         """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
  796.            read from an existing archive, 'a' to append data to an existing
  797.            file or 'w' to create a new file overwriting an existing one. `mode'
  798.            defaults to 'r'.
  799.            If `fileobj' is given, it is used for reading or writing data. If it
  800.            can be determined, `mode' is overridden by `fileobj's mode.
  801.            `fileobj' is not closed, when TarFile is closed.
  802.         """
  803.         self.name = name
  804.  
  805.         if len(mode) > 1 or mode not in "raw":
  806.             raise ValueError, "mode must be 'r', 'a' or 'w'"
  807.         self._mode = mode
  808.         self.mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
  809.  
  810.         if not fileobj:
  811.             fileobj = file(self.name, self.mode)
  812.             self._extfileobj = False
  813.         else:
  814.             if self.name is None and hasattr(fileobj, "name"):
  815.                 self.name = fileobj.name
  816.             if hasattr(fileobj, "mode"):
  817.                 self.mode = fileobj.mode
  818.             self._extfileobj = True
  819.         self.fileobj = fileobj
  820.  
  821.         # Init datastructures
  822.         self.closed      = False
  823.         self.members     = []       # list of members as TarInfo objects
  824.         self._loaded     = False    # flag if all members have been read
  825.         self.offset      = 0L       # current position in the archive file
  826.         self.inodes      = {}       # dictionary caching the inodes of
  827.                                     # archive members already added
  828.  
  829.         if self._mode == "r":
  830.             self.firstmember = None
  831.             self.firstmember = self.next()
  832.  
  833.         if self._mode == "a":
  834.             # Move to the end of the archive,
  835.             # before the first empty block.
  836.             self.firstmember = None
  837.             while True:
  838.                 try:
  839.                     tarinfo = self.next()
  840.                 except ReadError:
  841.                     self.fileobj.seek(0)
  842.                     break
  843.                 if tarinfo is None:
  844.                     self.fileobj.seek(- BLOCKSIZE, 1)
  845.                     break
  846.  
  847.         if self._mode in "aw":
  848.             self._loaded = True
  849.  
  850.     #--------------------------------------------------------------------------
  851.     # Below are the classmethods which act as alternate constructors to the
  852.     # TarFile class. The open() method is the only one that is needed for
  853.     # public use; it is the "super"-constructor and is able to select an
  854.     # adequate "sub"-constructor for a particular compression using the mapping
  855.     # from OPEN_METH.
  856.     #
  857.     # This concept allows one to subclass TarFile without losing the comfort of
  858.     # the super-constructor. A sub-constructor is registered and made available
  859.     # by adding it to the mapping in OPEN_METH.
  860.  
  861.     def open(cls, name=None, mode="r", fileobj=None, bufsize=20*512):
  862.         """Open a tar archive for reading, writing or appending. Return
  863.            an appropriate TarFile class.
  864.  
  865.            mode:
  866.            'r'          open for reading with transparent compression
  867.            'r:'         open for reading exclusively uncompressed
  868.            'r:gz'       open for reading with gzip compression
  869.            'r:bz2'      open for reading with bzip2 compression
  870.            'a' or 'a:'  open for appending
  871.            'w' or 'w:'  open for writing without compression
  872.            'w:gz'       open for writing with gzip compression
  873.            'w:bz2'      open for writing with bzip2 compression
  874.            'r|'         open an uncompressed stream of tar blocks for reading
  875.            'r|gz'       open a gzip compressed stream of tar blocks
  876.            'r|bz2'      open a bzip2 compressed stream of tar blocks
  877.            'w|'         open an uncompressed stream for writing
  878.            'w|gz'       open a gzip compressed stream for writing
  879.            'w|bz2'      open a bzip2 compressed stream for writing
  880.         """
  881.  
  882.         if not name and not fileobj:
  883.             raise ValueError, "nothing to open"
  884.  
  885.         if ":" in mode:
  886.             filemode, comptype = mode.split(":", 1)
  887.             filemode = filemode or "r"
  888.             comptype = comptype or "tar"
  889.  
  890.             # Select the *open() function according to
  891.             # given compression.
  892.             if comptype in cls.OPEN_METH:
  893.                 func = getattr(cls, cls.OPEN_METH[comptype])
  894.             else:
  895.                 raise CompressionError, "unknown compression type %r" % comptype
  896.             return func(name, filemode, fileobj)
  897.  
  898.         elif "|" in mode:
  899.             filemode, comptype = mode.split("|", 1)
  900.             filemode = filemode or "r"
  901.             comptype = comptype or "tar"
  902.  
  903.             if filemode not in "rw":
  904.                 raise ValueError, "mode must be 'r' or 'w'"
  905.  
  906.             t = cls(name, filemode,
  907.                     _Stream(name, filemode, comptype, fileobj, bufsize))
  908.             t._extfileobj = False
  909.             return t
  910.  
  911.         elif mode == "r":
  912.             # Find out which *open() is appropriate for opening the file.
  913.             for comptype in cls.OPEN_METH:
  914.                 func = getattr(cls, cls.OPEN_METH[comptype])
  915.                 try:
  916.                     return func(name, "r", fileobj)
  917.                 except (ReadError, CompressionError):
  918.                     continue
  919.             raise ReadError, "file could not be opened successfully"
  920.  
  921.         elif mode in "aw":
  922.             return cls.taropen(name, mode, fileobj)
  923.  
  924.         raise ValueError, "undiscernible mode"
  925.  
  926.     open = classmethod(open)
  927.  
  928.     def taropen(cls, name, mode="r", fileobj=None):
  929.         """Open uncompressed tar archive name for reading or writing.
  930.         """
  931.         if len(mode) > 1 or mode not in "raw":
  932.             raise ValueError, "mode must be 'r', 'a' or 'w'"
  933.         return cls(name, mode, fileobj)
  934.  
  935.     taropen = classmethod(taropen)
  936.  
  937.     def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9):
  938.         """Open gzip compressed tar archive name for reading or writing.
  939.            Appending is not allowed.
  940.         """
  941.         if len(mode) > 1 or mode not in "rw":
  942.             raise ValueError, "mode must be 'r' or 'w'"
  943.  
  944.         try:
  945.             import gzip
  946.             gzip.GzipFile
  947.         except (ImportError, AttributeError):
  948.             raise CompressionError, "gzip module is not available"
  949.  
  950.         pre, ext = os.path.splitext(name)
  951.         pre = os.path.basename(pre)
  952.         if ext == ".tgz":
  953.             ext = ".tar"
  954.         if ext == ".gz":
  955.             ext = ""
  956.         tarname = pre + ext
  957.  
  958.         if fileobj is None:
  959.             fileobj = file(name, mode + "b")
  960.  
  961.         if mode != "r":
  962.             name = tarname
  963.  
  964.         try:
  965.             t = cls.taropen(tarname, mode,
  966.                 gzip.GzipFile(name, mode, compresslevel, fileobj)
  967.             )
  968.         except IOError:
  969.             raise ReadError, "not a gzip file"
  970.         t._extfileobj = False
  971.         return t
  972.  
  973.     gzopen = classmethod(gzopen)
  974.  
  975.     def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9):
  976.         """Open bzip2 compressed tar archive name for reading or writing.
  977.            Appending is not allowed.
  978.         """
  979.         if len(mode) > 1 or mode not in "rw":
  980.             raise ValueError, "mode must be 'r' or 'w'."
  981.  
  982.         try:
  983.             import bz2
  984.         except ImportError:
  985.             raise CompressionError, "bz2 module is not available"
  986.  
  987.         pre, ext = os.path.splitext(name)
  988.         pre = os.path.basename(pre)
  989.         if ext == ".tbz2":
  990.             ext = ".tar"
  991.         if ext == ".bz2":
  992.             ext = ""
  993.         tarname = pre + ext
  994.  
  995.         if fileobj is not None:
  996.             raise ValueError, "no support for external file objects"
  997.  
  998.         try:
  999.             t = cls.taropen(tarname, mode, bz2.BZ2File(name, mode, compresslevel=compresslevel))
  1000.         except IOError:
  1001.             raise ReadError, "not a bzip2 file"
  1002.         t._extfileobj = False
  1003.         return t
  1004.  
  1005.     bz2open = classmethod(bz2open)
  1006.  
  1007.     # All *open() methods are registered here.
  1008.     OPEN_METH = {
  1009.         "tar": "taropen",   # uncompressed tar
  1010.         "gz":  "gzopen",    # gzip compressed tar
  1011.         "bz2": "bz2open"    # bzip2 compressed tar
  1012.     }
  1013.  
  1014.     #--------------------------------------------------------------------------
  1015.     # The public methods which TarFile provides:
  1016.  
  1017.     def close(self):
  1018.         """Close the TarFile. In write-mode, two finishing zero blocks are
  1019.            appended to the archive.
  1020.         """
  1021.         if self.closed:
  1022.             return
  1023.  
  1024.         if self._mode in "aw":
  1025.             self.fileobj.write(NUL * (BLOCKSIZE * 2))
  1026.             self.offset += (BLOCKSIZE * 2)
  1027.             # fill up the end with zero-blocks
  1028.             # (like option -b20 for tar does)
  1029.             blocks, remainder = divmod(self.offset, RECORDSIZE)
  1030.             if remainder > 0:
  1031.                 self.fileobj.write(NUL * (RECORDSIZE - remainder))
  1032.  
  1033.         if not self._extfileobj:
  1034.             self.fileobj.close()
  1035.         self.closed = True
  1036.  
  1037.     def getmember(self, name):
  1038.         """Return a TarInfo object for member `name'. If `name' can not be
  1039.            found in the archive, KeyError is raised. If a member occurs more
  1040.            than once in the archive, its last occurence is assumed to be the
  1041.            most up-to-date version.
  1042.         """
  1043.         tarinfo = self._getmember(name)
  1044.         if tarinfo is None:
  1045.             raise KeyError, "filename %r not found" % name
  1046.         return tarinfo
  1047.  
  1048.     def getmembers(self):
  1049.         """Return the members of the archive as a list of TarInfo objects. The
  1050.            list has the same order as the members in the archive.
  1051.         """
  1052.         self._check()
  1053.         if not self._loaded:    # if we want to obtain a list of
  1054.             self._load()        # all members, we first have to
  1055.                                 # scan the whole archive.
  1056.         return self.members
  1057.  
  1058.     def getnames(self):
  1059.         """Return the members of the archive as a list of their names. It has
  1060.            the same order as the list returned by getmembers().
  1061.         """
  1062.         return [tarinfo.name for tarinfo in self.getmembers()]
  1063.  
  1064.     def gettarinfo(self, name=None, arcname=None, fileobj=None):
  1065.         """Create a TarInfo object for either the file `name' or the file
  1066.            object `fileobj' (using os.fstat on its file descriptor). You can
  1067.            modify some of the TarInfo's attributes before you add it using
  1068.            addfile(). If given, `arcname' specifies an alternative name for the
  1069.            file in the archive.
  1070.         """
  1071.         self._check("aw")
  1072.  
  1073.         # When fileobj is given, replace name by
  1074.         # fileobj's real name.
  1075.         if fileobj is not None:
  1076.             name = fileobj.name
  1077.  
  1078.         # Building the name of the member in the archive.
  1079.         # Backward slashes are converted to forward slashes,
  1080.         # Absolute paths are turned to relative paths.
  1081.         if arcname is None:
  1082.             arcname = name
  1083.         arcname = normpath(arcname)
  1084.         drv, arcname = os.path.splitdrive(arcname)
  1085.         while arcname[0:1] == "/":
  1086.             arcname = arcname[1:]
  1087.  
  1088.         # Now, fill the TarInfo object with
  1089.         # information specific for the file.
  1090.         tarinfo = TarInfo()
  1091.  
  1092.         # Use os.stat or os.lstat, depending on platform
  1093.         # and if symlinks shall be resolved.
  1094.         if fileobj is None:
  1095.             if hasattr(os, "lstat") and not self.dereference:
  1096.                 statres = os.lstat(name)
  1097.             else:
  1098.                 statres = os.stat(name)
  1099.         else:
  1100.             statres = os.fstat(fileobj.fileno())
  1101.         linkname = ""
  1102.  
  1103.         stmd = statres.st_mode
  1104.         if stat.S_ISREG(stmd):
  1105.             inode = (statres.st_ino, statres.st_dev)
  1106.             if inode in self.inodes and not self.dereference:
  1107.                 # Is it a hardlink to an already
  1108.                 # archived file?
  1109.                 type = LNKTYPE
  1110.                 linkname = self.inodes[inode]
  1111.             else:
  1112.                 # The inode is added only if its valid.
  1113.                 # For win32 it is always 0.
  1114.                 type = REGTYPE
  1115.                 if inode[0]:
  1116.                     self.inodes[inode] = arcname
  1117.         elif stat.S_ISDIR(stmd):
  1118.             type = DIRTYPE
  1119.             if arcname[-1:] != "/":
  1120.                 arcname += "/"
  1121.         elif stat.S_ISFIFO(stmd):
  1122.             type = FIFOTYPE
  1123.         elif stat.S_ISLNK(stmd):
  1124.             type = SYMTYPE
  1125.             linkname = os.readlink(name)
  1126.         elif stat.S_ISCHR(stmd):
  1127.             type = CHRTYPE
  1128.         elif stat.S_ISBLK(stmd):
  1129.             type = BLKTYPE
  1130.         else:
  1131.             return None
  1132.  
  1133.         # Fill the TarInfo object with all
  1134.         # information we can get.
  1135.         tarinfo.name = arcname
  1136.         tarinfo.mode = stmd
  1137.         tarinfo.uid = statres.st_uid
  1138.         tarinfo.gid = statres.st_gid
  1139.         if stat.S_ISREG(stmd):
  1140.             tarinfo.size = statres.st_size
  1141.         else:
  1142.             tarinfo.size = 0L
  1143.         tarinfo.mtime = statres.st_mtime
  1144.         tarinfo.type = type
  1145.         tarinfo.linkname = linkname
  1146.         if pwd:
  1147.             try:
  1148.                 tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
  1149.             except KeyError:
  1150.                 pass
  1151.         if grp:
  1152.             try:
  1153.                 tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
  1154.             except KeyError:
  1155.                 pass
  1156.  
  1157.         if type in (CHRTYPE, BLKTYPE):
  1158.             if hasattr(os, "major") and hasattr(os, "minor"):
  1159.                 tarinfo.devmajor = os.major(statres.st_rdev)
  1160.                 tarinfo.devminor = os.minor(statres.st_rdev)
  1161.         return tarinfo
  1162.  
  1163.     def list(self, verbose=True):
  1164.         """Print a table of contents to sys.stdout. If `verbose' is False, only
  1165.            the names of the members are printed. If it is True, an `ls -l'-like
  1166.            output is produced.
  1167.         """
  1168.         self._check()
  1169.  
  1170.         for tarinfo in self:
  1171.             if verbose:
  1172.                 print filemode(tarinfo.mode),
  1173.                 print "%s/%s" % (tarinfo.uname or tarinfo.uid,
  1174.                                  tarinfo.gname or tarinfo.gid),
  1175.                 if tarinfo.ischr() or tarinfo.isblk():
  1176.                     print "%10s" % ("%d,%d" \
  1177.                                     % (tarinfo.devmajor, tarinfo.devminor)),
  1178.                 else:
  1179.                     print "%10d" % tarinfo.size,
  1180.                 print "%d-%02d-%02d %02d:%02d:%02d" \
  1181.                       % time.localtime(tarinfo.mtime)[:6],
  1182.  
  1183.             print tarinfo.name,
  1184.  
  1185.             if verbose:
  1186.                 if tarinfo.issym():
  1187.                     print "->", tarinfo.linkname,
  1188.                 if tarinfo.islnk():
  1189.                     print "link to", tarinfo.linkname,
  1190.             print
  1191.  
  1192.     def add(self, name, arcname=None, recursive=True):
  1193.         """Add the file `name' to the archive. `name' may be any type of file
  1194.            (directory, fifo, symbolic link, etc.). If given, `arcname'
  1195.            specifies an alternative name for the file in the archive.
  1196.            Directories are added recursively by default. This can be avoided by
  1197.            setting `recursive' to False.
  1198.         """
  1199.         self._check("aw")
  1200.  
  1201.         if arcname is None:
  1202.             arcname = name
  1203.  
  1204.         # Skip if somebody tries to archive the archive...
  1205.         if self.name is not None \
  1206.             and os.path.abspath(name) == os.path.abspath(self.name):
  1207.             self._dbg(2, "tarfile: Skipped %r" % name)
  1208.             return
  1209.  
  1210.         # Special case: The user wants to add the current
  1211.         # working directory.
  1212.         if name == ".":
  1213.             if recursive:
  1214.                 if arcname == ".":
  1215.                     arcname = ""
  1216.                 for f in os.listdir("."):
  1217.                     self.add(f, os.path.join(arcname, f))
  1218.             return
  1219.  
  1220.         self._dbg(1, name)
  1221.  
  1222.         # Create a TarInfo object from the file.
  1223.         tarinfo = self.gettarinfo(name, arcname)
  1224.  
  1225.         if tarinfo is None:
  1226.             self._dbg(1, "tarfile: Unsupported type %r" % name)
  1227.             return
  1228.  
  1229.         # Append the tar header and data to the archive.
  1230.         if tarinfo.isreg():
  1231.             f = file(name, "rb")
  1232.             self.addfile(tarinfo, f)
  1233.             f.close()
  1234.  
  1235.         elif tarinfo.isdir():
  1236.             self.addfile(tarinfo)
  1237.             if recursive:
  1238.                 for f in os.listdir(name):
  1239.                     self.add(os.path.join(name, f), os.path.join(arcname, f))
  1240.  
  1241.         else:
  1242.             self.addfile(tarinfo)
  1243.  
  1244.     def addfile(self, tarinfo, fileobj=None):
  1245.         """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
  1246.            given, tarinfo.size bytes are read from it and added to the archive.
  1247.            You can create TarInfo objects using gettarinfo().
  1248.            On Windows platforms, `fileobj' should always be opened with mode
  1249.            'rb' to avoid irritation about the file size.
  1250.         """
  1251.         self._check("aw")
  1252.  
  1253.         tarinfo.name = normpath(tarinfo.name)
  1254.         if tarinfo.isdir():
  1255.             # directories should end with '/'
  1256.             tarinfo.name += "/"
  1257.  
  1258.         if tarinfo.linkname:
  1259.             tarinfo.linkname = normpath(tarinfo.linkname)
  1260.  
  1261.         if tarinfo.size > MAXSIZE_MEMBER:
  1262.             if self.posix:
  1263.                 raise ValueError, "file is too large (>= 8 GB)"
  1264.             else:
  1265.                 self._dbg(2, "tarfile: Created GNU tar largefile header")
  1266.  
  1267.  
  1268.         if len(tarinfo.linkname) > LENGTH_LINK:
  1269.             if self.posix:
  1270.                 raise ValueError, "linkname is too long (>%d)" \
  1271.                                   % (LENGTH_LINK)
  1272.             else:
  1273.                 self._create_gnulong(tarinfo.linkname, GNUTYPE_LONGLINK)
  1274.                 tarinfo.linkname = tarinfo.linkname[:LENGTH_LINK -1]
  1275.                 self._dbg(2, "tarfile: Created GNU tar extension LONGLINK")
  1276.  
  1277.         if len(tarinfo.name) > LENGTH_NAME:
  1278.             if self.posix:
  1279.                 prefix = tarinfo.name[:LENGTH_PREFIX + 1]
  1280.                 while prefix and prefix[-1] != "/":
  1281.                     prefix = prefix[:-1]
  1282.  
  1283.                 name = tarinfo.name[len(prefix):]
  1284.                 prefix = prefix[:-1]
  1285.  
  1286.                 if not prefix or len(name) > LENGTH_NAME:
  1287.                     raise ValueError, "name is too long (>%d)" \
  1288.                                       % (LENGTH_NAME)
  1289.  
  1290.                 tarinfo.name   = name
  1291.                 tarinfo.prefix = prefix
  1292.             else:
  1293.                 self._create_gnulong(tarinfo.name, GNUTYPE_LONGNAME)
  1294.                 tarinfo.name = tarinfo.name[:LENGTH_NAME - 1]
  1295.                 self._dbg(2, "tarfile: Created GNU tar extension LONGNAME")
  1296.  
  1297.         self.fileobj.write(tarinfo.tobuf())
  1298.         self.offset += BLOCKSIZE
  1299.  
  1300.         # If there's data to follow, append it.
  1301.         if fileobj is not None:
  1302.             copyfileobj(fileobj, self.fileobj, tarinfo.size)
  1303.             blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
  1304.             if remainder > 0:
  1305.                 self.fileobj.write(NUL * (BLOCKSIZE - remainder))
  1306.                 blocks += 1
  1307.             self.offset += blocks * BLOCKSIZE
  1308.  
  1309.         self.members.append(tarinfo)
  1310.  
  1311.     def extract(self, member, path=""):
  1312.         """Extract a member from the archive to the current working directory,
  1313.            using its full name. Its file information is extracted as accurately
  1314.            as possible. `member' may be a filename or a TarInfo object. You can
  1315.            specify a different directory using `path'.
  1316.         """
  1317.         self._check("r")
  1318.  
  1319.         if isinstance(member, TarInfo):
  1320.             tarinfo = member
  1321.         else:
  1322.             tarinfo = self.getmember(member)
  1323.  
  1324.         # Prepare the link target for makelink().
  1325.         if tarinfo.islnk():
  1326.             tarinfo._link_target = os.path.join(path, tarinfo.linkname)
  1327.  
  1328.         try:
  1329.             self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
  1330.         except EnvironmentError, e:
  1331.             if self.errorlevel > 0:
  1332.                 raise
  1333.             else:
  1334.                 if e.filename is None:
  1335.                     self._dbg(1, "tarfile: %s" % e.strerror)
  1336.                 else:
  1337.                     self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
  1338.         except ExtractError, e:
  1339.             if self.errorlevel > 1:
  1340.                 raise
  1341.             else:
  1342.                 self._dbg(1, "tarfile: %s" % e)
  1343.  
  1344.     def extractfile(self, member):
  1345.         """Extract a member from the archive as a file object. `member' may be
  1346.            a filename or a TarInfo object. If `member' is a regular file, a
  1347.            file-like object is returned. If `member' is a link, a file-like
  1348.            object is constructed from the link's target. If `member' is none of
  1349.            the above, None is returned.
  1350.            The file-like object is read-only and provides the following
  1351.            methods: read(), readline(), readlines(), seek() and tell()
  1352.         """
  1353.         self._check("r")
  1354.  
  1355.         if isinstance(member, TarInfo):
  1356.             tarinfo = member
  1357.         else:
  1358.             tarinfo = self.getmember(member)
  1359.  
  1360.         if tarinfo.isreg():
  1361.             return self.fileobject(self, tarinfo)
  1362.  
  1363.         elif tarinfo.type not in SUPPORTED_TYPES:
  1364.             # If a member's type is unknown, it is treated as a
  1365.             # regular file.
  1366.             return self.fileobject(self, tarinfo)
  1367.  
  1368.         elif tarinfo.islnk() or tarinfo.issym():
  1369.             if isinstance(self.fileobj, _Stream):
  1370.                 # A small but ugly workaround for the case that someone tries
  1371.                 # to extract a (sym)link as a file-object from a non-seekable
  1372.                 # stream of tar blocks.
  1373.                 raise StreamError, "cannot extract (sym)link as file object"
  1374.             else:
  1375.                 # A (sym)link's file object is its target's file object.
  1376.                 return self.extractfile(self._getmember(tarinfo.linkname,
  1377.                                                         tarinfo))
  1378.         else:
  1379.             # If there's no data associated with the member (directory, chrdev,
  1380.             # blkdev, etc.), return None instead of a file object.
  1381.             return None
  1382.  
  1383.     def _extract_member(self, tarinfo, targetpath):
  1384.         """Extract the TarInfo object tarinfo to a physical
  1385.            file called targetpath.
  1386.         """
  1387.         # Fetch the TarInfo object for the given name
  1388.         # and build the destination pathname, replacing
  1389.         # forward slashes to platform specific separators.
  1390.         if targetpath[-1:] == "/":
  1391.             targetpath = targetpath[:-1]
  1392.         targetpath = os.path.normpath(targetpath)
  1393.  
  1394.         # Create all upper directories.
  1395.         upperdirs = os.path.dirname(targetpath)
  1396.         if upperdirs and not os.path.exists(upperdirs):
  1397.             ti = TarInfo()
  1398.             ti.name  = upperdirs
  1399.             ti.type  = DIRTYPE
  1400.             ti.mode  = 0777
  1401.             ti.mtime = tarinfo.mtime
  1402.             ti.uid   = tarinfo.uid
  1403.             ti.gid   = tarinfo.gid
  1404.             ti.uname = tarinfo.uname
  1405.             ti.gname = tarinfo.gname
  1406.             try:
  1407.                 self._extract_member(ti, ti.name)
  1408.             except:
  1409.                 pass
  1410.  
  1411.         if tarinfo.islnk() or tarinfo.issym():
  1412.             self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
  1413.         else:
  1414.             self._dbg(1, tarinfo.name)
  1415.  
  1416.         if tarinfo.isreg():
  1417.             self.makefile(tarinfo, targetpath)
  1418.         elif tarinfo.isdir():
  1419.             self.makedir(tarinfo, targetpath)
  1420.         elif tarinfo.isfifo():
  1421.             self.makefifo(tarinfo, targetpath)
  1422.         elif tarinfo.ischr() or tarinfo.isblk():
  1423.             self.makedev(tarinfo, targetpath)
  1424.         elif tarinfo.islnk() or tarinfo.issym():
  1425.             self.makelink(tarinfo, targetpath)
  1426.         elif tarinfo.type not in SUPPORTED_TYPES:
  1427.             self.makeunknown(tarinfo, targetpath)
  1428.         else:
  1429.             self.makefile(tarinfo, targetpath)
  1430.  
  1431.         self.chown(tarinfo, targetpath)
  1432.         if not tarinfo.issym():
  1433.             self.chmod(tarinfo, targetpath)
  1434.             self.utime(tarinfo, targetpath)
  1435.  
  1436.     #--------------------------------------------------------------------------
  1437.     # Below are the different file methods. They are called via
  1438.     # _extract_member() when extract() is called. They can be replaced in a
  1439.     # subclass to implement other functionality.
  1440.  
  1441.     def makedir(self, tarinfo, targetpath):
  1442.         """Make a directory called targetpath.
  1443.         """
  1444.         try:
  1445.             os.mkdir(targetpath)
  1446.         except EnvironmentError, e:
  1447.             if e.errno != errno.EEXIST:
  1448.                 raise
  1449.  
  1450.     def makefile(self, tarinfo, targetpath):
  1451.         """Make a file called targetpath.
  1452.         """
  1453.         source = self.extractfile(tarinfo)
  1454.         target = file(targetpath, "wb")
  1455.         copyfileobj(source, target)
  1456.         source.close()
  1457.         target.close()
  1458.  
  1459.     def makeunknown(self, tarinfo, targetpath):
  1460.         """Make a file from a TarInfo object with an unknown type
  1461.            at targetpath.
  1462.         """
  1463.         self.makefile(tarinfo, targetpath)
  1464.         self._dbg(1, "tarfile: Unknown file type %r, " \
  1465.                      "extracted as regular file." % tarinfo.type)
  1466.  
  1467.     def makefifo(self, tarinfo, targetpath):
  1468.         """Make a fifo called targetpath.
  1469.         """
  1470.         if hasattr(os, "mkfifo"):
  1471.             os.mkfifo(targetpath)
  1472.         else:
  1473.             raise ExtractError, "fifo not supported by system"
  1474.  
  1475.     def makedev(self, tarinfo, targetpath):
  1476.         """Make a character or block device called targetpath.
  1477.         """
  1478.         if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
  1479.             raise ExtractError, "special devices not supported by system"
  1480.  
  1481.         mode = tarinfo.mode
  1482.         if tarinfo.isblk():
  1483.             mode |= stat.S_IFBLK
  1484.         else:
  1485.             mode |= stat.S_IFCHR
  1486.  
  1487.         os.mknod(targetpath, mode,
  1488.                  os.makedev(tarinfo.devmajor, tarinfo.devminor))
  1489.  
  1490.     def makelink(self, tarinfo, targetpath):
  1491.         """Make a (symbolic) link called targetpath. If it cannot be created
  1492.           (platform limitation), we try to make a copy of the referenced file
  1493.           instead of a link.
  1494.         """
  1495.         linkpath = tarinfo.linkname
  1496.         try:
  1497.             if tarinfo.issym():
  1498.                 os.symlink(linkpath, targetpath)
  1499.             else:
  1500.                 # See extract().
  1501.                 os.link(tarinfo._link_target, targetpath)
  1502.         except AttributeError:
  1503.             if tarinfo.issym():
  1504.                 linkpath = os.path.join(os.path.dirname(tarinfo.name),
  1505.                                         linkpath)
  1506.                 linkpath = normpath(linkpath)
  1507.  
  1508.             try:
  1509.                 self._extract_member(self.getmember(linkpath), targetpath)
  1510.             except (EnvironmentError, KeyError), e:
  1511.                 linkpath = os.path.normpath(linkpath)
  1512.                 try:
  1513.                     shutil.copy2(linkpath, targetpath)
  1514.                 except EnvironmentError, e:
  1515.                     raise IOError, "link could not be created"
  1516.  
  1517.     def chown(self, tarinfo, targetpath):
  1518.         """Set owner of targetpath according to tarinfo.
  1519.         """
  1520.         if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
  1521.             # We have to be root to do so.
  1522.             try:
  1523.                 g = grp.getgrnam(tarinfo.gname)[2]
  1524.             except KeyError:
  1525.                 try:
  1526.                     g = grp.getgrgid(tarinfo.gid)[2]
  1527.                 except KeyError:
  1528.                     g = os.getgid()
  1529.             try:
  1530.                 u = pwd.getpwnam(tarinfo.uname)[2]
  1531.             except KeyError:
  1532.                 try:
  1533.                     u = pwd.getpwuid(tarinfo.uid)[2]
  1534.                 except KeyError:
  1535.                     u = os.getuid()
  1536.             try:
  1537.                 if tarinfo.issym() and hasattr(os, "lchown"):
  1538.                     os.lchown(targetpath, u, g)
  1539.                 else:
  1540.                     if sys.platform != "os2emx":
  1541.                         os.chown(targetpath, u, g)
  1542.             except EnvironmentError, e:
  1543.                 raise ExtractError, "could not change owner"
  1544.  
  1545.     def chmod(self, tarinfo, targetpath):
  1546.         """Set file permissions of targetpath according to tarinfo.
  1547.         """
  1548.         if hasattr(os, 'chmod'):
  1549.             try:
  1550.                 os.chmod(targetpath, tarinfo.mode)
  1551.             except EnvironmentError, e:
  1552.                 raise ExtractError, "could not change mode"
  1553.  
  1554.     def utime(self, tarinfo, targetpath):
  1555.         """Set modification time of targetpath according to tarinfo.
  1556.         """
  1557.         if not hasattr(os, 'utime'):
  1558.             return
  1559.         if sys.platform == "win32" and tarinfo.isdir():
  1560.             # According to msdn.microsoft.com, it is an error (EACCES)
  1561.             # to use utime() on directories.
  1562.             return
  1563.         try:
  1564.             os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
  1565.         except EnvironmentError, e:
  1566.             raise ExtractError, "could not change modification time"
  1567.  
  1568.     #--------------------------------------------------------------------------
  1569.  
  1570.     def next(self):
  1571.         """Return the next member of the archive as a TarInfo object, when
  1572.            TarFile is opened for reading. Return None if there is no more
  1573.            available.
  1574.         """
  1575.         self._check("ra")
  1576.         if self.firstmember is not None:
  1577.             m = self.firstmember
  1578.             self.firstmember = None
  1579.             return m
  1580.  
  1581.         # Read the next block.
  1582.         self.fileobj.seek(self.offset)
  1583.         while True:
  1584.             buf = self.fileobj.read(BLOCKSIZE)
  1585.             if not buf:
  1586.                 return None
  1587.             try:
  1588.                 tarinfo = TarInfo.frombuf(buf)
  1589.             except ValueError:
  1590.                 if self.ignore_zeros:
  1591.                     if buf.count(NUL) == BLOCKSIZE:
  1592.                         adj = "empty"
  1593.                     else:
  1594.                         adj = "invalid"
  1595.                     self._dbg(2, "0x%X: %s block" % (self.offset, adj))
  1596.                     self.offset += BLOCKSIZE
  1597.                     continue
  1598.                 else:
  1599.                     # Block is empty or unreadable.
  1600.                     if self.offset == 0:
  1601.                         # If the first block is invalid. That does not
  1602.                         # look like a tar archive we can handle.
  1603.                         raise ReadError,"empty, unreadable or compressed file"
  1604.                     return None
  1605.             break
  1606.  
  1607.         # We shouldn't rely on this checksum, because some tar programs
  1608.         # calculate it differently and it is merely validating the
  1609.         # header block. We could just as well skip this part, which would
  1610.         # have a slight effect on performance...
  1611.         if tarinfo.chksum != calc_chksum(buf):
  1612.             self._dbg(1, "tarfile: Bad Checksum %r" % tarinfo.name)
  1613.  
  1614.         # Set the TarInfo object's offset to the current position of the
  1615.         # TarFile and set self.offset to the position where the data blocks
  1616.         # should begin.
  1617.         tarinfo.offset = self.offset
  1618.         self.offset += BLOCKSIZE
  1619.  
  1620.         # Check if the TarInfo object has a typeflag for which a callback
  1621.         # method is registered in the TYPE_METH. If so, then call it.
  1622.         if tarinfo.type in self.TYPE_METH:
  1623.             return self.TYPE_METH[tarinfo.type](self, tarinfo)
  1624.  
  1625.         tarinfo.offset_data = self.offset
  1626.         if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES:
  1627.             # Skip the following data blocks.
  1628.             self.offset += self._block(tarinfo.size)
  1629.  
  1630.         if tarinfo.isreg() and tarinfo.name[:-1] == "/":
  1631.             # some old tar programs don't know DIRTYPE
  1632.             tarinfo.type = DIRTYPE
  1633.  
  1634.         self.members.append(tarinfo)
  1635.         return tarinfo
  1636.  
  1637.     #--------------------------------------------------------------------------
  1638.     # Below are some methods which are called for special typeflags in the
  1639.     # next() method, e.g. for unwrapping GNU longname/longlink blocks. They
  1640.     # are registered in TYPE_METH below. You can register your own methods
  1641.     # with this mapping.
  1642.     # A registered method is called with a TarInfo object as only argument.
  1643.     #
  1644.     # During its execution the method MUST perform the following tasks:
  1645.     # 1. set tarinfo.offset_data to the position where the data blocks begin,
  1646.     #    if there is data to follow.
  1647.     # 2. set self.offset to the position where the next member's header will
  1648.     #    begin.
  1649.     # 3. append the tarinfo object to self.members, if it is supposed to appear
  1650.     #    as a member of the TarFile object.
  1651.     # 4. return tarinfo or another valid TarInfo object.
  1652.  
  1653.     def proc_gnulong(self, tarinfo):
  1654.         """Evaluate the blocks that hold a GNU longname
  1655.            or longlink member.
  1656.         """
  1657.         buf = ""
  1658.         count = tarinfo.size
  1659.         while count > 0:
  1660.             block = self.fileobj.read(BLOCKSIZE)
  1661.             buf += block
  1662.             self.offset += BLOCKSIZE
  1663.             count -= BLOCKSIZE
  1664.  
  1665.         # Fetch the next header
  1666.         next = self.next()
  1667.  
  1668.         next.offset = tarinfo.offset
  1669.         if tarinfo.type == GNUTYPE_LONGNAME:
  1670.             next.name = nts(buf)
  1671.         elif tarinfo.type == GNUTYPE_LONGLINK:
  1672.             next.linkname = nts(buf)
  1673.  
  1674.         return next
  1675.  
  1676.     def proc_sparse(self, tarinfo):
  1677.         """Analyze a GNU sparse header plus extra headers.
  1678.         """
  1679.         buf = tarinfo.tobuf()
  1680.         sp = _ringbuffer()
  1681.         pos = 386
  1682.         lastpos = 0L
  1683.         realpos = 0L
  1684.         # There are 4 possible sparse structs in the
  1685.         # first header.
  1686.         for i in xrange(4):
  1687.             try:
  1688.                 offset = int(buf[pos:pos + 12], 8)
  1689.                 numbytes = int(buf[pos + 12:pos + 24], 8)
  1690.             except ValueError:
  1691.                 break
  1692.             if offset > lastpos:
  1693.                 sp.append(_hole(lastpos, offset - lastpos))
  1694.             sp.append(_data(offset, numbytes, realpos))
  1695.             realpos += numbytes
  1696.             lastpos = offset + numbytes
  1697.             pos += 24
  1698.  
  1699.         isextended = ord(buf[482])
  1700.         origsize = int(buf[483:495], 8)
  1701.  
  1702.         # If the isextended flag is given,
  1703.         # there are extra headers to process.
  1704.         while isextended == 1:
  1705.             buf = self.fileobj.read(BLOCKSIZE)
  1706.             self.offset += BLOCKSIZE
  1707.             pos = 0
  1708.             for i in xrange(21):
  1709.                 try:
  1710.                     offset = int(buf[pos:pos + 12], 8)
  1711.                     numbytes = int(buf[pos + 12:pos + 24], 8)
  1712.                 except ValueError:
  1713.                     break
  1714.                 if offset > lastpos:
  1715.                     sp.append(_hole(lastpos, offset - lastpos))
  1716.                 sp.append(_data(offset, numbytes, realpos))
  1717.                 realpos += numbytes
  1718.                 lastpos = offset + numbytes
  1719.                 pos += 24
  1720.             isextended = ord(buf[504])
  1721.  
  1722.         if lastpos < origsize:
  1723.             sp.append(_hole(lastpos, origsize - lastpos))
  1724.  
  1725.         tarinfo.sparse = sp
  1726.  
  1727.         tarinfo.offset_data = self.offset
  1728.         self.offset += self._block(tarinfo.size)
  1729.         tarinfo.size = origsize
  1730.  
  1731.         self.members.append(tarinfo)
  1732.         return tarinfo
  1733.  
  1734.     # The type mapping for the next() method. The keys are single character
  1735.     # strings, the typeflag. The values are methods which are called when
  1736.     # next() encounters such a typeflag.
  1737.     TYPE_METH = {
  1738.         GNUTYPE_LONGNAME: proc_gnulong,
  1739.         GNUTYPE_LONGLINK: proc_gnulong,
  1740.         GNUTYPE_SPARSE:   proc_sparse
  1741.     }
  1742.  
  1743.     #--------------------------------------------------------------------------
  1744.     # Little helper methods:
  1745.  
  1746.     def _block(self, count):
  1747.         """Round up a byte count by BLOCKSIZE and return it,
  1748.            e.g. _block(834) => 1024.
  1749.         """
  1750.         blocks, remainder = divmod(count, BLOCKSIZE)
  1751.         if remainder:
  1752.             blocks += 1
  1753.         return blocks * BLOCKSIZE
  1754.  
  1755.     def _getmember(self, name, tarinfo=None):
  1756.         """Find an archive member by name from bottom to top.
  1757.            If tarinfo is given, it is used as the starting point.
  1758.         """
  1759.         # Ensure that all members have been loaded.
  1760.         members = self.getmembers()
  1761.  
  1762.         if tarinfo is None:
  1763.             end = len(members)
  1764.         else:
  1765.             end = members.index(tarinfo)
  1766.  
  1767.         for i in xrange(end - 1, -1, -1):
  1768.             if name == members[i].name:
  1769.                 return members[i]
  1770.  
  1771.     def _load(self):
  1772.         """Read through the entire archive file and look for readable
  1773.            members.
  1774.         """
  1775.         while True:
  1776.             tarinfo = self.next()
  1777.             if tarinfo is None:
  1778.                 break
  1779.         self._loaded = True
  1780.  
  1781.     def _check(self, mode=None):
  1782.         """Check if TarFile is still open, and if the operation's mode
  1783.            corresponds to TarFile's mode.
  1784.         """
  1785.         if self.closed:
  1786.             raise IOError, "%s is closed" % self.__class__.__name__
  1787.         if mode is not None and self._mode not in mode:
  1788.             raise IOError, "bad operation for mode %r" % self._mode
  1789.  
  1790.     def __iter__(self):
  1791.         """Provide an iterator object.
  1792.         """
  1793.         if self._loaded:
  1794.             return iter(self.members)
  1795.         else:
  1796.             return TarIter(self)
  1797.  
  1798.     def _create_gnulong(self, name, type):
  1799.         """Write a GNU longname/longlink member to the TarFile.
  1800.            It consists of an extended tar header, with the length
  1801.            of the longname as size, followed by data blocks,
  1802.            which contain the longname as a null terminated string.
  1803.         """
  1804.         name += NUL
  1805.  
  1806.         tarinfo = TarInfo()
  1807.         tarinfo.name = "././@LongLink"
  1808.         tarinfo.type = type
  1809.         tarinfo.mode = 0
  1810.         tarinfo.size = len(name)
  1811.  
  1812.         # write extended header
  1813.         self.fileobj.write(tarinfo.tobuf())
  1814.         self.offset += BLOCKSIZE
  1815.         # write name blocks
  1816.         self.fileobj.write(name)
  1817.         blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
  1818.         if remainder > 0:
  1819.             self.fileobj.write(NUL * (BLOCKSIZE - remainder))
  1820.             blocks += 1
  1821.         self.offset += blocks * BLOCKSIZE
  1822.  
  1823.     def _dbg(self, level, msg):
  1824.         """Write debugging output to sys.stderr.
  1825.         """
  1826.         if level <= self.debug:
  1827.             print >> sys.stderr, msg
  1828. # class TarFile
  1829.  
  1830. class TarIter:
  1831.     """Iterator Class.
  1832.  
  1833.        for tarinfo in TarFile(...):
  1834.            suite...
  1835.     """
  1836.  
  1837.     def __init__(self, tarfile):
  1838.         """Construct a TarIter object.
  1839.         """
  1840.         self.tarfile = tarfile
  1841.         self.index = 0
  1842.     def __iter__(self):
  1843.         """Return iterator object.
  1844.         """
  1845.         return self
  1846.     def next(self):
  1847.         """Return the next item using TarFile's next() method.
  1848.            When all members have been read, set TarFile as _loaded.
  1849.         """
  1850.         # Fix for SF #1100429: Under rare circumstances it can
  1851.         # happen that getmembers() is called during iteration,
  1852.         # which will cause TarIter to stop prematurely.
  1853.         if not self.tarfile._loaded:
  1854.             tarinfo = self.tarfile.next()
  1855.             if not tarinfo:
  1856.                 self.tarfile._loaded = True
  1857.                 raise StopIteration
  1858.         else:
  1859.             try:
  1860.                 tarinfo = self.tarfile.members[self.index]
  1861.             except IndexError:
  1862.                 raise StopIteration
  1863.         self.index += 1
  1864.         return tarinfo
  1865.  
  1866. # Helper classes for sparse file support
  1867. class _section:
  1868.     """Base class for _data and _hole.
  1869.     """
  1870.     def __init__(self, offset, size):
  1871.         self.offset = offset
  1872.         self.size = size
  1873.     def __contains__(self, offset):
  1874.         return self.offset <= offset < self.offset + self.size
  1875.  
  1876. class _data(_section):
  1877.     """Represent a data section in a sparse file.
  1878.     """
  1879.     def __init__(self, offset, size, realpos):
  1880.         _section.__init__(self, offset, size)
  1881.         self.realpos = realpos
  1882.  
  1883. class _hole(_section):
  1884.     """Represent a hole section in a sparse file.
  1885.     """
  1886.     pass
  1887.  
  1888. class _ringbuffer(list):
  1889.     """Ringbuffer class which increases performance
  1890.        over a regular list.
  1891.     """
  1892.     def __init__(self):
  1893.         self.idx = 0
  1894.     def find(self, offset):
  1895.         idx = self.idx
  1896.         while True:
  1897.             item = self[idx]
  1898.             if offset in item:
  1899.                 break
  1900.             idx += 1
  1901.             if idx == len(self):
  1902.                 idx = 0
  1903.             if idx == self.idx:
  1904.                 # End of File
  1905.                 return None
  1906.         self.idx = idx
  1907.         return item
  1908.  
  1909. #---------------------------------------------
  1910. # zipfile compatible TarFile class
  1911. #---------------------------------------------
  1912. TAR_PLAIN = 0           # zipfile.ZIP_STORED
  1913. TAR_GZIPPED = 8         # zipfile.ZIP_DEFLATED
  1914. class TarFileCompat:
  1915.     """TarFile class compatible with standard module zipfile's
  1916.        ZipFile class.
  1917.     """
  1918.     def __init__(self, file, mode="r", compression=TAR_PLAIN):
  1919.         if compression == TAR_PLAIN:
  1920.             self.tarfile = TarFile.taropen(file, mode)
  1921.         elif compression == TAR_GZIPPED:
  1922.             self.tarfile = TarFile.gzopen(file, mode)
  1923.         else:
  1924.             raise ValueError, "unknown compression constant"
  1925.         if mode[0:1] == "r":
  1926.             members = self.tarfile.getmembers()
  1927.             for i in xrange(len(members)):
  1928.                 m = members[i]
  1929.                 m.filename = m.name
  1930.                 m.file_size = m.size
  1931.                 m.date_time = time.gmtime(m.mtime)[:6]
  1932.     def namelist(self):
  1933.         return map(lambda m: m.name, self.infolist())
  1934.     def infolist(self):
  1935.         return filter(lambda m: m.type in REGULAR_TYPES,
  1936.                       self.tarfile.getmembers())
  1937.     def printdir(self):
  1938.         self.tarfile.list()
  1939.     def testzip(self):
  1940.         return
  1941.     def getinfo(self, name):
  1942.         return self.tarfile.getmember(name)
  1943.     def read(self, name):
  1944.         return self.tarfile.extractfile(self.tarfile.getmember(name)).read()
  1945.     def write(self, filename, arcname=None, compress_type=None):
  1946.         self.tarfile.add(filename, arcname)
  1947.     def writestr(self, zinfo, bytes):
  1948.         import StringIO
  1949.         import calendar
  1950.         zinfo.name = zinfo.filename
  1951.         zinfo.size = zinfo.file_size
  1952.         zinfo.mtime = calendar.timegm(zinfo.date_time)
  1953.         self.tarfile.addfile(zinfo, StringIO.StringIO(bytes))
  1954.     def close(self):
  1955.         self.tarfile.close()
  1956. #class TarFileCompat
  1957.  
  1958. #--------------------
  1959. # exported functions
  1960. #--------------------
  1961. def is_tarfile(name):
  1962.     """Return True if name points to a tar archive that we
  1963.        are able to handle, else return False.
  1964.     """
  1965.     try:
  1966.         t = open(name)
  1967.         t.close()
  1968.         return True
  1969.     except TarError:
  1970.         return False
  1971.  
  1972. open = TarFile.open
  1973.