annotate Lib/tarfile.py @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents ea4bdf5a2e69
children 9b86fb6f5bc9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1 #!/usr/bin/env python
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2 # -*- coding: iso-8859-1 -*-
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
3 #-------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
4 # tarfile.py
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
5 #-------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
6 # Copyright (C) 2002 Lars Gustäbel <lars@gustaebel.de>
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
7 # All rights reserved.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
8 #
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
9 # Permission is hereby granted, free of charge, to any person
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
10 # obtaining a copy of this software and associated documentation
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
11 # files (the "Software"), to deal in the Software without
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
12 # restriction, including without limitation the rights to use,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
13 # copy, modify, merge, publish, distribute, sublicense, and/or sell
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
14 # copies of the Software, and to permit persons to whom the
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
15 # Software is furnished to do so, subject to the following
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
16 # conditions:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
17 #
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
18 # The above copyright notice and this permission notice shall be
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
19 # included in all copies or substantial portions of the Software.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
20 #
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
21 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
22 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
23 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
24 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
25 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
26 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
27 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
28 # OTHER DEALINGS IN THE SOFTWARE.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
29 #
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
30 """Read from and write to tar format archives.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
31 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
32
71539
f15442543e24 Fix closes Issue11439 - Handle the SVN Keywords in 2.7 by replacing them with a high number so that code relying on them does not break.
Senthil Kumaran <senthil@uthcode.com>
parents: 70166
diff changeset
33 __version__ = "$Revision: 85213 $"
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
34 # $Source$
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
35
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
36 version = "0.9.0"
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
37 __author__ = "Lars Gustäbel (lars@gustaebel.de)"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
38 __date__ = "$Date$"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
39 __cvsid__ = "$Id$"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
40 __credits__ = "Gustavo Niemeyer, Niels Gustäbel, Richard Townsend."
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
41
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
42 #---------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
43 # Imports
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
44 #---------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
45 import sys
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
46 import os
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
47 import shutil
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
48 import stat
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
49 import errno
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
50 import time
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
51 import struct
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
52 import copy
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
53 import re
48175
979f0a89903f Remove a dict.has_key() and list.sort(cmp=) usage from tarfile to silence
Brett Cannon <bcannon@gmail.com>
parents: 48138
diff changeset
54 import operator
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
55
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
56 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
57 import grp, pwd
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
58 except ImportError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
59 grp = pwd = None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
60
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
61 # from tarfile import *
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
62 __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
63
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
64 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
65 # tar constants
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
66 #---------------------------------------------------------
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
67 NUL = "\0" # the null character
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
68 BLOCKSIZE = 512 # length of processing blocks
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
69 RECORDSIZE = BLOCKSIZE * 20 # length of records
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
70 GNU_MAGIC = "ustar \0" # magic gnu tar string
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
71 POSIX_MAGIC = "ustar\x0000" # magic posix tar string
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
72
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
73 LENGTH_NAME = 100 # maximum length of a filename
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
74 LENGTH_LINK = 100 # maximum length of a linkname
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
75 LENGTH_PREFIX = 155 # maximum length of the prefix field
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
76
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
77 REGTYPE = "0" # regular file
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
78 AREGTYPE = "\0" # regular file
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
79 LNKTYPE = "1" # link (inside tarfile)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
80 SYMTYPE = "2" # symbolic link
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
81 CHRTYPE = "3" # character special device
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
82 BLKTYPE = "4" # block special device
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
83 DIRTYPE = "5" # directory
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
84 FIFOTYPE = "6" # fifo special device
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
85 CONTTYPE = "7" # contiguous file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
86
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
87 GNUTYPE_LONGNAME = "L" # GNU tar longname
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
88 GNUTYPE_LONGLINK = "K" # GNU tar longlink
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
89 GNUTYPE_SPARSE = "S" # GNU tar sparse file
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
90
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
91 XHDTYPE = "x" # POSIX.1-2001 extended header
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
92 XGLTYPE = "g" # POSIX.1-2001 global header
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
93 SOLARIS_XHDTYPE = "X" # Solaris extended header
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
94
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
95 USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
96 GNU_FORMAT = 1 # GNU tar format
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
97 PAX_FORMAT = 2 # POSIX.1-2001 (pax) format
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
98 DEFAULT_FORMAT = GNU_FORMAT
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
99
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
100 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
101 # tarfile constants
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
102 #---------------------------------------------------------
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
103 # File types that tarfile supports:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
104 SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
105 SYMTYPE, DIRTYPE, FIFOTYPE,
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
106 CONTTYPE, CHRTYPE, BLKTYPE,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
107 GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
108 GNUTYPE_SPARSE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
109
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
110 # File types that will be treated as a regular file.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
111 REGULAR_TYPES = (REGTYPE, AREGTYPE,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
112 CONTTYPE, GNUTYPE_SPARSE)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
113
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
114 # File types that are part of the GNU tar format.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
115 GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
116 GNUTYPE_SPARSE)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
117
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
118 # Fields from a pax header that override a TarInfo attribute.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
119 PAX_FIELDS = ("path", "linkpath", "size", "mtime",
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
120 "uid", "gid", "uname", "gname")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
121
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
122 # Fields in a pax header that are numbers, all other fields
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
123 # are treated as strings.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
124 PAX_NUMBER_FIELDS = {
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
125 "atime": float,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
126 "ctime": float,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
127 "mtime": float,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
128 "uid": int,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
129 "gid": int,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
130 "size": int
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
131 }
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
132
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
133 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
134 # Bits used in the mode field, values in octal.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
135 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
136 S_IFLNK = 0120000 # symbolic link
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
137 S_IFREG = 0100000 # regular file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
138 S_IFBLK = 0060000 # block device
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
139 S_IFDIR = 0040000 # directory
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
140 S_IFCHR = 0020000 # character device
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
141 S_IFIFO = 0010000 # fifo
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
142
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
143 TSUID = 04000 # set UID on execution
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
144 TSGID = 02000 # set GID on execution
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
145 TSVTX = 01000 # reserved
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
146
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
147 TUREAD = 0400 # read by owner
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
148 TUWRITE = 0200 # write by owner
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
149 TUEXEC = 0100 # execute/search by owner
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
150 TGREAD = 0040 # read by group
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
151 TGWRITE = 0020 # write by group
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
152 TGEXEC = 0010 # execute/search by group
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
153 TOREAD = 0004 # read by other
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
154 TOWRITE = 0002 # write by other
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
155 TOEXEC = 0001 # execute/search by other
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
156
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
157 #---------------------------------------------------------
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
158 # initialization
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
159 #---------------------------------------------------------
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
160 ENCODING = sys.getfilesystemencoding()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
161 if ENCODING is None:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
162 ENCODING = sys.getdefaultencoding()
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
163
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
164 #---------------------------------------------------------
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
165 # Some useful functions
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
166 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
167
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
168 def stn(s, length):
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
169 """Convert a python string to a null-terminated string buffer.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
170 """
40170
e82e696c03dc Patch [ 1583506 ] tarfile.py: 100-char filenames are truncated
Georg Brandl <georg@python.org>
parents: 40111
diff changeset
171 return s[:length] + (length - len(s)) * NUL
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
172
45282
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
173 def nts(s):
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
174 """Convert a null-terminated string field to a python string.
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
175 """
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
176 # Use the string up to the first null char.
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
177 p = s.find("\0")
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
178 if p == -1:
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
179 return s
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
180 return s[:p]
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
181
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
182 def nti(s):
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
183 """Convert a number field to a python number.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
184 """
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
185 # There are two possible encodings for a number field, see
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
186 # itn() below.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
187 if s[0] != chr(0200):
40491
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
188 try:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
189 n = int(nts(s) or "0", 8)
40491
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
190 except ValueError:
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
191 raise InvalidHeaderError("invalid header")
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
192 else:
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
193 n = 0L
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
194 for i in xrange(len(s) - 1):
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
195 n <<= 8
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
196 n += ord(s[i + 1])
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
197 return n
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
198
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
199 def itn(n, digits=8, format=DEFAULT_FORMAT):
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
200 """Convert a python number to a number field.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
201 """
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
202 # POSIX 1003.1-1988 requires numbers to be encoded as a string of
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
203 # octal digits followed by a null-byte, this allows values up to
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
204 # (8**(digits-1))-1. GNU tar allows storing numbers greater than
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
205 # that if necessary. A leading 0200 byte indicates this particular
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
206 # encoding, the following digits-1 bytes are a big-endian
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
207 # representation. This allows values up to (256**(digits-1))-1.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
208 if 0 <= n < 8 ** (digits - 1):
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
209 s = "%0*o" % (digits - 1, n) + NUL
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
210 else:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
211 if format != GNU_FORMAT or n >= 256 ** (digits - 1):
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
212 raise ValueError("overflow in number field")
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
213
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
214 if n < 0:
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
215 # XXX We mimic GNU tar's behaviour with negative numbers,
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
216 # this could raise OverflowError.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
217 n = struct.unpack("L", struct.pack("l", n))[0]
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
218
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
219 s = ""
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
220 for i in xrange(digits - 1):
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
221 s = chr(n & 0377) + s
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
222 n >>= 8
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
223 s = chr(0200) + s
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
224 return s
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
225
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
226 def uts(s, encoding, errors):
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
227 """Convert a unicode object to a string.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
228 """
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
229 if errors == "utf-8":
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
230 # An extra error handler similar to the -o invalid=UTF-8 option
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
231 # in POSIX.1-2001. Replace untranslatable characters with their
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
232 # UTF-8 representation.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
233 try:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
234 return s.encode(encoding, "strict")
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
235 except UnicodeEncodeError:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
236 x = []
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
237 for c in s:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
238 try:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
239 x.append(c.encode(encoding, "strict"))
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
240 except UnicodeEncodeError:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
241 x.append(c.encode("utf8"))
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
242 return "".join(x)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
243 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
244 return s.encode(encoding, errors)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
245
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
246 def calc_chksums(buf):
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
247 """Calculate the checksum for a member's header by summing up all
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
248 characters except for the chksum field which is treated as if
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
249 it was filled with spaces. According to the GNU tar sources,
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
250 some tars (Sun and NeXT) calculate chksum with signed char,
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
251 which will be different if there are chars in the buffer with
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
252 the high bit set. So we calculate two checksums, unsigned and
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
253 signed.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
254 """
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
255 unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512]))
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
256 signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512]))
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
257 return unsigned_chksum, signed_chksum
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
258
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
259 def copyfileobj(src, dst, length=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
260 """Copy length bytes from fileobj src to fileobj dst.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
261 If length is None, copy the entire content.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
262 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
263 if length == 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
264 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
265 if length is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
266 shutil.copyfileobj(src, dst)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
267 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
268
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
269 BUFSIZE = 16 * 1024
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
270 blocks, remainder = divmod(length, BUFSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
271 for b in xrange(blocks):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
272 buf = src.read(BUFSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
273 if len(buf) < BUFSIZE:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
274 raise IOError("end of file reached")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
275 dst.write(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
276
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
277 if remainder != 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
278 buf = src.read(remainder)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
279 if len(buf) < remainder:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
280 raise IOError("end of file reached")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
281 dst.write(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
282 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
283
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
284 filemode_table = (
33810
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
285 ((S_IFLNK, "l"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
286 (S_IFREG, "-"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
287 (S_IFBLK, "b"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
288 (S_IFDIR, "d"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
289 (S_IFCHR, "c"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
290 (S_IFIFO, "p")),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
291
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
292 ((TUREAD, "r"),),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
293 ((TUWRITE, "w"),),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
294 ((TUEXEC|TSUID, "s"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
295 (TSUID, "S"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
296 (TUEXEC, "x")),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
297
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
298 ((TGREAD, "r"),),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
299 ((TGWRITE, "w"),),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
300 ((TGEXEC|TSGID, "s"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
301 (TSGID, "S"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
302 (TGEXEC, "x")),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
303
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
304 ((TOREAD, "r"),),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
305 ((TOWRITE, "w"),),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
306 ((TOEXEC|TSVTX, "t"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
307 (TSVTX, "T"),
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
308 (TOEXEC, "x"))
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
309 )
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
310
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
311 def filemode(mode):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
312 """Convert a file's mode to a string of the form
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
313 -rwxrwxrwx.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
314 Used by TarFile.list()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
315 """
33810
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
316 perm = []
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
317 for table in filemode_table:
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
318 for bit, char in table:
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
319 if mode & bit == bit:
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
320 perm.append(char)
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
321 break
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
322 else:
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
323 perm.append("-")
3ff252715d93 [Patch #1043972, for bug #1017553] filemode() returns an incorrect value for the mode 07111
Andrew M. Kuchling <amk@amk.ca>
parents: 33507
diff changeset
324 return "".join(perm)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
325
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
326 class TarError(Exception):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
327 """Base exception."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
328 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
329 class ExtractError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
330 """General exception for extract errors."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
331 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
332 class ReadError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
333 """Exception for unreadble tar archives."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
334 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
335 class CompressionError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
336 """Exception for unavailable compression methods."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
337 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
338 class StreamError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
339 """Exception for unsupported operations on stream-like TarFiles."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
340 pass
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
341 class HeaderError(TarError):
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
342 """Base exception for header errors."""
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
343 pass
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
344 class EmptyHeaderError(HeaderError):
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
345 """Exception for empty headers."""
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
346 pass
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
347 class TruncatedHeaderError(HeaderError):
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
348 """Exception for truncated headers."""
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
349 pass
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
350 class EOFHeaderError(HeaderError):
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
351 """Exception for end of file headers."""
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
352 pass
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
353 class InvalidHeaderError(HeaderError):
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
354 """Exception for invalid headers."""
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
355 pass
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
356 class SubsequentHeaderError(HeaderError):
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
357 """Exception for missing and invalid extended headers."""
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
358 pass
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
359
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
360 #---------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
361 # internal stream interface
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
362 #---------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
363 class _LowLevelFile:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
364 """Low-level file object. Supports reading and writing.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
365 It is used instead of a regular file object for streaming
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
366 access.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
367 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
368
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
369 def __init__(self, name, mode):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
370 mode = {
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
371 "r": os.O_RDONLY,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
372 "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
373 }[mode]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
374 if hasattr(os, "O_BINARY"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
375 mode |= os.O_BINARY
61090
6cda601f4c58 Merged revisions 80616 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 57337
diff changeset
376 self.fd = os.open(name, mode, 0666)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
377
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
378 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
379 os.close(self.fd)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
380
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
381 def read(self, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
382 return os.read(self.fd, size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
383
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
384 def write(self, s):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
385 os.write(self.fd, s)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
386
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
387 class _Stream:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
388 """Class that serves as an adapter between TarFile and
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
389 a stream-like object. The stream-like object only
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
390 needs to have a read() or write() method and is accessed
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
391 blockwise. Use of gzip or bzip2 compression is possible.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
392 A stream-like object could be for example: sys.stdin,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
393 sys.stdout, a socket, a tape device etc.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
394
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
395 _Stream is intended to be used only internally.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
396 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
397
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
398 def __init__(self, name, mode, comptype, fileobj, bufsize):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
399 """Construct a _Stream object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
400 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
401 self._extfileobj = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
402 if fileobj is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
403 fileobj = _LowLevelFile(name, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
404 self._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
405
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
406 if comptype == '*':
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
407 # Enable transparent compression detection for the
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
408 # stream interface
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
409 fileobj = _StreamProxy(fileobj)
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
410 comptype = fileobj.getcomptype()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
411
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
412 self.name = name or ""
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
413 self.mode = mode
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
414 self.comptype = comptype
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
415 self.fileobj = fileobj
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
416 self.bufsize = bufsize
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
417 self.buf = ""
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
418 self.pos = 0L
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
419 self.closed = False
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
420
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
421 if comptype == "gz":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
422 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
423 import zlib
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
424 except ImportError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
425 raise CompressionError("zlib module is not available")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
426 self.zlib = zlib
46063
ce45fd3a7a3f A stab in the dark attempt to fix the alpha/tru64 buildbot problem and add more
Gregory P. Smith <greg@mad-scientist.com>
parents: 45164
diff changeset
427 self.crc = zlib.crc32("") & 0xffffffffL
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
428 if mode == "r":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
429 self._init_read_gz()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
430 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
431 self._init_write_gz()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
432
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
433 if comptype == "bz2":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
434 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
435 import bz2
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
436 except ImportError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
437 raise CompressionError("bz2 module is not available")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
438 if mode == "r":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
439 self.dbuf = ""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
440 self.cmp = bz2.BZ2Decompressor()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
441 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
442 self.cmp = bz2.BZ2Compressor()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
443
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
444 def __del__(self):
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
445 if hasattr(self, "closed") and not self.closed:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
446 self.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
447
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
448 def _init_write_gz(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
449 """Initialize for writing with gzip compression.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
450 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
451 self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
452 -self.zlib.MAX_WBITS,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
453 self.zlib.DEF_MEM_LEVEL,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
454 0)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
455 timestamp = struct.pack("<L", long(time.time()))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
456 self.__write("\037\213\010\010%s\002\377" % timestamp)
74121
a60a3610a97b Issue #13639: Accept unicode filenames in tarfile.open(mode="w|gz").
Lars Gustäbel <lars@gustaebel.de>
parents: 73870
diff changeset
457 if type(self.name) is unicode:
a60a3610a97b Issue #13639: Accept unicode filenames in tarfile.open(mode="w|gz").
Lars Gustäbel <lars@gustaebel.de>
parents: 73870
diff changeset
458 self.name = self.name.encode("iso-8859-1", "replace")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
459 if self.name.endswith(".gz"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
460 self.name = self.name[:-3]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
461 self.__write(self.name + NUL)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
462
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
463 def write(self, s):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
464 """Write string s to the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
465 """
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
466 if self.comptype == "gz":
46063
ce45fd3a7a3f A stab in the dark attempt to fix the alpha/tru64 buildbot problem and add more
Gregory P. Smith <greg@mad-scientist.com>
parents: 45164
diff changeset
467 self.crc = self.zlib.crc32(s, self.crc) & 0xffffffffL
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
468 self.pos += len(s)
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
469 if self.comptype != "tar":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
470 s = self.cmp.compress(s)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
471 self.__write(s)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
472
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
473 def __write(self, s):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
474 """Write string s to the stream if a whole new block
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
475 is ready to be written.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
476 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
477 self.buf += s
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
478 while len(self.buf) > self.bufsize:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
479 self.fileobj.write(self.buf[:self.bufsize])
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
480 self.buf = self.buf[self.bufsize:]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
481
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
482 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
483 """Close the _Stream object. No operation should be
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
484 done on it afterwards.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
485 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
486 if self.closed:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
487 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
488
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
489 if self.mode == "w" and self.comptype != "tar":
33234
ab34980ffa16 Flush bz2 data even if nothing had been written so far. Fixes #1013882.
Martin v. Löwis <martin@v.loewis.de>
parents: 33208
diff changeset
490 self.buf += self.cmp.flush()
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
491
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
492 if self.mode == "w" and self.buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
493 self.fileobj.write(self.buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
494 self.buf = ""
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
495 if self.comptype == "gz":
39349
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
496 # The native zlib crc is an unsigned 32-bit integer, but
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
497 # the Python wrapper implicitly casts that to a signed C
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
498 # long. So, on a 32-bit box self.crc may "look negative",
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
499 # while the same crc on a 64-bit box may "look positive".
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
500 # To avoid irksome warnings from the `struct` module, force
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
501 # it to look positive on all boxes.
fa2dac3926ff _Stream.close(): Try to kill struct.pack() warnings when
Tim Peters <tim.peters@gmail.com>
parents: 39042
diff changeset
502 self.fileobj.write(struct.pack("<L", self.crc & 0xffffffffL))
30769
2bc95d49fc7a [Backport fix for bug #822668] gzip filesize should be written out mod 2**32
Andrew M. Kuchling <amk@amk.ca>
parents: 28731
diff changeset
503 self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFFL))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
504
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
505 if not self._extfileobj:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
506 self.fileobj.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
507
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
508 self.closed = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
509
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
510 def _init_read_gz(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
511 """Initialize for reading a gzip compressed fileobj.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
512 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
513 self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
514 self.dbuf = ""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
515
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
516 # taken from gzip.GzipFile with some alterations
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
517 if self.__read(2) != "\037\213":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
518 raise ReadError("not a gzip file")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
519 if self.__read(1) != "\010":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
520 raise CompressionError("unsupported compression method")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
521
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
522 flag = ord(self.__read(1))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
523 self.__read(6)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
524
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
525 if flag & 4:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
526 xlen = ord(self.__read(1)) + 256 * ord(self.__read(1))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
527 self.read(xlen)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
528 if flag & 8:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
529 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
530 s = self.__read(1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
531 if not s or s == NUL:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
532 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
533 if flag & 16:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
534 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
535 s = self.__read(1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
536 if not s or s == NUL:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
537 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
538 if flag & 2:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
539 self.__read(2)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
540
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
541 def tell(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
542 """Return the stream's file pointer position.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
543 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
544 return self.pos
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
545
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
546 def seek(self, pos=0):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
547 """Set the stream's file pointer to pos. Negative seeking
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
548 is forbidden.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
549 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
550 if pos - self.pos >= 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
551 blocks, remainder = divmod(pos - self.pos, self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
552 for i in xrange(blocks):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
553 self.read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
554 self.read(remainder)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
555 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
556 raise StreamError("seeking backwards is not allowed")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
557 return self.pos
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
558
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
559 def read(self, size=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
560 """Return the next size number of bytes from the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
561 If size is not defined, return all bytes of the stream
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
562 up to EOF.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
563 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
564 if size is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
565 t = []
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
566 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
567 buf = self._read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
568 if not buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
569 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
570 t.append(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
571 buf = "".join(t)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
572 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
573 buf = self._read(size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
574 self.pos += len(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
575 return buf
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
576
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
577 def _read(self, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
578 """Return size bytes from the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
579 """
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
580 if self.comptype == "tar":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
581 return self.__read(size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
582
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
583 c = len(self.dbuf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
584 t = [self.dbuf]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
585 while c < size:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
586 buf = self.__read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
587 if not buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
588 break
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
589 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
590 buf = self.cmp.decompress(buf)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
591 except IOError:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
592 raise ReadError("invalid compressed data")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
593 t.append(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
594 c += len(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
595 t = "".join(t)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
596 self.dbuf = t[size:]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
597 return t[:size]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
598
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
599 def __read(self, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
600 """Return size bytes from stream. If internal buffer is empty,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
601 read another block from the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
602 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
603 c = len(self.buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
604 t = [self.buf]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
605 while c < size:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
606 buf = self.fileobj.read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
607 if not buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
608 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
609 t.append(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
610 c += len(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
611 t = "".join(t)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
612 self.buf = t[size:]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
613 return t[:size]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
614 # class _Stream
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
615
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
616 class _StreamProxy(object):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
617 """Small proxy class that enables transparent compression
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
618 detection for the Stream interface (mode 'r|*').
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
619 """
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
620
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
621 def __init__(self, fileobj):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
622 self.fileobj = fileobj
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
623 self.buf = self.fileobj.read(BLOCKSIZE)
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
624
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
625 def read(self, size):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
626 self.read = self.fileobj.read
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
627 return self.buf
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
628
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
629 def getcomptype(self):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
630 if self.buf.startswith("\037\213\010"):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
631 return "gz"
73870
6d1a91e9f506 Correctly detect bzip2 compressed streams with blocksizes other than 900k.
Lars Gustäbel <lars@gustaebel.de>
parents: 72274
diff changeset
632 if self.buf[0:3] == "BZh" and self.buf[4:10] == "1AY&SY":
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
633 return "bz2"
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
634 return "tar"
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
635
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
636 def close(self):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
637 self.fileobj.close()
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
638 # class StreamProxy
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
639
38185
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
640 class _BZ2Proxy(object):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
641 """Small proxy class that enables external file object
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
642 support for "r:bz2" and "w:bz2" modes. This is actually
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
643 a workaround for a limitation in bz2 module's BZ2File
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
644 class which (unlike gzip.GzipFile) has no support for
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
645 a file object argument.
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
646 """
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
647
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
648 blocksize = 16 * 1024
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
649
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
650 def __init__(self, fileobj, mode):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
651 self.fileobj = fileobj
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
652 self.mode = mode
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
653 self.name = getattr(self.fileobj, "name", None)
38185
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
654 self.init()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
655
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
656 def init(self):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
657 import bz2
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
658 self.pos = 0
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
659 if self.mode == "r":
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
660 self.bz2obj = bz2.BZ2Decompressor()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
661 self.fileobj.seek(0)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
662 self.buf = ""
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
663 else:
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
664 self.bz2obj = bz2.BZ2Compressor()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
665
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
666 def read(self, size):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
667 b = [self.buf]
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
668 x = len(self.buf)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
669 while x < size:
52271
dd9fddb0720d Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop
Lars Gustäbel <lars@gustaebel.de>
parents: 45282
diff changeset
670 raw = self.fileobj.read(self.blocksize)
dd9fddb0720d Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop
Lars Gustäbel <lars@gustaebel.de>
parents: 45282
diff changeset
671 if not raw:
38185
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
672 break
52267
445d404270ea Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop
Lars Gustäbel <lars@gustaebel.de>
parents: 51775
diff changeset
673 data = self.bz2obj.decompress(raw)
52271
dd9fddb0720d Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop
Lars Gustäbel <lars@gustaebel.de>
parents: 45282
diff changeset
674 b.append(data)
38185
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
675 x += len(data)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
676 self.buf = "".join(b)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
677
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
678 buf = self.buf[:size]
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
679 self.buf = self.buf[size:]
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
680 self.pos += len(buf)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
681 return buf
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
682
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
683 def seek(self, pos):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
684 if pos < self.pos:
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
685 self.init()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
686 self.read(pos - self.pos)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
687
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
688 def tell(self):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
689 return self.pos
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
690
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
691 def write(self, data):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
692 self.pos += len(data)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
693 raw = self.bz2obj.compress(data)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
694 self.fileobj.write(raw)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
695
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
696 def close(self):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
697 if self.mode == "w":
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
698 raw = self.bz2obj.flush()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
699 self.fileobj.write(raw)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
700 # class _BZ2Proxy
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
701
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
702 #------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
703 # Extraction file object
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
704 #------------------------
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
705 class _FileInFile(object):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
706 """A thin wrapper around an existing file object that
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
707 provides a part of its data as an individual file
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
708 object.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
709 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
710
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
711 def __init__(self, fileobj, offset, size, sparse=None):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
712 self.fileobj = fileobj
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
713 self.offset = offset
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
714 self.size = size
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
715 self.sparse = sparse
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
716 self.position = 0
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
717
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
718 def tell(self):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
719 """Return the current file position.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
720 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
721 return self.position
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
722
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
723 def seek(self, position):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
724 """Seek to a position in the file.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
725 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
726 self.position = position
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
727
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
728 def read(self, size=None):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
729 """Read data from the file.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
730 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
731 if size is None:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
732 size = self.size - self.position
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
733 else:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
734 size = min(size, self.size - self.position)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
735
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
736 if self.sparse is None:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
737 return self.readnormal(size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
738 else:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
739 return self.readsparse(size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
740
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
741 def readnormal(self, size):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
742 """Read operation for regular files.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
743 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
744 self.fileobj.seek(self.offset + self.position)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
745 self.position += size
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
746 return self.fileobj.read(size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
747
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
748 def readsparse(self, size):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
749 """Read operation for sparse files.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
750 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
751 data = []
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
752 while size > 0:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
753 buf = self.readsparsesection(size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
754 if not buf:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
755 break
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
756 size -= len(buf)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
757 data.append(buf)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
758 return "".join(data)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
759
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
760 def readsparsesection(self, size):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
761 """Read a single section of a sparse file.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
762 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
763 section = self.sparse.find(self.position)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
764
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
765 if section is None:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
766 return ""
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
767
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
768 size = min(size, section.offset + section.size - self.position)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
769
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
770 if isinstance(section, _data):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
771 realpos = section.realpos + self.position - section.offset
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
772 self.fileobj.seek(self.offset + realpos)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
773 self.position += size
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
774 return self.fileobj.read(size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
775 else:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
776 self.position += size
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
777 return NUL * size
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
778 #class _FileInFile
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
779
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
780
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
781 class ExFileObject(object):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
782 """File-like object for reading an archive member.
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
783 Is returned by TarFile.extractfile().
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
784 """
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
785 blocksize = 1024
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
786
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
787 def __init__(self, tarfile, tarinfo):
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
788 self.fileobj = _FileInFile(tarfile.fileobj,
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
789 tarinfo.offset_data,
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
790 tarinfo.size,
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
791 getattr(tarinfo, "sparse", None))
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
792 self.name = tarinfo.name
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
793 self.mode = "r"
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
794 self.closed = False
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
795 self.size = tarinfo.size
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
796
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
797 self.position = 0
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
798 self.buffer = ""
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
799
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
800 def read(self, size=None):
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
801 """Read at most size bytes from the file. If size is not
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
802 present or None, read all data until EOF is reached.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
803 """
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
804 if self.closed:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
805 raise ValueError("I/O operation on closed file")
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
806
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
807 buf = ""
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
808 if self.buffer:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
809 if size is None:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
810 buf = self.buffer
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
811 self.buffer = ""
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
812 else:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
813 buf = self.buffer[:size]
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
814 self.buffer = self.buffer[size:]
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
815
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
816 if size is None:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
817 buf += self.fileobj.read()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
818 else:
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
819 buf += self.fileobj.read(size - len(buf))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
820
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
821 self.position += len(buf)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
822 return buf
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
823
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
824 def readline(self, size=-1):
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
825 """Read one entire line from the file. If size is present
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
826 and non-negative, return a string with at most that
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
827 size, which may be an incomplete line.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
828 """
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
829 if self.closed:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
830 raise ValueError("I/O operation on closed file")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
831
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
832 if "\n" in self.buffer:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
833 pos = self.buffer.find("\n") + 1
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
834 else:
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
835 buffers = [self.buffer]
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
836 while True:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
837 buf = self.fileobj.read(self.blocksize)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
838 buffers.append(buf)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
839 if not buf or "\n" in buf:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
840 self.buffer = "".join(buffers)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
841 pos = self.buffer.find("\n") + 1
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
842 if pos == 0:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
843 # no newline found.
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
844 pos = len(self.buffer)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
845 break
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
846
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
847 if size != -1:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
848 pos = min(size, pos)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
849
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
850 buf = self.buffer[:pos]
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
851 self.buffer = self.buffer[pos:]
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
852 self.position += len(buf)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
853 return buf
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
854
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
855 def readlines(self):
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
856 """Return a list with all remaining lines.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
857 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
858 result = []
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
859 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
860 line = self.readline()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
861 if not line: break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
862 result.append(line)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
863 return result
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
864
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
865 def tell(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
866 """Return the current file position.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
867 """
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
868 if self.closed:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
869 raise ValueError("I/O operation on closed file")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
870
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
871 return self.position
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
872
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
873 def seek(self, pos, whence=os.SEEK_SET):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
874 """Seek to a position in the file.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
875 """
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
876 if self.closed:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
877 raise ValueError("I/O operation on closed file")
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
878
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
879 if whence == os.SEEK_SET:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
880 self.position = min(max(pos, 0), self.size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
881 elif whence == os.SEEK_CUR:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
882 if pos < 0:
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
883 self.position = max(self.position + pos, 0)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
884 else:
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
885 self.position = min(self.position + pos, self.size)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
886 elif whence == os.SEEK_END:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
887 self.position = max(min(self.size + pos, self.size), 0)
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
888 else:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
889 raise ValueError("Invalid argument")
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
890
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
891 self.buffer = ""
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
892 self.fileobj.seek(self.position)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
893
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
894 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
895 """Close the file object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
896 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
897 self.closed = True
34649
13a950a3624b Patch #1107973: tarfile.ExFileObject iterators.
Martin v. Löwis <martin@v.loewis.de>
parents: 34421
diff changeset
898
13a950a3624b Patch #1107973: tarfile.ExFileObject iterators.
Martin v. Löwis <martin@v.loewis.de>
parents: 34421
diff changeset
899 def __iter__(self):
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
900 """Get an iterator over the file's lines.
34649
13a950a3624b Patch #1107973: tarfile.ExFileObject iterators.
Martin v. Löwis <martin@v.loewis.de>
parents: 34421
diff changeset
901 """
40518
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
902 while True:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
903 line = self.readline()
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
904 if not line:
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
905 break
ac8a9a4121d1 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40424
diff changeset
906 yield line
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
907 #class ExFileObject
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
908
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
909 #------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
910 # Exported Classes
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
911 #------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
912 class TarInfo(object):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
913 """Informational class which holds the details about an
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
914 archive member given by a tar header block.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
915 TarInfo objects are returned by TarFile.getmember(),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
916 TarFile.getmembers() and TarFile.gettarinfo() and are
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
917 usually created internally.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
918 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
919
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
920 def __init__(self, name=""):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
921 """Construct a TarInfo object. name is the optional name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
922 of the member.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
923 """
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
924 self.name = name # member name
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
925 self.mode = 0644 # file permissions
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
926 self.uid = 0 # user id
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
927 self.gid = 0 # group id
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
928 self.size = 0 # file size
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
929 self.mtime = 0 # modification time
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
930 self.chksum = 0 # header checksum
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
931 self.type = REGTYPE # member type
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
932 self.linkname = "" # link name
65086
3633d8fe5550 Merged revisions 85211 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 62044
diff changeset
933 self.uname = "" # user name
3633d8fe5550 Merged revisions 85211 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 62044
diff changeset
934 self.gname = "" # group name
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
935 self.devmajor = 0 # device major number
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
936 self.devminor = 0 # device minor number
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
937
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
938 self.offset = 0 # the tar header starts here
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
939 self.offset_data = 0 # the file's data starts here
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
940
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
941 self.pax_headers = {} # pax header information
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
942
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
943 # In pax headers the "name" and "linkname" field are called
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
944 # "path" and "linkpath".
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
945 def _getpath(self):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
946 return self.name
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
947 def _setpath(self, name):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
948 self.name = name
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
949 path = property(_getpath, _setpath)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
950
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
951 def _getlinkpath(self):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
952 return self.linkname
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
953 def _setlinkpath(self, linkname):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
954 self.linkname = linkname
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
955 linkpath = property(_getlinkpath, _setlinkpath)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
956
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
957 def __repr__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
958 return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
959
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
960 def get_info(self, encoding, errors):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
961 """Return the TarInfo's attributes as a dictionary.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
962 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
963 info = {
55746
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
964 "name": self.name,
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
965 "mode": self.mode & 07777,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
966 "uid": self.uid,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
967 "gid": self.gid,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
968 "size": self.size,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
969 "mtime": self.mtime,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
970 "chksum": self.chksum,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
971 "type": self.type,
55746
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
972 "linkname": self.linkname,
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
973 "uname": self.uname,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
974 "gname": self.gname,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
975 "devmajor": self.devmajor,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
976 "devminor": self.devminor
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
977 }
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
978
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
979 if info["type"] == DIRTYPE and not info["name"].endswith("/"):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
980 info["name"] += "/"
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
981
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
982 for key in ("name", "linkname", "uname", "gname"):
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
983 if type(info[key]) is unicode:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
984 info[key] = info[key].encode(encoding, errors)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
985
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
986 return info
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
987
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
988 def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="strict"):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
989 """Return a tar header as a string of 512 byte blocks.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
990 """
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
991 info = self.get_info(encoding, errors)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
992
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
993 if format == USTAR_FORMAT:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
994 return self.create_ustar_header(info)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
995 elif format == GNU_FORMAT:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
996 return self.create_gnu_header(info)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
997 elif format == PAX_FORMAT:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
998 return self.create_pax_header(info, encoding, errors)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
999 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1000 raise ValueError("invalid format")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1001
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1002 def create_ustar_header(self, info):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1003 """Return the object as a ustar header block.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1004 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1005 info["magic"] = POSIX_MAGIC
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1006
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1007 if len(info["linkname"]) > LENGTH_LINK:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1008 raise ValueError("linkname is too long")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1009
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1010 if len(info["name"]) > LENGTH_NAME:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1011 info["prefix"], info["name"] = self._posix_split_name(info["name"])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1012
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1013 return self._create_header(info, USTAR_FORMAT)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1014
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1015 def create_gnu_header(self, info):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1016 """Return the object as a GNU header block sequence.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1017 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1018 info["magic"] = GNU_MAGIC
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1019
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1020 buf = ""
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1021 if len(info["linkname"]) > LENGTH_LINK:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1022 buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1023
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1024 if len(info["name"]) > LENGTH_NAME:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1025 buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1026
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1027 return buf + self._create_header(info, GNU_FORMAT)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1028
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1029 def create_pax_header(self, info, encoding, errors):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1030 """Return the object as a ustar header block. If it cannot be
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1031 represented this way, prepend a pax extended header sequence
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1032 with supplement information.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1033 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1034 info["magic"] = POSIX_MAGIC
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1035 pax_headers = self.pax_headers.copy()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1036
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1037 # Test string fields for values that exceed the field length or cannot
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1038 # be represented in ASCII encoding.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1039 for name, hname, length in (
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1040 ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1041 ("uname", "uname", 32), ("gname", "gname", 32)):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1042
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1043 if hname in pax_headers:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1044 # The pax header has priority.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1045 continue
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1046
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1047 val = info[name].decode(encoding, errors)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1048
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1049 # Try to encode the string as ASCII.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1050 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1051 val.encode("ascii")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1052 except UnicodeEncodeError:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1053 pax_headers[hname] = val
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1054 continue
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1055
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1056 if len(info[name]) > length:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1057 pax_headers[hname] = val
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1058
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1059 # Test number fields for values that exceed the field limit or values
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1060 # that like to be stored as float.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1061 for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)):
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1062 if name in pax_headers:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1063 # The pax header has priority. Avoid overflow.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1064 info[name] = 0
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1065 continue
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1066
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1067 val = info[name]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1068 if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1069 pax_headers[name] = unicode(val)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1070 info[name] = 0
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1071
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1072 # Create a pax extended header if necessary.
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1073 if pax_headers:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1074 buf = self._create_pax_generic_header(pax_headers)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1075 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1076 buf = ""
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1077
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1078 return buf + self._create_header(info, USTAR_FORMAT)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1079
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1080 @classmethod
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1081 def create_pax_global_header(cls, pax_headers):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1082 """Return the object as a pax global header block sequence.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1083 """
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1084 return cls._create_pax_generic_header(pax_headers, type=XGLTYPE)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1085
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1086 def _posix_split_name(self, name):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1087 """Split a name longer than 100 chars into a prefix
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1088 and a name part.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1089 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1090 prefix = name[:LENGTH_PREFIX + 1]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1091 while prefix and prefix[-1] != "/":
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1092 prefix = prefix[:-1]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1093
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1094 name = name[len(prefix):]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1095 prefix = prefix[:-1]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1096
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1097 if not prefix or len(name) > LENGTH_NAME:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1098 raise ValueError("name is too long")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1099 return prefix, name
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1100
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1101 @staticmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1102 def _create_header(info, format):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1103 """Return a header block. info is a dictionary with file
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1104 information, format must be one of the *_FORMAT constants.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1105 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1106 parts = [
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1107 stn(info.get("name", ""), 100),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1108 itn(info.get("mode", 0) & 07777, 8, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1109 itn(info.get("uid", 0), 8, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1110 itn(info.get("gid", 0), 8, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1111 itn(info.get("size", 0), 12, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1112 itn(info.get("mtime", 0), 12, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1113 " ", # checksum field
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1114 info.get("type", REGTYPE),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1115 stn(info.get("linkname", ""), 100),
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1116 stn(info.get("magic", POSIX_MAGIC), 8),
65086
3633d8fe5550 Merged revisions 85211 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 62044
diff changeset
1117 stn(info.get("uname", ""), 32),
3633d8fe5550 Merged revisions 85211 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 62044
diff changeset
1118 stn(info.get("gname", ""), 32),
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1119 itn(info.get("devmajor", 0), 8, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1120 itn(info.get("devminor", 0), 8, format),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1121 stn(info.get("prefix", ""), 155)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1122 ]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1123
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1124 buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1125 chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1126 buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1127 return buf
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1128
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1129 @staticmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1130 def _create_payload(payload):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1131 """Return the string payload filled with zero bytes
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1132 up to the next 512 byte border.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1133 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1134 blocks, remainder = divmod(len(payload), BLOCKSIZE)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1135 if remainder > 0:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1136 payload += (BLOCKSIZE - remainder) * NUL
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1137 return payload
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1138
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1139 @classmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1140 def _create_gnu_long_header(cls, name, type):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1141 """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1142 for name.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1143 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1144 name += NUL
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1145
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1146 info = {}
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1147 info["name"] = "././@LongLink"
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1148 info["type"] = type
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1149 info["size"] = len(name)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1150 info["magic"] = GNU_MAGIC
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1151
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1152 # create extended header + name blocks.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1153 return cls._create_header(info, USTAR_FORMAT) + \
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1154 cls._create_payload(name)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1155
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1156 @classmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1157 def _create_pax_generic_header(cls, pax_headers, type=XHDTYPE):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1158 """Return a POSIX.1-2001 extended or global header sequence
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1159 that contains a list of keyword, value pairs. The values
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1160 must be unicode objects.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1161 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1162 records = []
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1163 for keyword, value in pax_headers.iteritems():
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1164 keyword = keyword.encode("utf8")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1165 value = value.encode("utf8")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1166 l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n'
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1167 n = p = 0
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1168 while True:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1169 n = l + len(str(p))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1170 if n == p:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1171 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1172 p = n
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1173 records.append("%d %s=%s\n" % (p, keyword, value))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1174 records = "".join(records)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1175
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1176 # We use a hardcoded "././@PaxHeader" name like star does
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1177 # instead of the one that POSIX recommends.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1178 info = {}
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1179 info["name"] = "././@PaxHeader"
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1180 info["type"] = type
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1181 info["size"] = len(records)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1182 info["magic"] = POSIX_MAGIC
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1183
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1184 # Create pax header + record blocks.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1185 return cls._create_header(info, USTAR_FORMAT) + \
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1186 cls._create_payload(records)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1187
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1188 @classmethod
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1189 def frombuf(cls, buf):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1190 """Construct a TarInfo object from a 512 byte string buffer.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1191 """
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1192 if len(buf) == 0:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1193 raise EmptyHeaderError("empty header")
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1194 if len(buf) != BLOCKSIZE:
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1195 raise TruncatedHeaderError("truncated header")
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1196 if buf.count(NUL) == BLOCKSIZE:
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1197 raise EOFHeaderError("end of file header")
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
1198
40491
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
1199 chksum = nti(buf[148:156])
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
1200 if chksum not in calc_chksums(buf):
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1201 raise InvalidHeaderError("bad checksum")
32770
a3b1d6c99e46 SF #918101, allow files >= 8 GB using GNU extension
Neal Norwitz <nnorwitz@gmail.com>
parents: 32769
diff changeset
1202
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1203 obj = cls()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1204 obj.buf = buf
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1205 obj.name = nts(buf[0:100])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1206 obj.mode = nti(buf[100:108])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1207 obj.uid = nti(buf[108:116])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1208 obj.gid = nti(buf[116:124])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1209 obj.size = nti(buf[124:136])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1210 obj.mtime = nti(buf[136:148])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1211 obj.chksum = chksum
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1212 obj.type = buf[156:157]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1213 obj.linkname = nts(buf[157:257])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1214 obj.uname = nts(buf[265:297])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1215 obj.gname = nts(buf[297:329])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1216 obj.devmajor = nti(buf[329:337])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1217 obj.devminor = nti(buf[337:345])
45282
790554ae2b04 Backport the nts() function from the trunk. This fixes problems with
Lars Gustäbel <lars@gustaebel.de>
parents: 45165
diff changeset
1218 prefix = nts(buf[345:500])
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1219
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1220 # Old V7 tar format represents a directory as a regular
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1221 # file with a trailing slash.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1222 if obj.type == AREGTYPE and obj.name.endswith("/"):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1223 obj.type = DIRTYPE
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1224
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1225 # Remove redundant slashes from directories.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1226 if obj.isdir():
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1227 obj.name = obj.name.rstrip("/")
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1228
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1229 # Reconstruct a ustar longname.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1230 if prefix and obj.type not in GNU_TYPES:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1231 obj.name = prefix + "/" + obj.name
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1232 return obj
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1233
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1234 @classmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1235 def fromtarfile(cls, tarfile):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1236 """Return the next TarInfo object from TarFile object
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1237 tarfile.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1238 """
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1239 buf = tarfile.fileobj.read(BLOCKSIZE)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1240 obj = cls.frombuf(buf)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1241 obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1242 return obj._proc_member(tarfile)
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1243
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1244 #--------------------------------------------------------------------------
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1245 # The following are methods that are called depending on the type of a
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1246 # member. The entry point is _proc_member() which can be overridden in a
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1247 # subclass to add custom _proc_*() methods. A _proc_*() method MUST
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1248 # implement the following
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1249 # operations:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1250 # 1. Set self.offset_data to the position where the data blocks begin,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1251 # if there is data that follows.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1252 # 2. Set tarfile.offset to the position where the next member's header will
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1253 # begin.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1254 # 3. Return self or another valid TarInfo object.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1255 def _proc_member(self, tarfile):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1256 """Choose the right processing method depending on
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1257 the type and call it.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1258 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1259 if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1260 return self._proc_gnulong(tarfile)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1261 elif self.type == GNUTYPE_SPARSE:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1262 return self._proc_sparse(tarfile)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1263 elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1264 return self._proc_pax(tarfile)
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1265 else:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1266 return self._proc_builtin(tarfile)
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1267
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1268 def _proc_builtin(self, tarfile):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1269 """Process a builtin type or an unknown type which
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1270 will be treated as a regular file.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1271 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1272 self.offset_data = tarfile.fileobj.tell()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1273 offset = self.offset_data
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1274 if self.isreg() or self.type not in SUPPORTED_TYPES:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1275 # Skip the following data blocks.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1276 offset += self._block(self.size)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1277 tarfile.offset = offset
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1278
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1279 # Patch the TarInfo object with saved global
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1280 # header information.
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1281 self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1282
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1283 return self
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1284
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1285 def _proc_gnulong(self, tarfile):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1286 """Process the blocks that hold a GNU longname
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1287 or longlink member.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1288 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1289 buf = tarfile.fileobj.read(self._block(self.size))
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1290
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1291 # Fetch the next header and process it.
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1292 try:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1293 next = self.fromtarfile(tarfile)
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1294 except HeaderError:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1295 raise SubsequentHeaderError("missing or bad subsequent header")
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1296
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1297 # Patch the TarInfo object from the next header with
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1298 # the longname information.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1299 next.offset = self.offset
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1300 if self.type == GNUTYPE_LONGNAME:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1301 next.name = nts(buf)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1302 elif self.type == GNUTYPE_LONGLINK:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1303 next.linkname = nts(buf)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1304
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1305 return next
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1306
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1307 def _proc_sparse(self, tarfile):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1308 """Process a GNU sparse header plus extra headers.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1309 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1310 buf = self.buf
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1311 sp = _ringbuffer()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1312 pos = 386
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1313 lastpos = 0L
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1314 realpos = 0L
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1315 # There are 4 possible sparse structs in the
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1316 # first header.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1317 for i in xrange(4):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1318 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1319 offset = nti(buf[pos:pos + 12])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1320 numbytes = nti(buf[pos + 12:pos + 24])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1321 except ValueError:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1322 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1323 if offset > lastpos:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1324 sp.append(_hole(lastpos, offset - lastpos))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1325 sp.append(_data(offset, numbytes, realpos))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1326 realpos += numbytes
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1327 lastpos = offset + numbytes
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1328 pos += 24
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1329
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1330 isextended = ord(buf[482])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1331 origsize = nti(buf[483:495])
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1332
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1333 # If the isextended flag is given,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1334 # there are extra headers to process.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1335 while isextended == 1:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1336 buf = tarfile.fileobj.read(BLOCKSIZE)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1337 pos = 0
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1338 for i in xrange(21):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1339 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1340 offset = nti(buf[pos:pos + 12])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1341 numbytes = nti(buf[pos + 12:pos + 24])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1342 except ValueError:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1343 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1344 if offset > lastpos:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1345 sp.append(_hole(lastpos, offset - lastpos))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1346 sp.append(_data(offset, numbytes, realpos))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1347 realpos += numbytes
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1348 lastpos = offset + numbytes
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1349 pos += 24
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1350 isextended = ord(buf[504])
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1351
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1352 if lastpos < origsize:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1353 sp.append(_hole(lastpos, origsize - lastpos))
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1354
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1355 self.sparse = sp
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1356
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1357 self.offset_data = tarfile.fileobj.tell()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1358 tarfile.offset = self.offset_data + self._block(self.size)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1359 self.size = origsize
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1360
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1361 return self
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1362
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1363 def _proc_pax(self, tarfile):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1364 """Process an extended or global header as described in
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1365 POSIX.1-2001.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1366 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1367 # Read the header information.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1368 buf = tarfile.fileobj.read(self._block(self.size))
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1369
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1370 # A pax header stores supplemental information for either
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1371 # the following file (extended) or all following files
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1372 # (global).
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1373 if self.type == XGLTYPE:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1374 pax_headers = tarfile.pax_headers
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1375 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1376 pax_headers = tarfile.pax_headers.copy()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1377
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1378 # Parse pax header information. A record looks like that:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1379 # "%d %s=%s\n" % (length, keyword, value). length is the size
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1380 # of the complete record including the length field itself and
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1381 # the newline. keyword and value are both UTF-8 encoded strings.
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1382 regex = re.compile(r"(\d+) ([^=]+)=", re.U)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1383 pos = 0
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1384 while True:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1385 match = regex.match(buf, pos)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1386 if not match:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1387 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1388
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1389 length, keyword = match.groups()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1390 length = int(length)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1391 value = buf[match.end(2) + 1:match.start(1) + length - 1]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1392
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1393 keyword = keyword.decode("utf8")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1394 value = value.decode("utf8")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1395
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1396 pax_headers[keyword] = value
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1397 pos += length
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1398
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1399 # Fetch the next header.
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1400 try:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1401 next = self.fromtarfile(tarfile)
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1402 except HeaderError:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1403 raise SubsequentHeaderError("missing or bad subsequent header")
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1404
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1405 if self.type in (XHDTYPE, SOLARIS_XHDTYPE):
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1406 # Patch the TarInfo object with the extended header info.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1407 next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1408 next.offset = self.offset
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1409
48175
979f0a89903f Remove a dict.has_key() and list.sort(cmp=) usage from tarfile to silence
Brett Cannon <bcannon@gmail.com>
parents: 48138
diff changeset
1410 if "size" in pax_headers:
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1411 # If the extended header replaces the size field,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1412 # we need to recalculate the offset where the next
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1413 # header starts.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1414 offset = next.offset_data
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1415 if next.isreg() or next.type not in SUPPORTED_TYPES:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1416 offset += next._block(next.size)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1417 tarfile.offset = offset
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1418
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1419 return next
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1420
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1421 def _apply_pax_info(self, pax_headers, encoding, errors):
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1422 """Replace fields with supplemental information from a previous
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1423 pax extended or global header.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1424 """
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1425 for keyword, value in pax_headers.iteritems():
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1426 if keyword not in PAX_FIELDS:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1427 continue
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1428
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1429 if keyword == "path":
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1430 value = value.rstrip("/")
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1431
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1432 if keyword in PAX_NUMBER_FIELDS:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1433 try:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1434 value = PAX_NUMBER_FIELDS[keyword](value)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1435 except ValueError:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1436 value = 0
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1437 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1438 value = uts(value, encoding, errors)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1439
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1440 setattr(self, keyword, value)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1441
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1442 self.pax_headers = pax_headers.copy()
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1443
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1444 def _block(self, count):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1445 """Round up a byte count by BLOCKSIZE and return it,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1446 e.g. _block(834) => 1024.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1447 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1448 blocks, remainder = divmod(count, BLOCKSIZE)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1449 if remainder:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1450 blocks += 1
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1451 return blocks * BLOCKSIZE
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1452
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1453 def isreg(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1454 return self.type in REGULAR_TYPES
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1455 def isfile(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1456 return self.isreg()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1457 def isdir(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1458 return self.type == DIRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1459 def issym(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1460 return self.type == SYMTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1461 def islnk(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1462 return self.type == LNKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1463 def ischr(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1464 return self.type == CHRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1465 def isblk(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1466 return self.type == BLKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1467 def isfifo(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1468 return self.type == FIFOTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1469 def issparse(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1470 return self.type == GNUTYPE_SPARSE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1471 def isdev(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1472 return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1473 # class TarInfo
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1474
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1475 class TarFile(object):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1476 """The TarFile Class provides an interface to tar archives.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1477 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1478
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1479 debug = 0 # May be set from 0 (no msgs) to 3 (all msgs)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1480
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1481 dereference = False # If true, add content of linked file to the
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1482 # tar file, else the link.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1483
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1484 ignore_zeros = False # If true, skips empty or invalid blocks and
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1485 # continues processing.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1486
57679
493780ea35cf Issue #7357: No longer suppress fatal extraction errors by
Lars Gustäbel <lars@gustaebel.de>
parents: 57393
diff changeset
1487 errorlevel = 1 # If 0, fatal errors only appear in debug
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1488 # messages (if debug >= 0). If > 0, errors
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1489 # are passed to the caller as exceptions.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1490
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1491 format = DEFAULT_FORMAT # The format to use when creating an archive.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1492
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1493 encoding = ENCODING # Encoding for 8-bit character strings.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1494
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1495 errors = None # Error handler for unicode conversion.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1496
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1497 tarinfo = TarInfo # The default TarInfo class to use.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1498
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1499 fileobject = ExFileObject # The default ExFileObject class to use.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1500
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1501 def __init__(self, name=None, mode="r", fileobj=None, format=None,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1502 tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1503 errors=None, pax_headers=None, debug=None, errorlevel=None):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1504 """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1505 read from an existing archive, 'a' to append data to an existing
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1506 file or 'w' to create a new file overwriting an existing one. `mode'
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1507 defaults to 'r'.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1508 If `fileobj' is given, it is used for reading or writing data. If it
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1509 can be determined, `mode' is overridden by `fileobj's mode.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1510 `fileobj' is not closed, when TarFile is closed.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1511 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1512 if len(mode) > 1 or mode not in "raw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1513 raise ValueError("mode must be 'r', 'a' or 'w'")
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1514 self.mode = mode
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1515 self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1516
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1517 if not fileobj:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1518 if self.mode == "a" and not os.path.exists(name):
40748
09dcacc8a0bc Patch #1652681: create nonexistent files in append mode and
Lars Gustäbel <lars@gustaebel.de>
parents: 40698
diff changeset
1519 # Create nonexistent files in append mode.
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1520 self.mode = "w"
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1521 self._mode = "wb"
41881
3877f37c9861 Remove direct call's to file's constructor and replace them with calls to
Brett Cannon <bcannon@gmail.com>
parents: 41153
diff changeset
1522 fileobj = bltn_open(name, self._mode)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1523 self._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1524 else:
42950
66e36ce5a56c TarFile.__init__() no longer fails if no name argument is passed and
Lars Gustäbel <lars@gustaebel.de>
parents: 41499
diff changeset
1525 if name is None and hasattr(fileobj, "name"):
66e36ce5a56c TarFile.__init__() no longer fails if no name argument is passed and
Lars Gustäbel <lars@gustaebel.de>
parents: 41499
diff changeset
1526 name = fileobj.name
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1527 if hasattr(fileobj, "mode"):
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1528 self._mode = fileobj.mode
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1529 self._extfileobj = True
42950
66e36ce5a56c TarFile.__init__() no longer fails if no name argument is passed and
Lars Gustäbel <lars@gustaebel.de>
parents: 41499
diff changeset
1530 self.name = os.path.abspath(name) if name else None
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1531 self.fileobj = fileobj
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1532
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1533 # Init attributes.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1534 if format is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1535 self.format = format
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1536 if tarinfo is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1537 self.tarinfo = tarinfo
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1538 if dereference is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1539 self.dereference = dereference
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1540 if ignore_zeros is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1541 self.ignore_zeros = ignore_zeros
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1542 if encoding is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1543 self.encoding = encoding
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1544
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1545 if errors is not None:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1546 self.errors = errors
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1547 elif mode == "r":
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1548 self.errors = "utf-8"
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1549 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1550 self.errors = "strict"
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1551
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1552 if pax_headers is not None and self.format == PAX_FORMAT:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1553 self.pax_headers = pax_headers
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1554 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1555 self.pax_headers = {}
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1556
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1557 if debug is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1558 self.debug = debug
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1559 if errorlevel is not None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1560 self.errorlevel = errorlevel
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1561
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1562 # Init datastructures.
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1563 self.closed = False
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1564 self.members = [] # list of members as TarInfo objects
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1565 self._loaded = False # flag if all members have been read
44092
b21b1c4f0439 Issue #1531: Read fileobj from the current offset, do not seek to
Lars Gustäbel <lars@gustaebel.de>
parents: 42950
diff changeset
1566 self.offset = self.fileobj.tell()
b21b1c4f0439 Issue #1531: Read fileobj from the current offset, do not seek to
Lars Gustäbel <lars@gustaebel.de>
parents: 42950
diff changeset
1567 # current position in the archive file
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1568 self.inodes = {} # dictionary caching the inodes of
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1569 # archive members already added
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1570
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1571 try:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1572 if self.mode == "r":
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1573 self.firstmember = None
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1574 self.firstmember = self.next()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1575
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1576 if self.mode == "a":
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1577 # Move to the end of the archive,
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1578 # before the first empty block.
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1579 while True:
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1580 self.fileobj.seek(self.offset)
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1581 try:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1582 tarinfo = self.tarinfo.fromtarfile(self)
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1583 self.members.append(tarinfo)
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1584 except EOFHeaderError:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1585 self.fileobj.seek(self.offset)
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1586 break
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1587 except HeaderError, e:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1588 raise ReadError(str(e))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1589
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1590 if self.mode in "aw":
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1591 self._loaded = True
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1592
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1593 if self.pax_headers:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1594 buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy())
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1595 self.fileobj.write(buf)
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1596 self.offset += len(buf)
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1597 except:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1598 if not self._extfileobj:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1599 self.fileobj.close()
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1600 self.closed = True
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1601 raise
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1602
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1603 def _getposix(self):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1604 return self.format == USTAR_FORMAT
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1605 def _setposix(self, value):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1606 import warnings
53903
a36fa2ce61b1 Merged revisions 72458 via svnmerge from
Philip Jenvey <pjenvey@underboss.org>
parents: 52272
diff changeset
1607 warnings.warn("use the format attribute instead", DeprecationWarning,
a36fa2ce61b1 Merged revisions 72458 via svnmerge from
Philip Jenvey <pjenvey@underboss.org>
parents: 52272
diff changeset
1608 2)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1609 if value:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1610 self.format = USTAR_FORMAT
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1611 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1612 self.format = GNU_FORMAT
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1613 posix = property(_getposix, _setposix)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1614
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1615 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1616 # Below are the classmethods which act as alternate constructors to the
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1617 # TarFile class. The open() method is the only one that is needed for
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1618 # public use; it is the "super"-constructor and is able to select an
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1619 # adequate "sub"-constructor for a particular compression using the mapping
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1620 # from OPEN_METH.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1621 #
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1622 # This concept allows one to subclass TarFile without losing the comfort of
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1623 # the super-constructor. A sub-constructor is registered and made available
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1624 # by adding it to the mapping in OPEN_METH.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1625
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1626 @classmethod
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1627 def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1628 """Open a tar archive for reading, writing or appending. Return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1629 an appropriate TarFile class.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1630
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1631 mode:
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1632 'r' or 'r:*' open for reading with transparent compression
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1633 'r:' open for reading exclusively uncompressed
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1634 'r:gz' open for reading with gzip compression
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1635 'r:bz2' open for reading with bzip2 compression
40748
09dcacc8a0bc Patch #1652681: create nonexistent files in append mode and
Lars Gustäbel <lars@gustaebel.de>
parents: 40698
diff changeset
1636 'a' or 'a:' open for appending, creating the file if necessary
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1637 'w' or 'w:' open for writing without compression
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1638 'w:gz' open for writing with gzip compression
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1639 'w:bz2' open for writing with bzip2 compression
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1640
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1641 'r|*' open a stream of tar blocks with transparent compression
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1642 'r|' open an uncompressed stream of tar blocks for reading
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1643 'r|gz' open a gzip compressed stream of tar blocks
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1644 'r|bz2' open a bzip2 compressed stream of tar blocks
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1645 'w|' open an uncompressed stream for writing
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1646 'w|gz' open a gzip compressed stream for writing
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1647 'w|bz2' open a bzip2 compressed stream for writing
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1648 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1649
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1650 if not name and not fileobj:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1651 raise ValueError("nothing to open")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1652
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1653 if mode in ("r", "r:*"):
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1654 # Find out which *open() is appropriate for opening the file.
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1655 for comptype in cls.OPEN_METH:
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1656 func = getattr(cls, cls.OPEN_METH[comptype])
40524
2676d8287a11 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40520
diff changeset
1657 if fileobj is not None:
2676d8287a11 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40520
diff changeset
1658 saved_pos = fileobj.tell()
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1659 try:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1660 return func(name, "r", fileobj, **kwargs)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1661 except (ReadError, CompressionError), e:
40524
2676d8287a11 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40520
diff changeset
1662 if fileobj is not None:
2676d8287a11 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40520
diff changeset
1663 fileobj.seek(saved_pos)
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1664 continue
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1665 raise ReadError("file could not be opened successfully")
34697
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1666
79302e50910e Patch #918101: Add tarfile open mode r|* for auto-detection of the
Martin v. Löwis <martin@v.loewis.de>
parents: 34688
diff changeset
1667 elif ":" in mode:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1668 filemode, comptype = mode.split(":", 1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1669 filemode = filemode or "r"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1670 comptype = comptype or "tar"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1671
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1672 # Select the *open() function according to
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1673 # given compression.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1674 if comptype in cls.OPEN_METH:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1675 func = getattr(cls, cls.OPEN_METH[comptype])
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1676 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1677 raise CompressionError("unknown compression type %r" % comptype)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1678 return func(name, filemode, fileobj, **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1679
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1680 elif "|" in mode:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1681 filemode, comptype = mode.split("|", 1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1682 filemode = filemode or "r"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1683 comptype = comptype or "tar"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1684
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1685 if filemode not in "rw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1686 raise ValueError("mode must be 'r' or 'w'")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1687
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1688 t = cls(name, filemode,
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1689 _Stream(name, filemode, comptype, fileobj, bufsize),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1690 **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1691 t._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1692 return t
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1693
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1694 elif mode in "aw":
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1695 return cls.taropen(name, mode, fileobj, **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1696
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1697 raise ValueError("undiscernible mode")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1698
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1699 @classmethod
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1700 def taropen(cls, name, mode="r", fileobj=None, **kwargs):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1701 """Open uncompressed tar archive name for reading or writing.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1702 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1703 if len(mode) > 1 or mode not in "raw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1704 raise ValueError("mode must be 'r', 'a' or 'w'")
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1705 return cls(name, mode, fileobj, **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1706
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1707 @classmethod
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1708 def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1709 """Open gzip compressed tar archive name for reading or writing.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1710 Appending is not allowed.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1711 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1712 if len(mode) > 1 or mode not in "rw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1713 raise ValueError("mode must be 'r' or 'w'")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1714
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1715 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1716 import gzip
28576
1bd50c28203f Fix test_tarfile failure when gzip is not available
Neal Norwitz <nnorwitz@gmail.com>
parents: 28222
diff changeset
1717 gzip.GzipFile
1bd50c28203f Fix test_tarfile failure when gzip is not available
Neal Norwitz <nnorwitz@gmail.com>
parents: 28222
diff changeset
1718 except (ImportError, AttributeError):
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1719 raise CompressionError("gzip module is not available")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1720
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1721 if fileobj is None:
41881
3877f37c9861 Remove direct call's to file's constructor and replace them with calls to
Brett Cannon <bcannon@gmail.com>
parents: 41153
diff changeset
1722 fileobj = bltn_open(name, mode + "b")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1723
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1724 try:
40520
ef4b8fcd14d7 Patch #1262036: Prevent TarFiles from being added to themselves under
Lars Gustäbel <lars@gustaebel.de>
parents: 40518
diff changeset
1725 t = cls.taropen(name, mode,
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1726 gzip.GzipFile(name, mode, compresslevel, fileobj),
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1727 **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1728 except IOError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1729 raise ReadError("not a gzip file")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1730 t._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1731 return t
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1732
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1733 @classmethod
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1734 def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1735 """Open bzip2 compressed tar archive name for reading or writing.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1736 Appending is not allowed.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1737 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1738 if len(mode) > 1 or mode not in "rw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1739 raise ValueError("mode must be 'r' or 'w'.")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1740
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1741 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1742 import bz2
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1743 except ImportError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1744 raise CompressionError("bz2 module is not available")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1745
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1746 if fileobj is not None:
38185
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
1747 fileobj = _BZ2Proxy(fileobj, mode)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
1748 else:
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
1749 fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1750
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1751 try:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1752 t = cls.taropen(name, mode, fileobj, **kwargs)
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
1753 except (IOError, EOFError):
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1754 raise ReadError("not a bzip2 file")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1755 t._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1756 return t
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1757
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1758 # All *open() methods are registered here.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1759 OPEN_METH = {
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1760 "tar": "taropen", # uncompressed tar
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1761 "gz": "gzopen", # gzip compressed tar
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1762 "bz2": "bz2open" # bzip2 compressed tar
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1763 }
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1764
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1765 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1766 # The public methods which TarFile provides:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1767
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1768 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1769 """Close the TarFile. In write-mode, two finishing zero blocks are
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1770 appended to the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1771 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1772 if self.closed:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1773 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1774
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1775 if self.mode in "aw":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1776 self.fileobj.write(NUL * (BLOCKSIZE * 2))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1777 self.offset += (BLOCKSIZE * 2)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1778 # fill up the end with zero-blocks
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1779 # (like option -b20 for tar does)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1780 blocks, remainder = divmod(self.offset, RECORDSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1781 if remainder > 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1782 self.fileobj.write(NUL * (RECORDSIZE - remainder))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1783
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1784 if not self._extfileobj:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1785 self.fileobj.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1786 self.closed = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1787
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1788 def getmember(self, name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1789 """Return a TarInfo object for member `name'. If `name' can not be
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1790 found in the archive, KeyError is raised. If a member occurs more
55049
74c0a78114ae Merged revisions 69846 via svnmerge from
Jesus Cea <jcea@jcea.es>
parents: 53903
diff changeset
1791 than once in the archive, its last occurrence is assumed to be the
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1792 most up-to-date version.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1793 """
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
1794 tarinfo = self._getmember(name)
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
1795 if tarinfo is None:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1796 raise KeyError("filename %r not found" % name)
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
1797 return tarinfo
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1798
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1799 def getmembers(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1800 """Return the members of the archive as a list of TarInfo objects. The
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1801 list has the same order as the members in the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1802 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1803 self._check()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1804 if not self._loaded: # if we want to obtain a list of
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1805 self._load() # all members, we first have to
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1806 # scan the whole archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1807 return self.members
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1808
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1809 def getnames(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1810 """Return the members of the archive as a list of their names. It has
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1811 the same order as the list returned by getmembers().
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1812 """
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
1813 return [tarinfo.name for tarinfo in self.getmembers()]
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1814
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1815 def gettarinfo(self, name=None, arcname=None, fileobj=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1816 """Create a TarInfo object for either the file `name' or the file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1817 object `fileobj' (using os.fstat on its file descriptor). You can
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1818 modify some of the TarInfo's attributes before you add it using
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1819 addfile(). If given, `arcname' specifies an alternative name for the
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1820 file in the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1821 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1822 self._check("aw")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1823
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1824 # When fileobj is given, replace name by
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1825 # fileobj's real name.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1826 if fileobj is not None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1827 name = fileobj.name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1828
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1829 # Building the name of the member in the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1830 # Backward slashes are converted to forward slashes,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1831 # Absolute paths are turned to relative paths.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1832 if arcname is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1833 arcname = name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1834 drv, arcname = os.path.splitdrive(arcname)
55746
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
1835 arcname = arcname.replace(os.sep, "/")
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
1836 arcname = arcname.lstrip("/")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1837
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1838 # Now, fill the TarInfo object with
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1839 # information specific for the file.
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1840 tarinfo = self.tarinfo()
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1841 tarinfo.tarfile = self
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1842
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1843 # Use os.stat or os.lstat, depending on platform
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1844 # and if symlinks shall be resolved.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1845 if fileobj is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1846 if hasattr(os, "lstat") and not self.dereference:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1847 statres = os.lstat(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1848 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1849 statres = os.stat(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1850 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1851 statres = os.fstat(fileobj.fileno())
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1852 linkname = ""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1853
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1854 stmd = statres.st_mode
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1855 if stat.S_ISREG(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1856 inode = (statres.st_ino, statres.st_dev)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1857 if not self.dereference and statres.st_nlink > 1 and \
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1858 inode in self.inodes and arcname != self.inodes[inode]:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1859 # Is it a hardlink to an already
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1860 # archived file?
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1861 type = LNKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1862 linkname = self.inodes[inode]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1863 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1864 # The inode is added only if its valid.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1865 # For win32 it is always 0.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1866 type = REGTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1867 if inode[0]:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1868 self.inodes[inode] = arcname
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1869 elif stat.S_ISDIR(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1870 type = DIRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1871 elif stat.S_ISFIFO(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1872 type = FIFOTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1873 elif stat.S_ISLNK(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1874 type = SYMTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1875 linkname = os.readlink(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1876 elif stat.S_ISCHR(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1877 type = CHRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1878 elif stat.S_ISBLK(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1879 type = BLKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1880 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1881 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1882
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1883 # Fill the TarInfo object with all
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1884 # information we can get.
35466
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1885 tarinfo.name = arcname
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1886 tarinfo.mode = stmd
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1887 tarinfo.uid = statres.st_uid
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1888 tarinfo.gid = statres.st_gid
62041
ed983b116a7d Merged revisions 81663 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 61090
diff changeset
1889 if type == REGTYPE:
35466
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1890 tarinfo.size = statres.st_size
33208
04864c39b006 Replace tricky and/or with straight-forward if:else:
Martin v. Löwis <martin@v.loewis.de>
parents: 33179
diff changeset
1891 else:
35466
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1892 tarinfo.size = 0L
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1893 tarinfo.mtime = statres.st_mtime
35466
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1894 tarinfo.type = type
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1895 tarinfo.linkname = linkname
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1896 if pwd:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1897 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1898 tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1899 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1900 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1901 if grp:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1902 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1903 tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1904 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1905 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1906
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1907 if type in (CHRTYPE, BLKTYPE):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1908 if hasattr(os, "major") and hasattr(os, "minor"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1909 tarinfo.devmajor = os.major(statres.st_rdev)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1910 tarinfo.devminor = os.minor(statres.st_rdev)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1911 return tarinfo
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1912
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1913 def list(self, verbose=True):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1914 """Print a table of contents to sys.stdout. If `verbose' is False, only
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1915 the names of the members are printed. If it is True, an `ls -l'-like
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1916 output is produced.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1917 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1918 self._check()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1919
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1920 for tarinfo in self:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1921 if verbose:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1922 print filemode(tarinfo.mode),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1923 print "%s/%s" % (tarinfo.uname or tarinfo.uid,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1924 tarinfo.gname or tarinfo.gid),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1925 if tarinfo.ischr() or tarinfo.isblk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1926 print "%10s" % ("%d,%d" \
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1927 % (tarinfo.devmajor, tarinfo.devminor)),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1928 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1929 print "%10d" % tarinfo.size,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1930 print "%d-%02d-%02d %02d:%02d:%02d" \
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1931 % time.localtime(tarinfo.mtime)[:6],
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1932
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1933 print tarinfo.name + ("/" if tarinfo.isdir() else ""),
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1934
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1935 if verbose:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1936 if tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1937 print "->", tarinfo.linkname,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1938 if tarinfo.islnk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1939 print "link to", tarinfo.linkname,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1940 print
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1941
55916
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1942 def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1943 """Add the file `name' to the archive. `name' may be any type of file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1944 (directory, fifo, symbolic link, etc.). If given, `arcname'
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1945 specifies an alternative name for the file in the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1946 Directories are added recursively by default. This can be avoided by
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1947 setting `recursive' to False. `exclude' is a function that should
55916
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1948 return True for each filename to be excluded. `filter' is a function
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1949 that expects a TarInfo object argument and returns the changed
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1950 TarInfo object, if it returns None the TarInfo object will be
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1951 excluded from the archive.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1952 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1953 self._check("aw")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1954
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1955 if arcname is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1956 arcname = name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1957
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1958 # Exclude pathnames.
55916
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1959 if exclude is not None:
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1960 import warnings
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1961 warnings.warn("use the filter argument instead",
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1962 DeprecationWarning, 2)
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1963 if exclude(name):
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1964 self._dbg(2, "tarfile: Excluded %r" % name)
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1965 return
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1966
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1967 # Skip if somebody tries to archive the archive...
40520
ef4b8fcd14d7 Patch #1262036: Prevent TarFiles from being added to themselves under
Lars Gustäbel <lars@gustaebel.de>
parents: 40518
diff changeset
1968 if self.name is not None and os.path.abspath(name) == self.name:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1969 self._dbg(2, "tarfile: Skipped %r" % name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1970 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1971
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1972 self._dbg(1, name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1973
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1974 # Create a TarInfo object from the file.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1975 tarinfo = self.gettarinfo(name, arcname)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1976
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1977 if tarinfo is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1978 self._dbg(1, "tarfile: Unsupported type %r" % name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1979 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1980
55916
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1981 # Change or exclude the TarInfo object.
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1982 if filter is not None:
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1983 tarinfo = filter(tarinfo)
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1984 if tarinfo is None:
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1985 self._dbg(2, "tarfile: Excluded %r" % name)
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1986 return
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1987
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1988 # Append the tar header and data to the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1989 if tarinfo.isreg():
80651
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
1990 with bltn_open(name, "rb") as f:
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
1991 self.addfile(tarinfo, f)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1992
35466
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
1993 elif tarinfo.isdir():
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1994 self.addfile(tarinfo)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1995 if recursive:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1996 for f in os.listdir(name):
55916
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1997 self.add(os.path.join(name, f), os.path.join(arcname, f),
ecd22850d201 Issue #6856: Add a filter keyword argument to TarFile.add().
Lars Gustäbel <lars@gustaebel.de>
parents: 55746
diff changeset
1998 recursive, exclude, filter)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1999
35466
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
2000 else:
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
2001 self.addfile(tarinfo)
85960ca4fc08 Patch #1168594: set sizes of non-regular files to zero. Fixes #1167128.
Martin v. Löwis <martin@v.loewis.de>
parents: 35403
diff changeset
2002
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2003 def addfile(self, tarinfo, fileobj=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2004 """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2005 given, tarinfo.size bytes are read from it and added to the archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2006 You can create TarInfo objects using gettarinfo().
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2007 On Windows platforms, `fileobj' should always be opened with mode
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2008 'rb' to avoid irritation about the file size.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2009 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2010 self._check("aw")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2011
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
2012 tarinfo = copy.copy(tarinfo)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2013
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
2014 buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
2015 self.fileobj.write(buf)
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
2016 self.offset += len(buf)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2017
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2018 # If there's data to follow, append it.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2019 if fileobj is not None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2020 copyfileobj(fileobj, self.fileobj, tarinfo.size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2021 blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2022 if remainder > 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2023 self.fileobj.write(NUL * (BLOCKSIZE - remainder))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2024 blocks += 1
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2025 self.offset += blocks * BLOCKSIZE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2026
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2027 self.members.append(tarinfo)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2028
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2029 def extractall(self, path=".", members=None):
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2030 """Extract all members from the archive to the current working
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2031 directory and set owner, modification time and permissions on
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2032 directories afterwards. `path' specifies a different directory
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2033 to extract to. `members' is optional and must be a subset of the
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2034 list returned by getmembers().
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2035 """
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2036 directories = []
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2037
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2038 if members is None:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2039 members = self
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2040
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2041 for tarinfo in members:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2042 if tarinfo.isdir():
45165
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2043 # Extract directories with a safe mode.
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2044 directories.append(tarinfo)
45165
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2045 tarinfo = copy.copy(tarinfo)
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2046 tarinfo.mode = 0700
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2047 self.extract(tarinfo, path)
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2048
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2049 # Reverse sort directories.
48175
979f0a89903f Remove a dict.has_key() and list.sort(cmp=) usage from tarfile to silence
Brett Cannon <bcannon@gmail.com>
parents: 48138
diff changeset
2050 directories.sort(key=operator.attrgetter('name'))
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2051 directories.reverse()
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2052
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2053 # Set correct owner, mtime and filemode on directories.
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2054 for tarinfo in directories:
44471
292c5e51a0e5 Issue #1735: TarFile.extractall() now correctly sets directory
Lars Gustäbel <lars@gustaebel.de>
parents: 44092
diff changeset
2055 dirpath = os.path.join(path, tarinfo.name)
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2056 try:
44471
292c5e51a0e5 Issue #1735: TarFile.extractall() now correctly sets directory
Lars Gustäbel <lars@gustaebel.de>
parents: 44092
diff changeset
2057 self.chown(tarinfo, dirpath)
292c5e51a0e5 Issue #1735: TarFile.extractall() now correctly sets directory
Lars Gustäbel <lars@gustaebel.de>
parents: 44092
diff changeset
2058 self.utime(tarinfo, dirpath)
292c5e51a0e5 Issue #1735: TarFile.extractall() now correctly sets directory
Lars Gustäbel <lars@gustaebel.de>
parents: 44092
diff changeset
2059 self.chmod(tarinfo, dirpath)
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2060 except ExtractError, e:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2061 if self.errorlevel > 1:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2062 raise
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2063 else:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2064 self._dbg(1, "tarfile: %s" % e)
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2065
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2066 def extract(self, member, path=""):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2067 """Extract a member from the archive to the current working directory,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2068 using its full name. Its file information is extracted as accurately
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2069 as possible. `member' may be a filename or a TarInfo object. You can
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2070 specify a different directory using `path'.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2071 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2072 self._check("r")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2073
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2074 if isinstance(member, basestring):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2075 tarinfo = self.getmember(member)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2076 else:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2077 tarinfo = member
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2078
32769
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2079 # Prepare the link target for makelink().
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2080 if tarinfo.islnk():
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2081 tarinfo._link_target = os.path.join(path, tarinfo.linkname)
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2082
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2083 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2084 self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2085 except EnvironmentError, e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2086 if self.errorlevel > 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2087 raise
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2088 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2089 if e.filename is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2090 self._dbg(1, "tarfile: %s" % e.strerror)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2091 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2092 self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2093 except ExtractError, e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2094 if self.errorlevel > 1:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2095 raise
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2096 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2097 self._dbg(1, "tarfile: %s" % e)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2099 def extractfile(self, member):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2100 """Extract a member from the archive as a file object. `member' may be
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2101 a filename or a TarInfo object. If `member' is a regular file, a
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2102 file-like object is returned. If `member' is a link, a file-like
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2103 object is constructed from the link's target. If `member' is none of
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2104 the above, None is returned.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2105 The file-like object is read-only and provides the following
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2106 methods: read(), readline(), readlines(), seek() and tell()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2107 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2108 self._check("r")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2109
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2110 if isinstance(member, basestring):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2111 tarinfo = self.getmember(member)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2112 else:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2113 tarinfo = member
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2114
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2115 if tarinfo.isreg():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2116 return self.fileobject(self, tarinfo)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2117
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2118 elif tarinfo.type not in SUPPORTED_TYPES:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2119 # If a member's type is unknown, it is treated as a
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2120 # regular file.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2121 return self.fileobject(self, tarinfo)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2122
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2123 elif tarinfo.islnk() or tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2124 if isinstance(self.fileobj, _Stream):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2125 # A small but ugly workaround for the case that someone tries
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2126 # to extract a (sym)link as a file-object from a non-seekable
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2127 # stream of tar blocks.
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2128 raise StreamError("cannot extract (sym)link as file object")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2129 else:
35276
4adbd331d335 Fix all wrong instances of "it's".
Georg Brandl <georg@python.org>
parents: 34818
diff changeset
2130 # A (sym)link's file object is its target's file object.
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2131 return self.extractfile(self._find_link_target(tarinfo))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2132 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2133 # If there's no data associated with the member (directory, chrdev,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2134 # blkdev, etc.), return None instead of a file object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2135 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2136
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2137 def _extract_member(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2138 """Extract the TarInfo object tarinfo to a physical
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2139 file called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2140 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2141 # Fetch the TarInfo object for the given name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2142 # and build the destination pathname, replacing
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2143 # forward slashes to platform specific separators.
55746
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
2144 targetpath = targetpath.rstrip("/")
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
2145 targetpath = targetpath.replace("/", os.sep)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2146
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2147 # Create all upper directories.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2148 upperdirs = os.path.dirname(targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2149 if upperdirs and not os.path.exists(upperdirs):
45165
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2150 # Create directories that are not part of the archive with
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2151 # default permissions.
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2152 os.makedirs(upperdirs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2153
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2154 if tarinfo.islnk() or tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2155 self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2156 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2157 self._dbg(1, tarinfo.name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2158
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2159 if tarinfo.isreg():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2160 self.makefile(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2161 elif tarinfo.isdir():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2162 self.makedir(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2163 elif tarinfo.isfifo():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2164 self.makefifo(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2165 elif tarinfo.ischr() or tarinfo.isblk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2166 self.makedev(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2167 elif tarinfo.islnk() or tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2168 self.makelink(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2169 elif tarinfo.type not in SUPPORTED_TYPES:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2170 self.makeunknown(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2171 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2172 self.makefile(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2173
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2174 self.chown(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2175 if not tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2176 self.chmod(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2177 self.utime(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2178
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2179 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2180 # Below are the different file methods. They are called via
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2181 # _extract_member() when extract() is called. They can be replaced in a
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2182 # subclass to implement other functionality.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2183
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2184 def makedir(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2185 """Make a directory called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2186 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2187 try:
45165
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2188 # Use a safe mode for the directory, the real mode is set
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2189 # later in _extract_member().
f2f991634781 Issue #1507247, #2004: Use mode 0700 for temporary directories and
Lars Gustäbel <lars@gustaebel.de>
parents: 44471
diff changeset
2190 os.mkdir(targetpath, 0700)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2191 except EnvironmentError, e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2192 if e.errno != errno.EEXIST:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2193 raise
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2194
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2195 def makefile(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2196 """Make a file called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2197 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2198 source = self.extractfile(tarinfo)
80651
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
2199 try:
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
2200 with bltn_open(targetpath, "wb") as target:
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
2201 copyfileobj(source, target)
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
2202 finally:
ea4bdf5a2e69 Issue #16477: Close tarfile internal handlers in case of exception.
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 76540
diff changeset
2203 source.close()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2204
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2205 def makeunknown(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2206 """Make a file from a TarInfo object with an unknown type
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2207 at targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2208 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2209 self.makefile(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2210 self._dbg(1, "tarfile: Unknown file type %r, " \
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2211 "extracted as regular file." % tarinfo.type)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2212
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2213 def makefifo(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2214 """Make a fifo called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2215 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2216 if hasattr(os, "mkfifo"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2217 os.mkfifo(targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2218 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2219 raise ExtractError("fifo not supported by system")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2220
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2221 def makedev(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2222 """Make a character or block device called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2223 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2224 if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2225 raise ExtractError("special devices not supported by system")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2226
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2227 mode = tarinfo.mode
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2228 if tarinfo.isblk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2229 mode |= stat.S_IFBLK
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2230 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2231 mode |= stat.S_IFCHR
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2232
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2233 os.mknod(targetpath, mode,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2234 os.makedev(tarinfo.devmajor, tarinfo.devminor))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2235
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2236 def makelink(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2237 """Make a (symbolic) link called targetpath. If it cannot be created
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2238 (platform limitation), we try to make a copy of the referenced file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2239 instead of a link.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2240 """
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2241 if hasattr(os, "symlink") and hasattr(os, "link"):
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2242 # For systems that support symbolic and hard links.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2243 if tarinfo.issym():
70166
b29f0b6fcb76 Fix closes issue #12088 - fixes the tarfile.extractall issue when the
Senthil Kumaran <senthil@uthcode.com>
parents: 69653
diff changeset
2244 if os.path.lexists(targetpath):
69653
0c8bc3a0130a Fix closes issue10761: tarfile.extractall failure when symlinked files are present.
Senthil Kumaran <orsenthil@gmail.com>
parents: 68256
diff changeset
2245 os.unlink(targetpath)
55746
5f9e13066d36 Issue #6054: Do not normalize stored pathnames.
Lars Gustäbel <lars@gustaebel.de>
parents: 53901
diff changeset
2246 os.symlink(tarinfo.linkname, targetpath)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2247 else:
32769
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2248 # See extract().
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2249 if os.path.exists(tarinfo._link_target):
70166
b29f0b6fcb76 Fix closes issue #12088 - fixes the tarfile.extractall issue when the
Senthil Kumaran <senthil@uthcode.com>
parents: 69653
diff changeset
2250 if os.path.lexists(targetpath):
b29f0b6fcb76 Fix closes issue #12088 - fixes the tarfile.extractall issue when the
Senthil Kumaran <senthil@uthcode.com>
parents: 69653
diff changeset
2251 os.unlink(targetpath)
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2252 os.link(tarinfo._link_target, targetpath)
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2253 else:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2254 self._extract_member(self._find_link_target(tarinfo), targetpath)
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2255 else:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2256 try:
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2257 self._extract_member(self._find_link_target(tarinfo), targetpath)
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2258 except KeyError:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2259 raise ExtractError("unable to resolve link inside archive")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2260
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2261 def chown(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2262 """Set owner of targetpath according to tarinfo.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2263 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2264 if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2265 # We have to be root to do so.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2266 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2267 g = grp.getgrnam(tarinfo.gname)[2]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2268 except KeyError:
72274
b64ef2951093 Issue #12841: Fix tarfile extraction of non-existent uids/gids.
Lars Gustäbel <lars@gustaebel.de>
parents: 71539
diff changeset
2269 g = tarinfo.gid
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2270 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2271 u = pwd.getpwnam(tarinfo.uname)[2]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2272 except KeyError:
72274
b64ef2951093 Issue #12841: Fix tarfile extraction of non-existent uids/gids.
Lars Gustäbel <lars@gustaebel.de>
parents: 71539
diff changeset
2273 u = tarinfo.uid
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2274 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2275 if tarinfo.issym() and hasattr(os, "lchown"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2276 os.lchown(targetpath, u, g)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2277 else:
27972
53c802927202 OS/2 has no concept of file ownership, like DOS & MS Windows version
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 27507
diff changeset
2278 if sys.platform != "os2emx":
53c802927202 OS/2 has no concept of file ownership, like DOS & MS Windows version
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 27507
diff changeset
2279 os.chown(targetpath, u, g)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2280 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2281 raise ExtractError("could not change owner")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2282
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2283 def chmod(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2284 """Set file permissions of targetpath according to tarinfo.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2285 """
28214
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2286 if hasattr(os, 'chmod'):
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2287 try:
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2288 os.chmod(targetpath, tarinfo.mode)
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2289 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2290 raise ExtractError("could not change mode")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2291
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2292 def utime(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2293 """Set modification time of targetpath according to tarinfo.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2294 """
28214
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2295 if not hasattr(os, 'utime'):
28222
eca697e06a07 Somebody must not have run the test before checking this in -- it had
Tim Peters <tim.peters@gmail.com>
parents: 28217
diff changeset
2296 return
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2297 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2298 os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2299 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2300 raise ExtractError("could not change modification time")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2301
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2302 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2303 def next(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2304 """Return the next member of the archive as a TarInfo object, when
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2305 TarFile is opened for reading. Return None if there is no more
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2306 available.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2307 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2308 self._check("ra")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2309 if self.firstmember is not None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2310 m = self.firstmember
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2311 self.firstmember = None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2312 return m
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2313
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2314 # Read the next block.
32604
08d90460ab4d [Patch 988444]
Andrew M. Kuchling <amk@amk.ca>
parents: 31314
diff changeset
2315 self.fileobj.seek(self.offset)
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2316 tarinfo = None
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2317 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2318 try:
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2319 tarinfo = self.tarinfo.fromtarfile(self)
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2320 except EOFHeaderError, e:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2321 if self.ignore_zeros:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2322 self._dbg(2, "0x%X: %s" % (self.offset, e))
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2323 self.offset += BLOCKSIZE
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2324 continue
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2325 except InvalidHeaderError, e:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2326 if self.ignore_zeros:
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
2327 self._dbg(2, "0x%X: %s" % (self.offset, e))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2328 self.offset += BLOCKSIZE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2329 continue
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2330 elif self.offset == 0:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2331 raise ReadError(str(e))
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2332 except EmptyHeaderError:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2333 if self.offset == 0:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2334 raise ReadError("empty file")
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2335 except TruncatedHeaderError, e:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2336 if self.offset == 0:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2337 raise ReadError(str(e))
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2338 except SubsequentHeaderError, e:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2339 raise ReadError(str(e))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2340 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2341
57393
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2342 if tarinfo is not None:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2343 self.members.append(tarinfo)
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2344 else:
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2345 self._loaded = True
4e270eab452d Issue #6123: Fix opening empty archives and files.
Lars Gustäbel <lars@gustaebel.de>
parents: 57332
diff changeset
2346
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
2347 return tarinfo
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2348
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2349 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2350 # Little helper methods:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2351
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2352 def _getmember(self, name, tarinfo=None, normalize=False):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2353 """Find an archive member by name from bottom to top.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2354 If tarinfo is given, it is used as the starting point.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2355 """
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2356 # Ensure that all members have been loaded.
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2357 members = self.getmembers()
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2358
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2359 # Limit the member search list up to tarinfo.
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2360 if tarinfo is not None:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2361 members = members[:members.index(tarinfo)]
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2362
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2363 if normalize:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2364 name = os.path.normpath(name)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2365
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2366 for member in reversed(members):
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2367 if normalize:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2368 member_name = os.path.normpath(member.name)
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2369 else:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2370 member_name = member.name
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2371
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2372 if name == member_name:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2373 return member
32604
08d90460ab4d [Patch 988444]
Andrew M. Kuchling <amk@amk.ca>
parents: 31314
diff changeset
2374
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2375 def _load(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2376 """Read through the entire archive file and look for readable
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2377 members.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2378 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2379 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2380 tarinfo = self.next()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2381 if tarinfo is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2382 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2383 self._loaded = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2384
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2385 def _check(self, mode=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2386 """Check if TarFile is still open, and if the operation's mode
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2387 corresponds to TarFile's mode.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2388 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2389 if self.closed:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2390 raise IOError("%s is closed" % self.__class__.__name__)
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2391 if mode is not None and self.mode not in mode:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2392 raise IOError("bad operation for mode %r" % self.mode)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2393
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2394 def _find_link_target(self, tarinfo):
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2395 """Find the target member of a symlink or hardlink member in the
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2396 archive.
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2397 """
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2398 if tarinfo.issym():
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2399 # Always search the entire archive.
76540
aff14bea5596 Issue #14160: TarFile.extractfile() failed to resolve symbolic links when
Lars Gustäbel <lars@gustaebel.de>
parents: 74121
diff changeset
2400 linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname)))
62044
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2401 limit = None
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2402 else:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2403 # Search the archive before the link, because a hard link is
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2404 # just a reference to an already archived file.
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2405 linkname = tarinfo.linkname
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2406 limit = tarinfo
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2407
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2408 member = self._getmember(linkname, tarinfo=limit, normalize=True)
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2409 if member is None:
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2410 raise KeyError("linkname %r not found" % linkname)
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2411 return member
9af600a66115 Issue #8741: Fixed the TarFile.makelink() method that is responsible
Lars Gustäbel <lars@gustaebel.de>
parents: 62040
diff changeset
2412
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2413 def __iter__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2414 """Provide an iterator object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2415 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2416 if self._loaded:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2417 return iter(self.members)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2418 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2419 return TarIter(self)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2420
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2421 def _dbg(self, level, msg):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2422 """Write debugging output to sys.stderr.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2423 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2424 if level <= self.debug:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2425 print >> sys.stderr, msg
59301
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2426
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2427 def __enter__(self):
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2428 self._check()
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2429 return self
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2430
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2431 def __exit__(self, type, value, traceback):
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2432 if type is None:
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2433 self.close()
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2434 else:
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2435 # An exception occurred. We must not call close() because
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2436 # it would try to write end-of-archive blocks and padding.
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2437 if not self._extfileobj:
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2438 self.fileobj.close()
8ace2ead5523 Issue #7232: Add support for the context manager protocol
Lars Gustäbel <lars@gustaebel.de>
parents: 57679
diff changeset
2439 self.closed = True
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2440 # class TarFile
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2441
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2442 class TarIter:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2443 """Iterator Class.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2444
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2445 for tarinfo in TarFile(...):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2446 suite...
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2447 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2448
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2449 def __init__(self, tarfile):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2450 """Construct a TarIter object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2451 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2452 self.tarfile = tarfile
34680
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2453 self.index = 0
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2454 def __iter__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2455 """Return iterator object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2456 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2457 return self
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2458 def next(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2459 """Return the next item using TarFile's next() method.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2460 When all members have been read, set TarFile as _loaded.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2461 """
34680
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2462 # Fix for SF #1100429: Under rare circumstances it can
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2463 # happen that getmembers() is called during iteration,
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2464 # which will cause TarIter to stop prematurely.
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2465 if not self.tarfile._loaded:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2466 tarinfo = self.tarfile.next()
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2467 if not tarinfo:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2468 self.tarfile._loaded = True
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2469 raise StopIteration
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2470 else:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2471 try:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2472 tarinfo = self.tarfile.members[self.index]
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2473 except IndexError:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2474 raise StopIteration
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2475 self.index += 1
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2476 return tarinfo
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2477
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2478 # Helper classes for sparse file support
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2479 class _section:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2480 """Base class for _data and _hole.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2481 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2482 def __init__(self, offset, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2483 self.offset = offset
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2484 self.size = size
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2485 def __contains__(self, offset):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2486 return self.offset <= offset < self.offset + self.size
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2487
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2488 class _data(_section):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2489 """Represent a data section in a sparse file.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2490 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2491 def __init__(self, offset, size, realpos):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2492 _section.__init__(self, offset, size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2493 self.realpos = realpos
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2494
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2495 class _hole(_section):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2496 """Represent a hole section in a sparse file.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2497 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2498 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2499
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2500 class _ringbuffer(list):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2501 """Ringbuffer class which increases performance
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2502 over a regular list.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2503 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2504 def __init__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2505 self.idx = 0
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2506 def find(self, offset):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2507 idx = self.idx
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2508 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2509 item = self[idx]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2510 if offset in item:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2511 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2512 idx += 1
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2513 if idx == len(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2514 idx = 0
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2515 if idx == self.idx:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2516 # End of File
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2517 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2518 self.idx = idx
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2519 return item
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2520
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2521 #---------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2522 # zipfile compatible TarFile class
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2523 #---------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2524 TAR_PLAIN = 0 # zipfile.ZIP_STORED
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2525 TAR_GZIPPED = 8 # zipfile.ZIP_DEFLATED
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2526 class TarFileCompat:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2527 """TarFile class compatible with standard module zipfile's
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2528 ZipFile class.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2529 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2530 def __init__(self, file, mode="r", compression=TAR_PLAIN):
48138
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2531 from warnings import warnpy3k
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2532 warnpy3k("the TarFileCompat class has been removed in Python 3.0",
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2533 stacklevel=2)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2534 if compression == TAR_PLAIN:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2535 self.tarfile = TarFile.taropen(file, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2536 elif compression == TAR_GZIPPED:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2537 self.tarfile = TarFile.gzopen(file, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2538 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2539 raise ValueError("unknown compression constant")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2540 if mode[0:1] == "r":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2541 members = self.tarfile.getmembers()
35532
d504a302bf53 Minor cleanup.
Raymond Hettinger <python@rcn.com>
parents: 35466
diff changeset
2542 for m in members:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2543 m.filename = m.name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2544 m.file_size = m.size
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2545 m.date_time = time.gmtime(m.mtime)[:6]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2546 def namelist(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2547 return map(lambda m: m.name, self.infolist())
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2548 def infolist(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2549 return filter(lambda m: m.type in REGULAR_TYPES,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2550 self.tarfile.getmembers())
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2551 def printdir(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2552 self.tarfile.list()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2553 def testzip(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2554 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2555 def getinfo(self, name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2556 return self.tarfile.getmember(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2557 def read(self, name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2558 return self.tarfile.extractfile(self.tarfile.getmember(name)).read()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2559 def write(self, filename, arcname=None, compress_type=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2560 self.tarfile.add(filename, arcname)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2561 def writestr(self, zinfo, bytes):
34293
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2562 try:
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2563 from cStringIO import StringIO
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2564 except ImportError:
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2565 from StringIO import StringIO
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2566 import calendar
48138
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2567 tinfo = TarInfo(zinfo.filename)
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2568 tinfo.size = len(bytes)
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2569 tinfo.mtime = calendar.timegm(zinfo.date_time)
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2570 self.tarfile.addfile(tinfo, StringIO(bytes))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2571 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2572 self.tarfile.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2573 #class TarFileCompat
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2574
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2575 #--------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2576 # exported functions
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2577 #--------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2578 def is_tarfile(name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2579 """Return True if name points to a tar archive that we
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2580 are able to handle, else return False.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2581 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2582 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2583 t = open(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2584 t.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2585 return True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2586 except TarError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2587 return False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2588
41881
3877f37c9861 Remove direct call's to file's constructor and replace them with calls to
Brett Cannon <bcannon@gmail.com>
parents: 41153
diff changeset
2589 bltn_open = open
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2590 open = TarFile.open