blob: 105a75880dbe40ff6743b1c5c57ecd1c6ae4adb7 [file] [log] [blame]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001#!/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$"
34# $Source$
35
Lars Gustäbelc64e4022007-03-13 10:47:19 +000036version = "0.9.0"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000037__author__ = "Lars Gustäbel (lars@gustaebel.de)"
38__date__ = "$Date$"
39__cvsid__ = "$Id$"
40__credits__ = "Gustavo Niemeyer, Niels Gustäbel, Richard Townsend."
41
42#---------
43# Imports
44#---------
45import sys
46import os
47import shutil
48import stat
49import errno
50import time
51import struct
Georg Brandl3354f282006-10-29 09:16:12 +000052import copy
Lars Gustäbelc64e4022007-03-13 10:47:19 +000053import re
Brett Cannon132fc542008-08-04 21:23:07 +000054import operator
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000055
56try:
57 import grp, pwd
58except ImportError:
59 grp = pwd = None
60
61# from tarfile import *
62__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
63
64#---------------------------------------------------------
65# tar constants
66#---------------------------------------------------------
Lars Gustäbelc64e4022007-03-13 10:47:19 +000067NUL = "\0" # the null character
68BLOCKSIZE = 512 # length of processing blocks
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000069RECORDSIZE = BLOCKSIZE * 20 # length of records
Lars Gustäbelc64e4022007-03-13 10:47:19 +000070GNU_MAGIC = "ustar \0" # magic gnu tar string
71POSIX_MAGIC = "ustar\x0000" # magic posix tar string
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000072
Lars Gustäbelc64e4022007-03-13 10:47:19 +000073LENGTH_NAME = 100 # maximum length of a filename
74LENGTH_LINK = 100 # maximum length of a linkname
75LENGTH_PREFIX = 155 # maximum length of the prefix field
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000076
Lars Gustäbelc64e4022007-03-13 10:47:19 +000077REGTYPE = "0" # regular file
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000078AREGTYPE = "\0" # regular file
Lars Gustäbelc64e4022007-03-13 10:47:19 +000079LNKTYPE = "1" # link (inside tarfile)
80SYMTYPE = "2" # symbolic link
81CHRTYPE = "3" # character special device
82BLKTYPE = "4" # block special device
83DIRTYPE = "5" # directory
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000084FIFOTYPE = "6" # fifo special device
85CONTTYPE = "7" # contiguous file
86
Lars Gustäbelc64e4022007-03-13 10:47:19 +000087GNUTYPE_LONGNAME = "L" # GNU tar longname
88GNUTYPE_LONGLINK = "K" # GNU tar longlink
89GNUTYPE_SPARSE = "S" # GNU tar sparse file
90
91XHDTYPE = "x" # POSIX.1-2001 extended header
92XGLTYPE = "g" # POSIX.1-2001 global header
93SOLARIS_XHDTYPE = "X" # Solaris extended header
94
95USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format
96GNU_FORMAT = 1 # GNU tar format
97PAX_FORMAT = 2 # POSIX.1-2001 (pax) format
98DEFAULT_FORMAT = GNU_FORMAT
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000099
100#---------------------------------------------------------
101# tarfile constants
102#---------------------------------------------------------
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000103# File types that tarfile supports:
104SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,
105 SYMTYPE, DIRTYPE, FIFOTYPE,
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000106 CONTTYPE, CHRTYPE, BLKTYPE,
107 GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
108 GNUTYPE_SPARSE)
109
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000110# File types that will be treated as a regular file.
111REGULAR_TYPES = (REGTYPE, AREGTYPE,
112 CONTTYPE, GNUTYPE_SPARSE)
113
114# File types that are part of the GNU tar format.
115GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
116 GNUTYPE_SPARSE)
117
118# Fields from a pax header that override a TarInfo attribute.
119PAX_FIELDS = ("path", "linkpath", "size", "mtime",
120 "uid", "gid", "uname", "gname")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000121
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000122# Fields in a pax header that are numbers, all other fields
123# are treated as strings.
124PAX_NUMBER_FIELDS = {
125 "atime": float,
126 "ctime": float,
127 "mtime": float,
128 "uid": int,
129 "gid": int,
130 "size": int
131}
132
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000133#---------------------------------------------------------
134# Bits used in the mode field, values in octal.
135#---------------------------------------------------------
136S_IFLNK = 0120000 # symbolic link
137S_IFREG = 0100000 # regular file
138S_IFBLK = 0060000 # block device
139S_IFDIR = 0040000 # directory
140S_IFCHR = 0020000 # character device
141S_IFIFO = 0010000 # fifo
142
143TSUID = 04000 # set UID on execution
144TSGID = 02000 # set GID on execution
145TSVTX = 01000 # reserved
146
147TUREAD = 0400 # read by owner
148TUWRITE = 0200 # write by owner
149TUEXEC = 0100 # execute/search by owner
150TGREAD = 0040 # read by group
151TGWRITE = 0020 # write by group
152TGEXEC = 0010 # execute/search by group
153TOREAD = 0004 # read by other
154TOWRITE = 0002 # write by other
155TOEXEC = 0001 # execute/search by other
156
157#---------------------------------------------------------
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000158# initialization
159#---------------------------------------------------------
160ENCODING = sys.getfilesystemencoding()
161if ENCODING is None:
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000162 ENCODING = sys.getdefaultencoding()
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000163
164#---------------------------------------------------------
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000165# Some useful functions
166#---------------------------------------------------------
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000167
Georg Brandl38c6a222006-05-10 16:26:03 +0000168def stn(s, length):
169 """Convert a python string to a null-terminated string buffer.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000170 """
Georg Brandla32e0a02006-10-24 16:54:16 +0000171 return s[:length] + (length - len(s)) * NUL
Georg Brandl38c6a222006-05-10 16:26:03 +0000172
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000173def nts(s):
174 """Convert a null-terminated string field to a python string.
175 """
176 # Use the string up to the first null char.
177 p = s.find("\0")
178 if p == -1:
179 return s
180 return s[:p]
181
Georg Brandl38c6a222006-05-10 16:26:03 +0000182def nti(s):
183 """Convert a number field to a python number.
184 """
185 # There are two possible encodings for a number field, see
186 # itn() below.
187 if s[0] != chr(0200):
Georg Brandlded1c4d2006-12-20 11:55:16 +0000188 try:
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000189 n = int(nts(s) or "0", 8)
Georg Brandlded1c4d2006-12-20 11:55:16 +0000190 except ValueError:
Lars Gustäbeldd866d52009-11-22 18:30:53 +0000191 raise InvalidHeaderError("invalid header")
Georg Brandl38c6a222006-05-10 16:26:03 +0000192 else:
193 n = 0L
194 for i in xrange(len(s) - 1):
195 n <<= 8
196 n += ord(s[i + 1])
197 return n
198
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000199def itn(n, digits=8, format=DEFAULT_FORMAT):
Georg Brandl38c6a222006-05-10 16:26:03 +0000200 """Convert a python number to a number field.
201 """
202 # POSIX 1003.1-1988 requires numbers to be encoded as a string of
203 # octal digits followed by a null-byte, this allows values up to
204 # (8**(digits-1))-1. GNU tar allows storing numbers greater than
205 # that if necessary. A leading 0200 byte indicates this particular
206 # encoding, the following digits-1 bytes are a big-endian
207 # representation. This allows values up to (256**(digits-1))-1.
208 if 0 <= n < 8 ** (digits - 1):
209 s = "%0*o" % (digits - 1, n) + NUL
210 else:
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000211 if format != GNU_FORMAT or n >= 256 ** (digits - 1):
Georg Brandle4751e32006-05-18 06:11:19 +0000212 raise ValueError("overflow in number field")
Georg Brandl38c6a222006-05-10 16:26:03 +0000213
214 if n < 0:
215 # XXX We mimic GNU tar's behaviour with negative numbers,
216 # this could raise OverflowError.
217 n = struct.unpack("L", struct.pack("l", n))[0]
218
219 s = ""
220 for i in xrange(digits - 1):
221 s = chr(n & 0377) + s
222 n >>= 8
223 s = chr(0200) + s
224 return s
225
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000226def uts(s, encoding, errors):
227 """Convert a unicode object to a string.
228 """
229 if errors == "utf-8":
230 # An extra error handler similar to the -o invalid=UTF-8 option
231 # in POSIX.1-2001. Replace untranslatable characters with their
232 # UTF-8 representation.
233 try:
234 return s.encode(encoding, "strict")
235 except UnicodeEncodeError:
236 x = []
237 for c in s:
238 try:
239 x.append(c.encode(encoding, "strict"))
240 except UnicodeEncodeError:
241 x.append(c.encode("utf8"))
242 return "".join(x)
243 else:
244 return s.encode(encoding, errors)
245
Georg Brandl38c6a222006-05-10 16:26:03 +0000246def calc_chksums(buf):
247 """Calculate the checksum for a member's header by summing up all
248 characters except for the chksum field which is treated as if
249 it was filled with spaces. According to the GNU tar sources,
250 some tars (Sun and NeXT) calculate chksum with signed char,
251 which will be different if there are chars in the buffer with
252 the high bit set. So we calculate two checksums, unsigned and
253 signed.
254 """
255 unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512]))
256 signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512]))
257 return unsigned_chksum, signed_chksum
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000258
259def copyfileobj(src, dst, length=None):
260 """Copy length bytes from fileobj src to fileobj dst.
261 If length is None, copy the entire content.
262 """
263 if length == 0:
264 return
265 if length is None:
266 shutil.copyfileobj(src, dst)
267 return
268
269 BUFSIZE = 16 * 1024
270 blocks, remainder = divmod(length, BUFSIZE)
271 for b in xrange(blocks):
272 buf = src.read(BUFSIZE)
273 if len(buf) < BUFSIZE:
Georg Brandle4751e32006-05-18 06:11:19 +0000274 raise IOError("end of file reached")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000275 dst.write(buf)
276
277 if remainder != 0:
278 buf = src.read(remainder)
279 if len(buf) < remainder:
Georg Brandle4751e32006-05-18 06:11:19 +0000280 raise IOError("end of file reached")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000281 dst.write(buf)
282 return
283
284filemode_table = (
Andrew M. Kuchling8bc462f2004-10-20 11:48:42 +0000285 ((S_IFLNK, "l"),
286 (S_IFREG, "-"),
287 (S_IFBLK, "b"),
288 (S_IFDIR, "d"),
289 (S_IFCHR, "c"),
290 (S_IFIFO, "p")),
291
292 ((TUREAD, "r"),),
293 ((TUWRITE, "w"),),
294 ((TUEXEC|TSUID, "s"),
295 (TSUID, "S"),
296 (TUEXEC, "x")),
297
298 ((TGREAD, "r"),),
299 ((TGWRITE, "w"),),
300 ((TGEXEC|TSGID, "s"),
301 (TSGID, "S"),
302 (TGEXEC, "x")),
303
304 ((TOREAD, "r"),),
305 ((TOWRITE, "w"),),
306 ((TOEXEC|TSVTX, "t"),
307 (TSVTX, "T"),
308 (TOEXEC, "x"))
309)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000310
311def filemode(mode):
312 """Convert a file's mode to a string of the form
313 -rwxrwxrwx.
314 Used by TarFile.list()
315 """
Andrew M. Kuchling8bc462f2004-10-20 11:48:42 +0000316 perm = []
317 for table in filemode_table:
318 for bit, char in table:
319 if mode & bit == bit:
320 perm.append(char)
321 break
322 else:
323 perm.append("-")
324 return "".join(perm)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000325
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000326class TarError(Exception):
327 """Base exception."""
328 pass
329class ExtractError(TarError):
330 """General exception for extract errors."""
331 pass
332class ReadError(TarError):
333 """Exception for unreadble tar archives."""
334 pass
335class CompressionError(TarError):
336 """Exception for unavailable compression methods."""
337 pass
338class StreamError(TarError):
339 """Exception for unsupported operations on stream-like TarFiles."""
340 pass
Georg Brandlebbeed72006-12-19 22:06:46 +0000341class HeaderError(TarError):
Lars Gustäbeldd866d52009-11-22 18:30:53 +0000342 """Base exception for header errors."""
343 pass
344class EmptyHeaderError(HeaderError):
345 """Exception for empty headers."""
346 pass
347class TruncatedHeaderError(HeaderError):
348 """Exception for truncated headers."""
349 pass
350class EOFHeaderError(HeaderError):
351 """Exception for end of file headers."""
352 pass
353class InvalidHeaderError(HeaderError):
Georg Brandlebbeed72006-12-19 22:06:46 +0000354 """Exception for invalid headers."""
355 pass
Lars Gustäbeldd866d52009-11-22 18:30:53 +0000356class SubsequentHeaderError(HeaderError):
357 """Exception for missing and invalid extended headers."""
358 pass
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000359
360#---------------------------
361# internal stream interface
362#---------------------------
363class _LowLevelFile:
364 """Low-level file object. Supports reading and writing.
365 It is used instead of a regular file object for streaming
366 access.
367 """
368
369 def __init__(self, name, mode):
370 mode = {
371 "r": os.O_RDONLY,
372 "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
373 }[mode]
374 if hasattr(os, "O_BINARY"):
375 mode |= os.O_BINARY
Lars Gustäbel5c4c4612010-04-29 15:23:38 +0000376 self.fd = os.open(name, mode, 0666)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000377
378 def close(self):
379 os.close(self.fd)
380
381 def read(self, size):
382 return os.read(self.fd, size)
383
384 def write(self, s):
385 os.write(self.fd, s)
386
387class _Stream:
388 """Class that serves as an adapter between TarFile and
389 a stream-like object. The stream-like object only
390 needs to have a read() or write() method and is accessed
391 blockwise. Use of gzip or bzip2 compression is possible.
392 A stream-like object could be for example: sys.stdin,
393 sys.stdout, a socket, a tape device etc.
394
395 _Stream is intended to be used only internally.
396 """
397
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000398 def __init__(self, name, mode, comptype, fileobj, bufsize):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000399 """Construct a _Stream object.
400 """
401 self._extfileobj = True
402 if fileobj is None:
403 fileobj = _LowLevelFile(name, mode)
404 self._extfileobj = False
405
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000406 if comptype == '*':
407 # Enable transparent compression detection for the
408 # stream interface
409 fileobj = _StreamProxy(fileobj)
410 comptype = fileobj.getcomptype()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000411
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000412 self.name = name or ""
413 self.mode = mode
414 self.comptype = comptype
415 self.fileobj = fileobj
416 self.bufsize = bufsize
417 self.buf = ""
418 self.pos = 0L
419 self.closed = False
420
421 if comptype == "gz":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000422 try:
423 import zlib
424 except ImportError:
Georg Brandle4751e32006-05-18 06:11:19 +0000425 raise CompressionError("zlib module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000426 self.zlib = zlib
Gregory P. Smith88440962008-03-25 06:12:45 +0000427 self.crc = zlib.crc32("") & 0xffffffffL
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000428 if mode == "r":
429 self._init_read_gz()
430 else:
431 self._init_write_gz()
432
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000433 if comptype == "bz2":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000434 try:
435 import bz2
436 except ImportError:
Georg Brandle4751e32006-05-18 06:11:19 +0000437 raise CompressionError("bz2 module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000438 if mode == "r":
439 self.dbuf = ""
440 self.cmp = bz2.BZ2Decompressor()
441 else:
442 self.cmp = bz2.BZ2Compressor()
443
444 def __del__(self):
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000445 if hasattr(self, "closed") and not self.closed:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000446 self.close()
447
448 def _init_write_gz(self):
449 """Initialize for writing with gzip compression.
450 """
451 self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
452 -self.zlib.MAX_WBITS,
453 self.zlib.DEF_MEM_LEVEL,
454 0)
455 timestamp = struct.pack("<L", long(time.time()))
456 self.__write("\037\213\010\010%s\002\377" % timestamp)
457 if self.name.endswith(".gz"):
458 self.name = self.name[:-3]
459 self.__write(self.name + NUL)
460
461 def write(self, s):
462 """Write string s to the stream.
463 """
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000464 if self.comptype == "gz":
Gregory P. Smith88440962008-03-25 06:12:45 +0000465 self.crc = self.zlib.crc32(s, self.crc) & 0xffffffffL
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000466 self.pos += len(s)
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000467 if self.comptype != "tar":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000468 s = self.cmp.compress(s)
469 self.__write(s)
470
471 def __write(self, s):
472 """Write string s to the stream if a whole new block
473 is ready to be written.
474 """
475 self.buf += s
476 while len(self.buf) > self.bufsize:
477 self.fileobj.write(self.buf[:self.bufsize])
478 self.buf = self.buf[self.bufsize:]
479
480 def close(self):
481 """Close the _Stream object. No operation should be
482 done on it afterwards.
483 """
484 if self.closed:
485 return
486
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000487 if self.mode == "w" and self.comptype != "tar":
Martin v. Löwisc234a522004-08-22 21:28:33 +0000488 self.buf += self.cmp.flush()
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000489
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000490 if self.mode == "w" and self.buf:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000491 self.fileobj.write(self.buf)
492 self.buf = ""
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000493 if self.comptype == "gz":
Tim Petersa05f6e22006-08-02 05:20:08 +0000494 # The native zlib crc is an unsigned 32-bit integer, but
495 # the Python wrapper implicitly casts that to a signed C
496 # long. So, on a 32-bit box self.crc may "look negative",
497 # while the same crc on a 64-bit box may "look positive".
498 # To avoid irksome warnings from the `struct` module, force
499 # it to look positive on all boxes.
500 self.fileobj.write(struct.pack("<L", self.crc & 0xffffffffL))
Andrew M. Kuchling10a44492003-10-24 17:38:34 +0000501 self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFFL))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000502
503 if not self._extfileobj:
504 self.fileobj.close()
505
506 self.closed = True
507
508 def _init_read_gz(self):
509 """Initialize for reading a gzip compressed fileobj.
510 """
511 self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
512 self.dbuf = ""
513
514 # taken from gzip.GzipFile with some alterations
515 if self.__read(2) != "\037\213":
Georg Brandle4751e32006-05-18 06:11:19 +0000516 raise ReadError("not a gzip file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000517 if self.__read(1) != "\010":
Georg Brandle4751e32006-05-18 06:11:19 +0000518 raise CompressionError("unsupported compression method")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000519
520 flag = ord(self.__read(1))
521 self.__read(6)
522
523 if flag & 4:
524 xlen = ord(self.__read(1)) + 256 * ord(self.__read(1))
525 self.read(xlen)
526 if flag & 8:
527 while True:
528 s = self.__read(1)
529 if not s or s == NUL:
530 break
531 if flag & 16:
532 while True:
533 s = self.__read(1)
534 if not s or s == NUL:
535 break
536 if flag & 2:
537 self.__read(2)
538
539 def tell(self):
540 """Return the stream's file pointer position.
541 """
542 return self.pos
543
544 def seek(self, pos=0):
545 """Set the stream's file pointer to pos. Negative seeking
546 is forbidden.
547 """
548 if pos - self.pos >= 0:
549 blocks, remainder = divmod(pos - self.pos, self.bufsize)
550 for i in xrange(blocks):
551 self.read(self.bufsize)
552 self.read(remainder)
553 else:
Georg Brandle4751e32006-05-18 06:11:19 +0000554 raise StreamError("seeking backwards is not allowed")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000555 return self.pos
556
557 def read(self, size=None):
558 """Return the next size number of bytes from the stream.
559 If size is not defined, return all bytes of the stream
560 up to EOF.
561 """
562 if size is None:
563 t = []
564 while True:
565 buf = self._read(self.bufsize)
566 if not buf:
567 break
568 t.append(buf)
569 buf = "".join(t)
570 else:
571 buf = self._read(size)
572 self.pos += len(buf)
573 return buf
574
575 def _read(self, size):
576 """Return size bytes from the stream.
577 """
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000578 if self.comptype == "tar":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000579 return self.__read(size)
580
581 c = len(self.dbuf)
582 t = [self.dbuf]
583 while c < size:
584 buf = self.__read(self.bufsize)
585 if not buf:
586 break
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000587 try:
588 buf = self.cmp.decompress(buf)
589 except IOError:
590 raise ReadError("invalid compressed data")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000591 t.append(buf)
592 c += len(buf)
593 t = "".join(t)
594 self.dbuf = t[size:]
595 return t[:size]
596
597 def __read(self, size):
598 """Return size bytes from stream. If internal buffer is empty,
599 read another block from the stream.
600 """
601 c = len(self.buf)
602 t = [self.buf]
603 while c < size:
604 buf = self.fileobj.read(self.bufsize)
605 if not buf:
606 break
607 t.append(buf)
608 c += len(buf)
609 t = "".join(t)
610 self.buf = t[size:]
611 return t[:size]
612# class _Stream
613
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000614class _StreamProxy(object):
615 """Small proxy class that enables transparent compression
616 detection for the Stream interface (mode 'r|*').
617 """
618
619 def __init__(self, fileobj):
620 self.fileobj = fileobj
621 self.buf = self.fileobj.read(BLOCKSIZE)
622
623 def read(self, size):
624 self.read = self.fileobj.read
625 return self.buf
626
627 def getcomptype(self):
628 if self.buf.startswith("\037\213\010"):
629 return "gz"
630 if self.buf.startswith("BZh91"):
631 return "bz2"
632 return "tar"
633
634 def close(self):
635 self.fileobj.close()
636# class StreamProxy
637
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000638class _BZ2Proxy(object):
639 """Small proxy class that enables external file object
640 support for "r:bz2" and "w:bz2" modes. This is actually
641 a workaround for a limitation in bz2 module's BZ2File
642 class which (unlike gzip.GzipFile) has no support for
643 a file object argument.
644 """
645
646 blocksize = 16 * 1024
647
648 def __init__(self, fileobj, mode):
649 self.fileobj = fileobj
650 self.mode = mode
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000651 self.name = getattr(self.fileobj, "name", None)
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000652 self.init()
653
654 def init(self):
655 import bz2
656 self.pos = 0
657 if self.mode == "r":
658 self.bz2obj = bz2.BZ2Decompressor()
659 self.fileobj.seek(0)
660 self.buf = ""
661 else:
662 self.bz2obj = bz2.BZ2Compressor()
663
664 def read(self, size):
665 b = [self.buf]
666 x = len(self.buf)
667 while x < size:
Lars Gustäbel2020a592009-03-22 20:09:33 +0000668 raw = self.fileobj.read(self.blocksize)
669 if not raw:
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000670 break
Lars Gustäbel2020a592009-03-22 20:09:33 +0000671 data = self.bz2obj.decompress(raw)
672 b.append(data)
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000673 x += len(data)
674 self.buf = "".join(b)
675
676 buf = self.buf[:size]
677 self.buf = self.buf[size:]
678 self.pos += len(buf)
679 return buf
680
681 def seek(self, pos):
682 if pos < self.pos:
683 self.init()
684 self.read(pos - self.pos)
685
686 def tell(self):
687 return self.pos
688
689 def write(self, data):
690 self.pos += len(data)
691 raw = self.bz2obj.compress(data)
692 self.fileobj.write(raw)
693
694 def close(self):
695 if self.mode == "w":
696 raw = self.bz2obj.flush()
697 self.fileobj.write(raw)
Georg Brandl49c8f4c2006-05-15 19:30:35 +0000698# class _BZ2Proxy
699
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000700#------------------------
701# Extraction file object
702#------------------------
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000703class _FileInFile(object):
704 """A thin wrapper around an existing file object that
705 provides a part of its data as an individual file
706 object.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000707 """
708
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000709 def __init__(self, fileobj, offset, size, sparse=None):
710 self.fileobj = fileobj
711 self.offset = offset
712 self.size = size
713 self.sparse = sparse
714 self.position = 0
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000715
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000716 def tell(self):
717 """Return the current file position.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000718 """
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000719 return self.position
720
721 def seek(self, position):
722 """Seek to a position in the file.
723 """
724 self.position = position
725
726 def read(self, size=None):
727 """Read data from the file.
728 """
729 if size is None:
730 size = self.size - self.position
731 else:
732 size = min(size, self.size - self.position)
733
734 if self.sparse is None:
735 return self.readnormal(size)
736 else:
737 return self.readsparse(size)
738
739 def readnormal(self, size):
740 """Read operation for regular files.
741 """
742 self.fileobj.seek(self.offset + self.position)
743 self.position += size
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000744 return self.fileobj.read(size)
745
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000746 def readsparse(self, size):
747 """Read operation for sparse files.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000748 """
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000749 data = []
750 while size > 0:
751 buf = self.readsparsesection(size)
752 if not buf:
753 break
754 size -= len(buf)
755 data.append(buf)
756 return "".join(data)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000757
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000758 def readsparsesection(self, size):
759 """Read a single section of a sparse file.
760 """
761 section = self.sparse.find(self.position)
762
763 if section is None:
764 return ""
765
766 size = min(size, section.offset + section.size - self.position)
767
768 if isinstance(section, _data):
769 realpos = section.realpos + self.position - section.offset
770 self.fileobj.seek(self.offset + realpos)
771 self.position += size
772 return self.fileobj.read(size)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000773 else:
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000774 self.position += size
775 return NUL * size
776#class _FileInFile
777
778
779class ExFileObject(object):
780 """File-like object for reading an archive member.
781 Is returned by TarFile.extractfile().
782 """
783 blocksize = 1024
784
785 def __init__(self, tarfile, tarinfo):
786 self.fileobj = _FileInFile(tarfile.fileobj,
787 tarinfo.offset_data,
788 tarinfo.size,
789 getattr(tarinfo, "sparse", None))
790 self.name = tarinfo.name
791 self.mode = "r"
792 self.closed = False
793 self.size = tarinfo.size
794
795 self.position = 0
796 self.buffer = ""
797
798 def read(self, size=None):
799 """Read at most size bytes from the file. If size is not
800 present or None, read all data until EOF is reached.
801 """
802 if self.closed:
803 raise ValueError("I/O operation on closed file")
804
805 buf = ""
806 if self.buffer:
807 if size is None:
808 buf = self.buffer
809 self.buffer = ""
810 else:
811 buf = self.buffer[:size]
812 self.buffer = self.buffer[size:]
813
814 if size is None:
815 buf += self.fileobj.read()
816 else:
817 buf += self.fileobj.read(size - len(buf))
818
819 self.position += len(buf)
820 return buf
821
822 def readline(self, size=-1):
823 """Read one entire line from the file. If size is present
824 and non-negative, return a string with at most that
825 size, which may be an incomplete line.
826 """
827 if self.closed:
828 raise ValueError("I/O operation on closed file")
829
830 if "\n" in self.buffer:
831 pos = self.buffer.find("\n") + 1
832 else:
833 buffers = [self.buffer]
834 while True:
835 buf = self.fileobj.read(self.blocksize)
836 buffers.append(buf)
837 if not buf or "\n" in buf:
838 self.buffer = "".join(buffers)
839 pos = self.buffer.find("\n") + 1
840 if pos == 0:
841 # no newline found.
842 pos = len(self.buffer)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000843 break
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000844
845 if size != -1:
846 pos = min(size, pos)
847
848 buf = self.buffer[:pos]
849 self.buffer = self.buffer[pos:]
850 self.position += len(buf)
851 return buf
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000852
853 def readlines(self):
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000854 """Return a list with all remaining lines.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000855 """
856 result = []
857 while True:
858 line = self.readline()
859 if not line: break
860 result.append(line)
861 return result
862
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000863 def tell(self):
864 """Return the current file position.
865 """
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000866 if self.closed:
867 raise ValueError("I/O operation on closed file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000868
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000869 return self.position
870
871 def seek(self, pos, whence=os.SEEK_SET):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000872 """Seek to a position in the file.
873 """
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000874 if self.closed:
875 raise ValueError("I/O operation on closed file")
876
877 if whence == os.SEEK_SET:
878 self.position = min(max(pos, 0), self.size)
879 elif whence == os.SEEK_CUR:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000880 if pos < 0:
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000881 self.position = max(self.position + pos, 0)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000882 else:
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000883 self.position = min(self.position + pos, self.size)
884 elif whence == os.SEEK_END:
885 self.position = max(min(self.size + pos, self.size), 0)
886 else:
887 raise ValueError("Invalid argument")
888
889 self.buffer = ""
890 self.fileobj.seek(self.position)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000891
892 def close(self):
893 """Close the file object.
894 """
895 self.closed = True
Martin v. Löwisdf241532005-03-03 08:17:42 +0000896
897 def __iter__(self):
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000898 """Get an iterator over the file's lines.
Martin v. Löwisdf241532005-03-03 08:17:42 +0000899 """
Lars Gustäbel6baa5022006-12-23 16:40:13 +0000900 while True:
901 line = self.readline()
902 if not line:
903 break
904 yield line
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000905#class ExFileObject
906
907#------------------
908# Exported Classes
909#------------------
910class TarInfo(object):
911 """Informational class which holds the details about an
912 archive member given by a tar header block.
913 TarInfo objects are returned by TarFile.getmember(),
914 TarFile.getmembers() and TarFile.gettarinfo() and are
915 usually created internally.
916 """
917
918 def __init__(self, name=""):
919 """Construct a TarInfo object. name is the optional name
920 of the member.
921 """
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000922 self.name = name # member name
923 self.mode = 0644 # file permissions
Georg Brandl38c6a222006-05-10 16:26:03 +0000924 self.uid = 0 # user id
925 self.gid = 0 # group id
926 self.size = 0 # file size
927 self.mtime = 0 # modification time
928 self.chksum = 0 # header checksum
929 self.type = REGTYPE # member type
930 self.linkname = "" # link name
Lars Gustäbel6aab8d02010-10-04 15:37:53 +0000931 self.uname = "" # user name
932 self.gname = "" # group name
Georg Brandl38c6a222006-05-10 16:26:03 +0000933 self.devmajor = 0 # device major number
934 self.devminor = 0 # device minor number
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000935
Georg Brandl38c6a222006-05-10 16:26:03 +0000936 self.offset = 0 # the tar header starts here
937 self.offset_data = 0 # the file's data starts here
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000938
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000939 self.pax_headers = {} # pax header information
940
941 # In pax headers the "name" and "linkname" field are called
942 # "path" and "linkpath".
943 def _getpath(self):
944 return self.name
945 def _setpath(self, name):
946 self.name = name
947 path = property(_getpath, _setpath)
948
949 def _getlinkpath(self):
950 return self.linkname
951 def _setlinkpath(self, linkname):
952 self.linkname = linkname
953 linkpath = property(_getlinkpath, _setlinkpath)
954
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000955 def __repr__(self):
956 return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
957
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000958 def get_info(self, encoding, errors):
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000959 """Return the TarInfo's attributes as a dictionary.
960 """
961 info = {
Lars Gustäbelf7cda522009-08-28 19:23:44 +0000962 "name": self.name,
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000963 "mode": self.mode & 07777,
964 "uid": self.uid,
965 "gid": self.gid,
966 "size": self.size,
967 "mtime": self.mtime,
968 "chksum": self.chksum,
969 "type": self.type,
Lars Gustäbelf7cda522009-08-28 19:23:44 +0000970 "linkname": self.linkname,
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000971 "uname": self.uname,
972 "gname": self.gname,
973 "devmajor": self.devmajor,
974 "devminor": self.devminor
975 }
976
977 if info["type"] == DIRTYPE and not info["name"].endswith("/"):
978 info["name"] += "/"
979
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000980 for key in ("name", "linkname", "uname", "gname"):
981 if type(info[key]) is unicode:
982 info[key] = info[key].encode(encoding, errors)
983
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000984 return info
985
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000986 def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="strict"):
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000987 """Return a tar header as a string of 512 byte blocks.
988 """
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000989 info = self.get_info(encoding, errors)
990
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000991 if format == USTAR_FORMAT:
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000992 return self.create_ustar_header(info)
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000993 elif format == GNU_FORMAT:
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000994 return self.create_gnu_header(info)
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000995 elif format == PAX_FORMAT:
Lars Gustäbela0fcb932007-05-27 19:49:30 +0000996 return self.create_pax_header(info, encoding, errors)
Lars Gustäbelc64e4022007-03-13 10:47:19 +0000997 else:
998 raise ValueError("invalid format")
999
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001000 def create_ustar_header(self, info):
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001001 """Return the object as a ustar header block.
1002 """
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001003 info["magic"] = POSIX_MAGIC
1004
1005 if len(info["linkname"]) > LENGTH_LINK:
1006 raise ValueError("linkname is too long")
1007
1008 if len(info["name"]) > LENGTH_NAME:
1009 info["prefix"], info["name"] = self._posix_split_name(info["name"])
1010
1011 return self._create_header(info, USTAR_FORMAT)
1012
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001013 def create_gnu_header(self, info):
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001014 """Return the object as a GNU header block sequence.
1015 """
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001016 info["magic"] = GNU_MAGIC
1017
1018 buf = ""
1019 if len(info["linkname"]) > LENGTH_LINK:
1020 buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK)
1021
1022 if len(info["name"]) > LENGTH_NAME:
1023 buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME)
1024
1025 return buf + self._create_header(info, GNU_FORMAT)
1026
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001027 def create_pax_header(self, info, encoding, errors):
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001028 """Return the object as a ustar header block. If it cannot be
1029 represented this way, prepend a pax extended header sequence
1030 with supplement information.
1031 """
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001032 info["magic"] = POSIX_MAGIC
1033 pax_headers = self.pax_headers.copy()
1034
1035 # Test string fields for values that exceed the field length or cannot
1036 # be represented in ASCII encoding.
1037 for name, hname, length in (
1038 ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK),
1039 ("uname", "uname", 32), ("gname", "gname", 32)):
1040
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001041 if hname in pax_headers:
1042 # The pax header has priority.
1043 continue
1044
1045 val = info[name].decode(encoding, errors)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001046
1047 # Try to encode the string as ASCII.
1048 try:
1049 val.encode("ascii")
1050 except UnicodeEncodeError:
1051 pax_headers[hname] = val
1052 continue
1053
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001054 if len(info[name]) > length:
1055 pax_headers[hname] = val
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001056
1057 # Test number fields for values that exceed the field limit or values
1058 # that like to be stored as float.
1059 for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)):
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001060 if name in pax_headers:
1061 # The pax header has priority. Avoid overflow.
1062 info[name] = 0
1063 continue
1064
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001065 val = info[name]
1066 if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
1067 pax_headers[name] = unicode(val)
1068 info[name] = 0
1069
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001070 # Create a pax extended header if necessary.
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001071 if pax_headers:
1072 buf = self._create_pax_generic_header(pax_headers)
1073 else:
1074 buf = ""
1075
1076 return buf + self._create_header(info, USTAR_FORMAT)
1077
1078 @classmethod
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001079 def create_pax_global_header(cls, pax_headers):
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001080 """Return the object as a pax global header block sequence.
1081 """
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001082 return cls._create_pax_generic_header(pax_headers, type=XGLTYPE)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001083
1084 def _posix_split_name(self, name):
1085 """Split a name longer than 100 chars into a prefix
1086 and a name part.
1087 """
1088 prefix = name[:LENGTH_PREFIX + 1]
1089 while prefix and prefix[-1] != "/":
1090 prefix = prefix[:-1]
1091
1092 name = name[len(prefix):]
1093 prefix = prefix[:-1]
1094
1095 if not prefix or len(name) > LENGTH_NAME:
1096 raise ValueError("name is too long")
1097 return prefix, name
1098
1099 @staticmethod
1100 def _create_header(info, format):
1101 """Return a header block. info is a dictionary with file
1102 information, format must be one of the *_FORMAT constants.
1103 """
1104 parts = [
1105 stn(info.get("name", ""), 100),
1106 itn(info.get("mode", 0) & 07777, 8, format),
1107 itn(info.get("uid", 0), 8, format),
1108 itn(info.get("gid", 0), 8, format),
1109 itn(info.get("size", 0), 12, format),
1110 itn(info.get("mtime", 0), 12, format),
1111 " ", # checksum field
1112 info.get("type", REGTYPE),
1113 stn(info.get("linkname", ""), 100),
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001114 stn(info.get("magic", POSIX_MAGIC), 8),
Lars Gustäbel6aab8d02010-10-04 15:37:53 +00001115 stn(info.get("uname", ""), 32),
1116 stn(info.get("gname", ""), 32),
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001117 itn(info.get("devmajor", 0), 8, format),
1118 itn(info.get("devminor", 0), 8, format),
1119 stn(info.get("prefix", ""), 155)
1120 ]
1121
1122 buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts))
1123 chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
1124 buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
1125 return buf
1126
1127 @staticmethod
1128 def _create_payload(payload):
1129 """Return the string payload filled with zero bytes
1130 up to the next 512 byte border.
1131 """
1132 blocks, remainder = divmod(len(payload), BLOCKSIZE)
1133 if remainder > 0:
1134 payload += (BLOCKSIZE - remainder) * NUL
1135 return payload
1136
1137 @classmethod
1138 def _create_gnu_long_header(cls, name, type):
1139 """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence
1140 for name.
1141 """
1142 name += NUL
1143
1144 info = {}
1145 info["name"] = "././@LongLink"
1146 info["type"] = type
1147 info["size"] = len(name)
1148 info["magic"] = GNU_MAGIC
1149
1150 # create extended header + name blocks.
1151 return cls._create_header(info, USTAR_FORMAT) + \
1152 cls._create_payload(name)
1153
1154 @classmethod
1155 def _create_pax_generic_header(cls, pax_headers, type=XHDTYPE):
1156 """Return a POSIX.1-2001 extended or global header sequence
1157 that contains a list of keyword, value pairs. The values
1158 must be unicode objects.
1159 """
1160 records = []
1161 for keyword, value in pax_headers.iteritems():
1162 keyword = keyword.encode("utf8")
1163 value = value.encode("utf8")
1164 l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n'
1165 n = p = 0
1166 while True:
1167 n = l + len(str(p))
1168 if n == p:
1169 break
1170 p = n
1171 records.append("%d %s=%s\n" % (p, keyword, value))
1172 records = "".join(records)
1173
1174 # We use a hardcoded "././@PaxHeader" name like star does
1175 # instead of the one that POSIX recommends.
1176 info = {}
1177 info["name"] = "././@PaxHeader"
1178 info["type"] = type
1179 info["size"] = len(records)
1180 info["magic"] = POSIX_MAGIC
1181
1182 # Create pax header + record blocks.
1183 return cls._create_header(info, USTAR_FORMAT) + \
1184 cls._create_payload(records)
1185
Guido van Rossum75b64e62005-01-16 00:16:11 +00001186 @classmethod
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001187 def frombuf(cls, buf):
1188 """Construct a TarInfo object from a 512 byte string buffer.
1189 """
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001190 if len(buf) == 0:
1191 raise EmptyHeaderError("empty header")
Georg Brandl38c6a222006-05-10 16:26:03 +00001192 if len(buf) != BLOCKSIZE:
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001193 raise TruncatedHeaderError("truncated header")
Georg Brandl38c6a222006-05-10 16:26:03 +00001194 if buf.count(NUL) == BLOCKSIZE:
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001195 raise EOFHeaderError("end of file header")
Georg Brandlebbeed72006-12-19 22:06:46 +00001196
Georg Brandlded1c4d2006-12-20 11:55:16 +00001197 chksum = nti(buf[148:156])
Georg Brandlebbeed72006-12-19 22:06:46 +00001198 if chksum not in calc_chksums(buf):
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001199 raise InvalidHeaderError("bad checksum")
Georg Brandl38c6a222006-05-10 16:26:03 +00001200
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001201 obj = cls()
1202 obj.buf = buf
1203 obj.name = nts(buf[0:100])
1204 obj.mode = nti(buf[100:108])
1205 obj.uid = nti(buf[108:116])
1206 obj.gid = nti(buf[116:124])
1207 obj.size = nti(buf[124:136])
1208 obj.mtime = nti(buf[136:148])
1209 obj.chksum = chksum
1210 obj.type = buf[156:157]
1211 obj.linkname = nts(buf[157:257])
1212 obj.uname = nts(buf[265:297])
1213 obj.gname = nts(buf[297:329])
1214 obj.devmajor = nti(buf[329:337])
1215 obj.devminor = nti(buf[337:345])
1216 prefix = nts(buf[345:500])
Georg Brandl3354f282006-10-29 09:16:12 +00001217
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001218 # Old V7 tar format represents a directory as a regular
1219 # file with a trailing slash.
1220 if obj.type == AREGTYPE and obj.name.endswith("/"):
1221 obj.type = DIRTYPE
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001222
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001223 # Remove redundant slashes from directories.
1224 if obj.isdir():
1225 obj.name = obj.name.rstrip("/")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001226
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001227 # Reconstruct a ustar longname.
1228 if prefix and obj.type not in GNU_TYPES:
1229 obj.name = prefix + "/" + obj.name
1230 return obj
1231
1232 @classmethod
1233 def fromtarfile(cls, tarfile):
1234 """Return the next TarInfo object from TarFile object
1235 tarfile.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001236 """
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001237 buf = tarfile.fileobj.read(BLOCKSIZE)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001238 obj = cls.frombuf(buf)
1239 obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
1240 return obj._proc_member(tarfile)
Georg Brandl3354f282006-10-29 09:16:12 +00001241
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001242 #--------------------------------------------------------------------------
1243 # The following are methods that are called depending on the type of a
1244 # member. The entry point is _proc_member() which can be overridden in a
1245 # subclass to add custom _proc_*() methods. A _proc_*() method MUST
1246 # implement the following
1247 # operations:
1248 # 1. Set self.offset_data to the position where the data blocks begin,
1249 # if there is data that follows.
1250 # 2. Set tarfile.offset to the position where the next member's header will
1251 # begin.
1252 # 3. Return self or another valid TarInfo object.
1253 def _proc_member(self, tarfile):
1254 """Choose the right processing method depending on
1255 the type and call it.
Georg Brandl3354f282006-10-29 09:16:12 +00001256 """
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001257 if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
1258 return self._proc_gnulong(tarfile)
1259 elif self.type == GNUTYPE_SPARSE:
1260 return self._proc_sparse(tarfile)
1261 elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE):
1262 return self._proc_pax(tarfile)
1263 else:
1264 return self._proc_builtin(tarfile)
Georg Brandl3354f282006-10-29 09:16:12 +00001265
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001266 def _proc_builtin(self, tarfile):
1267 """Process a builtin type or an unknown type which
1268 will be treated as a regular file.
1269 """
1270 self.offset_data = tarfile.fileobj.tell()
1271 offset = self.offset_data
1272 if self.isreg() or self.type not in SUPPORTED_TYPES:
1273 # Skip the following data blocks.
1274 offset += self._block(self.size)
1275 tarfile.offset = offset
Georg Brandl3354f282006-10-29 09:16:12 +00001276
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001277 # Patch the TarInfo object with saved global
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001278 # header information.
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001279 self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001280
1281 return self
1282
1283 def _proc_gnulong(self, tarfile):
1284 """Process the blocks that hold a GNU longname
1285 or longlink member.
1286 """
1287 buf = tarfile.fileobj.read(self._block(self.size))
1288
1289 # Fetch the next header and process it.
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001290 try:
1291 next = self.fromtarfile(tarfile)
1292 except HeaderError:
1293 raise SubsequentHeaderError("missing or bad subsequent header")
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001294
1295 # Patch the TarInfo object from the next header with
1296 # the longname information.
1297 next.offset = self.offset
1298 if self.type == GNUTYPE_LONGNAME:
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001299 next.name = nts(buf)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001300 elif self.type == GNUTYPE_LONGLINK:
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001301 next.linkname = nts(buf)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001302
1303 return next
1304
1305 def _proc_sparse(self, tarfile):
1306 """Process a GNU sparse header plus extra headers.
1307 """
1308 buf = self.buf
1309 sp = _ringbuffer()
1310 pos = 386
1311 lastpos = 0L
1312 realpos = 0L
1313 # There are 4 possible sparse structs in the
1314 # first header.
1315 for i in xrange(4):
1316 try:
1317 offset = nti(buf[pos:pos + 12])
1318 numbytes = nti(buf[pos + 12:pos + 24])
1319 except ValueError:
1320 break
1321 if offset > lastpos:
1322 sp.append(_hole(lastpos, offset - lastpos))
1323 sp.append(_data(offset, numbytes, realpos))
1324 realpos += numbytes
1325 lastpos = offset + numbytes
1326 pos += 24
1327
1328 isextended = ord(buf[482])
1329 origsize = nti(buf[483:495])
1330
1331 # If the isextended flag is given,
1332 # there are extra headers to process.
1333 while isextended == 1:
1334 buf = tarfile.fileobj.read(BLOCKSIZE)
1335 pos = 0
1336 for i in xrange(21):
1337 try:
1338 offset = nti(buf[pos:pos + 12])
1339 numbytes = nti(buf[pos + 12:pos + 24])
1340 except ValueError:
1341 break
1342 if offset > lastpos:
1343 sp.append(_hole(lastpos, offset - lastpos))
1344 sp.append(_data(offset, numbytes, realpos))
1345 realpos += numbytes
1346 lastpos = offset + numbytes
1347 pos += 24
1348 isextended = ord(buf[504])
1349
1350 if lastpos < origsize:
1351 sp.append(_hole(lastpos, origsize - lastpos))
1352
1353 self.sparse = sp
1354
1355 self.offset_data = tarfile.fileobj.tell()
1356 tarfile.offset = self.offset_data + self._block(self.size)
1357 self.size = origsize
1358
1359 return self
1360
1361 def _proc_pax(self, tarfile):
1362 """Process an extended or global header as described in
1363 POSIX.1-2001.
1364 """
1365 # Read the header information.
1366 buf = tarfile.fileobj.read(self._block(self.size))
1367
1368 # A pax header stores supplemental information for either
1369 # the following file (extended) or all following files
1370 # (global).
1371 if self.type == XGLTYPE:
1372 pax_headers = tarfile.pax_headers
1373 else:
1374 pax_headers = tarfile.pax_headers.copy()
1375
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001376 # Parse pax header information. A record looks like that:
1377 # "%d %s=%s\n" % (length, keyword, value). length is the size
1378 # of the complete record including the length field itself and
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001379 # the newline. keyword and value are both UTF-8 encoded strings.
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001380 regex = re.compile(r"(\d+) ([^=]+)=", re.U)
1381 pos = 0
1382 while True:
1383 match = regex.match(buf, pos)
1384 if not match:
1385 break
1386
1387 length, keyword = match.groups()
1388 length = int(length)
1389 value = buf[match.end(2) + 1:match.start(1) + length - 1]
1390
1391 keyword = keyword.decode("utf8")
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001392 value = value.decode("utf8")
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001393
1394 pax_headers[keyword] = value
1395 pos += length
1396
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001397 # Fetch the next header.
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001398 try:
1399 next = self.fromtarfile(tarfile)
1400 except HeaderError:
1401 raise SubsequentHeaderError("missing or bad subsequent header")
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001402
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001403 if self.type in (XHDTYPE, SOLARIS_XHDTYPE):
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001404 # Patch the TarInfo object with the extended header info.
1405 next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors)
1406 next.offset = self.offset
1407
Brett Cannon132fc542008-08-04 21:23:07 +00001408 if "size" in pax_headers:
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001409 # If the extended header replaces the size field,
1410 # we need to recalculate the offset where the next
1411 # header starts.
1412 offset = next.offset_data
1413 if next.isreg() or next.type not in SUPPORTED_TYPES:
1414 offset += next._block(next.size)
1415 tarfile.offset = offset
1416
1417 return next
1418
1419 def _apply_pax_info(self, pax_headers, encoding, errors):
1420 """Replace fields with supplemental information from a previous
1421 pax extended or global header.
1422 """
1423 for keyword, value in pax_headers.iteritems():
1424 if keyword not in PAX_FIELDS:
1425 continue
1426
1427 if keyword == "path":
1428 value = value.rstrip("/")
1429
1430 if keyword in PAX_NUMBER_FIELDS:
1431 try:
1432 value = PAX_NUMBER_FIELDS[keyword](value)
1433 except ValueError:
1434 value = 0
1435 else:
1436 value = uts(value, encoding, errors)
1437
1438 setattr(self, keyword, value)
1439
1440 self.pax_headers = pax_headers.copy()
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001441
1442 def _block(self, count):
1443 """Round up a byte count by BLOCKSIZE and return it,
1444 e.g. _block(834) => 1024.
1445 """
1446 blocks, remainder = divmod(count, BLOCKSIZE)
1447 if remainder:
1448 blocks += 1
1449 return blocks * BLOCKSIZE
Georg Brandl3354f282006-10-29 09:16:12 +00001450
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001451 def isreg(self):
1452 return self.type in REGULAR_TYPES
1453 def isfile(self):
1454 return self.isreg()
1455 def isdir(self):
1456 return self.type == DIRTYPE
1457 def issym(self):
1458 return self.type == SYMTYPE
1459 def islnk(self):
1460 return self.type == LNKTYPE
1461 def ischr(self):
1462 return self.type == CHRTYPE
1463 def isblk(self):
1464 return self.type == BLKTYPE
1465 def isfifo(self):
1466 return self.type == FIFOTYPE
1467 def issparse(self):
1468 return self.type == GNUTYPE_SPARSE
1469 def isdev(self):
1470 return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE)
1471# class TarInfo
1472
1473class TarFile(object):
1474 """The TarFile Class provides an interface to tar archives.
1475 """
1476
1477 debug = 0 # May be set from 0 (no msgs) to 3 (all msgs)
1478
1479 dereference = False # If true, add content of linked file to the
1480 # tar file, else the link.
1481
1482 ignore_zeros = False # If true, skips empty or invalid blocks and
1483 # continues processing.
1484
Lars Gustäbel92ca7562009-12-13 11:32:27 +00001485 errorlevel = 1 # If 0, fatal errors only appear in debug
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001486 # messages (if debug >= 0). If > 0, errors
1487 # are passed to the caller as exceptions.
1488
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001489 format = DEFAULT_FORMAT # The format to use when creating an archive.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001490
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001491 encoding = ENCODING # Encoding for 8-bit character strings.
1492
1493 errors = None # Error handler for unicode conversion.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001494
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001495 tarinfo = TarInfo # The default TarInfo class to use.
1496
1497 fileobject = ExFileObject # The default ExFileObject class to use.
1498
1499 def __init__(self, name=None, mode="r", fileobj=None, format=None,
1500 tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001501 errors=None, pax_headers=None, debug=None, errorlevel=None):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001502 """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
1503 read from an existing archive, 'a' to append data to an existing
1504 file or 'w' to create a new file overwriting an existing one. `mode'
1505 defaults to 'r'.
1506 If `fileobj' is given, it is used for reading or writing data. If it
1507 can be determined, `mode' is overridden by `fileobj's mode.
1508 `fileobj' is not closed, when TarFile is closed.
1509 """
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001510 if len(mode) > 1 or mode not in "raw":
Georg Brandle4751e32006-05-18 06:11:19 +00001511 raise ValueError("mode must be 'r', 'a' or 'w'")
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001512 self.mode = mode
1513 self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001514
1515 if not fileobj:
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001516 if self.mode == "a" and not os.path.exists(name):
Lars Gustäbel3f8aca12007-02-06 18:38:13 +00001517 # Create nonexistent files in append mode.
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001518 self.mode = "w"
1519 self._mode = "wb"
Brett Cannon6cef0762007-05-25 20:17:15 +00001520 fileobj = bltn_open(name, self._mode)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001521 self._extfileobj = False
1522 else:
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001523 if name is None and hasattr(fileobj, "name"):
1524 name = fileobj.name
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001525 if hasattr(fileobj, "mode"):
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001526 self._mode = fileobj.mode
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001527 self._extfileobj = True
Lars Gustäbel0f4a14b2007-08-28 12:31:09 +00001528 self.name = os.path.abspath(name) if name else None
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001529 self.fileobj = fileobj
1530
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001531 # Init attributes.
1532 if format is not None:
1533 self.format = format
1534 if tarinfo is not None:
1535 self.tarinfo = tarinfo
1536 if dereference is not None:
1537 self.dereference = dereference
1538 if ignore_zeros is not None:
1539 self.ignore_zeros = ignore_zeros
1540 if encoding is not None:
1541 self.encoding = encoding
Lars Gustäbela0fcb932007-05-27 19:49:30 +00001542
1543 if errors is not None:
1544 self.errors = errors
1545 elif mode == "r":
1546 self.errors = "utf-8"
1547 else:
1548 self.errors = "strict"
1549
1550 if pax_headers is not None and self.format == PAX_FORMAT:
1551 self.pax_headers = pax_headers
1552 else:
1553 self.pax_headers = {}
1554
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001555 if debug is not None:
1556 self.debug = debug
1557 if errorlevel is not None:
1558 self.errorlevel = errorlevel
1559
1560 # Init datastructures.
Georg Brandl38c6a222006-05-10 16:26:03 +00001561 self.closed = False
1562 self.members = [] # list of members as TarInfo objects
1563 self._loaded = False # flag if all members have been read
Lars Gustäbel77b2d632007-12-01 21:02:12 +00001564 self.offset = self.fileobj.tell()
1565 # current position in the archive file
Georg Brandl38c6a222006-05-10 16:26:03 +00001566 self.inodes = {} # dictionary caching the inodes of
1567 # archive members already added
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001568
Lars Gustäbel355538e2009-11-18 20:24:54 +00001569 try:
1570 if self.mode == "r":
1571 self.firstmember = None
1572 self.firstmember = self.next()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001573
Lars Gustäbel355538e2009-11-18 20:24:54 +00001574 if self.mode == "a":
1575 # Move to the end of the archive,
1576 # before the first empty block.
Lars Gustäbel355538e2009-11-18 20:24:54 +00001577 while True:
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001578 self.fileobj.seek(self.offset)
1579 try:
1580 tarinfo = self.tarinfo.fromtarfile(self)
1581 self.members.append(tarinfo)
1582 except EOFHeaderError:
1583 self.fileobj.seek(self.offset)
Lars Gustäbel355538e2009-11-18 20:24:54 +00001584 break
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001585 except HeaderError, e:
1586 raise ReadError(str(e))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001587
Lars Gustäbel355538e2009-11-18 20:24:54 +00001588 if self.mode in "aw":
1589 self._loaded = True
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001590
Lars Gustäbel355538e2009-11-18 20:24:54 +00001591 if self.pax_headers:
1592 buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy())
1593 self.fileobj.write(buf)
1594 self.offset += len(buf)
1595 except:
1596 if not self._extfileobj:
1597 self.fileobj.close()
1598 self.closed = True
1599 raise
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001600
1601 def _getposix(self):
1602 return self.format == USTAR_FORMAT
1603 def _setposix(self, value):
1604 import warnings
Philip Jenveyd846f1d2009-05-08 02:28:39 +00001605 warnings.warn("use the format attribute instead", DeprecationWarning,
1606 2)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001607 if value:
1608 self.format = USTAR_FORMAT
1609 else:
1610 self.format = GNU_FORMAT
1611 posix = property(_getposix, _setposix)
1612
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001613 #--------------------------------------------------------------------------
1614 # Below are the classmethods which act as alternate constructors to the
1615 # TarFile class. The open() method is the only one that is needed for
1616 # public use; it is the "super"-constructor and is able to select an
1617 # adequate "sub"-constructor for a particular compression using the mapping
1618 # from OPEN_METH.
1619 #
1620 # This concept allows one to subclass TarFile without losing the comfort of
1621 # the super-constructor. A sub-constructor is registered and made available
1622 # by adding it to the mapping in OPEN_METH.
1623
Guido van Rossum75b64e62005-01-16 00:16:11 +00001624 @classmethod
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001625 def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001626 """Open a tar archive for reading, writing or appending. Return
1627 an appropriate TarFile class.
1628
1629 mode:
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001630 'r' or 'r:*' open for reading with transparent compression
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001631 'r:' open for reading exclusively uncompressed
1632 'r:gz' open for reading with gzip compression
1633 'r:bz2' open for reading with bzip2 compression
Lars Gustäbel3f8aca12007-02-06 18:38:13 +00001634 'a' or 'a:' open for appending, creating the file if necessary
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001635 'w' or 'w:' open for writing without compression
1636 'w:gz' open for writing with gzip compression
1637 'w:bz2' open for writing with bzip2 compression
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001638
1639 'r|*' open a stream of tar blocks with transparent compression
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001640 'r|' open an uncompressed stream of tar blocks for reading
1641 'r|gz' open a gzip compressed stream of tar blocks
1642 'r|bz2' open a bzip2 compressed stream of tar blocks
1643 'w|' open an uncompressed stream for writing
1644 'w|gz' open a gzip compressed stream for writing
1645 'w|bz2' open a bzip2 compressed stream for writing
1646 """
1647
1648 if not name and not fileobj:
Georg Brandle4751e32006-05-18 06:11:19 +00001649 raise ValueError("nothing to open")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001650
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001651 if mode in ("r", "r:*"):
1652 # Find out which *open() is appropriate for opening the file.
1653 for comptype in cls.OPEN_METH:
1654 func = getattr(cls, cls.OPEN_METH[comptype])
Lars Gustäbela7ba6fc2006-12-27 10:30:46 +00001655 if fileobj is not None:
1656 saved_pos = fileobj.tell()
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001657 try:
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001658 return func(name, "r", fileobj, **kwargs)
1659 except (ReadError, CompressionError), e:
Lars Gustäbela7ba6fc2006-12-27 10:30:46 +00001660 if fileobj is not None:
1661 fileobj.seek(saved_pos)
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001662 continue
Georg Brandle4751e32006-05-18 06:11:19 +00001663 raise ReadError("file could not be opened successfully")
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001664
1665 elif ":" in mode:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001666 filemode, comptype = mode.split(":", 1)
1667 filemode = filemode or "r"
1668 comptype = comptype or "tar"
1669
1670 # Select the *open() function according to
1671 # given compression.
1672 if comptype in cls.OPEN_METH:
1673 func = getattr(cls, cls.OPEN_METH[comptype])
1674 else:
Georg Brandle4751e32006-05-18 06:11:19 +00001675 raise CompressionError("unknown compression type %r" % comptype)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001676 return func(name, filemode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001677
1678 elif "|" in mode:
1679 filemode, comptype = mode.split("|", 1)
1680 filemode = filemode or "r"
1681 comptype = comptype or "tar"
1682
1683 if filemode not in "rw":
Georg Brandle4751e32006-05-18 06:11:19 +00001684 raise ValueError("mode must be 'r' or 'w'")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001685
1686 t = cls(name, filemode,
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001687 _Stream(name, filemode, comptype, fileobj, bufsize),
1688 **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001689 t._extfileobj = False
1690 return t
1691
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001692 elif mode in "aw":
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001693 return cls.taropen(name, mode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001694
Georg Brandle4751e32006-05-18 06:11:19 +00001695 raise ValueError("undiscernible mode")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001696
Guido van Rossum75b64e62005-01-16 00:16:11 +00001697 @classmethod
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001698 def taropen(cls, name, mode="r", fileobj=None, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001699 """Open uncompressed tar archive name for reading or writing.
1700 """
1701 if len(mode) > 1 or mode not in "raw":
Georg Brandle4751e32006-05-18 06:11:19 +00001702 raise ValueError("mode must be 'r', 'a' or 'w'")
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001703 return cls(name, mode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001704
Guido van Rossum75b64e62005-01-16 00:16:11 +00001705 @classmethod
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001706 def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001707 """Open gzip compressed tar archive name for reading or writing.
1708 Appending is not allowed.
1709 """
1710 if len(mode) > 1 or mode not in "rw":
Georg Brandle4751e32006-05-18 06:11:19 +00001711 raise ValueError("mode must be 'r' or 'w'")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001712
1713 try:
1714 import gzip
Neal Norwitz4ec68242003-04-11 03:05:56 +00001715 gzip.GzipFile
1716 except (ImportError, AttributeError):
Georg Brandle4751e32006-05-18 06:11:19 +00001717 raise CompressionError("gzip module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001718
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001719 if fileobj is None:
Brett Cannon6cef0762007-05-25 20:17:15 +00001720 fileobj = bltn_open(name, mode + "b")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001721
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001722 try:
Lars Gustäbela4b23812006-12-23 17:57:23 +00001723 t = cls.taropen(name, mode,
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001724 gzip.GzipFile(name, mode, compresslevel, fileobj),
1725 **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001726 except IOError:
Georg Brandle4751e32006-05-18 06:11:19 +00001727 raise ReadError("not a gzip file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001728 t._extfileobj = False
1729 return t
1730
Guido van Rossum75b64e62005-01-16 00:16:11 +00001731 @classmethod
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001732 def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001733 """Open bzip2 compressed tar archive name for reading or writing.
1734 Appending is not allowed.
1735 """
1736 if len(mode) > 1 or mode not in "rw":
Georg Brandle4751e32006-05-18 06:11:19 +00001737 raise ValueError("mode must be 'r' or 'w'.")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001738
1739 try:
1740 import bz2
1741 except ImportError:
Georg Brandle4751e32006-05-18 06:11:19 +00001742 raise CompressionError("bz2 module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001743
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001744 if fileobj is not None:
Georg Brandl49c8f4c2006-05-15 19:30:35 +00001745 fileobj = _BZ2Proxy(fileobj, mode)
1746 else:
1747 fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001748
1749 try:
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001750 t = cls.taropen(name, mode, fileobj, **kwargs)
Lars Gustäbeldd866d52009-11-22 18:30:53 +00001751 except (IOError, EOFError):
Georg Brandle4751e32006-05-18 06:11:19 +00001752 raise ReadError("not a bzip2 file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001753 t._extfileobj = False
1754 return t
1755
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001756 # All *open() methods are registered here.
1757 OPEN_METH = {
1758 "tar": "taropen", # uncompressed tar
1759 "gz": "gzopen", # gzip compressed tar
1760 "bz2": "bz2open" # bzip2 compressed tar
1761 }
1762
1763 #--------------------------------------------------------------------------
1764 # The public methods which TarFile provides:
1765
1766 def close(self):
1767 """Close the TarFile. In write-mode, two finishing zero blocks are
1768 appended to the archive.
1769 """
1770 if self.closed:
1771 return
1772
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001773 if self.mode in "aw":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001774 self.fileobj.write(NUL * (BLOCKSIZE * 2))
1775 self.offset += (BLOCKSIZE * 2)
1776 # fill up the end with zero-blocks
1777 # (like option -b20 for tar does)
1778 blocks, remainder = divmod(self.offset, RECORDSIZE)
1779 if remainder > 0:
1780 self.fileobj.write(NUL * (RECORDSIZE - remainder))
1781
1782 if not self._extfileobj:
1783 self.fileobj.close()
1784 self.closed = True
1785
1786 def getmember(self, name):
1787 """Return a TarInfo object for member `name'. If `name' can not be
1788 found in the archive, KeyError is raised. If a member occurs more
Mark Dickinson3e4caeb2009-02-21 20:27:01 +00001789 than once in the archive, its last occurrence is assumed to be the
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001790 most up-to-date version.
1791 """
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001792 tarinfo = self._getmember(name)
1793 if tarinfo is None:
Georg Brandle4751e32006-05-18 06:11:19 +00001794 raise KeyError("filename %r not found" % name)
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001795 return tarinfo
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001796
1797 def getmembers(self):
1798 """Return the members of the archive as a list of TarInfo objects. The
1799 list has the same order as the members in the archive.
1800 """
1801 self._check()
1802 if not self._loaded: # if we want to obtain a list of
1803 self._load() # all members, we first have to
1804 # scan the whole archive.
1805 return self.members
1806
1807 def getnames(self):
1808 """Return the members of the archive as a list of their names. It has
1809 the same order as the list returned by getmembers().
1810 """
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001811 return [tarinfo.name for tarinfo in self.getmembers()]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001812
1813 def gettarinfo(self, name=None, arcname=None, fileobj=None):
1814 """Create a TarInfo object for either the file `name' or the file
1815 object `fileobj' (using os.fstat on its file descriptor). You can
1816 modify some of the TarInfo's attributes before you add it using
1817 addfile(). If given, `arcname' specifies an alternative name for the
1818 file in the archive.
1819 """
1820 self._check("aw")
1821
1822 # When fileobj is given, replace name by
1823 # fileobj's real name.
1824 if fileobj is not None:
1825 name = fileobj.name
1826
1827 # Building the name of the member in the archive.
1828 # Backward slashes are converted to forward slashes,
1829 # Absolute paths are turned to relative paths.
1830 if arcname is None:
1831 arcname = name
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001832 drv, arcname = os.path.splitdrive(arcname)
Lars Gustäbelf7cda522009-08-28 19:23:44 +00001833 arcname = arcname.replace(os.sep, "/")
1834 arcname = arcname.lstrip("/")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001835
1836 # Now, fill the TarInfo object with
1837 # information specific for the file.
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001838 tarinfo = self.tarinfo()
1839 tarinfo.tarfile = self
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001840
1841 # Use os.stat or os.lstat, depending on platform
1842 # and if symlinks shall be resolved.
1843 if fileobj is None:
1844 if hasattr(os, "lstat") and not self.dereference:
1845 statres = os.lstat(name)
1846 else:
1847 statres = os.stat(name)
1848 else:
1849 statres = os.fstat(fileobj.fileno())
1850 linkname = ""
1851
1852 stmd = statres.st_mode
1853 if stat.S_ISREG(stmd):
1854 inode = (statres.st_ino, statres.st_dev)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001855 if not self.dereference and statres.st_nlink > 1 and \
1856 inode in self.inodes and arcname != self.inodes[inode]:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001857 # Is it a hardlink to an already
1858 # archived file?
1859 type = LNKTYPE
1860 linkname = self.inodes[inode]
1861 else:
1862 # The inode is added only if its valid.
1863 # For win32 it is always 0.
1864 type = REGTYPE
1865 if inode[0]:
1866 self.inodes[inode] = arcname
1867 elif stat.S_ISDIR(stmd):
1868 type = DIRTYPE
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001869 elif stat.S_ISFIFO(stmd):
1870 type = FIFOTYPE
1871 elif stat.S_ISLNK(stmd):
1872 type = SYMTYPE
1873 linkname = os.readlink(name)
1874 elif stat.S_ISCHR(stmd):
1875 type = CHRTYPE
1876 elif stat.S_ISBLK(stmd):
1877 type = BLKTYPE
1878 else:
1879 return None
1880
1881 # Fill the TarInfo object with all
1882 # information we can get.
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001883 tarinfo.name = arcname
1884 tarinfo.mode = stmd
1885 tarinfo.uid = statres.st_uid
1886 tarinfo.gid = statres.st_gid
Lars Gustäbel2ee9c6f2010-06-03 09:56:22 +00001887 if type == REGTYPE:
Martin v. Löwis61d77e02004-08-20 06:35:46 +00001888 tarinfo.size = statres.st_size
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001889 else:
1890 tarinfo.size = 0L
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001891 tarinfo.mtime = statres.st_mtime
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001892 tarinfo.type = type
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001893 tarinfo.linkname = linkname
1894 if pwd:
1895 try:
1896 tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
1897 except KeyError:
1898 pass
1899 if grp:
1900 try:
1901 tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
1902 except KeyError:
1903 pass
1904
1905 if type in (CHRTYPE, BLKTYPE):
1906 if hasattr(os, "major") and hasattr(os, "minor"):
1907 tarinfo.devmajor = os.major(statres.st_rdev)
1908 tarinfo.devminor = os.minor(statres.st_rdev)
1909 return tarinfo
1910
1911 def list(self, verbose=True):
1912 """Print a table of contents to sys.stdout. If `verbose' is False, only
1913 the names of the members are printed. If it is True, an `ls -l'-like
1914 output is produced.
1915 """
1916 self._check()
1917
1918 for tarinfo in self:
1919 if verbose:
1920 print filemode(tarinfo.mode),
1921 print "%s/%s" % (tarinfo.uname or tarinfo.uid,
1922 tarinfo.gname or tarinfo.gid),
1923 if tarinfo.ischr() or tarinfo.isblk():
1924 print "%10s" % ("%d,%d" \
1925 % (tarinfo.devmajor, tarinfo.devminor)),
1926 else:
1927 print "%10d" % tarinfo.size,
1928 print "%d-%02d-%02d %02d:%02d:%02d" \
1929 % time.localtime(tarinfo.mtime)[:6],
1930
Lars Gustäbelc64e4022007-03-13 10:47:19 +00001931 print tarinfo.name + ("/" if tarinfo.isdir() else ""),
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001932
1933 if verbose:
1934 if tarinfo.issym():
1935 print "->", tarinfo.linkname,
1936 if tarinfo.islnk():
1937 print "link to", tarinfo.linkname,
1938 print
1939
Lars Gustäbel21121e62009-09-12 10:28:15 +00001940 def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001941 """Add the file `name' to the archive. `name' may be any type of file
1942 (directory, fifo, symbolic link, etc.). If given, `arcname'
1943 specifies an alternative name for the file in the archive.
1944 Directories are added recursively by default. This can be avoided by
Lars Gustäbel104490e2007-06-18 11:42:11 +00001945 setting `recursive' to False. `exclude' is a function that should
Lars Gustäbel21121e62009-09-12 10:28:15 +00001946 return True for each filename to be excluded. `filter' is a function
1947 that expects a TarInfo object argument and returns the changed
1948 TarInfo object, if it returns None the TarInfo object will be
1949 excluded from the archive.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001950 """
1951 self._check("aw")
1952
1953 if arcname is None:
1954 arcname = name
1955
Lars Gustäbel104490e2007-06-18 11:42:11 +00001956 # Exclude pathnames.
Lars Gustäbel21121e62009-09-12 10:28:15 +00001957 if exclude is not None:
1958 import warnings
1959 warnings.warn("use the filter argument instead",
1960 DeprecationWarning, 2)
1961 if exclude(name):
1962 self._dbg(2, "tarfile: Excluded %r" % name)
1963 return
Lars Gustäbel104490e2007-06-18 11:42:11 +00001964
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001965 # Skip if somebody tries to archive the archive...
Lars Gustäbela4b23812006-12-23 17:57:23 +00001966 if self.name is not None and os.path.abspath(name) == self.name:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001967 self._dbg(2, "tarfile: Skipped %r" % name)
1968 return
1969
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001970 self._dbg(1, name)
1971
1972 # Create a TarInfo object from the file.
1973 tarinfo = self.gettarinfo(name, arcname)
1974
1975 if tarinfo is None:
1976 self._dbg(1, "tarfile: Unsupported type %r" % name)
1977 return
1978
Lars Gustäbel21121e62009-09-12 10:28:15 +00001979 # Change or exclude the TarInfo object.
1980 if filter is not None:
1981 tarinfo = filter(tarinfo)
1982 if tarinfo is None:
1983 self._dbg(2, "tarfile: Excluded %r" % name)
1984 return
1985
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001986 # Append the tar header and data to the archive.
1987 if tarinfo.isreg():
Brett Cannon6cef0762007-05-25 20:17:15 +00001988 f = bltn_open(name, "rb")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001989 self.addfile(tarinfo, f)
1990 f.close()
1991
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001992 elif tarinfo.isdir():
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001993 self.addfile(tarinfo)
1994 if recursive:
1995 for f in os.listdir(name):
Lars Gustäbel21121e62009-09-12 10:28:15 +00001996 self.add(os.path.join(name, f), os.path.join(arcname, f),
1997 recursive, exclude, filter)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001998
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001999 else:
2000 self.addfile(tarinfo)
2001
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002002 def addfile(self, tarinfo, fileobj=None):
2003 """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
2004 given, tarinfo.size bytes are read from it and added to the archive.
2005 You can create TarInfo objects using gettarinfo().
2006 On Windows platforms, `fileobj' should always be opened with mode
2007 'rb' to avoid irritation about the file size.
2008 """
2009 self._check("aw")
2010
Georg Brandl3354f282006-10-29 09:16:12 +00002011 tarinfo = copy.copy(tarinfo)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002012
Lars Gustäbela0fcb932007-05-27 19:49:30 +00002013 buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
Georg Brandl3354f282006-10-29 09:16:12 +00002014 self.fileobj.write(buf)
2015 self.offset += len(buf)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002016
2017 # If there's data to follow, append it.
2018 if fileobj is not None:
2019 copyfileobj(fileobj, self.fileobj, tarinfo.size)
2020 blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
2021 if remainder > 0:
2022 self.fileobj.write(NUL * (BLOCKSIZE - remainder))
2023 blocks += 1
2024 self.offset += blocks * BLOCKSIZE
2025
Martin v. Löwisf3c56112004-09-18 09:08:52 +00002026 self.members.append(tarinfo)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002027
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002028 def extractall(self, path=".", members=None):
2029 """Extract all members from the archive to the current working
2030 directory and set owner, modification time and permissions on
2031 directories afterwards. `path' specifies a different directory
2032 to extract to. `members' is optional and must be a subset of the
2033 list returned by getmembers().
2034 """
2035 directories = []
2036
2037 if members is None:
2038 members = self
2039
2040 for tarinfo in members:
2041 if tarinfo.isdir():
Lars Gustäbel0192e432008-02-05 11:51:40 +00002042 # Extract directories with a safe mode.
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002043 directories.append(tarinfo)
Lars Gustäbel0192e432008-02-05 11:51:40 +00002044 tarinfo = copy.copy(tarinfo)
2045 tarinfo.mode = 0700
2046 self.extract(tarinfo, path)
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002047
2048 # Reverse sort directories.
Brett Cannon132fc542008-08-04 21:23:07 +00002049 directories.sort(key=operator.attrgetter('name'))
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002050 directories.reverse()
2051
2052 # Set correct owner, mtime and filemode on directories.
2053 for tarinfo in directories:
Lars Gustäbel2ee1c762008-01-04 14:00:33 +00002054 dirpath = os.path.join(path, tarinfo.name)
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002055 try:
Lars Gustäbel2ee1c762008-01-04 14:00:33 +00002056 self.chown(tarinfo, dirpath)
2057 self.utime(tarinfo, dirpath)
2058 self.chmod(tarinfo, dirpath)
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002059 except ExtractError, e:
2060 if self.errorlevel > 1:
2061 raise
2062 else:
2063 self._dbg(1, "tarfile: %s" % e)
2064
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002065 def extract(self, member, path=""):
2066 """Extract a member from the archive to the current working directory,
2067 using its full name. Its file information is extracted as accurately
2068 as possible. `member' may be a filename or a TarInfo object. You can
2069 specify a different directory using `path'.
2070 """
2071 self._check("r")
2072
Lars Gustäbelc64e4022007-03-13 10:47:19 +00002073 if isinstance(member, basestring):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002074 tarinfo = self.getmember(member)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00002075 else:
2076 tarinfo = member
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002077
Neal Norwitza4f651a2004-07-20 22:07:44 +00002078 # Prepare the link target for makelink().
2079 if tarinfo.islnk():
2080 tarinfo._link_target = os.path.join(path, tarinfo.linkname)
2081
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002082 try:
2083 self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
2084 except EnvironmentError, e:
2085 if self.errorlevel > 0:
2086 raise
2087 else:
2088 if e.filename is None:
2089 self._dbg(1, "tarfile: %s" % e.strerror)
2090 else:
2091 self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
2092 except ExtractError, e:
2093 if self.errorlevel > 1:
2094 raise
2095 else:
2096 self._dbg(1, "tarfile: %s" % e)
2097
2098 def extractfile(self, member):
2099 """Extract a member from the archive as a file object. `member' may be
2100 a filename or a TarInfo object. If `member' is a regular file, a
2101 file-like object is returned. If `member' is a link, a file-like
2102 object is constructed from the link's target. If `member' is none of
2103 the above, None is returned.
2104 The file-like object is read-only and provides the following
2105 methods: read(), readline(), readlines(), seek() and tell()
2106 """
2107 self._check("r")
2108
Lars Gustäbelc64e4022007-03-13 10:47:19 +00002109 if isinstance(member, basestring):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002110 tarinfo = self.getmember(member)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00002111 else:
2112 tarinfo = member
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002113
2114 if tarinfo.isreg():
2115 return self.fileobject(self, tarinfo)
2116
2117 elif tarinfo.type not in SUPPORTED_TYPES:
2118 # If a member's type is unknown, it is treated as a
2119 # regular file.
2120 return self.fileobject(self, tarinfo)
2121
2122 elif tarinfo.islnk() or tarinfo.issym():
2123 if isinstance(self.fileobj, _Stream):
2124 # A small but ugly workaround for the case that someone tries
2125 # to extract a (sym)link as a file-object from a non-seekable
2126 # stream of tar blocks.
Georg Brandle4751e32006-05-18 06:11:19 +00002127 raise StreamError("cannot extract (sym)link as file object")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002128 else:
Georg Brandl7eb4b7d2005-07-22 21:49:32 +00002129 # A (sym)link's file object is its target's file object.
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002130 return self.extractfile(self._find_link_target(tarinfo))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002131 else:
2132 # If there's no data associated with the member (directory, chrdev,
2133 # blkdev, etc.), return None instead of a file object.
2134 return None
2135
2136 def _extract_member(self, tarinfo, targetpath):
2137 """Extract the TarInfo object tarinfo to a physical
2138 file called targetpath.
2139 """
2140 # Fetch the TarInfo object for the given name
2141 # and build the destination pathname, replacing
2142 # forward slashes to platform specific separators.
Lars Gustäbelf7cda522009-08-28 19:23:44 +00002143 targetpath = targetpath.rstrip("/")
2144 targetpath = targetpath.replace("/", os.sep)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002145
2146 # Create all upper directories.
2147 upperdirs = os.path.dirname(targetpath)
2148 if upperdirs and not os.path.exists(upperdirs):
Lars Gustäbel0192e432008-02-05 11:51:40 +00002149 # Create directories that are not part of the archive with
2150 # default permissions.
Lars Gustäbeld2e22902007-01-23 11:17:33 +00002151 os.makedirs(upperdirs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002152
2153 if tarinfo.islnk() or tarinfo.issym():
2154 self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
2155 else:
2156 self._dbg(1, tarinfo.name)
2157
2158 if tarinfo.isreg():
2159 self.makefile(tarinfo, targetpath)
2160 elif tarinfo.isdir():
2161 self.makedir(tarinfo, targetpath)
2162 elif tarinfo.isfifo():
2163 self.makefifo(tarinfo, targetpath)
2164 elif tarinfo.ischr() or tarinfo.isblk():
2165 self.makedev(tarinfo, targetpath)
2166 elif tarinfo.islnk() or tarinfo.issym():
2167 self.makelink(tarinfo, targetpath)
2168 elif tarinfo.type not in SUPPORTED_TYPES:
2169 self.makeunknown(tarinfo, targetpath)
2170 else:
2171 self.makefile(tarinfo, targetpath)
2172
2173 self.chown(tarinfo, targetpath)
2174 if not tarinfo.issym():
2175 self.chmod(tarinfo, targetpath)
2176 self.utime(tarinfo, targetpath)
2177
2178 #--------------------------------------------------------------------------
2179 # Below are the different file methods. They are called via
2180 # _extract_member() when extract() is called. They can be replaced in a
2181 # subclass to implement other functionality.
2182
2183 def makedir(self, tarinfo, targetpath):
2184 """Make a directory called targetpath.
2185 """
2186 try:
Lars Gustäbel0192e432008-02-05 11:51:40 +00002187 # Use a safe mode for the directory, the real mode is set
2188 # later in _extract_member().
2189 os.mkdir(targetpath, 0700)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002190 except EnvironmentError, e:
2191 if e.errno != errno.EEXIST:
2192 raise
2193
2194 def makefile(self, tarinfo, targetpath):
2195 """Make a file called targetpath.
2196 """
2197 source = self.extractfile(tarinfo)
Brett Cannon6cef0762007-05-25 20:17:15 +00002198 target = bltn_open(targetpath, "wb")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002199 copyfileobj(source, target)
2200 source.close()
2201 target.close()
2202
2203 def makeunknown(self, tarinfo, targetpath):
2204 """Make a file from a TarInfo object with an unknown type
2205 at targetpath.
2206 """
2207 self.makefile(tarinfo, targetpath)
2208 self._dbg(1, "tarfile: Unknown file type %r, " \
2209 "extracted as regular file." % tarinfo.type)
2210
2211 def makefifo(self, tarinfo, targetpath):
2212 """Make a fifo called targetpath.
2213 """
2214 if hasattr(os, "mkfifo"):
2215 os.mkfifo(targetpath)
2216 else:
Georg Brandle4751e32006-05-18 06:11:19 +00002217 raise ExtractError("fifo not supported by system")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002218
2219 def makedev(self, tarinfo, targetpath):
2220 """Make a character or block device called targetpath.
2221 """
2222 if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
Georg Brandle4751e32006-05-18 06:11:19 +00002223 raise ExtractError("special devices not supported by system")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002224
2225 mode = tarinfo.mode
2226 if tarinfo.isblk():
2227 mode |= stat.S_IFBLK
2228 else:
2229 mode |= stat.S_IFCHR
2230
2231 os.mknod(targetpath, mode,
2232 os.makedev(tarinfo.devmajor, tarinfo.devminor))
2233
2234 def makelink(self, tarinfo, targetpath):
2235 """Make a (symbolic) link called targetpath. If it cannot be created
2236 (platform limitation), we try to make a copy of the referenced file
2237 instead of a link.
2238 """
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002239 if hasattr(os, "symlink") and hasattr(os, "link"):
2240 # For systems that support symbolic and hard links.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002241 if tarinfo.issym():
Senthil Kumaran011525e2011-04-28 15:30:31 +08002242 if os.path.exists(targetpath):
2243 os.unlink(targetpath)
Lars Gustäbelf7cda522009-08-28 19:23:44 +00002244 os.symlink(tarinfo.linkname, targetpath)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002245 else:
Neal Norwitza4f651a2004-07-20 22:07:44 +00002246 # See extract().
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002247 if os.path.exists(tarinfo._link_target):
2248 os.link(tarinfo._link_target, targetpath)
2249 else:
2250 self._extract_member(self._find_link_target(tarinfo), targetpath)
2251 else:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002252 try:
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002253 self._extract_member(self._find_link_target(tarinfo), targetpath)
2254 except KeyError:
2255 raise ExtractError("unable to resolve link inside archive")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002256
2257 def chown(self, tarinfo, targetpath):
2258 """Set owner of targetpath according to tarinfo.
2259 """
2260 if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
2261 # We have to be root to do so.
2262 try:
2263 g = grp.getgrnam(tarinfo.gname)[2]
2264 except KeyError:
2265 try:
2266 g = grp.getgrgid(tarinfo.gid)[2]
2267 except KeyError:
2268 g = os.getgid()
2269 try:
2270 u = pwd.getpwnam(tarinfo.uname)[2]
2271 except KeyError:
2272 try:
2273 u = pwd.getpwuid(tarinfo.uid)[2]
2274 except KeyError:
2275 u = os.getuid()
2276 try:
2277 if tarinfo.issym() and hasattr(os, "lchown"):
2278 os.lchown(targetpath, u, g)
2279 else:
Andrew MacIntyre7970d202003-02-19 12:51:34 +00002280 if sys.platform != "os2emx":
2281 os.chown(targetpath, u, g)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002282 except EnvironmentError, e:
Georg Brandle4751e32006-05-18 06:11:19 +00002283 raise ExtractError("could not change owner")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002284
2285 def chmod(self, tarinfo, targetpath):
2286 """Set file permissions of targetpath according to tarinfo.
2287 """
Jack Jansen834eff62003-03-07 12:47:06 +00002288 if hasattr(os, 'chmod'):
2289 try:
2290 os.chmod(targetpath, tarinfo.mode)
2291 except EnvironmentError, e:
Georg Brandle4751e32006-05-18 06:11:19 +00002292 raise ExtractError("could not change mode")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002293
2294 def utime(self, tarinfo, targetpath):
2295 """Set modification time of targetpath according to tarinfo.
2296 """
Jack Jansen834eff62003-03-07 12:47:06 +00002297 if not hasattr(os, 'utime'):
Tim Petersf9347782003-03-07 15:36:41 +00002298 return
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002299 try:
2300 os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
2301 except EnvironmentError, e:
Georg Brandle4751e32006-05-18 06:11:19 +00002302 raise ExtractError("could not change modification time")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002303
2304 #--------------------------------------------------------------------------
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002305 def next(self):
2306 """Return the next member of the archive as a TarInfo object, when
2307 TarFile is opened for reading. Return None if there is no more
2308 available.
2309 """
2310 self._check("ra")
2311 if self.firstmember is not None:
2312 m = self.firstmember
2313 self.firstmember = None
2314 return m
2315
2316 # Read the next block.
Andrew M. Kuchling864bba12004-07-10 22:02:11 +00002317 self.fileobj.seek(self.offset)
Lars Gustäbeldd866d52009-11-22 18:30:53 +00002318 tarinfo = None
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002319 while True:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002320 try:
Lars Gustäbelc64e4022007-03-13 10:47:19 +00002321 tarinfo = self.tarinfo.fromtarfile(self)
Lars Gustäbeldd866d52009-11-22 18:30:53 +00002322 except EOFHeaderError, e:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002323 if self.ignore_zeros:
Georg Brandlebbeed72006-12-19 22:06:46 +00002324 self._dbg(2, "0x%X: %s" % (self.offset, e))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002325 self.offset += BLOCKSIZE
2326 continue
Lars Gustäbeldd866d52009-11-22 18:30:53 +00002327 except InvalidHeaderError, e:
2328 if self.ignore_zeros:
2329 self._dbg(2, "0x%X: %s" % (self.offset, e))
2330 self.offset += BLOCKSIZE
2331 continue
2332 elif self.offset == 0:
2333 raise ReadError(str(e))
2334 except EmptyHeaderError:
2335 if self.offset == 0:
2336 raise ReadError("empty file")
2337 except TruncatedHeaderError, e:
2338 if self.offset == 0:
2339 raise ReadError(str(e))
2340 except SubsequentHeaderError, e:
2341 raise ReadError(str(e))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002342 break
2343
Lars Gustäbeldd866d52009-11-22 18:30:53 +00002344 if tarinfo is not None:
2345 self.members.append(tarinfo)
2346 else:
2347 self._loaded = True
2348
Georg Brandl38c6a222006-05-10 16:26:03 +00002349 return tarinfo
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002350
2351 #--------------------------------------------------------------------------
2352 # Little helper methods:
2353
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002354 def _getmember(self, name, tarinfo=None, normalize=False):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002355 """Find an archive member by name from bottom to top.
2356 If tarinfo is given, it is used as the starting point.
2357 """
Martin v. Löwisf3c56112004-09-18 09:08:52 +00002358 # Ensure that all members have been loaded.
2359 members = self.getmembers()
2360
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002361 # Limit the member search list up to tarinfo.
2362 if tarinfo is not None:
2363 members = members[:members.index(tarinfo)]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002364
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002365 if normalize:
2366 name = os.path.normpath(name)
2367
2368 for member in reversed(members):
2369 if normalize:
2370 member_name = os.path.normpath(member.name)
2371 else:
2372 member_name = member.name
2373
2374 if name == member_name:
2375 return member
Andrew M. Kuchling864bba12004-07-10 22:02:11 +00002376
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002377 def _load(self):
2378 """Read through the entire archive file and look for readable
2379 members.
2380 """
2381 while True:
2382 tarinfo = self.next()
2383 if tarinfo is None:
2384 break
2385 self._loaded = True
2386
2387 def _check(self, mode=None):
2388 """Check if TarFile is still open, and if the operation's mode
2389 corresponds to TarFile's mode.
2390 """
2391 if self.closed:
Georg Brandle4751e32006-05-18 06:11:19 +00002392 raise IOError("%s is closed" % self.__class__.__name__)
Lars Gustäbelc64e4022007-03-13 10:47:19 +00002393 if mode is not None and self.mode not in mode:
2394 raise IOError("bad operation for mode %r" % self.mode)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002395
Lars Gustäbel4da7d412010-06-03 12:34:14 +00002396 def _find_link_target(self, tarinfo):
2397 """Find the target member of a symlink or hardlink member in the
2398 archive.
2399 """
2400 if tarinfo.issym():
2401 # Always search the entire archive.
2402 linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname
2403 limit = None
2404 else:
2405 # Search the archive before the link, because a hard link is
2406 # just a reference to an already archived file.
2407 linkname = tarinfo.linkname
2408 limit = tarinfo
2409
2410 member = self._getmember(linkname, tarinfo=limit, normalize=True)
2411 if member is None:
2412 raise KeyError("linkname %r not found" % linkname)
2413 return member
2414
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002415 def __iter__(self):
2416 """Provide an iterator object.
2417 """
2418 if self._loaded:
2419 return iter(self.members)
2420 else:
2421 return TarIter(self)
2422
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002423 def _dbg(self, level, msg):
2424 """Write debugging output to sys.stderr.
2425 """
2426 if level <= self.debug:
2427 print >> sys.stderr, msg
Lars Gustäbel64581042010-03-03 11:55:48 +00002428
2429 def __enter__(self):
2430 self._check()
2431 return self
2432
2433 def __exit__(self, type, value, traceback):
2434 if type is None:
2435 self.close()
2436 else:
2437 # An exception occurred. We must not call close() because
2438 # it would try to write end-of-archive blocks and padding.
2439 if not self._extfileobj:
2440 self.fileobj.close()
2441 self.closed = True
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002442# class TarFile
2443
2444class TarIter:
2445 """Iterator Class.
2446
2447 for tarinfo in TarFile(...):
2448 suite...
2449 """
2450
2451 def __init__(self, tarfile):
2452 """Construct a TarIter object.
2453 """
2454 self.tarfile = tarfile
Martin v. Löwis637431b2005-03-03 23:12:42 +00002455 self.index = 0
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002456 def __iter__(self):
2457 """Return iterator object.
2458 """
2459 return self
2460 def next(self):
2461 """Return the next item using TarFile's next() method.
2462 When all members have been read, set TarFile as _loaded.
2463 """
Martin v. Löwis637431b2005-03-03 23:12:42 +00002464 # Fix for SF #1100429: Under rare circumstances it can
2465 # happen that getmembers() is called during iteration,
2466 # which will cause TarIter to stop prematurely.
2467 if not self.tarfile._loaded:
2468 tarinfo = self.tarfile.next()
2469 if not tarinfo:
2470 self.tarfile._loaded = True
2471 raise StopIteration
2472 else:
2473 try:
2474 tarinfo = self.tarfile.members[self.index]
2475 except IndexError:
2476 raise StopIteration
2477 self.index += 1
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002478 return tarinfo
2479
2480# Helper classes for sparse file support
2481class _section:
2482 """Base class for _data and _hole.
2483 """
2484 def __init__(self, offset, size):
2485 self.offset = offset
2486 self.size = size
2487 def __contains__(self, offset):
2488 return self.offset <= offset < self.offset + self.size
2489
2490class _data(_section):
2491 """Represent a data section in a sparse file.
2492 """
2493 def __init__(self, offset, size, realpos):
2494 _section.__init__(self, offset, size)
2495 self.realpos = realpos
2496
2497class _hole(_section):
2498 """Represent a hole section in a sparse file.
2499 """
2500 pass
2501
2502class _ringbuffer(list):
2503 """Ringbuffer class which increases performance
2504 over a regular list.
2505 """
2506 def __init__(self):
2507 self.idx = 0
2508 def find(self, offset):
2509 idx = self.idx
2510 while True:
2511 item = self[idx]
2512 if offset in item:
2513 break
2514 idx += 1
2515 if idx == len(self):
2516 idx = 0
2517 if idx == self.idx:
2518 # End of File
2519 return None
2520 self.idx = idx
2521 return item
2522
2523#---------------------------------------------
2524# zipfile compatible TarFile class
2525#---------------------------------------------
2526TAR_PLAIN = 0 # zipfile.ZIP_STORED
2527TAR_GZIPPED = 8 # zipfile.ZIP_DEFLATED
2528class TarFileCompat:
2529 """TarFile class compatible with standard module zipfile's
2530 ZipFile class.
2531 """
2532 def __init__(self, file, mode="r", compression=TAR_PLAIN):
Lars Gustäbel727bd0b2008-08-02 11:26:39 +00002533 from warnings import warnpy3k
2534 warnpy3k("the TarFileCompat class has been removed in Python 3.0",
2535 stacklevel=2)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002536 if compression == TAR_PLAIN:
2537 self.tarfile = TarFile.taropen(file, mode)
2538 elif compression == TAR_GZIPPED:
2539 self.tarfile = TarFile.gzopen(file, mode)
2540 else:
Georg Brandle4751e32006-05-18 06:11:19 +00002541 raise ValueError("unknown compression constant")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002542 if mode[0:1] == "r":
2543 members = self.tarfile.getmembers()
Raymond Hettingera1d09e22005-09-11 16:34:05 +00002544 for m in members:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002545 m.filename = m.name
2546 m.file_size = m.size
2547 m.date_time = time.gmtime(m.mtime)[:6]
2548 def namelist(self):
2549 return map(lambda m: m.name, self.infolist())
2550 def infolist(self):
2551 return filter(lambda m: m.type in REGULAR_TYPES,
2552 self.tarfile.getmembers())
2553 def printdir(self):
2554 self.tarfile.list()
2555 def testzip(self):
2556 return
2557 def getinfo(self, name):
2558 return self.tarfile.getmember(name)
2559 def read(self, name):
2560 return self.tarfile.extractfile(self.tarfile.getmember(name)).read()
2561 def write(self, filename, arcname=None, compress_type=None):
2562 self.tarfile.add(filename, arcname)
2563 def writestr(self, zinfo, bytes):
Raymond Hettingera6172712004-12-31 19:15:26 +00002564 try:
2565 from cStringIO import StringIO
2566 except ImportError:
2567 from StringIO import StringIO
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002568 import calendar
Lars Gustäbel727bd0b2008-08-02 11:26:39 +00002569 tinfo = TarInfo(zinfo.filename)
2570 tinfo.size = len(bytes)
2571 tinfo.mtime = calendar.timegm(zinfo.date_time)
2572 self.tarfile.addfile(tinfo, StringIO(bytes))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002573 def close(self):
2574 self.tarfile.close()
2575#class TarFileCompat
2576
2577#--------------------
2578# exported functions
2579#--------------------
2580def is_tarfile(name):
2581 """Return True if name points to a tar archive that we
2582 are able to handle, else return False.
2583 """
2584 try:
2585 t = open(name)
2586 t.close()
2587 return True
2588 except TarError:
2589 return False
2590
Brett Cannon6cef0762007-05-25 20:17:15 +00002591bltn_open = open
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002592open = TarFile.open