blob: 7b7c25e831a7625ac6d8129fee7f48175ec36aea [file] [log] [blame]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001#!/usr/bin/env python
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002#-------------------------------------------------------------------
3# tarfile.py
4#-------------------------------------------------------------------
Christian Heimes9c1257e2007-11-04 11:37:22 +00005# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de>
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00006# All rights reserved.
7#
8# Permission is hereby granted, free of charge, to any person
9# obtaining a copy of this software and associated documentation
10# files (the "Software"), to deal in the Software without
11# restriction, including without limitation the rights to use,
12# copy, modify, merge, publish, distribute, sublicense, and/or sell
13# copies of the Software, and to permit persons to whom the
14# Software is furnished to do so, subject to the following
15# conditions:
16#
17# The above copyright notice and this permission notice shall be
18# included in all copies or substantial portions of the Software.
19#
20# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27# OTHER DEALINGS IN THE SOFTWARE.
28#
29"""Read from and write to tar format archives.
30"""
31
32__version__ = "$Revision$"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000033
Guido van Rossumd8faa362007-04-27 19:54:29 +000034version = "0.9.0"
Guido van Rossum98297ee2007-11-06 21:34:58 +000035__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)"
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000036__date__ = "$Date$"
37__cvsid__ = "$Id$"
Guido van Rossum98297ee2007-11-06 21:34:58 +000038__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend."
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000039
40#---------
41# Imports
42#---------
43import sys
44import os
45import shutil
46import stat
47import errno
48import time
49import struct
Thomas Wouters89f507f2006-12-13 04:49:30 +000050import copy
Guido van Rossumd8faa362007-04-27 19:54:29 +000051import re
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000052
Jack Jansencfc49022003-03-07 13:37:32 +000053if sys.platform == 'mac':
54 # This module needs work for MacOS9, especially in the area of pathname
55 # handling. In many places it is assumed a simple substitution of / by the
56 # local os.path.sep is good enough to convert pathnames, but this does not
57 # work with the mac rooted:path:name versus :nonrooted:path:name syntax
Collin Winterce36ad82007-08-30 01:19:48 +000058 raise ImportError("tarfile does not work for platform==mac")
Jack Jansencfc49022003-03-07 13:37:32 +000059
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000060try:
61 import grp, pwd
62except ImportError:
63 grp = pwd = None
64
65# from tarfile import *
66__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
67
Georg Brandl1a3284e2007-12-02 09:40:06 +000068from builtins import open as _open # Since 'open' is TarFile.open
Guido van Rossum8f78fe92006-08-24 04:03:53 +000069
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000070#---------------------------------------------------------
71# tar constants
72#---------------------------------------------------------
Lars Gustäbelb506dc32007-08-07 18:36:16 +000073NUL = b"\0" # the null character
Guido van Rossumd8faa362007-04-27 19:54:29 +000074BLOCKSIZE = 512 # length of processing blocks
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000075RECORDSIZE = BLOCKSIZE * 20 # length of records
Lars Gustäbelb506dc32007-08-07 18:36:16 +000076GNU_MAGIC = b"ustar \0" # magic gnu tar string
77POSIX_MAGIC = b"ustar\x0000" # magic posix tar string
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000078
Guido van Rossumd8faa362007-04-27 19:54:29 +000079LENGTH_NAME = 100 # maximum length of a filename
80LENGTH_LINK = 100 # maximum length of a linkname
81LENGTH_PREFIX = 155 # maximum length of the prefix field
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000082
Lars Gustäbelb506dc32007-08-07 18:36:16 +000083REGTYPE = b"0" # regular file
84AREGTYPE = b"\0" # regular file
85LNKTYPE = b"1" # link (inside tarfile)
86SYMTYPE = b"2" # symbolic link
87CHRTYPE = b"3" # character special device
88BLKTYPE = b"4" # block special device
89DIRTYPE = b"5" # directory
90FIFOTYPE = b"6" # fifo special device
91CONTTYPE = b"7" # contiguous file
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +000092
Lars Gustäbelb506dc32007-08-07 18:36:16 +000093GNUTYPE_LONGNAME = b"L" # GNU tar longname
94GNUTYPE_LONGLINK = b"K" # GNU tar longlink
95GNUTYPE_SPARSE = b"S" # GNU tar sparse file
Guido van Rossumd8faa362007-04-27 19:54:29 +000096
Lars Gustäbelb506dc32007-08-07 18:36:16 +000097XHDTYPE = b"x" # POSIX.1-2001 extended header
98XGLTYPE = b"g" # POSIX.1-2001 global header
99SOLARIS_XHDTYPE = b"X" # Solaris extended header
Guido van Rossumd8faa362007-04-27 19:54:29 +0000100
101USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format
102GNU_FORMAT = 1 # GNU tar format
103PAX_FORMAT = 2 # POSIX.1-2001 (pax) format
104DEFAULT_FORMAT = GNU_FORMAT
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000105
106#---------------------------------------------------------
107# tarfile constants
108#---------------------------------------------------------
Guido van Rossumd8faa362007-04-27 19:54:29 +0000109# File types that tarfile supports:
110SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,
111 SYMTYPE, DIRTYPE, FIFOTYPE,
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000112 CONTTYPE, CHRTYPE, BLKTYPE,
113 GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
114 GNUTYPE_SPARSE)
115
Guido van Rossumd8faa362007-04-27 19:54:29 +0000116# File types that will be treated as a regular file.
117REGULAR_TYPES = (REGTYPE, AREGTYPE,
118 CONTTYPE, GNUTYPE_SPARSE)
119
120# File types that are part of the GNU tar format.
121GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
122 GNUTYPE_SPARSE)
123
124# Fields from a pax header that override a TarInfo attribute.
125PAX_FIELDS = ("path", "linkpath", "size", "mtime",
126 "uid", "gid", "uname", "gname")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000127
Guido van Rossume7ba4952007-06-06 23:52:48 +0000128# Fields in a pax header that are numbers, all other fields
129# are treated as strings.
130PAX_NUMBER_FIELDS = {
131 "atime": float,
132 "ctime": float,
133 "mtime": float,
134 "uid": int,
135 "gid": int,
136 "size": int
137}
138
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000139#---------------------------------------------------------
140# Bits used in the mode field, values in octal.
141#---------------------------------------------------------
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000142S_IFLNK = 0o120000 # symbolic link
143S_IFREG = 0o100000 # regular file
144S_IFBLK = 0o060000 # block device
145S_IFDIR = 0o040000 # directory
146S_IFCHR = 0o020000 # character device
147S_IFIFO = 0o010000 # fifo
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000148
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000149TSUID = 0o4000 # set UID on execution
150TSGID = 0o2000 # set GID on execution
151TSVTX = 0o1000 # reserved
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000152
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000153TUREAD = 0o400 # read by owner
154TUWRITE = 0o200 # write by owner
155TUEXEC = 0o100 # execute/search by owner
156TGREAD = 0o040 # read by group
157TGWRITE = 0o020 # write by group
158TGEXEC = 0o010 # execute/search by group
159TOREAD = 0o004 # read by other
160TOWRITE = 0o002 # write by other
161TOEXEC = 0o001 # execute/search by other
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000162
163#---------------------------------------------------------
Guido van Rossumd8faa362007-04-27 19:54:29 +0000164# initialization
165#---------------------------------------------------------
166ENCODING = sys.getfilesystemencoding()
167if ENCODING is None:
Lars Gustäbel3741eff2007-08-21 12:17:05 +0000168 ENCODING = "ascii"
Guido van Rossumd8faa362007-04-27 19:54:29 +0000169
170#---------------------------------------------------------
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000171# Some useful functions
172#---------------------------------------------------------
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000173
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000174def stn(s, length, encoding, errors):
175 """Convert a string to a null-terminated bytes object.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000176 """
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000177 s = s.encode(encoding, errors)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000178 return s[:length] + (length - len(s)) * NUL
Thomas Wouters477c8d52006-05-27 19:21:47 +0000179
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000180def nts(s, encoding, errors):
181 """Convert a null-terminated bytes object to a string.
Guido van Rossumd8faa362007-04-27 19:54:29 +0000182 """
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000183 p = s.find(b"\0")
184 if p != -1:
185 s = s[:p]
186 return s.decode(encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000187
Thomas Wouters477c8d52006-05-27 19:21:47 +0000188def nti(s):
189 """Convert a number field to a python number.
190 """
191 # There are two possible encodings for a number field, see
192 # itn() below.
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000193 if s[0] != chr(0o200):
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000194 try:
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000195 n = int(nts(s, "ascii", "strict") or "0", 8)
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000196 except ValueError:
197 raise HeaderError("invalid header")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000198 else:
Guido van Rossume2a383d2007-01-15 16:59:06 +0000199 n = 0
Guido van Rossum805365e2007-05-07 22:24:25 +0000200 for i in range(len(s) - 1):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000201 n <<= 8
202 n += ord(s[i + 1])
203 return n
204
Guido van Rossumd8faa362007-04-27 19:54:29 +0000205def itn(n, digits=8, format=DEFAULT_FORMAT):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000206 """Convert a python number to a number field.
207 """
208 # POSIX 1003.1-1988 requires numbers to be encoded as a string of
209 # octal digits followed by a null-byte, this allows values up to
210 # (8**(digits-1))-1. GNU tar allows storing numbers greater than
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000211 # that if necessary. A leading 0o200 byte indicates this particular
Thomas Wouters477c8d52006-05-27 19:21:47 +0000212 # encoding, the following digits-1 bytes are a big-endian
213 # representation. This allows values up to (256**(digits-1))-1.
214 if 0 <= n < 8 ** (digits - 1):
Lars Gustäbela280ca752007-08-28 07:34:33 +0000215 s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL
Thomas Wouters477c8d52006-05-27 19:21:47 +0000216 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000217 if format != GNU_FORMAT or n >= 256 ** (digits - 1):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000218 raise ValueError("overflow in number field")
219
220 if n < 0:
221 # XXX We mimic GNU tar's behaviour with negative numbers,
222 # this could raise OverflowError.
223 n = struct.unpack("L", struct.pack("l", n))[0]
224
Guido van Rossum254348e2007-11-21 19:29:53 +0000225 s = bytearray()
Guido van Rossum805365e2007-05-07 22:24:25 +0000226 for i in range(digits - 1):
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000227 s.insert(0, n & 0o377)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000228 n >>= 8
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000229 s.insert(0, 0o200)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000230 return s
231
232def calc_chksums(buf):
233 """Calculate the checksum for a member's header by summing up all
234 characters except for the chksum field which is treated as if
235 it was filled with spaces. According to the GNU tar sources,
236 some tars (Sun and NeXT) calculate chksum with signed char,
237 which will be different if there are chars in the buffer with
238 the high bit set. So we calculate two checksums, unsigned and
239 signed.
240 """
241 unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512]))
242 signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512]))
243 return unsigned_chksum, signed_chksum
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000244
245def copyfileobj(src, dst, length=None):
246 """Copy length bytes from fileobj src to fileobj dst.
247 If length is None, copy the entire content.
248 """
249 if length == 0:
250 return
251 if length is None:
252 shutil.copyfileobj(src, dst)
253 return
254
255 BUFSIZE = 16 * 1024
256 blocks, remainder = divmod(length, BUFSIZE)
Guido van Rossum805365e2007-05-07 22:24:25 +0000257 for b in range(blocks):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000258 buf = src.read(BUFSIZE)
259 if len(buf) < BUFSIZE:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000260 raise IOError("end of file reached")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000261 dst.write(buf)
262
263 if remainder != 0:
264 buf = src.read(remainder)
265 if len(buf) < remainder:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000266 raise IOError("end of file reached")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000267 dst.write(buf)
268 return
269
270filemode_table = (
Andrew M. Kuchling8bc462f2004-10-20 11:48:42 +0000271 ((S_IFLNK, "l"),
272 (S_IFREG, "-"),
273 (S_IFBLK, "b"),
274 (S_IFDIR, "d"),
275 (S_IFCHR, "c"),
276 (S_IFIFO, "p")),
277
278 ((TUREAD, "r"),),
279 ((TUWRITE, "w"),),
280 ((TUEXEC|TSUID, "s"),
281 (TSUID, "S"),
282 (TUEXEC, "x")),
283
284 ((TGREAD, "r"),),
285 ((TGWRITE, "w"),),
286 ((TGEXEC|TSGID, "s"),
287 (TSGID, "S"),
288 (TGEXEC, "x")),
289
290 ((TOREAD, "r"),),
291 ((TOWRITE, "w"),),
292 ((TOEXEC|TSVTX, "t"),
293 (TSVTX, "T"),
294 (TOEXEC, "x"))
295)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000296
297def filemode(mode):
298 """Convert a file's mode to a string of the form
299 -rwxrwxrwx.
300 Used by TarFile.list()
301 """
Andrew M. Kuchling8bc462f2004-10-20 11:48:42 +0000302 perm = []
303 for table in filemode_table:
304 for bit, char in table:
305 if mode & bit == bit:
306 perm.append(char)
307 break
308 else:
309 perm.append("-")
310 return "".join(perm)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000311
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000312class TarError(Exception):
313 """Base exception."""
314 pass
315class ExtractError(TarError):
316 """General exception for extract errors."""
317 pass
318class ReadError(TarError):
319 """Exception for unreadble tar archives."""
320 pass
321class CompressionError(TarError):
322 """Exception for unavailable compression methods."""
323 pass
324class StreamError(TarError):
325 """Exception for unsupported operations on stream-like TarFiles."""
326 pass
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000327class HeaderError(TarError):
328 """Exception for invalid headers."""
329 pass
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000330
331#---------------------------
332# internal stream interface
333#---------------------------
334class _LowLevelFile:
335 """Low-level file object. Supports reading and writing.
336 It is used instead of a regular file object for streaming
337 access.
338 """
339
340 def __init__(self, name, mode):
341 mode = {
342 "r": os.O_RDONLY,
343 "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
344 }[mode]
345 if hasattr(os, "O_BINARY"):
346 mode |= os.O_BINARY
347 self.fd = os.open(name, mode)
348
349 def close(self):
350 os.close(self.fd)
351
352 def read(self, size):
353 return os.read(self.fd, size)
354
355 def write(self, s):
356 os.write(self.fd, s)
357
358class _Stream:
359 """Class that serves as an adapter between TarFile and
360 a stream-like object. The stream-like object only
361 needs to have a read() or write() method and is accessed
362 blockwise. Use of gzip or bzip2 compression is possible.
363 A stream-like object could be for example: sys.stdin,
364 sys.stdout, a socket, a tape device etc.
365
366 _Stream is intended to be used only internally.
367 """
368
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000369 def __init__(self, name, mode, comptype, fileobj, bufsize):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000370 """Construct a _Stream object.
371 """
372 self._extfileobj = True
373 if fileobj is None:
374 fileobj = _LowLevelFile(name, mode)
375 self._extfileobj = False
376
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000377 if comptype == '*':
378 # Enable transparent compression detection for the
379 # stream interface
380 fileobj = _StreamProxy(fileobj)
381 comptype = fileobj.getcomptype()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000382
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000383 self.name = name or ""
384 self.mode = mode
385 self.comptype = comptype
386 self.fileobj = fileobj
387 self.bufsize = bufsize
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000388 self.buf = b""
Guido van Rossume2a383d2007-01-15 16:59:06 +0000389 self.pos = 0
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000390 self.closed = False
391
392 if comptype == "gz":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000393 try:
394 import zlib
395 except ImportError:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000396 raise CompressionError("zlib module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000397 self.zlib = zlib
398 self.crc = zlib.crc32("")
399 if mode == "r":
400 self._init_read_gz()
401 else:
402 self._init_write_gz()
403
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000404 if comptype == "bz2":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000405 try:
406 import bz2
407 except ImportError:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000408 raise CompressionError("bz2 module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000409 if mode == "r":
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000410 self.dbuf = b""
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000411 self.cmp = bz2.BZ2Decompressor()
412 else:
413 self.cmp = bz2.BZ2Compressor()
414
415 def __del__(self):
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000416 if hasattr(self, "closed") and not self.closed:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000417 self.close()
418
419 def _init_write_gz(self):
420 """Initialize for writing with gzip compression.
421 """
422 self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
423 -self.zlib.MAX_WBITS,
424 self.zlib.DEF_MEM_LEVEL,
425 0)
Guido van Rossume2a383d2007-01-15 16:59:06 +0000426 timestamp = struct.pack("<L", int(time.time()))
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000427 self.__write(b"\037\213\010\010" + timestamp + b"\002\377")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000428 if self.name.endswith(".gz"):
429 self.name = self.name[:-3]
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000430 # RFC1952 says we must use ISO-8859-1 for the FNAME field.
431 self.__write(self.name.encode("iso-8859-1", "replace") + NUL)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000432
433 def write(self, s):
434 """Write string s to the stream.
435 """
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000436 if self.comptype == "gz":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000437 self.crc = self.zlib.crc32(s, self.crc)
438 self.pos += len(s)
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000439 if self.comptype != "tar":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000440 s = self.cmp.compress(s)
441 self.__write(s)
442
443 def __write(self, s):
444 """Write string s to the stream if a whole new block
445 is ready to be written.
446 """
447 self.buf += s
448 while len(self.buf) > self.bufsize:
449 self.fileobj.write(self.buf[:self.bufsize])
450 self.buf = self.buf[self.bufsize:]
451
452 def close(self):
453 """Close the _Stream object. No operation should be
454 done on it afterwards.
455 """
456 if self.closed:
457 return
458
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000459 if self.mode == "w" and self.comptype != "tar":
Martin v. Löwisc234a522004-08-22 21:28:33 +0000460 self.buf += self.cmp.flush()
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000461
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000462 if self.mode == "w" and self.buf:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000463 self.fileobj.write(self.buf)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000464 self.buf = b""
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000465 if self.comptype == "gz":
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000466 # The native zlib crc is an unsigned 32-bit integer, but
467 # the Python wrapper implicitly casts that to a signed C
468 # long. So, on a 32-bit box self.crc may "look negative",
469 # while the same crc on a 64-bit box may "look positive".
470 # To avoid irksome warnings from the `struct` module, force
471 # it to look positive on all boxes.
Guido van Rossume2a383d2007-01-15 16:59:06 +0000472 self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff))
473 self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000474
475 if not self._extfileobj:
476 self.fileobj.close()
477
478 self.closed = True
479
480 def _init_read_gz(self):
481 """Initialize for reading a gzip compressed fileobj.
482 """
483 self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000484 self.dbuf = b""
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000485
486 # taken from gzip.GzipFile with some alterations
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000487 if self.__read(2) != b"\037\213":
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488 raise ReadError("not a gzip file")
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000489 if self.__read(1) != b"\010":
Thomas Wouters477c8d52006-05-27 19:21:47 +0000490 raise CompressionError("unsupported compression method")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000491
492 flag = ord(self.__read(1))
493 self.__read(6)
494
495 if flag & 4:
496 xlen = ord(self.__read(1)) + 256 * ord(self.__read(1))
497 self.read(xlen)
498 if flag & 8:
499 while True:
500 s = self.__read(1)
501 if not s or s == NUL:
502 break
503 if flag & 16:
504 while True:
505 s = self.__read(1)
506 if not s or s == NUL:
507 break
508 if flag & 2:
509 self.__read(2)
510
511 def tell(self):
512 """Return the stream's file pointer position.
513 """
514 return self.pos
515
516 def seek(self, pos=0):
517 """Set the stream's file pointer to pos. Negative seeking
518 is forbidden.
519 """
520 if pos - self.pos >= 0:
521 blocks, remainder = divmod(pos - self.pos, self.bufsize)
Guido van Rossum805365e2007-05-07 22:24:25 +0000522 for i in range(blocks):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000523 self.read(self.bufsize)
524 self.read(remainder)
525 else:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526 raise StreamError("seeking backwards is not allowed")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000527 return self.pos
528
529 def read(self, size=None):
530 """Return the next size number of bytes from the stream.
531 If size is not defined, return all bytes of the stream
532 up to EOF.
533 """
534 if size is None:
535 t = []
536 while True:
537 buf = self._read(self.bufsize)
538 if not buf:
539 break
540 t.append(buf)
541 buf = "".join(t)
542 else:
543 buf = self._read(size)
544 self.pos += len(buf)
545 return buf
546
547 def _read(self, size):
548 """Return size bytes from the stream.
549 """
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000550 if self.comptype == "tar":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000551 return self.__read(size)
552
553 c = len(self.dbuf)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000554 while c < size:
555 buf = self.__read(self.bufsize)
556 if not buf:
557 break
Guido van Rossumd8faa362007-04-27 19:54:29 +0000558 try:
559 buf = self.cmp.decompress(buf)
560 except IOError:
561 raise ReadError("invalid compressed data")
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000562 self.dbuf += buf
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000563 c += len(buf)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000564 buf = self.dbuf[:size]
565 self.dbuf = self.dbuf[size:]
566 return buf
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000567
568 def __read(self, size):
569 """Return size bytes from stream. If internal buffer is empty,
570 read another block from the stream.
571 """
572 c = len(self.buf)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000573 while c < size:
574 buf = self.fileobj.read(self.bufsize)
575 if not buf:
576 break
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000577 self.buf += buf
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000578 c += len(buf)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000579 buf = self.buf[:size]
580 self.buf = self.buf[size:]
581 return buf
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000582# class _Stream
583
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000584class _StreamProxy(object):
585 """Small proxy class that enables transparent compression
586 detection for the Stream interface (mode 'r|*').
587 """
588
589 def __init__(self, fileobj):
590 self.fileobj = fileobj
591 self.buf = self.fileobj.read(BLOCKSIZE)
592
593 def read(self, size):
594 self.read = self.fileobj.read
595 return self.buf
596
597 def getcomptype(self):
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000598 if self.buf.startswith(b"\037\213\010"):
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000599 return "gz"
Lars Gustäbela280ca752007-08-28 07:34:33 +0000600 if self.buf.startswith(b"BZh91"):
Martin v. Löwis78be7df2005-03-05 12:47:42 +0000601 return "bz2"
602 return "tar"
603
604 def close(self):
605 self.fileobj.close()
606# class StreamProxy
607
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608class _BZ2Proxy(object):
609 """Small proxy class that enables external file object
610 support for "r:bz2" and "w:bz2" modes. This is actually
611 a workaround for a limitation in bz2 module's BZ2File
612 class which (unlike gzip.GzipFile) has no support for
613 a file object argument.
614 """
615
616 blocksize = 16 * 1024
617
618 def __init__(self, fileobj, mode):
619 self.fileobj = fileobj
620 self.mode = mode
Guido van Rossumd8faa362007-04-27 19:54:29 +0000621 self.name = getattr(self.fileobj, "name", None)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000622 self.init()
623
624 def init(self):
625 import bz2
626 self.pos = 0
627 if self.mode == "r":
628 self.bz2obj = bz2.BZ2Decompressor()
629 self.fileobj.seek(0)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000630 self.buf = b""
Thomas Wouters477c8d52006-05-27 19:21:47 +0000631 else:
632 self.bz2obj = bz2.BZ2Compressor()
633
634 def read(self, size):
Thomas Wouters477c8d52006-05-27 19:21:47 +0000635 x = len(self.buf)
636 while x < size:
Lars Gustäbel42e00912009-03-22 20:34:29 +0000637 raw = self.fileobj.read(self.blocksize)
638 if not raw:
Thomas Wouters477c8d52006-05-27 19:21:47 +0000639 break
Lars Gustäbel42e00912009-03-22 20:34:29 +0000640 data = self.bz2obj.decompress(raw)
641 self.buf += data
Thomas Wouters477c8d52006-05-27 19:21:47 +0000642 x += len(data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000643
644 buf = self.buf[:size]
645 self.buf = self.buf[size:]
646 self.pos += len(buf)
647 return buf
648
649 def seek(self, pos):
650 if pos < self.pos:
651 self.init()
652 self.read(pos - self.pos)
653
654 def tell(self):
655 return self.pos
656
657 def write(self, data):
658 self.pos += len(data)
659 raw = self.bz2obj.compress(data)
660 self.fileobj.write(raw)
661
662 def close(self):
663 if self.mode == "w":
664 raw = self.bz2obj.flush()
665 self.fileobj.write(raw)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000666# class _BZ2Proxy
667
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000668#------------------------
669# Extraction file object
670#------------------------
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000671class _FileInFile(object):
672 """A thin wrapper around an existing file object that
673 provides a part of its data as an individual file
674 object.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000675 """
676
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000677 def __init__(self, fileobj, offset, size, sparse=None):
678 self.fileobj = fileobj
679 self.offset = offset
680 self.size = size
681 self.sparse = sparse
682 self.position = 0
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000683
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000684 def seekable(self):
685 if not hasattr(self.fileobj, "seekable"):
686 # XXX gzip.GzipFile and bz2.BZ2File
687 return True
688 return self.fileobj.seekable()
689
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000690 def tell(self):
691 """Return the current file position.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000692 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000693 return self.position
694
695 def seek(self, position):
696 """Seek to a position in the file.
697 """
698 self.position = position
699
700 def read(self, size=None):
701 """Read data from the file.
702 """
703 if size is None:
704 size = self.size - self.position
705 else:
706 size = min(size, self.size - self.position)
707
708 if self.sparse is None:
709 return self.readnormal(size)
710 else:
711 return self.readsparse(size)
712
713 def readnormal(self, size):
714 """Read operation for regular files.
715 """
716 self.fileobj.seek(self.offset + self.position)
717 self.position += size
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000718 return self.fileobj.read(size)
719
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000720 def readsparse(self, size):
721 """Read operation for sparse files.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000722 """
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000723 data = b""
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000724 while size > 0:
725 buf = self.readsparsesection(size)
726 if not buf:
727 break
728 size -= len(buf)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000729 data += buf
730 return data
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000731
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000732 def readsparsesection(self, size):
733 """Read a single section of a sparse file.
734 """
735 section = self.sparse.find(self.position)
736
737 if section is None:
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000738 return b""
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000739
740 size = min(size, section.offset + section.size - self.position)
741
742 if isinstance(section, _data):
743 realpos = section.realpos + self.position - section.offset
744 self.fileobj.seek(self.offset + realpos)
745 self.position += size
746 return self.fileobj.read(size)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000747 else:
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000748 self.position += size
749 return NUL * size
750#class _FileInFile
751
752
753class ExFileObject(object):
754 """File-like object for reading an archive member.
755 Is returned by TarFile.extractfile().
756 """
757 blocksize = 1024
758
759 def __init__(self, tarfile, tarinfo):
760 self.fileobj = _FileInFile(tarfile.fileobj,
761 tarinfo.offset_data,
762 tarinfo.size,
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +0000763 tarinfo.sparse)
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000764 self.name = tarinfo.name
765 self.mode = "r"
766 self.closed = False
767 self.size = tarinfo.size
768
769 self.position = 0
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000770 self.buffer = b""
771
772 def readable(self):
773 return True
774
775 def writable(self):
776 return False
777
778 def seekable(self):
779 return self.fileobj.seekable()
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000780
781 def read(self, size=None):
782 """Read at most size bytes from the file. If size is not
783 present or None, read all data until EOF is reached.
784 """
785 if self.closed:
786 raise ValueError("I/O operation on closed file")
787
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000788 buf = b""
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000789 if self.buffer:
790 if size is None:
791 buf = self.buffer
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000792 self.buffer = b""
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000793 else:
794 buf = self.buffer[:size]
795 self.buffer = self.buffer[size:]
796
797 if size is None:
798 buf += self.fileobj.read()
799 else:
800 buf += self.fileobj.read(size - len(buf))
801
802 self.position += len(buf)
803 return buf
804
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000805 # XXX TextIOWrapper uses the read1() method.
806 read1 = read
807
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000808 def readline(self, size=-1):
809 """Read one entire line from the file. If size is present
810 and non-negative, return a string with at most that
811 size, which may be an incomplete line.
812 """
813 if self.closed:
814 raise ValueError("I/O operation on closed file")
815
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000816 pos = self.buffer.find(b"\n") + 1
817 if pos == 0:
818 # no newline found.
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000819 while True:
820 buf = self.fileobj.read(self.blocksize)
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000821 self.buffer += buf
822 if not buf or b"\n" in buf:
823 pos = self.buffer.find(b"\n") + 1
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000824 if pos == 0:
825 # no newline found.
826 pos = len(self.buffer)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000827 break
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000828
829 if size != -1:
830 pos = min(size, pos)
831
832 buf = self.buffer[:pos]
833 self.buffer = self.buffer[pos:]
834 self.position += len(buf)
835 return buf
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000836
837 def readlines(self):
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000838 """Return a list with all remaining lines.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000839 """
840 result = []
841 while True:
842 line = self.readline()
843 if not line: break
844 result.append(line)
845 return result
846
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000847 def tell(self):
848 """Return the current file position.
849 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000850 if self.closed:
851 raise ValueError("I/O operation on closed file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000852
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000853 return self.position
854
855 def seek(self, pos, whence=os.SEEK_SET):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000856 """Seek to a position in the file.
857 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000858 if self.closed:
859 raise ValueError("I/O operation on closed file")
860
861 if whence == os.SEEK_SET:
862 self.position = min(max(pos, 0), self.size)
863 elif whence == os.SEEK_CUR:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000864 if pos < 0:
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000865 self.position = max(self.position + pos, 0)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000866 else:
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000867 self.position = min(self.position + pos, self.size)
868 elif whence == os.SEEK_END:
869 self.position = max(min(self.size + pos, self.size), 0)
870 else:
871 raise ValueError("Invalid argument")
872
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000873 self.buffer = b""
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000874 self.fileobj.seek(self.position)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000875
876 def close(self):
877 """Close the file object.
878 """
879 self.closed = True
Martin v. Löwisdf241532005-03-03 08:17:42 +0000880
881 def __iter__(self):
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000882 """Get an iterator over the file's lines.
Martin v. Löwisdf241532005-03-03 08:17:42 +0000883 """
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000884 while True:
885 line = self.readline()
886 if not line:
887 break
888 yield line
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000889#class ExFileObject
890
891#------------------
892# Exported Classes
893#------------------
894class TarInfo(object):
895 """Informational class which holds the details about an
896 archive member given by a tar header block.
897 TarInfo objects are returned by TarFile.getmember(),
898 TarFile.getmembers() and TarFile.gettarinfo() and are
899 usually created internally.
900 """
901
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +0000902 __slots__ = ("name", "mode", "uid", "gid", "size", "mtime",
903 "chksum", "type", "linkname", "uname", "gname",
904 "devmajor", "devminor",
905 "offset", "offset_data", "pax_headers", "sparse",
906 "tarfile", "_sparse_structs", "_link_target")
907
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000908 def __init__(self, name=""):
909 """Construct a TarInfo object. name is the optional name
910 of the member.
911 """
Guido van Rossumd8faa362007-04-27 19:54:29 +0000912 self.name = name # member name
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000913 self.mode = 0o644 # file permissions
Thomas Wouters477c8d52006-05-27 19:21:47 +0000914 self.uid = 0 # user id
915 self.gid = 0 # group id
916 self.size = 0 # file size
917 self.mtime = 0 # modification time
918 self.chksum = 0 # header checksum
919 self.type = REGTYPE # member type
920 self.linkname = "" # link name
Guido van Rossumd8faa362007-04-27 19:54:29 +0000921 self.uname = "root" # user name
922 self.gname = "root" # group name
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923 self.devmajor = 0 # device major number
924 self.devminor = 0 # device minor number
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000925
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926 self.offset = 0 # the tar header starts here
927 self.offset_data = 0 # the file's data starts here
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000928
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +0000929 self.sparse = None # sparse member information
Guido van Rossumd8faa362007-04-27 19:54:29 +0000930 self.pax_headers = {} # pax header information
931
932 # In pax headers the "name" and "linkname" field are called
933 # "path" and "linkpath".
934 def _getpath(self):
935 return self.name
936 def _setpath(self, name):
937 self.name = name
938 path = property(_getpath, _setpath)
939
940 def _getlinkpath(self):
941 return self.linkname
942 def _setlinkpath(self, linkname):
943 self.linkname = linkname
944 linkpath = property(_getlinkpath, _setlinkpath)
945
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +0000946 def __repr__(self):
947 return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
948
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000949 def get_info(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000950 """Return the TarInfo's attributes as a dictionary.
951 """
952 info = {
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +0000953 "name": self.name,
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000954 "mode": self.mode & 0o7777,
Guido van Rossumd8faa362007-04-27 19:54:29 +0000955 "uid": self.uid,
956 "gid": self.gid,
957 "size": self.size,
958 "mtime": self.mtime,
959 "chksum": self.chksum,
960 "type": self.type,
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +0000961 "linkname": self.linkname,
Guido van Rossumd8faa362007-04-27 19:54:29 +0000962 "uname": self.uname,
963 "gname": self.gname,
964 "devmajor": self.devmajor,
965 "devminor": self.devminor
966 }
967
968 if info["type"] == DIRTYPE and not info["name"].endswith("/"):
969 info["name"] += "/"
970
971 return info
972
Guido van Rossume7ba4952007-06-06 23:52:48 +0000973 def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="strict"):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000974 """Return a tar header as a string of 512 byte blocks.
975 """
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000976 info = self.get_info()
Guido van Rossume7ba4952007-06-06 23:52:48 +0000977
Guido van Rossumd8faa362007-04-27 19:54:29 +0000978 if format == USTAR_FORMAT:
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000979 return self.create_ustar_header(info, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000980 elif format == GNU_FORMAT:
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000981 return self.create_gnu_header(info, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000982 elif format == PAX_FORMAT:
Lars Gustäbel3741eff2007-08-21 12:17:05 +0000983 return self.create_pax_header(info)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000984 else:
985 raise ValueError("invalid format")
986
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000987 def create_ustar_header(self, info, encoding, errors):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000988 """Return the object as a ustar header block.
989 """
Guido van Rossumd8faa362007-04-27 19:54:29 +0000990 info["magic"] = POSIX_MAGIC
991
992 if len(info["linkname"]) > LENGTH_LINK:
993 raise ValueError("linkname is too long")
994
995 if len(info["name"]) > LENGTH_NAME:
996 info["prefix"], info["name"] = self._posix_split_name(info["name"])
997
Lars Gustäbelb506dc32007-08-07 18:36:16 +0000998 return self._create_header(info, USTAR_FORMAT, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000999
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001000 def create_gnu_header(self, info, encoding, errors):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001001 """Return the object as a GNU header block sequence.
1002 """
Guido van Rossumd8faa362007-04-27 19:54:29 +00001003 info["magic"] = GNU_MAGIC
1004
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001005 buf = b""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001006 if len(info["linkname"]) > LENGTH_LINK:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001007 buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001008
1009 if len(info["name"]) > LENGTH_NAME:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001010 buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001011
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001012 return buf + self._create_header(info, GNU_FORMAT, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001014 def create_pax_header(self, info):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001015 """Return the object as a ustar header block. If it cannot be
1016 represented this way, prepend a pax extended header sequence
1017 with supplement information.
1018 """
Guido van Rossumd8faa362007-04-27 19:54:29 +00001019 info["magic"] = POSIX_MAGIC
1020 pax_headers = self.pax_headers.copy()
1021
1022 # Test string fields for values that exceed the field length or cannot
1023 # be represented in ASCII encoding.
1024 for name, hname, length in (
1025 ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK),
1026 ("uname", "uname", 32), ("gname", "gname", 32)):
1027
Guido van Rossume7ba4952007-06-06 23:52:48 +00001028 if hname in pax_headers:
1029 # The pax header has priority.
1030 continue
1031
Guido van Rossumd8faa362007-04-27 19:54:29 +00001032 # Try to encode the string as ASCII.
1033 try:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001034 info[name].encode("ascii", "strict")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001035 except UnicodeEncodeError:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001036 pax_headers[hname] = info[name]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001037 continue
1038
Guido van Rossume7ba4952007-06-06 23:52:48 +00001039 if len(info[name]) > length:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001040 pax_headers[hname] = info[name]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001041
1042 # Test number fields for values that exceed the field limit or values
1043 # that like to be stored as float.
1044 for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)):
Guido van Rossume7ba4952007-06-06 23:52:48 +00001045 if name in pax_headers:
1046 # The pax header has priority. Avoid overflow.
1047 info[name] = 0
1048 continue
1049
Guido van Rossumd8faa362007-04-27 19:54:29 +00001050 val = info[name]
1051 if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
Guido van Rossumef87d6e2007-05-02 19:09:54 +00001052 pax_headers[name] = str(val)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001053 info[name] = 0
1054
Guido van Rossume7ba4952007-06-06 23:52:48 +00001055 # Create a pax extended header if necessary.
Guido van Rossumd8faa362007-04-27 19:54:29 +00001056 if pax_headers:
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001057 buf = self._create_pax_generic_header(pax_headers, XHDTYPE)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001058 else:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001059 buf = b""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001060
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001061 return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001062
1063 @classmethod
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001064 def create_pax_global_header(cls, pax_headers):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001065 """Return the object as a pax global header block sequence.
1066 """
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001067 return cls._create_pax_generic_header(pax_headers, XGLTYPE)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001068
1069 def _posix_split_name(self, name):
1070 """Split a name longer than 100 chars into a prefix
1071 and a name part.
1072 """
1073 prefix = name[:LENGTH_PREFIX + 1]
1074 while prefix and prefix[-1] != "/":
1075 prefix = prefix[:-1]
1076
1077 name = name[len(prefix):]
1078 prefix = prefix[:-1]
1079
1080 if not prefix or len(name) > LENGTH_NAME:
1081 raise ValueError("name is too long")
1082 return prefix, name
1083
1084 @staticmethod
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001085 def _create_header(info, format, encoding, errors):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001086 """Return a header block. info is a dictionary with file
1087 information, format must be one of the *_FORMAT constants.
1088 """
1089 parts = [
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001090 stn(info.get("name", ""), 100, encoding, errors),
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001091 itn(info.get("mode", 0) & 0o7777, 8, format),
Guido van Rossumd8faa362007-04-27 19:54:29 +00001092 itn(info.get("uid", 0), 8, format),
1093 itn(info.get("gid", 0), 8, format),
1094 itn(info.get("size", 0), 12, format),
1095 itn(info.get("mtime", 0), 12, format),
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001096 b" ", # checksum field
Guido van Rossumd8faa362007-04-27 19:54:29 +00001097 info.get("type", REGTYPE),
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001098 stn(info.get("linkname", ""), 100, encoding, errors),
1099 info.get("magic", POSIX_MAGIC),
1100 stn(info.get("uname", "root"), 32, encoding, errors),
1101 stn(info.get("gname", "root"), 32, encoding, errors),
Guido van Rossumd8faa362007-04-27 19:54:29 +00001102 itn(info.get("devmajor", 0), 8, format),
1103 itn(info.get("devminor", 0), 8, format),
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001104 stn(info.get("prefix", ""), 155, encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001105 ]
1106
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001107 buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts))
Guido van Rossumd8faa362007-04-27 19:54:29 +00001108 chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
Lars Gustäbela280ca752007-08-28 07:34:33 +00001109 buf = buf[:-364] + bytes("%06o\0" % chksum, "ascii") + buf[-357:]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001110 return buf
1111
1112 @staticmethod
1113 def _create_payload(payload):
1114 """Return the string payload filled with zero bytes
1115 up to the next 512 byte border.
1116 """
1117 blocks, remainder = divmod(len(payload), BLOCKSIZE)
1118 if remainder > 0:
1119 payload += (BLOCKSIZE - remainder) * NUL
1120 return payload
1121
1122 @classmethod
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001123 def _create_gnu_long_header(cls, name, type, encoding, errors):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001124 """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence
1125 for name.
1126 """
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001127 name = name.encode(encoding, errors) + NUL
Guido van Rossumd8faa362007-04-27 19:54:29 +00001128
1129 info = {}
1130 info["name"] = "././@LongLink"
1131 info["type"] = type
1132 info["size"] = len(name)
1133 info["magic"] = GNU_MAGIC
1134
1135 # create extended header + name blocks.
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001136 return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \
Guido van Rossumd8faa362007-04-27 19:54:29 +00001137 cls._create_payload(name)
1138
1139 @classmethod
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001140 def _create_pax_generic_header(cls, pax_headers, type):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001141 """Return a POSIX.1-2001 extended or global header sequence
1142 that contains a list of keyword, value pairs. The values
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001143 must be strings.
Guido van Rossumd8faa362007-04-27 19:54:29 +00001144 """
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001145 records = b""
Guido van Rossumd8faa362007-04-27 19:54:29 +00001146 for keyword, value in pax_headers.items():
1147 keyword = keyword.encode("utf8")
1148 value = value.encode("utf8")
1149 l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n'
1150 n = p = 0
1151 while True:
1152 n = l + len(str(p))
1153 if n == p:
1154 break
1155 p = n
Lars Gustäbela280ca752007-08-28 07:34:33 +00001156 records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n"
Guido van Rossumd8faa362007-04-27 19:54:29 +00001157
1158 # We use a hardcoded "././@PaxHeader" name like star does
1159 # instead of the one that POSIX recommends.
1160 info = {}
1161 info["name"] = "././@PaxHeader"
1162 info["type"] = type
1163 info["size"] = len(records)
1164 info["magic"] = POSIX_MAGIC
1165
1166 # Create pax header + record blocks.
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001167 return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \
Guido van Rossumd8faa362007-04-27 19:54:29 +00001168 cls._create_payload(records)
1169
Guido van Rossum75b64e62005-01-16 00:16:11 +00001170 @classmethod
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001171 def frombuf(cls, buf, encoding, errors):
1172 """Construct a TarInfo object from a 512 byte bytes object.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001173 """
Thomas Wouters477c8d52006-05-27 19:21:47 +00001174 if len(buf) != BLOCKSIZE:
Thomas Wouters902d6eb2007-01-09 23:18:33 +00001175 raise HeaderError("truncated header")
Thomas Wouters477c8d52006-05-27 19:21:47 +00001176 if buf.count(NUL) == BLOCKSIZE:
Thomas Wouters902d6eb2007-01-09 23:18:33 +00001177 raise HeaderError("empty header")
1178
1179 chksum = nti(buf[148:156])
1180 if chksum not in calc_chksums(buf):
1181 raise HeaderError("bad checksum")
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182
Guido van Rossumd8faa362007-04-27 19:54:29 +00001183 obj = cls()
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001184 obj.name = nts(buf[0:100], encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001185 obj.mode = nti(buf[100:108])
1186 obj.uid = nti(buf[108:116])
1187 obj.gid = nti(buf[116:124])
1188 obj.size = nti(buf[124:136])
1189 obj.mtime = nti(buf[136:148])
1190 obj.chksum = chksum
1191 obj.type = buf[156:157]
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001192 obj.linkname = nts(buf[157:257], encoding, errors)
1193 obj.uname = nts(buf[265:297], encoding, errors)
1194 obj.gname = nts(buf[297:329], encoding, errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001195 obj.devmajor = nti(buf[329:337])
1196 obj.devminor = nti(buf[337:345])
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001197 prefix = nts(buf[345:500], encoding, errors)
Thomas Wouters89f507f2006-12-13 04:49:30 +00001198
Guido van Rossumd8faa362007-04-27 19:54:29 +00001199 # Old V7 tar format represents a directory as a regular
1200 # file with a trailing slash.
1201 if obj.type == AREGTYPE and obj.name.endswith("/"):
1202 obj.type = DIRTYPE
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001203
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +00001204 # The old GNU sparse format occupies some of the unused
1205 # space in the buffer for up to 4 sparse structures.
1206 # Save the them for later processing in _proc_sparse().
1207 if obj.type == GNUTYPE_SPARSE:
1208 pos = 386
1209 structs = []
1210 for i in range(4):
1211 try:
1212 offset = nti(buf[pos:pos + 12])
1213 numbytes = nti(buf[pos + 12:pos + 24])
1214 except ValueError:
1215 break
1216 structs.append((offset, numbytes))
1217 pos += 24
1218 isextended = bool(buf[482])
1219 origsize = nti(buf[483:495])
1220 obj._sparse_structs = (structs, isextended, origsize)
1221
Guido van Rossumd8faa362007-04-27 19:54:29 +00001222 # Remove redundant slashes from directories.
1223 if obj.isdir():
1224 obj.name = obj.name.rstrip("/")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001225
Guido van Rossumd8faa362007-04-27 19:54:29 +00001226 # Reconstruct a ustar longname.
1227 if prefix and obj.type not in GNU_TYPES:
1228 obj.name = prefix + "/" + obj.name
1229 return obj
1230
1231 @classmethod
1232 def fromtarfile(cls, tarfile):
1233 """Return the next TarInfo object from TarFile object
1234 tarfile.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001235 """
Guido van Rossumd8faa362007-04-27 19:54:29 +00001236 buf = tarfile.fileobj.read(BLOCKSIZE)
1237 if not buf:
1238 return
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001239 obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001240 obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
1241 return obj._proc_member(tarfile)
Thomas Wouters89f507f2006-12-13 04:49:30 +00001242
Guido van Rossumd8faa362007-04-27 19:54:29 +00001243 #--------------------------------------------------------------------------
1244 # The following are methods that are called depending on the type of a
1245 # member. The entry point is _proc_member() which can be overridden in a
1246 # subclass to add custom _proc_*() methods. A _proc_*() method MUST
1247 # implement the following
1248 # operations:
1249 # 1. Set self.offset_data to the position where the data blocks begin,
1250 # if there is data that follows.
1251 # 2. Set tarfile.offset to the position where the next member's header will
1252 # begin.
1253 # 3. Return self or another valid TarInfo object.
1254 def _proc_member(self, tarfile):
1255 """Choose the right processing method depending on
1256 the type and call it.
Thomas Wouters89f507f2006-12-13 04:49:30 +00001257 """
Guido van Rossumd8faa362007-04-27 19:54:29 +00001258 if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
1259 return self._proc_gnulong(tarfile)
1260 elif self.type == GNUTYPE_SPARSE:
1261 return self._proc_sparse(tarfile)
1262 elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE):
1263 return self._proc_pax(tarfile)
1264 else:
1265 return self._proc_builtin(tarfile)
Thomas Wouters89f507f2006-12-13 04:49:30 +00001266
Guido van Rossumd8faa362007-04-27 19:54:29 +00001267 def _proc_builtin(self, tarfile):
1268 """Process a builtin type or an unknown type which
1269 will be treated as a regular file.
1270 """
1271 self.offset_data = tarfile.fileobj.tell()
1272 offset = self.offset_data
1273 if self.isreg() or self.type not in SUPPORTED_TYPES:
1274 # Skip the following data blocks.
1275 offset += self._block(self.size)
1276 tarfile.offset = offset
Thomas Wouters89f507f2006-12-13 04:49:30 +00001277
Guido van Rossume7ba4952007-06-06 23:52:48 +00001278 # Patch the TarInfo object with saved global
Guido van Rossumd8faa362007-04-27 19:54:29 +00001279 # header information.
Guido van Rossume7ba4952007-06-06 23:52:48 +00001280 self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001281
1282 return self
1283
1284 def _proc_gnulong(self, tarfile):
1285 """Process the blocks that hold a GNU longname
1286 or longlink member.
1287 """
1288 buf = tarfile.fileobj.read(self._block(self.size))
1289
1290 # Fetch the next header and process it.
Guido van Rossume7ba4952007-06-06 23:52:48 +00001291 next = self.fromtarfile(tarfile)
1292 if next is None:
1293 raise HeaderError("missing subsequent header")
Guido van Rossumd8faa362007-04-27 19:54:29 +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äbelb506dc32007-08-07 18:36:16 +00001299 next.name = nts(buf, tarfile.encoding, tarfile.errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001300 elif self.type == GNUTYPE_LONGLINK:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001301 next.linkname = nts(buf, tarfile.encoding, tarfile.errors)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001302
1303 return next
1304
1305 def _proc_sparse(self, tarfile):
1306 """Process a GNU sparse header plus extra headers.
1307 """
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +00001308 # We already collected some sparse structures in frombuf().
1309 structs, isextended, origsize = self._sparse_structs
1310 del self._sparse_structs
Guido van Rossumd8faa362007-04-27 19:54:29 +00001311
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +00001312 # Collect sparse structures from extended header blocks.
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001313 while isextended:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001314 buf = tarfile.fileobj.read(BLOCKSIZE)
1315 pos = 0
Guido van Rossum805365e2007-05-07 22:24:25 +00001316 for i in range(21):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001317 try:
1318 offset = nti(buf[pos:pos + 12])
1319 numbytes = nti(buf[pos + 12:pos + 24])
1320 except ValueError:
1321 break
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +00001322 structs.append((offset, numbytes))
Guido van Rossumd8faa362007-04-27 19:54:29 +00001323 pos += 24
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001324 isextended = bool(buf[504])
Guido van Rossumd8faa362007-04-27 19:54:29 +00001325
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +00001326 # Transform the sparse structures to something we can use
1327 # in ExFileObject.
1328 self.sparse = _ringbuffer()
1329 lastpos = 0
1330 realpos = 0
1331 for offset, numbytes in structs:
1332 if offset > lastpos:
1333 self.sparse.append(_hole(lastpos, offset - lastpos))
1334 self.sparse.append(_data(offset, numbytes, realpos))
1335 realpos += numbytes
1336 lastpos = offset + numbytes
Guido van Rossumd8faa362007-04-27 19:54:29 +00001337 if lastpos < origsize:
Lars Gustäbelc2ea8c62008-04-14 10:05:48 +00001338 self.sparse.append(_hole(lastpos, origsize - lastpos))
Guido van Rossumd8faa362007-04-27 19:54:29 +00001339
1340 self.offset_data = tarfile.fileobj.tell()
1341 tarfile.offset = self.offset_data + self._block(self.size)
1342 self.size = origsize
1343
1344 return self
1345
1346 def _proc_pax(self, tarfile):
1347 """Process an extended or global header as described in
1348 POSIX.1-2001.
1349 """
1350 # Read the header information.
1351 buf = tarfile.fileobj.read(self._block(self.size))
1352
1353 # A pax header stores supplemental information for either
1354 # the following file (extended) or all following files
1355 # (global).
1356 if self.type == XGLTYPE:
1357 pax_headers = tarfile.pax_headers
1358 else:
1359 pax_headers = tarfile.pax_headers.copy()
1360
Guido van Rossumd8faa362007-04-27 19:54:29 +00001361 # Parse pax header information. A record looks like that:
1362 # "%d %s=%s\n" % (length, keyword, value). length is the size
1363 # of the complete record including the length field itself and
Guido van Rossume7ba4952007-06-06 23:52:48 +00001364 # the newline. keyword and value are both UTF-8 encoded strings.
Antoine Pitroufd036452008-08-19 17:56:33 +00001365 regex = re.compile(br"(\d+) ([^=]+)=")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001366 pos = 0
1367 while True:
1368 match = regex.match(buf, pos)
1369 if not match:
1370 break
1371
1372 length, keyword = match.groups()
1373 length = int(length)
1374 value = buf[match.end(2) + 1:match.start(1) + length - 1]
1375
1376 keyword = keyword.decode("utf8")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001377 value = value.decode("utf8")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001378
1379 pax_headers[keyword] = value
1380 pos += length
1381
Guido van Rossume7ba4952007-06-06 23:52:48 +00001382 # Fetch the next header.
1383 next = self.fromtarfile(tarfile)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001384
Guido van Rossume7ba4952007-06-06 23:52:48 +00001385 if self.type in (XHDTYPE, SOLARIS_XHDTYPE):
1386 if next is None:
1387 raise HeaderError("missing subsequent header")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001388
Guido van Rossume7ba4952007-06-06 23:52:48 +00001389 # Patch the TarInfo object with the extended header info.
1390 next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors)
1391 next.offset = self.offset
1392
1393 if "size" in pax_headers:
1394 # If the extended header replaces the size field,
1395 # we need to recalculate the offset where the next
1396 # header starts.
1397 offset = next.offset_data
1398 if next.isreg() or next.type not in SUPPORTED_TYPES:
1399 offset += next._block(next.size)
1400 tarfile.offset = offset
1401
1402 return next
1403
1404 def _apply_pax_info(self, pax_headers, encoding, errors):
1405 """Replace fields with supplemental information from a previous
1406 pax extended or global header.
1407 """
1408 for keyword, value in pax_headers.items():
1409 if keyword not in PAX_FIELDS:
1410 continue
1411
1412 if keyword == "path":
1413 value = value.rstrip("/")
1414
1415 if keyword in PAX_NUMBER_FIELDS:
1416 try:
1417 value = PAX_NUMBER_FIELDS[keyword](value)
1418 except ValueError:
1419 value = 0
Guido van Rossume7ba4952007-06-06 23:52:48 +00001420
1421 setattr(self, keyword, value)
1422
1423 self.pax_headers = pax_headers.copy()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001424
1425 def _block(self, count):
1426 """Round up a byte count by BLOCKSIZE and return it,
1427 e.g. _block(834) => 1024.
1428 """
1429 blocks, remainder = divmod(count, BLOCKSIZE)
1430 if remainder:
1431 blocks += 1
1432 return blocks * BLOCKSIZE
Thomas Wouters89f507f2006-12-13 04:49:30 +00001433
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001434 def isreg(self):
1435 return self.type in REGULAR_TYPES
1436 def isfile(self):
1437 return self.isreg()
1438 def isdir(self):
1439 return self.type == DIRTYPE
1440 def issym(self):
1441 return self.type == SYMTYPE
1442 def islnk(self):
1443 return self.type == LNKTYPE
1444 def ischr(self):
1445 return self.type == CHRTYPE
1446 def isblk(self):
1447 return self.type == BLKTYPE
1448 def isfifo(self):
1449 return self.type == FIFOTYPE
1450 def issparse(self):
1451 return self.type == GNUTYPE_SPARSE
1452 def isdev(self):
1453 return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE)
1454# class TarInfo
1455
1456class TarFile(object):
1457 """The TarFile Class provides an interface to tar archives.
1458 """
1459
1460 debug = 0 # May be set from 0 (no msgs) to 3 (all msgs)
1461
1462 dereference = False # If true, add content of linked file to the
1463 # tar file, else the link.
1464
1465 ignore_zeros = False # If true, skips empty or invalid blocks and
1466 # continues processing.
1467
1468 errorlevel = 0 # If 0, fatal errors only appear in debug
1469 # messages (if debug >= 0). If > 0, errors
1470 # are passed to the caller as exceptions.
1471
Guido van Rossumd8faa362007-04-27 19:54:29 +00001472 format = DEFAULT_FORMAT # The format to use when creating an archive.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001473
Guido van Rossume7ba4952007-06-06 23:52:48 +00001474 encoding = ENCODING # Encoding for 8-bit character strings.
1475
1476 errors = None # Error handler for unicode conversion.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001477
Guido van Rossumd8faa362007-04-27 19:54:29 +00001478 tarinfo = TarInfo # The default TarInfo class to use.
1479
1480 fileobject = ExFileObject # The default ExFileObject class to use.
1481
1482 def __init__(self, name=None, mode="r", fileobj=None, format=None,
1483 tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
Guido van Rossume7ba4952007-06-06 23:52:48 +00001484 errors=None, pax_headers=None, debug=None, errorlevel=None):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001485 """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
1486 read from an existing archive, 'a' to append data to an existing
1487 file or 'w' to create a new file overwriting an existing one. `mode'
1488 defaults to 'r'.
1489 If `fileobj' is given, it is used for reading or writing data. If it
1490 can be determined, `mode' is overridden by `fileobj's mode.
1491 `fileobj' is not closed, when TarFile is closed.
1492 """
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001493 if len(mode) > 1 or mode not in "raw":
Thomas Wouters477c8d52006-05-27 19:21:47 +00001494 raise ValueError("mode must be 'r', 'a' or 'w'")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001495 self.mode = mode
1496 self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001497
1498 if not fileobj:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001499 if self.mode == "a" and not os.path.exists(name):
Thomas Wouterscf297e42007-02-23 15:07:44 +00001500 # Create nonexistent files in append mode.
Guido van Rossumd8faa362007-04-27 19:54:29 +00001501 self.mode = "w"
1502 self._mode = "wb"
Guido van Rossume7ba4952007-06-06 23:52:48 +00001503 fileobj = bltn_open(name, self._mode)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001504 self._extfileobj = False
1505 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001506 if name is None and hasattr(fileobj, "name"):
1507 name = fileobj.name
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001508 if hasattr(fileobj, "mode"):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001509 self._mode = fileobj.mode
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001510 self._extfileobj = True
Thomas Woutersed03b412007-08-28 21:37:11 +00001511 self.name = os.path.abspath(name) if name else None
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001512 self.fileobj = fileobj
1513
Guido van Rossumd8faa362007-04-27 19:54:29 +00001514 # Init attributes.
1515 if format is not None:
1516 self.format = format
1517 if tarinfo is not None:
1518 self.tarinfo = tarinfo
1519 if dereference is not None:
1520 self.dereference = dereference
1521 if ignore_zeros is not None:
1522 self.ignore_zeros = ignore_zeros
1523 if encoding is not None:
1524 self.encoding = encoding
Guido van Rossume7ba4952007-06-06 23:52:48 +00001525
1526 if errors is not None:
1527 self.errors = errors
1528 elif mode == "r":
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001529 self.errors = "replace"
Guido van Rossume7ba4952007-06-06 23:52:48 +00001530 else:
1531 self.errors = "strict"
1532
1533 if pax_headers is not None and self.format == PAX_FORMAT:
1534 self.pax_headers = pax_headers
1535 else:
1536 self.pax_headers = {}
1537
Guido van Rossumd8faa362007-04-27 19:54:29 +00001538 if debug is not None:
1539 self.debug = debug
1540 if errorlevel is not None:
1541 self.errorlevel = errorlevel
1542
1543 # Init datastructures.
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544 self.closed = False
1545 self.members = [] # list of members as TarInfo objects
1546 self._loaded = False # flag if all members have been read
Christian Heimesd8654cf2007-12-02 15:22:16 +00001547 self.offset = self.fileobj.tell()
1548 # current position in the archive file
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549 self.inodes = {} # dictionary caching the inodes of
1550 # archive members already added
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001551
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552 if self.mode == "r":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001553 self.firstmember = None
1554 self.firstmember = self.next()
1555
Guido van Rossumd8faa362007-04-27 19:54:29 +00001556 if self.mode == "a":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001557 # Move to the end of the archive,
1558 # before the first empty block.
1559 self.firstmember = None
1560 while True:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001561 if self.next() is None:
Thomas Wouterscf297e42007-02-23 15:07:44 +00001562 if self.offset > 0:
Lars Gustäbelb506dc32007-08-07 18:36:16 +00001563 self.fileobj.seek(self.fileobj.tell() - BLOCKSIZE)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001564 break
1565
Guido van Rossumd8faa362007-04-27 19:54:29 +00001566 if self.mode in "aw":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001567 self._loaded = True
1568
Guido van Rossume7ba4952007-06-06 23:52:48 +00001569 if self.pax_headers:
Lars Gustäbel3741eff2007-08-21 12:17:05 +00001570 buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy())
Guido van Rossumd8faa362007-04-27 19:54:29 +00001571 self.fileobj.write(buf)
1572 self.offset += len(buf)
1573
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001574 #--------------------------------------------------------------------------
1575 # Below are the classmethods which act as alternate constructors to the
1576 # TarFile class. The open() method is the only one that is needed for
1577 # public use; it is the "super"-constructor and is able to select an
1578 # adequate "sub"-constructor for a particular compression using the mapping
1579 # from OPEN_METH.
1580 #
1581 # This concept allows one to subclass TarFile without losing the comfort of
1582 # the super-constructor. A sub-constructor is registered and made available
1583 # by adding it to the mapping in OPEN_METH.
1584
Guido van Rossum75b64e62005-01-16 00:16:11 +00001585 @classmethod
Guido van Rossumd8faa362007-04-27 19:54:29 +00001586 def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001587 """Open a tar archive for reading, writing or appending. Return
1588 an appropriate TarFile class.
1589
1590 mode:
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001591 'r' or 'r:*' open for reading with transparent compression
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001592 'r:' open for reading exclusively uncompressed
1593 'r:gz' open for reading with gzip compression
1594 'r:bz2' open for reading with bzip2 compression
Thomas Wouterscf297e42007-02-23 15:07:44 +00001595 'a' or 'a:' open for appending, creating the file if necessary
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001596 'w' or 'w:' open for writing without compression
1597 'w:gz' open for writing with gzip compression
1598 'w:bz2' open for writing with bzip2 compression
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001599
1600 'r|*' open a stream of tar blocks with transparent compression
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001601 'r|' open an uncompressed stream of tar blocks for reading
1602 'r|gz' open a gzip compressed stream of tar blocks
1603 'r|bz2' open a bzip2 compressed stream of tar blocks
1604 'w|' open an uncompressed stream for writing
1605 'w|gz' open a gzip compressed stream for writing
1606 'w|bz2' open a bzip2 compressed stream for writing
1607 """
1608
1609 if not name and not fileobj:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610 raise ValueError("nothing to open")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001611
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001612 if mode in ("r", "r:*"):
1613 # Find out which *open() is appropriate for opening the file.
1614 for comptype in cls.OPEN_METH:
1615 func = getattr(cls, cls.OPEN_METH[comptype])
Thomas Wouters902d6eb2007-01-09 23:18:33 +00001616 if fileobj is not None:
1617 saved_pos = fileobj.tell()
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001618 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001619 return func(name, "r", fileobj, **kwargs)
1620 except (ReadError, CompressionError) as e:
Thomas Wouters902d6eb2007-01-09 23:18:33 +00001621 if fileobj is not None:
1622 fileobj.seek(saved_pos)
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001623 continue
Thomas Wouters477c8d52006-05-27 19:21:47 +00001624 raise ReadError("file could not be opened successfully")
Martin v. Löwis78be7df2005-03-05 12:47:42 +00001625
1626 elif ":" in mode:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001627 filemode, comptype = mode.split(":", 1)
1628 filemode = filemode or "r"
1629 comptype = comptype or "tar"
1630
1631 # Select the *open() function according to
1632 # given compression.
1633 if comptype in cls.OPEN_METH:
1634 func = getattr(cls, cls.OPEN_METH[comptype])
1635 else:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001636 raise CompressionError("unknown compression type %r" % comptype)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001637 return func(name, filemode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001638
1639 elif "|" in mode:
1640 filemode, comptype = mode.split("|", 1)
1641 filemode = filemode or "r"
1642 comptype = comptype or "tar"
1643
1644 if filemode not in "rw":
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645 raise ValueError("mode must be 'r' or 'w'")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001646
1647 t = cls(name, filemode,
Guido van Rossumd8faa362007-04-27 19:54:29 +00001648 _Stream(name, filemode, comptype, fileobj, bufsize),
1649 **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001650 t._extfileobj = False
1651 return t
1652
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001653 elif mode in "aw":
Guido van Rossumd8faa362007-04-27 19:54:29 +00001654 return cls.taropen(name, mode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001655
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656 raise ValueError("undiscernible mode")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001657
Guido van Rossum75b64e62005-01-16 00:16:11 +00001658 @classmethod
Guido van Rossumd8faa362007-04-27 19:54:29 +00001659 def taropen(cls, name, mode="r", fileobj=None, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001660 """Open uncompressed tar archive name for reading or writing.
1661 """
1662 if len(mode) > 1 or mode not in "raw":
Thomas Wouters477c8d52006-05-27 19:21:47 +00001663 raise ValueError("mode must be 'r', 'a' or 'w'")
Guido van Rossumd8faa362007-04-27 19:54:29 +00001664 return cls(name, mode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001665
Guido van Rossum75b64e62005-01-16 00:16:11 +00001666 @classmethod
Guido van Rossumd8faa362007-04-27 19:54:29 +00001667 def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001668 """Open gzip compressed tar archive name for reading or writing.
1669 Appending is not allowed.
1670 """
1671 if len(mode) > 1 or mode not in "rw":
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672 raise ValueError("mode must be 'r' or 'w'")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001673
1674 try:
1675 import gzip
Neal Norwitz4ec68242003-04-11 03:05:56 +00001676 gzip.GzipFile
1677 except (ImportError, AttributeError):
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678 raise CompressionError("gzip module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001679
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001680 if fileobj is None:
Guido van Rossume7ba4952007-06-06 23:52:48 +00001681 fileobj = bltn_open(name, mode + "b")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001682
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001683 try:
Thomas Wouters902d6eb2007-01-09 23:18:33 +00001684 t = cls.taropen(name, mode,
Guido van Rossumd8faa362007-04-27 19:54:29 +00001685 gzip.GzipFile(name, mode, compresslevel, fileobj),
1686 **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001687 except IOError:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001688 raise ReadError("not a gzip file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001689 t._extfileobj = False
1690 return t
1691
Guido van Rossum75b64e62005-01-16 00:16:11 +00001692 @classmethod
Guido van Rossumd8faa362007-04-27 19:54:29 +00001693 def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001694 """Open bzip2 compressed tar archive name for reading or writing.
1695 Appending is not allowed.
1696 """
1697 if len(mode) > 1 or mode not in "rw":
Thomas Wouters477c8d52006-05-27 19:21:47 +00001698 raise ValueError("mode must be 'r' or 'w'.")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001699
1700 try:
1701 import bz2
1702 except ImportError:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001703 raise CompressionError("bz2 module is not available")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001704
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001705 if fileobj is not None:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001706 fileobj = _BZ2Proxy(fileobj, mode)
1707 else:
1708 fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001709
1710 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001711 t = cls.taropen(name, mode, fileobj, **kwargs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001712 except IOError:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001713 raise ReadError("not a bzip2 file")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001714 t._extfileobj = False
1715 return t
1716
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001717 # All *open() methods are registered here.
1718 OPEN_METH = {
1719 "tar": "taropen", # uncompressed tar
1720 "gz": "gzopen", # gzip compressed tar
1721 "bz2": "bz2open" # bzip2 compressed tar
1722 }
1723
1724 #--------------------------------------------------------------------------
1725 # The public methods which TarFile provides:
1726
1727 def close(self):
1728 """Close the TarFile. In write-mode, two finishing zero blocks are
1729 appended to the archive.
1730 """
1731 if self.closed:
1732 return
1733
Guido van Rossumd8faa362007-04-27 19:54:29 +00001734 if self.mode in "aw":
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001735 self.fileobj.write(NUL * (BLOCKSIZE * 2))
1736 self.offset += (BLOCKSIZE * 2)
1737 # fill up the end with zero-blocks
1738 # (like option -b20 for tar does)
1739 blocks, remainder = divmod(self.offset, RECORDSIZE)
1740 if remainder > 0:
1741 self.fileobj.write(NUL * (RECORDSIZE - remainder))
1742
1743 if not self._extfileobj:
1744 self.fileobj.close()
1745 self.closed = True
1746
1747 def getmember(self, name):
1748 """Return a TarInfo object for member `name'. If `name' can not be
1749 found in the archive, KeyError is raised. If a member occurs more
Mark Dickinson934896d2009-02-21 20:59:32 +00001750 than once in the archive, its last occurrence is assumed to be the
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001751 most up-to-date version.
1752 """
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001753 tarinfo = self._getmember(name)
1754 if tarinfo is None:
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755 raise KeyError("filename %r not found" % name)
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001756 return tarinfo
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001757
1758 def getmembers(self):
1759 """Return the members of the archive as a list of TarInfo objects. The
1760 list has the same order as the members in the archive.
1761 """
1762 self._check()
1763 if not self._loaded: # if we want to obtain a list of
1764 self._load() # all members, we first have to
1765 # scan the whole archive.
1766 return self.members
1767
1768 def getnames(self):
1769 """Return the members of the archive as a list of their names. It has
1770 the same order as the list returned by getmembers().
1771 """
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001772 return [tarinfo.name for tarinfo in self.getmembers()]
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001773
1774 def gettarinfo(self, name=None, arcname=None, fileobj=None):
1775 """Create a TarInfo object for either the file `name' or the file
1776 object `fileobj' (using os.fstat on its file descriptor). You can
1777 modify some of the TarInfo's attributes before you add it using
1778 addfile(). If given, `arcname' specifies an alternative name for the
1779 file in the archive.
1780 """
1781 self._check("aw")
1782
1783 # When fileobj is given, replace name by
1784 # fileobj's real name.
1785 if fileobj is not None:
1786 name = fileobj.name
1787
1788 # Building the name of the member in the archive.
1789 # Backward slashes are converted to forward slashes,
1790 # Absolute paths are turned to relative paths.
1791 if arcname is None:
1792 arcname = name
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001793 drv, arcname = os.path.splitdrive(arcname)
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +00001794 arcname = arcname.replace(os.sep, "/")
1795 arcname = arcname.lstrip("/")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001796
1797 # Now, fill the TarInfo object with
1798 # information specific for the file.
Guido van Rossumd8faa362007-04-27 19:54:29 +00001799 tarinfo = self.tarinfo()
1800 tarinfo.tarfile = self
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001801
1802 # Use os.stat or os.lstat, depending on platform
1803 # and if symlinks shall be resolved.
1804 if fileobj is None:
1805 if hasattr(os, "lstat") and not self.dereference:
1806 statres = os.lstat(name)
1807 else:
1808 statres = os.stat(name)
1809 else:
1810 statres = os.fstat(fileobj.fileno())
1811 linkname = ""
1812
1813 stmd = statres.st_mode
1814 if stat.S_ISREG(stmd):
1815 inode = (statres.st_ino, statres.st_dev)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001816 if not self.dereference and statres.st_nlink > 1 and \
1817 inode in self.inodes and arcname != self.inodes[inode]:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001818 # Is it a hardlink to an already
1819 # archived file?
1820 type = LNKTYPE
1821 linkname = self.inodes[inode]
1822 else:
1823 # The inode is added only if its valid.
1824 # For win32 it is always 0.
1825 type = REGTYPE
1826 if inode[0]:
1827 self.inodes[inode] = arcname
1828 elif stat.S_ISDIR(stmd):
1829 type = DIRTYPE
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001830 elif stat.S_ISFIFO(stmd):
1831 type = FIFOTYPE
1832 elif stat.S_ISLNK(stmd):
1833 type = SYMTYPE
1834 linkname = os.readlink(name)
1835 elif stat.S_ISCHR(stmd):
1836 type = CHRTYPE
1837 elif stat.S_ISBLK(stmd):
1838 type = BLKTYPE
1839 else:
1840 return None
1841
1842 # Fill the TarInfo object with all
1843 # information we can get.
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001844 tarinfo.name = arcname
1845 tarinfo.mode = stmd
1846 tarinfo.uid = statres.st_uid
1847 tarinfo.gid = statres.st_gid
1848 if stat.S_ISREG(stmd):
Martin v. Löwis61d77e02004-08-20 06:35:46 +00001849 tarinfo.size = statres.st_size
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001850 else:
Guido van Rossume2a383d2007-01-15 16:59:06 +00001851 tarinfo.size = 0
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001852 tarinfo.mtime = statres.st_mtime
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001853 tarinfo.type = type
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001854 tarinfo.linkname = linkname
1855 if pwd:
1856 try:
1857 tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
1858 except KeyError:
1859 pass
1860 if grp:
1861 try:
1862 tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
1863 except KeyError:
1864 pass
1865
1866 if type in (CHRTYPE, BLKTYPE):
1867 if hasattr(os, "major") and hasattr(os, "minor"):
1868 tarinfo.devmajor = os.major(statres.st_rdev)
1869 tarinfo.devminor = os.minor(statres.st_rdev)
1870 return tarinfo
1871
1872 def list(self, verbose=True):
1873 """Print a table of contents to sys.stdout. If `verbose' is False, only
1874 the names of the members are printed. If it is True, an `ls -l'-like
1875 output is produced.
1876 """
1877 self._check()
1878
1879 for tarinfo in self:
1880 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001881 print(filemode(tarinfo.mode), end=' ')
1882 print("%s/%s" % (tarinfo.uname or tarinfo.uid,
1883 tarinfo.gname or tarinfo.gid), end=' ')
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001884 if tarinfo.ischr() or tarinfo.isblk():
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001885 print("%10s" % ("%d,%d" \
1886 % (tarinfo.devmajor, tarinfo.devminor)), end=' ')
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001887 else:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001888 print("%10d" % tarinfo.size, end=' ')
1889 print("%d-%02d-%02d %02d:%02d:%02d" \
1890 % time.localtime(tarinfo.mtime)[:6], end=' ')
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001891
Guido van Rossumd8faa362007-04-27 19:54:29 +00001892 print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ')
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001893
1894 if verbose:
1895 if tarinfo.issym():
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001896 print("->", tarinfo.linkname, end=' ')
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001897 if tarinfo.islnk():
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001898 print("link to", tarinfo.linkname, end=' ')
1899 print()
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001900
Lars Gustäbel049d2aa2009-09-12 10:44:00 +00001901 def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001902 """Add the file `name' to the archive. `name' may be any type of file
1903 (directory, fifo, symbolic link, etc.). If given, `arcname'
1904 specifies an alternative name for the file in the archive.
1905 Directories are added recursively by default. This can be avoided by
Guido van Rossum486364b2007-06-30 05:01:58 +00001906 setting `recursive' to False. `exclude' is a function that should
Lars Gustäbel049d2aa2009-09-12 10:44:00 +00001907 return True for each filename to be excluded. `filter' is a function
1908 that expects a TarInfo object argument and returns the changed
1909 TarInfo object, if it returns None the TarInfo object will be
1910 excluded from the archive.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001911 """
1912 self._check("aw")
1913
1914 if arcname is None:
1915 arcname = name
1916
Guido van Rossum486364b2007-06-30 05:01:58 +00001917 # Exclude pathnames.
Lars Gustäbel049d2aa2009-09-12 10:44:00 +00001918 if exclude is not None:
1919 import warnings
1920 warnings.warn("use the filter argument instead",
1921 DeprecationWarning, 2)
1922 if exclude(name):
1923 self._dbg(2, "tarfile: Excluded %r" % name)
1924 return
Guido van Rossum486364b2007-06-30 05:01:58 +00001925
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001926 # Skip if somebody tries to archive the archive...
Thomas Wouters902d6eb2007-01-09 23:18:33 +00001927 if self.name is not None and os.path.abspath(name) == self.name:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001928 self._dbg(2, "tarfile: Skipped %r" % name)
1929 return
1930
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001931 self._dbg(1, name)
1932
1933 # Create a TarInfo object from the file.
1934 tarinfo = self.gettarinfo(name, arcname)
1935
1936 if tarinfo is None:
1937 self._dbg(1, "tarfile: Unsupported type %r" % name)
1938 return
1939
Lars Gustäbel049d2aa2009-09-12 10:44:00 +00001940 # Change or exclude the TarInfo object.
1941 if filter is not None:
1942 tarinfo = filter(tarinfo)
1943 if tarinfo is None:
1944 self._dbg(2, "tarfile: Excluded %r" % name)
1945 return
1946
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001947 # Append the tar header and data to the archive.
1948 if tarinfo.isreg():
Guido van Rossume7ba4952007-06-06 23:52:48 +00001949 f = bltn_open(name, "rb")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001950 self.addfile(tarinfo, f)
1951 f.close()
1952
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001953 elif tarinfo.isdir():
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001954 self.addfile(tarinfo)
1955 if recursive:
1956 for f in os.listdir(name):
Lars Gustäbel049d2aa2009-09-12 10:44:00 +00001957 self.add(os.path.join(name, f), os.path.join(arcname, f),
1958 recursive, exclude, filter)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001959
Martin v. Löwis5dbdc592005-08-27 10:07:56 +00001960 else:
1961 self.addfile(tarinfo)
1962
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001963 def addfile(self, tarinfo, fileobj=None):
1964 """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
1965 given, tarinfo.size bytes are read from it and added to the archive.
1966 You can create TarInfo objects using gettarinfo().
1967 On Windows platforms, `fileobj' should always be opened with mode
1968 'rb' to avoid irritation about the file size.
1969 """
1970 self._check("aw")
1971
Thomas Wouters89f507f2006-12-13 04:49:30 +00001972 tarinfo = copy.copy(tarinfo)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001973
Guido van Rossume7ba4952007-06-06 23:52:48 +00001974 buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
Thomas Wouters89f507f2006-12-13 04:49:30 +00001975 self.fileobj.write(buf)
1976 self.offset += len(buf)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001977
1978 # If there's data to follow, append it.
1979 if fileobj is not None:
1980 copyfileobj(fileobj, self.fileobj, tarinfo.size)
1981 blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
1982 if remainder > 0:
1983 self.fileobj.write(NUL * (BLOCKSIZE - remainder))
1984 blocks += 1
1985 self.offset += blocks * BLOCKSIZE
1986
Martin v. Löwisf3c56112004-09-18 09:08:52 +00001987 self.members.append(tarinfo)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00001988
Martin v. Löwis00a73e72005-03-04 19:40:34 +00001989 def extractall(self, path=".", members=None):
1990 """Extract all members from the archive to the current working
1991 directory and set owner, modification time and permissions on
1992 directories afterwards. `path' specifies a different directory
1993 to extract to. `members' is optional and must be a subset of the
1994 list returned by getmembers().
1995 """
1996 directories = []
1997
1998 if members is None:
1999 members = self
2000
2001 for tarinfo in members:
2002 if tarinfo.isdir():
Christian Heimes2202f872008-02-06 14:31:34 +00002003 # Extract directories with a safe mode.
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002004 directories.append(tarinfo)
Christian Heimes2202f872008-02-06 14:31:34 +00002005 tarinfo = copy.copy(tarinfo)
2006 tarinfo.mode = 0o700
2007 self.extract(tarinfo, path)
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002008
2009 # Reverse sort directories.
Raymond Hettingerd4cb56d2008-01-30 02:55:10 +00002010 directories.sort(key=lambda a: a.name)
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002011 directories.reverse()
2012
2013 # Set correct owner, mtime and filemode on directories.
2014 for tarinfo in directories:
Christian Heimesfaf2f632008-01-06 16:59:19 +00002015 dirpath = os.path.join(path, tarinfo.name)
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002016 try:
Christian Heimesfaf2f632008-01-06 16:59:19 +00002017 self.chown(tarinfo, dirpath)
2018 self.utime(tarinfo, dirpath)
2019 self.chmod(tarinfo, dirpath)
Guido van Rossumb940e112007-01-10 16:19:56 +00002020 except ExtractError as e:
Martin v. Löwis00a73e72005-03-04 19:40:34 +00002021 if self.errorlevel > 1:
2022 raise
2023 else:
2024 self._dbg(1, "tarfile: %s" % e)
2025
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002026 def extract(self, member, path=""):
2027 """Extract a member from the archive to the current working directory,
2028 using its full name. Its file information is extracted as accurately
2029 as possible. `member' may be a filename or a TarInfo object. You can
2030 specify a different directory using `path'.
2031 """
2032 self._check("r")
2033
Guido van Rossum3172c5d2007-10-16 18:12:55 +00002034 if isinstance(member, str):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002035 tarinfo = self.getmember(member)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002036 else:
2037 tarinfo = member
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002038
Neal Norwitza4f651a2004-07-20 22:07:44 +00002039 # Prepare the link target for makelink().
2040 if tarinfo.islnk():
2041 tarinfo._link_target = os.path.join(path, tarinfo.linkname)
2042
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002043 try:
2044 self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
Guido van Rossumb940e112007-01-10 16:19:56 +00002045 except EnvironmentError as e:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002046 if self.errorlevel > 0:
2047 raise
2048 else:
2049 if e.filename is None:
2050 self._dbg(1, "tarfile: %s" % e.strerror)
2051 else:
2052 self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
Guido van Rossumb940e112007-01-10 16:19:56 +00002053 except ExtractError as e:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002054 if self.errorlevel > 1:
2055 raise
2056 else:
2057 self._dbg(1, "tarfile: %s" % e)
2058
2059 def extractfile(self, member):
2060 """Extract a member from the archive as a file object. `member' may be
2061 a filename or a TarInfo object. If `member' is a regular file, a
2062 file-like object is returned. If `member' is a link, a file-like
2063 object is constructed from the link's target. If `member' is none of
2064 the above, None is returned.
2065 The file-like object is read-only and provides the following
2066 methods: read(), readline(), readlines(), seek() and tell()
2067 """
2068 self._check("r")
2069
Guido van Rossum3172c5d2007-10-16 18:12:55 +00002070 if isinstance(member, str):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002071 tarinfo = self.getmember(member)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002072 else:
2073 tarinfo = member
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002074
2075 if tarinfo.isreg():
2076 return self.fileobject(self, tarinfo)
2077
2078 elif tarinfo.type not in SUPPORTED_TYPES:
2079 # If a member's type is unknown, it is treated as a
2080 # regular file.
2081 return self.fileobject(self, tarinfo)
2082
2083 elif tarinfo.islnk() or tarinfo.issym():
2084 if isinstance(self.fileobj, _Stream):
2085 # A small but ugly workaround for the case that someone tries
2086 # to extract a (sym)link as a file-object from a non-seekable
2087 # stream of tar blocks.
Thomas Wouters477c8d52006-05-27 19:21:47 +00002088 raise StreamError("cannot extract (sym)link as file object")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002089 else:
Georg Brandl7eb4b7d2005-07-22 21:49:32 +00002090 # A (sym)link's file object is its target's file object.
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002091 return self.extractfile(self._getmember(tarinfo.linkname,
2092 tarinfo))
2093 else:
2094 # If there's no data associated with the member (directory, chrdev,
2095 # blkdev, etc.), return None instead of a file object.
2096 return None
2097
2098 def _extract_member(self, tarinfo, targetpath):
2099 """Extract the TarInfo object tarinfo to a physical
2100 file called targetpath.
2101 """
2102 # Fetch the TarInfo object for the given name
2103 # and build the destination pathname, replacing
2104 # forward slashes to platform specific separators.
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +00002105 targetpath = targetpath.rstrip("/")
2106 targetpath = targetpath.replace("/", os.sep)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002107
2108 # Create all upper directories.
2109 upperdirs = os.path.dirname(targetpath)
2110 if upperdirs and not os.path.exists(upperdirs):
Christian Heimes2202f872008-02-06 14:31:34 +00002111 # Create directories that are not part of the archive with
2112 # default permissions.
Thomas Woutersb2137042007-02-01 18:02:27 +00002113 os.makedirs(upperdirs)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002114
2115 if tarinfo.islnk() or tarinfo.issym():
2116 self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
2117 else:
2118 self._dbg(1, tarinfo.name)
2119
2120 if tarinfo.isreg():
2121 self.makefile(tarinfo, targetpath)
2122 elif tarinfo.isdir():
2123 self.makedir(tarinfo, targetpath)
2124 elif tarinfo.isfifo():
2125 self.makefifo(tarinfo, targetpath)
2126 elif tarinfo.ischr() or tarinfo.isblk():
2127 self.makedev(tarinfo, targetpath)
2128 elif tarinfo.islnk() or tarinfo.issym():
2129 self.makelink(tarinfo, targetpath)
2130 elif tarinfo.type not in SUPPORTED_TYPES:
2131 self.makeunknown(tarinfo, targetpath)
2132 else:
2133 self.makefile(tarinfo, targetpath)
2134
2135 self.chown(tarinfo, targetpath)
2136 if not tarinfo.issym():
2137 self.chmod(tarinfo, targetpath)
2138 self.utime(tarinfo, targetpath)
2139
2140 #--------------------------------------------------------------------------
2141 # Below are the different file methods. They are called via
2142 # _extract_member() when extract() is called. They can be replaced in a
2143 # subclass to implement other functionality.
2144
2145 def makedir(self, tarinfo, targetpath):
2146 """Make a directory called targetpath.
2147 """
2148 try:
Christian Heimes2202f872008-02-06 14:31:34 +00002149 # Use a safe mode for the directory, the real mode is set
2150 # later in _extract_member().
2151 os.mkdir(targetpath, 0o700)
Guido van Rossumb940e112007-01-10 16:19:56 +00002152 except EnvironmentError as e:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002153 if e.errno != errno.EEXIST:
2154 raise
2155
2156 def makefile(self, tarinfo, targetpath):
2157 """Make a file called targetpath.
2158 """
2159 source = self.extractfile(tarinfo)
Guido van Rossume7ba4952007-06-06 23:52:48 +00002160 target = bltn_open(targetpath, "wb")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002161 copyfileobj(source, target)
2162 source.close()
2163 target.close()
2164
2165 def makeunknown(self, tarinfo, targetpath):
2166 """Make a file from a TarInfo object with an unknown type
2167 at targetpath.
2168 """
2169 self.makefile(tarinfo, targetpath)
2170 self._dbg(1, "tarfile: Unknown file type %r, " \
2171 "extracted as regular file." % tarinfo.type)
2172
2173 def makefifo(self, tarinfo, targetpath):
2174 """Make a fifo called targetpath.
2175 """
2176 if hasattr(os, "mkfifo"):
2177 os.mkfifo(targetpath)
2178 else:
Thomas Wouters477c8d52006-05-27 19:21:47 +00002179 raise ExtractError("fifo not supported by system")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002180
2181 def makedev(self, tarinfo, targetpath):
2182 """Make a character or block device called targetpath.
2183 """
2184 if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
Thomas Wouters477c8d52006-05-27 19:21:47 +00002185 raise ExtractError("special devices not supported by system")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002186
2187 mode = tarinfo.mode
2188 if tarinfo.isblk():
2189 mode |= stat.S_IFBLK
2190 else:
2191 mode |= stat.S_IFCHR
2192
2193 os.mknod(targetpath, mode,
2194 os.makedev(tarinfo.devmajor, tarinfo.devminor))
2195
2196 def makelink(self, tarinfo, targetpath):
2197 """Make a (symbolic) link called targetpath. If it cannot be created
2198 (platform limitation), we try to make a copy of the referenced file
2199 instead of a link.
2200 """
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002201 try:
2202 if tarinfo.issym():
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +00002203 os.symlink(tarinfo.linkname, targetpath)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002204 else:
Neal Norwitza4f651a2004-07-20 22:07:44 +00002205 # See extract().
2206 os.link(tarinfo._link_target, targetpath)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002207 except AttributeError:
2208 if tarinfo.issym():
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +00002209 linkpath = os.path.dirname(tarinfo.name) + "/" + \
2210 tarinfo.linkname
2211 else:
2212 linkpath = tarinfo.linkname
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002213
2214 try:
2215 self._extract_member(self.getmember(linkpath), targetpath)
Guido van Rossumb940e112007-01-10 16:19:56 +00002216 except (EnvironmentError, KeyError) as e:
Lars Gustäbelbfdfdda2009-08-28 19:59:59 +00002217 linkpath = linkpath.replace("/", os.sep)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002218 try:
2219 shutil.copy2(linkpath, targetpath)
Guido van Rossumb940e112007-01-10 16:19:56 +00002220 except EnvironmentError as e:
Thomas Wouters477c8d52006-05-27 19:21:47 +00002221 raise IOError("link could not be created")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002222
2223 def chown(self, tarinfo, targetpath):
2224 """Set owner of targetpath according to tarinfo.
2225 """
2226 if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
2227 # We have to be root to do so.
2228 try:
2229 g = grp.getgrnam(tarinfo.gname)[2]
2230 except KeyError:
2231 try:
2232 g = grp.getgrgid(tarinfo.gid)[2]
2233 except KeyError:
2234 g = os.getgid()
2235 try:
2236 u = pwd.getpwnam(tarinfo.uname)[2]
2237 except KeyError:
2238 try:
2239 u = pwd.getpwuid(tarinfo.uid)[2]
2240 except KeyError:
2241 u = os.getuid()
2242 try:
2243 if tarinfo.issym() and hasattr(os, "lchown"):
2244 os.lchown(targetpath, u, g)
2245 else:
Andrew MacIntyre7970d202003-02-19 12:51:34 +00002246 if sys.platform != "os2emx":
2247 os.chown(targetpath, u, g)
Guido van Rossumb940e112007-01-10 16:19:56 +00002248 except EnvironmentError as e:
Thomas Wouters477c8d52006-05-27 19:21:47 +00002249 raise ExtractError("could not change owner")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002250
2251 def chmod(self, tarinfo, targetpath):
2252 """Set file permissions of targetpath according to tarinfo.
2253 """
Jack Jansen834eff62003-03-07 12:47:06 +00002254 if hasattr(os, 'chmod'):
2255 try:
2256 os.chmod(targetpath, tarinfo.mode)
Guido van Rossumb940e112007-01-10 16:19:56 +00002257 except EnvironmentError as e:
Thomas Wouters477c8d52006-05-27 19:21:47 +00002258 raise ExtractError("could not change mode")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002259
2260 def utime(self, tarinfo, targetpath):
2261 """Set modification time of targetpath according to tarinfo.
2262 """
Jack Jansen834eff62003-03-07 12:47:06 +00002263 if not hasattr(os, 'utime'):
Tim Petersf9347782003-03-07 15:36:41 +00002264 return
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002265 try:
2266 os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
Guido van Rossumb940e112007-01-10 16:19:56 +00002267 except EnvironmentError as e:
Thomas Wouters477c8d52006-05-27 19:21:47 +00002268 raise ExtractError("could not change modification time")
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002269
2270 #--------------------------------------------------------------------------
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002271 def next(self):
2272 """Return the next member of the archive as a TarInfo object, when
2273 TarFile is opened for reading. Return None if there is no more
2274 available.
2275 """
2276 self._check("ra")
2277 if self.firstmember is not None:
2278 m = self.firstmember
2279 self.firstmember = None
2280 return m
2281
2282 # Read the next block.
Andrew M. Kuchling864bba12004-07-10 22:02:11 +00002283 self.fileobj.seek(self.offset)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002284 while True:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002285 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +00002286 tarinfo = self.tarinfo.fromtarfile(self)
2287 if tarinfo is None:
2288 return
2289 self.members.append(tarinfo)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002290
Guido van Rossumb940e112007-01-10 16:19:56 +00002291 except HeaderError as e:
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002292 if self.ignore_zeros:
Thomas Wouters902d6eb2007-01-09 23:18:33 +00002293 self._dbg(2, "0x%X: %s" % (self.offset, e))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002294 self.offset += BLOCKSIZE
2295 continue
2296 else:
Andrew M. Kuchling864bba12004-07-10 22:02:11 +00002297 if self.offset == 0:
Thomas Wouters902d6eb2007-01-09 23:18:33 +00002298 raise ReadError(str(e))
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002299 return None
2300 break
2301
Thomas Wouters477c8d52006-05-27 19:21:47 +00002302 return tarinfo
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002303
2304 #--------------------------------------------------------------------------
2305 # Little helper methods:
2306
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002307 def _getmember(self, name, tarinfo=None):
2308 """Find an archive member by name from bottom to top.
2309 If tarinfo is given, it is used as the starting point.
2310 """
Martin v. Löwisf3c56112004-09-18 09:08:52 +00002311 # Ensure that all members have been loaded.
2312 members = self.getmembers()
2313
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002314 if tarinfo is None:
Martin v. Löwisf3c56112004-09-18 09:08:52 +00002315 end = len(members)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002316 else:
Martin v. Löwisf3c56112004-09-18 09:08:52 +00002317 end = members.index(tarinfo)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002318
Guido van Rossum805365e2007-05-07 22:24:25 +00002319 for i in range(end - 1, -1, -1):
Martin v. Löwisf3c56112004-09-18 09:08:52 +00002320 if name == members[i].name:
2321 return members[i]
Andrew M. Kuchling864bba12004-07-10 22:02:11 +00002322
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002323 def _load(self):
2324 """Read through the entire archive file and look for readable
2325 members.
2326 """
2327 while True:
2328 tarinfo = self.next()
2329 if tarinfo is None:
2330 break
2331 self._loaded = True
2332
2333 def _check(self, mode=None):
2334 """Check if TarFile is still open, and if the operation's mode
2335 corresponds to TarFile's mode.
2336 """
2337 if self.closed:
Thomas Wouters477c8d52006-05-27 19:21:47 +00002338 raise IOError("%s is closed" % self.__class__.__name__)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002339 if mode is not None and self.mode not in mode:
2340 raise IOError("bad operation for mode %r" % self.mode)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002341
2342 def __iter__(self):
2343 """Provide an iterator object.
2344 """
2345 if self._loaded:
2346 return iter(self.members)
2347 else:
2348 return TarIter(self)
2349
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002350 def _dbg(self, level, msg):
2351 """Write debugging output to sys.stderr.
2352 """
2353 if level <= self.debug:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00002354 print(msg, file=sys.stderr)
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002355# class TarFile
2356
2357class TarIter:
2358 """Iterator Class.
2359
2360 for tarinfo in TarFile(...):
2361 suite...
2362 """
2363
2364 def __init__(self, tarfile):
2365 """Construct a TarIter object.
2366 """
2367 self.tarfile = tarfile
Martin v. Löwis637431b2005-03-03 23:12:42 +00002368 self.index = 0
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002369 def __iter__(self):
2370 """Return iterator object.
2371 """
2372 return self
Georg Brandla18af4e2007-04-21 15:47:16 +00002373 def __next__(self):
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002374 """Return the next item using TarFile's next() method.
2375 When all members have been read, set TarFile as _loaded.
2376 """
Martin v. Löwis637431b2005-03-03 23:12:42 +00002377 # Fix for SF #1100429: Under rare circumstances it can
2378 # happen that getmembers() is called during iteration,
2379 # which will cause TarIter to stop prematurely.
2380 if not self.tarfile._loaded:
2381 tarinfo = self.tarfile.next()
2382 if not tarinfo:
2383 self.tarfile._loaded = True
2384 raise StopIteration
2385 else:
2386 try:
2387 tarinfo = self.tarfile.members[self.index]
2388 except IndexError:
2389 raise StopIteration
2390 self.index += 1
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002391 return tarinfo
2392
2393# Helper classes for sparse file support
2394class _section:
2395 """Base class for _data and _hole.
2396 """
2397 def __init__(self, offset, size):
2398 self.offset = offset
2399 self.size = size
2400 def __contains__(self, offset):
2401 return self.offset <= offset < self.offset + self.size
2402
2403class _data(_section):
2404 """Represent a data section in a sparse file.
2405 """
2406 def __init__(self, offset, size, realpos):
2407 _section.__init__(self, offset, size)
2408 self.realpos = realpos
2409
2410class _hole(_section):
2411 """Represent a hole section in a sparse file.
2412 """
2413 pass
2414
2415class _ringbuffer(list):
2416 """Ringbuffer class which increases performance
2417 over a regular list.
2418 """
2419 def __init__(self):
2420 self.idx = 0
2421 def find(self, offset):
2422 idx = self.idx
2423 while True:
2424 item = self[idx]
2425 if offset in item:
2426 break
2427 idx += 1
2428 if idx == len(self):
2429 idx = 0
2430 if idx == self.idx:
2431 # End of File
2432 return None
2433 self.idx = idx
2434 return item
2435
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002436#--------------------
2437# exported functions
2438#--------------------
2439def is_tarfile(name):
2440 """Return True if name points to a tar archive that we
2441 are able to handle, else return False.
2442 """
2443 try:
2444 t = open(name)
2445 t.close()
2446 return True
2447 except TarError:
2448 return False
2449
Guido van Rossume7ba4952007-06-06 23:52:48 +00002450bltn_open = open
Neal Norwitzb9ef4ae2003-01-05 23:19:43 +00002451open = TarFile.open