annotate Lib/tarfile.py @ 58925:eecf1bef052d 2.6

Merged revisions 78207 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r78207 | ezio.melotti | 2010-02-17 01:26:09 +0200 (Wed, 17 Feb 2010) | 1 line #7930: fix stripid ........
author Ezio Melotti <ezio.melotti@gmail.com>
date Tue, 16 Feb 2010 23:29:44 +0000
parents a345bb50ec0f
children 6cda601f4c58
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
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
33 __version__ = "$Revision$"
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
28217
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
56 if sys.platform == 'mac':
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
57 # This module needs work for MacOS9, especially in the area of pathname
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
58 # handling. In many places it is assumed a simple substitution of / by the
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
59 # local os.path.sep is good enough to convert pathnames, but this does not
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
60 # work with the mac rooted:path:name versus :nonrooted:path:name syntax
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
61 raise ImportError, "tarfile does not work for platform==mac"
73b0dc28c91a Make tarfile raise ImportError on MacOS9. The pathname handling needs work, and I don't have time to fix it. I'll file a bug report.
Jack Jansen <jack.jansen@cwi.nl>
parents: 28214
diff changeset
62
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
63 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
64 import grp, pwd
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
65 except ImportError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
66 grp = pwd = None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
67
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
68 # from tarfile import *
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
69 __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
70
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
71 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
72 # tar constants
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
73 #---------------------------------------------------------
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
74 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
75 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
76 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
77 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
78 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
79
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
80 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
81 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
82 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
83
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
84 REGTYPE = "0" # regular file
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
85 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
86 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
87 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
88 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
89 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
90 DIRTYPE = "5" # directory
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
91 FIFOTYPE = "6" # fifo special device
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
92 CONTTYPE = "7" # contiguous file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
93
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
94 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
95 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
96 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
97
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
98 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
99 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
100 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
101
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
102 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
103 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
104 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
105 DEFAULT_FORMAT = GNU_FORMAT
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
106
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
107 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
108 # tarfile constants
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 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
111 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
112 SYMTYPE, DIRTYPE, FIFOTYPE,
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
113 CONTTYPE, CHRTYPE, BLKTYPE,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
114 GNUTYPE_LONGNAME, GNUTYPE_LONGLINK,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
115 GNUTYPE_SPARSE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
116
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
117 # 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
118 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
119 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
120
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
121 # 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
122 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
123 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
124
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
125 # 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
126 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
127 "uid", "gid", "uname", "gname")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
128
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
129 # 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
130 # 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
131 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
132 "atime": float,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
133 "ctime": float,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
134 "mtime": float,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
135 "uid": int,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
136 "gid": int,
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
137 "size": int
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
138 }
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
139
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
140 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
141 # 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
142 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
143 S_IFLNK = 0120000 # symbolic link
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
144 S_IFREG = 0100000 # regular file
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
145 S_IFBLK = 0060000 # block device
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
146 S_IFDIR = 0040000 # directory
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
147 S_IFCHR = 0020000 # character device
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
148 S_IFIFO = 0010000 # fifo
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
149
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
150 TSUID = 04000 # set UID on execution
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
151 TSGID = 02000 # set GID on execution
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
152 TSVTX = 01000 # reserved
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
153
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
154 TUREAD = 0400 # read by owner
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
155 TUWRITE = 0200 # write by owner
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
156 TUEXEC = 0100 # execute/search by owner
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
157 TGREAD = 0040 # read by group
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
158 TGWRITE = 0020 # write by group
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
159 TGEXEC = 0010 # execute/search by group
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
160 TOREAD = 0004 # read by other
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
161 TOWRITE = 0002 # write by other
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
162 TOEXEC = 0001 # execute/search by other
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
163
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
164 #---------------------------------------------------------
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
165 # initialization
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
166 #---------------------------------------------------------
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
167 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
168 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
169 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
170
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
171 #---------------------------------------------------------
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
172 # Some useful functions
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
173 #---------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
174
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
175 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
176 """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
177 """
40170
e82e696c03dc Patch [ 1583506 ] tarfile.py: 100-char filenames are truncated
Georg Brandl <georg@python.org>
parents: 40111
diff changeset
178 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
179
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
180 def nts(s):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
181 """Convert a null-terminated string field to a python string.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
182 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
183 # Use the string up to the first null char.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
184 p = s.find("\0")
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
185 if p == -1:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
186 return s
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
187 return s[:p]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
188
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
189 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
190 """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
191 """
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
192 # 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
193 # itn() below.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
194 if s[0] != chr(0200):
40491
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
195 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
196 n = int(nts(s) or "0", 8)
40491
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
197 except ValueError:
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
198 raise HeaderError("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
199 else:
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
200 n = 0L
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
201 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
202 n <<= 8
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
203 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
204 return n
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
205
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
206 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
207 """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
208 """
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
209 # 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
210 # 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
211 # (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
212 # 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
213 # 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
214 # 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
215 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
216 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
217 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
218 if format != GNU_FORMAT or n >= 256 ** (digits - 1):
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
219 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
220
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
221 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
222 # 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
223 # 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
224 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
225
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
226 s = ""
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
227 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
228 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
229 n >>= 8
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
230 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
231 return s
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
232
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
233 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
234 """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
235 """
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
236 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
237 # 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
238 # 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
239 # 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
240 try:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
241 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
242 except UnicodeEncodeError:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
243 x = []
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
244 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
245 try:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
246 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
247 except UnicodeEncodeError:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
248 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
249 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
250 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
251 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
252
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
253 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
254 """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
255 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
256 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
257 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
258 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
259 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
260 signed.
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
261 """
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
262 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
263 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
264 return unsigned_chksum, signed_chksum
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
265
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
266 def copyfileobj(src, dst, length=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
267 """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
268 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
269 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
270 if length == 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
271 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
272 if length is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
273 shutil.copyfileobj(src, dst)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
274 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
275
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
276 BUFSIZE = 16 * 1024
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
277 blocks, remainder = divmod(length, BUFSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
278 for b in xrange(blocks):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
279 buf = src.read(BUFSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
280 if len(buf) < BUFSIZE:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
281 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
282 dst.write(buf)
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 if remainder != 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
285 buf = src.read(remainder)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
286 if len(buf) < remainder:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
287 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
288 dst.write(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
289 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
290
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
291 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
292 ((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
293 (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
294 (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
295 (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
296 (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
297 (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
298
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 ((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
300 ((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
301 ((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
302 (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
303 (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
304
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 ((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
306 ((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
307 ((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
308 (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
309 (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
310
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
311 ((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
312 ((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
313 ((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
314 (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
315 (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
316 )
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
317
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
318 def filemode(mode):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
319 """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
320 -rwxrwxrwx.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
321 Used by TarFile.list()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
322 """
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
323 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
324 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
325 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
326 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
327 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
328 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
329 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
330 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
331 return "".join(perm)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
332
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
333 if os.sep != "/":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
334 normpath = lambda path: os.path.normpath(path).replace(os.sep, "/")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
335 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
336 normpath = os.path.normpath
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
337
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
338 class TarError(Exception):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
339 """Base exception."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
340 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
341 class ExtractError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
342 """General exception for extract errors."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
343 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
344 class ReadError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
345 """Exception for unreadble tar archives."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
346 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
347 class CompressionError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
348 """Exception for unavailable compression methods."""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
349 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
350 class StreamError(TarError):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
351 """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
352 pass
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
353 class HeaderError(TarError):
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
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
356
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
357 #---------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
358 # internal stream interface
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 class _LowLevelFile:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
361 """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
362 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
363 access.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
364 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
365
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
366 def __init__(self, name, mode):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
367 mode = {
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
368 "r": os.O_RDONLY,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
369 "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
370 }[mode]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
371 if hasattr(os, "O_BINARY"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
372 mode |= os.O_BINARY
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
373 self.fd = os.open(name, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
374
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
375 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
376 os.close(self.fd)
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 read(self, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
379 return os.read(self.fd, size)
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 write(self, s):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
382 os.write(self.fd, s)
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 class _Stream:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
385 """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
386 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
387 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
388 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
389 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
390 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
391
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
392 _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
393 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
394
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
395 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
396 """Construct a _Stream object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
397 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
398 self._extfileobj = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
399 if fileobj is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
400 fileobj = _LowLevelFile(name, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
401 self._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
402
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
403 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
404 # 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
405 # 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
406 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
407 comptype = fileobj.getcomptype()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
408
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
409 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
410 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
411 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
412 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
413 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
414 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
415 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
416 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
417
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 if comptype == "gz":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
419 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
420 import zlib
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
421 except ImportError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
422 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
423 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
424 self.crc = zlib.crc32("") & 0xffffffffL
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
425 if mode == "r":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
426 self._init_read_gz()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
427 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
428 self._init_write_gz()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
429
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
430 if comptype == "bz2":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
431 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
432 import bz2
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
433 except ImportError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
434 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
435 if mode == "r":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
436 self.dbuf = ""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
437 self.cmp = bz2.BZ2Decompressor()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
438 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
439 self.cmp = bz2.BZ2Compressor()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
440
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
441 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
442 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
443 self.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
444
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
445 def _init_write_gz(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
446 """Initialize for writing with gzip compression.
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 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
449 -self.zlib.MAX_WBITS,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
450 self.zlib.DEF_MEM_LEVEL,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
451 0)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
452 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
453 self.__write("\037\213\010\010%s\002\377" % timestamp)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
454 if self.name.endswith(".gz"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
455 self.name = self.name[:-3]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
456 self.__write(self.name + NUL)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
457
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
458 def write(self, s):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
459 """Write string s to the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
460 """
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
461 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
462 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
463 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
464 if self.comptype != "tar":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
465 s = self.cmp.compress(s)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
466 self.__write(s)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
467
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
468 def __write(self, s):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
469 """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
470 is ready to be written.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
471 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
472 self.buf += s
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
473 while len(self.buf) > self.bufsize:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
474 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
475 self.buf = self.buf[self.bufsize:]
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 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
478 """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
479 done on it afterwards.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
480 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
481 if self.closed:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
482 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
483
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
484 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
485 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
486
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
487 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
488 self.fileobj.write(self.buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
489 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
490 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
491 # 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
492 # 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
493 # 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
494 # 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
495 # 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
496 # 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
497 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
498 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
499
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
500 if not self._extfileobj:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
501 self.fileobj.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
502
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
503 self.closed = True
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 def _init_read_gz(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
506 """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
507 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
508 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
509 self.dbuf = ""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
510
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
511 # 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
512 if self.__read(2) != "\037\213":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
513 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
514 if self.__read(1) != "\010":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
515 raise CompressionError("unsupported compression method")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
516
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
517 flag = ord(self.__read(1))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
518 self.__read(6)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
519
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
520 if flag & 4:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
521 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
522 self.read(xlen)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
523 if flag & 8:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
524 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
525 s = self.__read(1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
526 if not s or s == NUL:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
527 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
528 if flag & 16:
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 & 2:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
534 self.__read(2)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
535
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
536 def tell(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
537 """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
538 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
539 return self.pos
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 seek(self, pos=0):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
542 """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
543 is forbidden.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
544 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
545 if pos - self.pos >= 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
546 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
547 for i in xrange(blocks):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
548 self.read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
549 self.read(remainder)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
550 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
551 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
552 return self.pos
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
553
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
554 def read(self, size=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
555 """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
556 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
557 up to EOF.
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 if size is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
560 t = []
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
561 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
562 buf = self._read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
563 if not buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
564 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
565 t.append(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
566 buf = "".join(t)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
567 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
568 buf = self._read(size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
569 self.pos += len(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
570 return buf
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
571
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
572 def _read(self, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
573 """Return size bytes from the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
574 """
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
575 if self.comptype == "tar":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
576 return self.__read(size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
577
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
578 c = len(self.dbuf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
579 t = [self.dbuf]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
580 while c < size:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
581 buf = self.__read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
582 if not buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
583 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
584 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
585 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
586 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
587 raise ReadError("invalid compressed data")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
588 t.append(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
589 c += len(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
590 t = "".join(t)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
591 self.dbuf = t[size:]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
592 return t[:size]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
593
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
594 def __read(self, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
595 """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
596 read another block from the stream.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
597 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
598 c = len(self.buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
599 t = [self.buf]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
600 while c < size:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
601 buf = self.fileobj.read(self.bufsize)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
602 if not buf:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
603 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
604 t.append(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
605 c += len(buf)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
606 t = "".join(t)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
607 self.buf = t[size:]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
608 return t[:size]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
609 # class _Stream
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
610
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
611 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
612 """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
613 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
614 """
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
615
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 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
617 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
618 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
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 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
621 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
622 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
623
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 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
625 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
626 return "gz"
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 if self.buf.startswith("BZh91"):
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 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
629 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
630
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 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
632 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
633 # 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
634
38185
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
635 class _BZ2Proxy(object):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
636 """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
637 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
638 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
639 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
640 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
641 """
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
642
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
643 blocksize = 16 * 1024
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
644
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
645 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
646 self.fileobj = fileobj
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
647 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
648 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
649 self.init()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
650
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
651 def init(self):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
652 import bz2
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
653 self.pos = 0
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
654 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
655 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
656 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
657 self.buf = ""
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
658 else:
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
659 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
660
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
661 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
662 b = [self.buf]
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
663 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
664 while x < size:
52268
856ed418768c Merged revisions 70523 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 50130
diff changeset
665 raw = self.fileobj.read(self.blocksize)
856ed418768c Merged revisions 70523 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 50130
diff changeset
666 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
667 break
52272
6cb843075e69 Avoid EOFError being passed to the caller (restoring the
Lars Gustäbel <lars@gustaebel.de>
parents: 52268
diff changeset
668 try:
6cb843075e69 Avoid EOFError being passed to the caller (restoring the
Lars Gustäbel <lars@gustaebel.de>
parents: 52268
diff changeset
669 data = self.bz2obj.decompress(raw)
6cb843075e69 Avoid EOFError being passed to the caller (restoring the
Lars Gustäbel <lars@gustaebel.de>
parents: 52268
diff changeset
670 except EOFError:
6cb843075e69 Avoid EOFError being passed to the caller (restoring the
Lars Gustäbel <lars@gustaebel.de>
parents: 52268
diff changeset
671 break
52268
856ed418768c Merged revisions 70523 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 50130
diff changeset
672 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
673 x += len(data)
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
674 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
675
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
676 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
677 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
678 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
679 return buf
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
680
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
681 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
682 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
683 self.init()
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
684 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
685
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
686 def tell(self):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
687 return self.pos
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
688
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
689 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
690 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
691 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
692 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
693
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
694 def close(self):
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
695 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
696 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
697 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
698 # class _BZ2Proxy
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
699
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
700 #------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
701 # Extraction file object
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
702 #------------------------
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
703 class _FileInFile(object):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
704 """A thin wrapper around an existing file object that
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
705 provides a part of its data as an individual file
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
706 object.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
707 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
708
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
709 def __init__(self, fileobj, offset, size, sparse=None):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
710 self.fileobj = fileobj
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
711 self.offset = offset
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
712 self.size = size
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
713 self.sparse = sparse
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
714 self.position = 0
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
715
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
716 def tell(self):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
717 """Return the current file position.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
718 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
719 return self.position
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
720
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
721 def seek(self, position):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
722 """Seek to a position in the file.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
723 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
724 self.position = position
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
725
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
726 def read(self, size=None):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
727 """Read data from the file.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
728 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
729 if size is None:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
730 size = self.size - self.position
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
731 else:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
732 size = min(size, self.size - self.position)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
733
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
734 if self.sparse is None:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
735 return self.readnormal(size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
736 else:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
737 return self.readsparse(size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
738
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
739 def readnormal(self, size):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
740 """Read operation for regular files.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
741 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
742 self.fileobj.seek(self.offset + self.position)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
743 self.position += size
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
744 return self.fileobj.read(size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
745
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
746 def readsparse(self, size):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
747 """Read operation for sparse files.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
748 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
749 data = []
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
750 while size > 0:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
751 buf = self.readsparsesection(size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
752 if not buf:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
753 break
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
754 size -= len(buf)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
755 data.append(buf)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
756 return "".join(data)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
757
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
758 def readsparsesection(self, size):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
759 """Read a single section of a sparse file.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
760 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
761 section = self.sparse.find(self.position)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
762
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
763 if section is None:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
764 return ""
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
765
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
766 size = min(size, section.offset + section.size - self.position)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
767
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
768 if isinstance(section, _data):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
769 realpos = section.realpos + self.position - section.offset
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
770 self.fileobj.seek(self.offset + realpos)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
771 self.position += size
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
772 return self.fileobj.read(size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
773 else:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
774 self.position += size
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
775 return NUL * size
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
776 #class _FileInFile
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
777
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
778
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
779 class ExFileObject(object):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
780 """File-like object for reading an archive member.
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
781 Is returned by TarFile.extractfile().
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
782 """
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
783 blocksize = 1024
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
784
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
785 def __init__(self, tarfile, tarinfo):
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
786 self.fileobj = _FileInFile(tarfile.fileobj,
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
787 tarinfo.offset_data,
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
788 tarinfo.size,
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
789 getattr(tarinfo, "sparse", None))
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
790 self.name = tarinfo.name
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
791 self.mode = "r"
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
792 self.closed = False
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
793 self.size = tarinfo.size
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
794
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
795 self.position = 0
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
796 self.buffer = ""
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
797
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
798 def read(self, size=None):
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
799 """Read at most size bytes from the file. If size is not
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
800 present or None, read all data until EOF is reached.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
801 """
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
802 if self.closed:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
803 raise ValueError("I/O operation on closed file")
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
804
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
805 buf = ""
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
806 if self.buffer:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
807 if size is None:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
808 buf = self.buffer
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
809 self.buffer = ""
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
810 else:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
811 buf = self.buffer[:size]
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
812 self.buffer = self.buffer[size:]
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
813
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
814 if size is None:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
815 buf += self.fileobj.read()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
816 else:
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
817 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
818
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
819 self.position += len(buf)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
820 return buf
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
821
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
822 def readline(self, size=-1):
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
823 """Read one entire line from the file. If size is present
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
824 and non-negative, return a string with at most that
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
825 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
826 """
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
827 if self.closed:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
828 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
829
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
830 if "\n" in self.buffer:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
831 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
832 else:
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
833 buffers = [self.buffer]
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
834 while True:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
835 buf = self.fileobj.read(self.blocksize)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
836 buffers.append(buf)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
837 if not buf or "\n" in buf:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
838 self.buffer = "".join(buffers)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
839 pos = self.buffer.find("\n") + 1
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
840 if pos == 0:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
841 # no newline found.
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
842 pos = len(self.buffer)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
843 break
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
844
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
845 if size != -1:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
846 pos = min(size, pos)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
847
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
848 buf = self.buffer[:pos]
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
849 self.buffer = self.buffer[pos:]
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
850 self.position += len(buf)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
851 return buf
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
852
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
853 def readlines(self):
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
854 """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
855 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
856 result = []
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
857 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
858 line = self.readline()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
859 if not line: break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
860 result.append(line)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
861 return result
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
862
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
863 def tell(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
864 """Return the current file position.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
865 """
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
866 if self.closed:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
867 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
868
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
869 return self.position
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
870
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
871 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
872 """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
873 """
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
874 if self.closed:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
875 raise ValueError("I/O operation on closed file")
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
876
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
877 if whence == os.SEEK_SET:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
878 self.position = min(max(pos, 0), self.size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
879 elif whence == os.SEEK_CUR:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
880 if pos < 0:
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
881 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
882 else:
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
883 self.position = min(self.position + pos, self.size)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
884 elif whence == os.SEEK_END:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
885 self.position = max(min(self.size + pos, self.size), 0)
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
886 else:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
887 raise ValueError("Invalid argument")
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
888
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
889 self.buffer = ""
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
890 self.fileobj.seek(self.position)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
891
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
892 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
893 """Close the file object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
894 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
895 self.closed = True
34649
13a950a3624b Patch #1107973: tarfile.ExFileObject iterators.
Martin v. Löwis <martin@v.loewis.de>
parents: 34421
diff changeset
896
13a950a3624b Patch #1107973: tarfile.ExFileObject iterators.
Martin v. Löwis <martin@v.loewis.de>
parents: 34421
diff changeset
897 def __iter__(self):
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
898 """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
899 """
40517
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
900 while True:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
901 line = self.readline()
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
902 if not line:
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
903 break
5c7ea9346f12 Patch #1230446: tarfile.py: fix ExFileObject so that read() and tell()
Lars Gustäbel <lars@gustaebel.de>
parents: 40491
diff changeset
904 yield line
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
905 #class ExFileObject
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
906
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
907 #------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
908 # Exported Classes
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 class TarInfo(object):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
911 """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
912 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
913 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
914 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
915 usually created internally.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
916 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
917
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
918 def __init__(self, name=""):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
919 """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
920 of the member.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
921 """
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
922 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
923 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
924 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
925 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
926 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
927 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
928 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
929 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
930 self.linkname = "" # link 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
931 self.uname = "root" # user name
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
932 self.gname = "root" # 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
933 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
934 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
935
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
936 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
937 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
938
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
939 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
940
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
941 # 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
942 # "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
943 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
944 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
945 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
946 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
947 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
948
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
949 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
950 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
951 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
952 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
953 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
954
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
955 def __repr__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
956 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
957
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
958 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
959 """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
960 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
961 info = {
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
962 "name": normpath(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
963 "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
964 "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
965 "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
966 "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
967 "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
968 "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
969 "type": self.type,
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
970 "linkname": normpath(self.linkname) if self.linkname else "",
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
971 "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
972 "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
973 "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
974 "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
975 }
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
976
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
977 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
978 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
979
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
980 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
981 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
982 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
983
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
984 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
985
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
986 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
987 """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
988 """
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
989 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
990
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
991 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
992 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
993 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
994 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
995 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
996 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
997 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
998 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
999
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1000 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
1001 """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
1002 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1003 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
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 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
1006 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
1007
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1008 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
1009 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
1010
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1011 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
1012
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1013 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
1014 """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
1015 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1016 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
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 buf = ""
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1019 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
1020 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
1021
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1022 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
1023 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
1024
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1025 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
1026
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1027 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
1028 """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
1029 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
1030 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
1031 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1032 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
1033 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
1034
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1035 # 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
1036 # 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
1037 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
1038 ("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
1039 ("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
1040
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1041 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
1042 # 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
1043 continue
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1044
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1045 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
1046
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1047 # 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
1048 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1049 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
1050 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
1051 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
1052 continue
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1053
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1054 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
1055 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
1056
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1057 # 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
1058 # 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
1059 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
1060 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
1061 # 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
1062 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
1063 continue
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1064
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1065 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
1066 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
1067 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
1068 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
1069
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1070 # 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
1071 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
1072 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
1073 else:
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 = ""
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1075
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1076 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
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 @classmethod
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1079 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
1080 """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
1081 """
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1082 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
1083
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1084 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
1085 """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
1086 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
1087 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1088 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
1089 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
1090 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
1091
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1092 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
1093 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
1094
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1095 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
1096 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
1097 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
1098
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1099 @staticmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1100 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
1101 """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
1102 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
1103 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1104 parts = [
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1105 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
1106 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
1107 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
1108 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
1109 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
1110 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
1111 " ", # 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
1112 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
1113 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
1114 stn(info.get("magic", POSIX_MAGIC), 8),
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1115 stn(info.get("uname", "root"), 32),
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("gname", "root"), 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
1117 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
1118 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
1119 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
1120 ]
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1121
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1122 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
1123 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
1124 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
1125 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
1126
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1127 @staticmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1128 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
1129 """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
1130 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
1131 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1132 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
1133 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
1134 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
1135 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
1136
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1137 @classmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1138 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
1139 """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
1140 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
1141 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1142 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
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 info = {}
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1145 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
1146 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
1147 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
1148 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
1149
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1150 # 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
1151 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
1152 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
1153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1154 @classmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1155 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
1156 """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
1157 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
1158 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
1159 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1160 records = []
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1161 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
1162 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
1163 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
1164 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
1165 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
1166 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
1167 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
1168 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
1169 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1170 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
1171 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
1172 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
1173
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1174 # 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
1175 # 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
1176 info = {}
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1177 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
1178 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
1179 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
1180 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
1181
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1182 # 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
1183 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
1184 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
1185
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1186 @classmethod
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1187 def frombuf(cls, buf):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1188 """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
1189 """
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
1190 if len(buf) != BLOCKSIZE:
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
1191 raise HeaderError("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
1192 if buf.count(NUL) == BLOCKSIZE:
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
1193 raise HeaderError("empty header")
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
1194
40491
1250fe42ce5c Testcase for patch #1484695.
Georg Brandl <georg@python.org>
parents: 40487
diff changeset
1195 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
1196 if chksum not in calc_chksums(buf):
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
1197 raise HeaderError("bad checksum")
32770
a3b1d6c99e46 SF #918101, allow files >= 8 GB using GNU extension
Neal Norwitz <nnorwitz@gmail.com>
parents: 32769
diff changeset
1198
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1199 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
1200 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
1201 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
1202 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
1203 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
1204 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
1205 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
1206 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
1207 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
1208 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
1209 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
1210 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
1211 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
1212 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
1213 obj.devminor = nti(buf[337:345])
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1214 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
1215
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1216 # 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
1217 # 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
1218 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
1219 obj.type = DIRTYPE
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1220
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1221 # 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
1222 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
1223 obj.name = obj.name.rstrip("/")
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 # 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
1226 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
1227 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
1228 return obj
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1229
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1230 @classmethod
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1231 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
1232 """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
1233 tarfile.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1234 """
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1235 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
1236 if not buf:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1237 return
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1238 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
1239 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
1240 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
1241
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1242 #--------------------------------------------------------------------------
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1243 # 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
1244 # 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
1245 # 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
1246 # 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
1247 # operations:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1248 # 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
1249 # 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
1250 # 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
1251 # begin.
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1252 # 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
1253 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
1254 """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
1255 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
1256 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1257 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
1258 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
1259 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
1260 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
1261 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
1262 return self._proc_pax(tarfile)
40424
eb30d30f22a1 Patch #1610437: fix a tarfile bug with long filename headers.
Georg Brandl <georg@python.org>
parents: 40246
diff changeset
1263 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
1264 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
1265
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 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
1267 """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
1268 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
1269 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1270 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
1271 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
1272 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
1273 # 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
1274 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
1275 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
1276
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1277 # 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
1278 # 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
1279 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
1280
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1281 return self
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1282
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1283 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
1284 """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
1285 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
1286 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1287 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
1288
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1289 # Fetch the next header and process it.
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1290 next = self.fromtarfile(tarfile)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1291 if next is None:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1292 raise HeaderError("missing subsequent header")
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1293
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1294 # 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
1295 # 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
1296 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
1297 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
1298 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
1299 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
1300 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
1301
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1302 return next
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1303
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 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
1305 """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
1306 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1307 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
1308 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
1309 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
1310 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
1311 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
1312 # 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
1313 # 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
1314 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
1315 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1316 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
1317 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
1318 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
1319 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1320 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
1321 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
1322 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
1323 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
1324 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
1325 pos += 24
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1326
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1327 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
1328 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
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 # 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
1331 # 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
1332 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
1333 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
1334 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
1335 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
1336 try:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1337 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
1338 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
1339 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
1340 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1341 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
1342 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
1343 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
1344 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
1345 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
1346 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
1347 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
1348
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1349 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
1350 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
1351
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1352 self.sparse = sp
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1353
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1354 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
1355 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
1356 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
1357
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1358 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
1359
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1360 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
1361 """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
1362 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
1363 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1364 # 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
1365 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
1366
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1367 # 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
1368 # 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
1369 # (global).
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1370 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
1371 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
1372 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1373 pax_headers = tarfile.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
1374
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1375 # 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
1376 # "%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
1377 # 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
1378 # 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
1379 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
1380 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
1381 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
1382 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
1383 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
1384 break
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1385
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1386 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
1387 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
1388 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
1389
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1390 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
1391 value = value.decode("utf8")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1392
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1393 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
1394 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
1395
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1396 # Fetch the next header.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1397 next = self.fromtarfile(tarfile)
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1398
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1399 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
1400 if next is None:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1401 raise HeaderError("missing subsequent header")
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1402
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1403 # 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
1404 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
1405 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
1406
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
1407 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
1408 # 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
1409 # 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
1410 # header starts.
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1411 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
1412 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
1413 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
1414 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
1415
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1416 return next
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
1417
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1418 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
1419 """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
1420 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
1421 """
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1422 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
1423 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
1424 continue
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1425
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 == "path":
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1427 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
1428
41897
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 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
1430 try:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1431 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
1432 except ValueError:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1433 value = 0
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1434 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1435 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
1436
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1437 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
1438
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1439 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
1440
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1441 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
1442 """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
1443 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
1444 """
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1445 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
1446 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
1447 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
1448 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
1449
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1450 def isreg(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1451 return self.type in REGULAR_TYPES
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1452 def isfile(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1453 return self.isreg()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1454 def isdir(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1455 return self.type == DIRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1456 def issym(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1457 return self.type == SYMTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1458 def islnk(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1459 return self.type == LNKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1460 def ischr(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1461 return self.type == CHRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1462 def isblk(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1463 return self.type == BLKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1464 def isfifo(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1465 return self.type == FIFOTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1466 def issparse(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1467 return self.type == GNUTYPE_SPARSE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1468 def isdev(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1469 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
1470 # class TarInfo
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1471
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1472 class TarFile(object):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1473 """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
1474 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1475
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1476 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
1477
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1478 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
1479 # tar file, else the link.
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 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
1482 # continues processing.
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 errorlevel = 0 # If 0, fatal errors only appear in debug
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1485 # 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
1486 # 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
1487
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1488 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
1489
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1490 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
1491
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1492 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
1493
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1494 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
1495
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1496 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
1497
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1498 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
1499 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
1500 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
1501 """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
1502 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
1503 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
1504 defaults to 'r'.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1505 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
1506 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
1507 `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
1508 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1509 if len(mode) > 1 or mode not in "raw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1510 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
1511 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
1512 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
1513
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1514 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
1515 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
1516 # 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
1517 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
1518 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
1519 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
1520 self._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1521 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
1522 if name is None and hasattr(fileobj, "name"):
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1523 name = fileobj.name
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1524 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
1525 self._mode = fileobj.mode
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1526 self._extfileobj = True
42949
3bf2cad8f22a TarFile.__init__() no longer fails if no name argument is passed and
Lars Gustäbel <lars@gustaebel.de>
parents: 42109
diff changeset
1527 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
1528 self.fileobj = fileobj
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1529
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1530 # 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
1531 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
1532 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
1533 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
1534 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
1535 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
1536 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
1537 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
1538 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
1539 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
1540 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
1541
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1542 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
1543 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
1544 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
1545 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
1546 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1547 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
1548
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1549 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
1550 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
1551 else:
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
1552 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
1553
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1554 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
1555 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
1556 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
1557 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
1558
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1559 # 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
1560 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
1561 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
1562 self._loaded = False # flag if all members have been read
44091
e634511b4af5 Issue #1531: Read fileobj from the current offset, do not seek to
Lars Gustäbel <lars@gustaebel.de>
parents: 42949
diff changeset
1563 self.offset = self.fileobj.tell()
e634511b4af5 Issue #1531: Read fileobj from the current offset, do not seek to
Lars Gustäbel <lars@gustaebel.de>
parents: 42949
diff changeset
1564 # 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
1565 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
1566 # archive members already added
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1567
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1568 try:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1569 if self.mode == "r":
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1570 self.firstmember = None
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1571 self.firstmember = self.next()
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1572
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1573 if self.mode == "a":
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1574 # Move to the end of the archive,
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1575 # before the first empty block.
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1576 self.firstmember = None
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1577 while True:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1578 if self.next() is None:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1579 if self.offset > 0:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1580 self.fileobj.seek(- BLOCKSIZE, 1)
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1581 break
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1582
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1583 if self.mode in "aw":
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1584 self._loaded = True
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1585
57337
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1586 if self.pax_headers:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1587 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
1588 self.fileobj.write(buf)
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1589 self.offset += len(buf)
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1590 except:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1591 if not self._extfileobj:
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1592 self.fileobj.close()
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1593 self.closed = True
a345bb50ec0f Merged revisions 76381 via svnmerge from
Lars Gustäbel <lars@gustaebel.de>
parents: 55049
diff changeset
1594 raise
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1595
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1596 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
1597 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
1598 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
1599 import warnings
53903
a36fa2ce61b1 Merged revisions 72458 via svnmerge from
Philip Jenvey <pjenvey@underboss.org>
parents: 52272
diff changeset
1600 warnings.warn("use the format attribute instead", DeprecationWarning,
a36fa2ce61b1 Merged revisions 72458 via svnmerge from
Philip Jenvey <pjenvey@underboss.org>
parents: 52272
diff changeset
1601 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
1602 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
1603 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
1604 else:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1605 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
1606 posix = property(_getposix, _setposix)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1607
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1608 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1609 # 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
1610 # 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
1611 # 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
1612 # 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
1613 # from OPEN_METH.
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 # 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
1616 # 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
1617 # 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
1618
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1619 @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
1620 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
1621 """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
1622 an appropriate TarFile class.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1623
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1624 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
1625 '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
1626 'r:' open for reading exclusively uncompressed
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1627 '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
1628 '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
1629 '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
1630 '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
1631 '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
1632 '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
1633
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
1634 '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
1635 '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
1636 '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
1637 '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
1638 '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
1639 '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
1640 '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
1641 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1642
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1643 if not name and not fileobj:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1644 raise ValueError("nothing to open")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1645
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
1646 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
1647 # 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
1648 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
1649 func = getattr(cls, cls.OPEN_METH[comptype])
40523
e85ca3fd4bd6 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40519
diff changeset
1650 if fileobj is not None:
e85ca3fd4bd6 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40519
diff changeset
1651 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
1652 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
1653 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
1654 except (ReadError, CompressionError), e:
40523
e85ca3fd4bd6 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40519
diff changeset
1655 if fileobj is not None:
e85ca3fd4bd6 Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
Lars Gustäbel <lars@gustaebel.de>
parents: 40519
diff changeset
1656 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
1657 continue
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1658 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
1659
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
1660 elif ":" in mode:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1661 filemode, comptype = mode.split(":", 1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1662 filemode = filemode or "r"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1663 comptype = comptype or "tar"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1664
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1665 # Select the *open() function according to
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1666 # given compression.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1667 if comptype in cls.OPEN_METH:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1668 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
1669 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1670 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
1671 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
1672
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1673 elif "|" in mode:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1674 filemode, comptype = mode.split("|", 1)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1675 filemode = filemode or "r"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1676 comptype = comptype or "tar"
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1677
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1678 if filemode not in "rw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1679 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
1680
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1681 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
1682 _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
1683 **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1684 t._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1685 return t
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1686
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1687 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
1688 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
1689
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1690 raise ValueError("undiscernible mode")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1691
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1692 @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
1693 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
1694 """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
1695 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1696 if len(mode) > 1 or mode not in "raw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1697 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
1698 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
1699
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1700 @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
1701 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
1702 """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
1703 Appending is not allowed.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1704 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1705 if len(mode) > 1 or mode not in "rw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1706 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
1707
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1708 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1709 import gzip
28576
1bd50c28203f Fix test_tarfile failure when gzip is not available
Neal Norwitz <nnorwitz@gmail.com>
parents: 28222
diff changeset
1710 gzip.GzipFile
1bd50c28203f Fix test_tarfile failure when gzip is not available
Neal Norwitz <nnorwitz@gmail.com>
parents: 28222
diff changeset
1711 except (ImportError, AttributeError):
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1712 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
1713
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1714 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
1715 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
1716
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1717 try:
40519
6763e45c7f7d Patch #1262036: Prevent TarFiles from being added to themselves under
Lars Gustäbel <lars@gustaebel.de>
parents: 40517
diff changeset
1718 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
1719 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
1720 **kwargs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1721 except IOError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1722 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
1723 t._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1724 return t
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1725
34421
3316aa540e68 Use decorators.
Guido van Rossum <guido@python.org>
parents: 34293
diff changeset
1726 @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
1727 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
1728 """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
1729 Appending is not allowed.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1730 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1731 if len(mode) > 1 or mode not in "rw":
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1732 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
1733
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1734 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1735 import bz2
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1736 except ImportError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1737 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
1738
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1739 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
1740 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
1741 else:
ad8b76e99261 [ 1488881 ] tarfile.py: support for file-objects and bz2 (cp. #1488634)
Georg Brandl <georg@python.org>
parents: 38146
diff changeset
1742 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
1743
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1744 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
1745 t = 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
1746 except IOError:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1747 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
1748 t._extfileobj = False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1749 return t
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 # All *open() methods are registered here.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1752 OPEN_METH = {
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1753 "tar": "taropen", # uncompressed tar
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1754 "gz": "gzopen", # gzip compressed tar
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1755 "bz2": "bz2open" # bzip2 compressed tar
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1756 }
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 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1759 # The public methods which TarFile provides:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1760
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1761 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1762 """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
1763 appended to the archive.
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 if self.closed:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1766 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1767
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1768 if self.mode in "aw":
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1769 self.fileobj.write(NUL * (BLOCKSIZE * 2))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1770 self.offset += (BLOCKSIZE * 2)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1771 # 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
1772 # (like option -b20 for tar does)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1773 blocks, remainder = divmod(self.offset, RECORDSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1774 if remainder > 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1775 self.fileobj.write(NUL * (RECORDSIZE - remainder))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1776
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1777 if not self._extfileobj:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1778 self.fileobj.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1779 self.closed = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1780
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1781 def getmember(self, name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1782 """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
1783 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
1784 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
1785 most up-to-date version.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1786 """
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
1787 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
1788 if tarinfo is None:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
1789 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
1790 return tarinfo
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1791
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1792 def getmembers(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1793 """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
1794 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
1795 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1796 self._check()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1797 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
1798 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
1799 # scan the whole archive.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1800 return self.members
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1801
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1802 def getnames(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1803 """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
1804 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
1805 """
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
1806 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
1807
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1808 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
1809 """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
1810 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
1811 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
1812 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
1813 file in the archive.
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 self._check("aw")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1816
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1817 # 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
1818 # fileobj's real name.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1819 if fileobj is not None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1820 name = fileobj.name
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 # 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
1823 # 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
1824 # 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
1825 if arcname is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1826 arcname = name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1827 arcname = normpath(arcname)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1828 drv, arcname = os.path.splitdrive(arcname)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1829 while arcname[0:1] == "/":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1830 arcname = arcname[1:]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1831
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1832 # Now, fill the TarInfo object with
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1833 # 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
1834 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
1835 tarinfo.tarfile = self
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1836
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1837 # 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
1838 # and if symlinks shall be resolved.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1839 if fileobj is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1840 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
1841 statres = os.lstat(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1842 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1843 statres = os.stat(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1844 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1845 statres = os.fstat(fileobj.fileno())
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1846 linkname = ""
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1847
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1848 stmd = statres.st_mode
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1849 if stat.S_ISREG(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1850 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
1851 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
1852 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
1853 # 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
1854 # archived file?
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1855 type = LNKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1856 linkname = self.inodes[inode]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1857 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1858 # 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
1859 # For win32 it is always 0.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1860 type = REGTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1861 if inode[0]:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1862 self.inodes[inode] = arcname
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1863 elif stat.S_ISDIR(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1864 type = DIRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1865 elif stat.S_ISFIFO(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1866 type = FIFOTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1867 elif stat.S_ISLNK(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1868 type = SYMTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1869 linkname = os.readlink(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1870 elif stat.S_ISCHR(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1871 type = CHRTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1872 elif stat.S_ISBLK(stmd):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1873 type = BLKTYPE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1874 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1875 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1876
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1877 # Fill the TarInfo object with all
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1878 # 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
1879 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
1880 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
1881 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
1882 tarinfo.gid = statres.st_gid
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
1883 if stat.S_ISREG(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
1884 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
1885 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
1886 tarinfo.size = 0L
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1887 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
1888 tarinfo.type = type
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1889 tarinfo.linkname = linkname
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1890 if pwd:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1891 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1892 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
1893 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1894 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1895 if grp:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1896 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1897 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
1898 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1899 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1900
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1901 if type in (CHRTYPE, BLKTYPE):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1902 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
1903 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
1904 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
1905 return tarinfo
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 def list(self, verbose=True):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1908 """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
1909 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
1910 output is produced.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1911 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1912 self._check()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1913
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1914 for tarinfo in self:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1915 if verbose:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1916 print filemode(tarinfo.mode),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1917 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
1918 tarinfo.gname or tarinfo.gid),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1919 if tarinfo.ischr() or tarinfo.isblk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1920 print "%10s" % ("%d,%d" \
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1921 % (tarinfo.devmajor, tarinfo.devminor)),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1922 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1923 print "%10d" % tarinfo.size,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1924 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
1925 % time.localtime(tarinfo.mtime)[:6],
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1926
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1927 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
1928
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1929 if verbose:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1930 if tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1931 print "->", tarinfo.linkname,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1932 if tarinfo.islnk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1933 print "link to", tarinfo.linkname,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1934 print
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1935
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1936 def add(self, name, arcname=None, recursive=True, exclude=None):
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1937 """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
1938 (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
1939 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
1940 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
1941 setting `recursive' to False. `exclude' is a function that should
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1942 return True for each filename to be excluded.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1943 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1944 self._check("aw")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1945
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1946 if arcname is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1947 arcname = name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1948
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1949 # Exclude pathnames.
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1950 if exclude is not None and exclude(name):
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1951 self._dbg(2, "tarfile: Excluded %r" % name)
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1952 return
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1953
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1954 # Skip if somebody tries to archive the archive...
40519
6763e45c7f7d Patch #1262036: Prevent TarFiles from being added to themselves under
Lars Gustäbel <lars@gustaebel.de>
parents: 40517
diff changeset
1955 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
1956 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
1957 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1958
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1959 # Special case: The user wants to add the current
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1960 # working directory.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1961 if name == ".":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1962 if recursive:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1963 if arcname == ".":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1964 arcname = ""
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
1965 for f in os.listdir(name):
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1966 self.add(f, os.path.join(arcname, f), recursive, exclude)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1967 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1968
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1969 self._dbg(1, name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1970
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1971 # 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
1972 tarinfo = self.gettarinfo(name, arcname)
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 if tarinfo is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1975 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
1976 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1977
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1978 # 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
1979 if tarinfo.isreg():
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
1980 f = bltn_open(name, "rb")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1981 self.addfile(tarinfo, f)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1982 f.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1983
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
1984 elif tarinfo.isdir():
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1985 self.addfile(tarinfo)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1986 if recursive:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1987 for f in os.listdir(name):
42109
b2e7336feb82 Added exclude keyword argument to the TarFile.add() method.
Lars Gustäbel <lars@gustaebel.de>
parents: 41897
diff changeset
1988 self.add(os.path.join(name, f), os.path.join(arcname, f), recursive, exclude)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1989
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
1990 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
1991 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
1992
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1993 def addfile(self, tarinfo, fileobj=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
1994 """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
1995 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
1996 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
1997 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
1998 '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
1999 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2000 self._check("aw")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2001
40246
fd8a5f925d4d Patch #1583880: fix tarfile's problems with long names and posix/
Georg Brandl <georg@python.org>
parents: 40170
diff changeset
2002 tarinfo = copy.copy(tarinfo)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2003
41897
9de87569181c Added errors argument to TarFile class that allows the user to
Lars Gustäbel <lars@gustaebel.de>
parents: 41881
diff changeset
2004 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
2005 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
2006 self.offset += len(buf)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2007
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2008 # 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
2009 if fileobj is not None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2010 copyfileobj(fileobj, self.fileobj, tarinfo.size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2011 blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2012 if remainder > 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2013 self.fileobj.write(NUL * (BLOCKSIZE - remainder))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2014 blocks += 1
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2015 self.offset += blocks * BLOCKSIZE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2016
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2017 self.members.append(tarinfo)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2018
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2019 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
2020 """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
2021 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
2022 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
2023 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
2024 list returned by getmembers().
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2025 """
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2026 directories = []
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2027
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2028 if members is None:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2029 members = self
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2030
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2031 for tarinfo in members:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2032 if tarinfo.isdir():
45164
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2033 # 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
2034 directories.append(tarinfo)
45164
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2035 tarinfo = copy.copy(tarinfo)
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2036 tarinfo.mode = 0700
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2037 self.extract(tarinfo, path)
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2038
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2039 # 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
2040 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
2041 directories.reverse()
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2042
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2043 # 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
2044 for tarinfo in directories:
44470
bd0258df330e Issue #1735: TarFile.extractall() now correctly sets
Lars Gustäbel <lars@gustaebel.de>
parents: 44091
diff changeset
2045 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
2046 try:
44470
bd0258df330e Issue #1735: TarFile.extractall() now correctly sets
Lars Gustäbel <lars@gustaebel.de>
parents: 44091
diff changeset
2047 self.chown(tarinfo, dirpath)
bd0258df330e Issue #1735: TarFile.extractall() now correctly sets
Lars Gustäbel <lars@gustaebel.de>
parents: 44091
diff changeset
2048 self.utime(tarinfo, dirpath)
bd0258df330e Issue #1735: TarFile.extractall() now correctly sets
Lars Gustäbel <lars@gustaebel.de>
parents: 44091
diff changeset
2049 self.chmod(tarinfo, dirpath)
34688
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2050 except ExtractError, e:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2051 if self.errorlevel > 1:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2052 raise
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2053 else:
1ac24e9183e5 Patch #1043890: tarfile: add extractall() method.
Martin v. Löwis <martin@v.loewis.de>
parents: 34680
diff changeset
2054 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
2055
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2056 def extract(self, member, path=""):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2057 """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
2058 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
2059 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
2060 specify a different directory using `path'.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2061 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2062 self._check("r")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2063
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2064 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
2065 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
2066 else:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2067 tarinfo = member
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2068
32769
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2069 # 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
2070 if tarinfo.islnk():
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2071 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
2072
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2073 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2074 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
2075 except EnvironmentError, e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2076 if self.errorlevel > 0:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2077 raise
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2078 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2079 if e.filename is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2080 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
2081 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2082 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
2083 except ExtractError, e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2084 if self.errorlevel > 1:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2085 raise
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2086 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2087 self._dbg(1, "tarfile: %s" % e)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2088
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2089 def extractfile(self, member):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2090 """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
2091 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
2092 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
2093 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
2094 the above, None is returned.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2095 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
2096 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
2097 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2098 self._check("r")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2099
41153
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2100 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
2101 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
2102 else:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2103 tarinfo = member
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2104
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2105 if tarinfo.isreg():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2106 return self.fileobject(self, tarinfo)
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 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
2109 # 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
2110 # regular file.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2111 return self.fileobject(self, tarinfo)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2112
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2113 elif tarinfo.islnk() or tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2114 if isinstance(self.fileobj, _Stream):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2115 # 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
2116 # 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
2117 # stream of tar blocks.
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2118 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
2119 else:
35276
4adbd331d335 Fix all wrong instances of "it's".
Georg Brandl <georg@python.org>
parents: 34818
diff changeset
2120 # A (sym)link's file object is its target's file object.
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2121 return self.extractfile(self._getmember(tarinfo.linkname,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2122 tarinfo))
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2123 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2124 # 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
2125 # 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
2126 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2127
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2128 def _extract_member(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2129 """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
2130 file called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2131 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2132 # 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
2133 # and build the destination pathname, replacing
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2134 # forward slashes to platform specific separators.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2135 if targetpath[-1:] == "/":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2136 targetpath = targetpath[:-1]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2137 targetpath = os.path.normpath(targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2138
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2139 # Create all upper directories.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2140 upperdirs = os.path.dirname(targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2141 if upperdirs and not os.path.exists(upperdirs):
45164
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2142 # Create directories that are not part of the archive with
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2143 # default permissions.
40698
7f4065efa44e Patch #1507247: tarfile.py: use current umask for intermediate
Lars Gustäbel <lars@gustaebel.de>
parents: 40523
diff changeset
2144 os.makedirs(upperdirs)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2145
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2146 if tarinfo.islnk() or tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2147 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
2148 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2149 self._dbg(1, tarinfo.name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2150
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2151 if tarinfo.isreg():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2152 self.makefile(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2153 elif tarinfo.isdir():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2154 self.makedir(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2155 elif tarinfo.isfifo():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2156 self.makefifo(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2157 elif tarinfo.ischr() or tarinfo.isblk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2158 self.makedev(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2159 elif tarinfo.islnk() or tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2160 self.makelink(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2161 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
2162 self.makeunknown(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2163 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2164 self.makefile(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2165
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2166 self.chown(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2167 if not tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2168 self.chmod(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2169 self.utime(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2170
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2171 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2172 # 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
2173 # _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
2174 # subclass to implement other functionality.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2175
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2176 def makedir(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2177 """Make a directory called 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 try:
45164
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2180 # Use a safe mode for the directory, the real mode is set
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2181 # later in _extract_member().
94d980966056 Issue #2004: Use mode 0700 for temporary directories and default
Lars Gustäbel <lars@gustaebel.de>
parents: 44470
diff changeset
2182 os.mkdir(targetpath, 0700)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2183 except EnvironmentError, e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2184 if e.errno != errno.EEXIST:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2185 raise
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 def makefile(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2188 """Make a file called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2189 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2190 source = self.extractfile(tarinfo)
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
2191 target = bltn_open(targetpath, "wb")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2192 copyfileobj(source, target)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2193 source.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2194 target.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2195
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2196 def makeunknown(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2197 """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
2198 at targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2199 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2200 self.makefile(tarinfo, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2201 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
2202 "extracted as regular file." % tarinfo.type)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2203
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2204 def makefifo(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2205 """Make a fifo called targetpath.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2206 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2207 if hasattr(os, "mkfifo"):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2208 os.mkfifo(targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2209 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2210 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
2211
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2212 def makedev(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2213 """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
2214 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2215 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
2216 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
2217
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2218 mode = tarinfo.mode
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2219 if tarinfo.isblk():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2220 mode |= stat.S_IFBLK
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2221 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2222 mode |= stat.S_IFCHR
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 os.mknod(targetpath, mode,
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2225 os.makedev(tarinfo.devmajor, tarinfo.devminor))
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 def makelink(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2228 """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
2229 (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
2230 instead of a link.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2231 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2232 linkpath = tarinfo.linkname
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2233 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2234 if tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2235 os.symlink(linkpath, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2236 else:
32769
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2237 # See extract().
983a91b50f6e SF #857297 and 916874, improve handling of hard links when extracting
Neal Norwitz <nnorwitz@gmail.com>
parents: 32768
diff changeset
2238 os.link(tarinfo._link_target, targetpath)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2239 except AttributeError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2240 if tarinfo.issym():
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2241 linkpath = os.path.join(os.path.dirname(tarinfo.name),
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2242 linkpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2243 linkpath = normpath(linkpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2244
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2245 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2246 self._extract_member(self.getmember(linkpath), targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2247 except (EnvironmentError, KeyError), e:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2248 linkpath = os.path.normpath(linkpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2249 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2250 shutil.copy2(linkpath, targetpath)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2251 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2252 raise IOError("link could not be created")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2253
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2254 def chown(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2255 """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
2256 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2257 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
2258 # 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
2259 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2260 g = grp.getgrnam(tarinfo.gname)[2]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2261 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2262 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2263 g = grp.getgrgid(tarinfo.gid)[2]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2264 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2265 g = os.getgid()
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 u = pwd.getpwnam(tarinfo.uname)[2]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2268 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2269 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2270 u = pwd.getpwuid(tarinfo.uid)[2]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2271 except KeyError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2272 u = os.getuid()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2273 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2274 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
2275 os.lchown(targetpath, u, g)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2276 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
2277 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
2278 os.chown(targetpath, u, g)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2279 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2280 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
2281
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2282 def chmod(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2283 """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
2284 """
28214
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2285 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
2286 try:
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2287 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
2288 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2289 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
2290
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2291 def utime(self, tarinfo, targetpath):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2292 """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
2293 """
28214
d4b262fbd04a Test that os.utime and os.chmod actually exist before using them.
Jack Jansen <jack.jansen@cwi.nl>
parents: 27972
diff changeset
2294 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
2295 return
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2296 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2297 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
2298 except EnvironmentError, e:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2299 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
2300
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 def next(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2303 """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
2304 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
2305 available.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2306 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2307 self._check("ra")
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2308 if self.firstmember is not None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2309 m = self.firstmember
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2310 self.firstmember = None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2311 return m
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2312
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2313 # Read the next block.
32604
08d90460ab4d [Patch 988444]
Andrew M. Kuchling <amk@amk.ca>
parents: 31314
diff changeset
2314 self.fileobj.seek(self.offset)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2315 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2316 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
2317 tarinfo = self.tarinfo.fromtarfile(self)
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2318 if tarinfo is None:
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2319 return
5a3a1b02418a This is the implementation of POSIX.1-2001 (pax) format read/write
Lars Gustäbel <lars@gustaebel.de>
parents: 40748
diff changeset
2320 self.members.append(tarinfo)
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
2321
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
2322 except HeaderError, e:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2323 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
2324 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
2325 self.offset += BLOCKSIZE
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2326 continue
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2327 else:
32604
08d90460ab4d [Patch 988444]
Andrew M. Kuchling <amk@amk.ca>
parents: 31314
diff changeset
2328 if self.offset == 0:
40487
51395c0b5482 Patch #1484695: The tarfile module now raises a HeaderError exception
Georg Brandl <georg@python.org>
parents: 40424
diff changeset
2329 raise ReadError(str(e))
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2330 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2331 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2332
38146
f61c892cadac Patch #1484695: Update the tarfile module to version 0.8. This fixes
Georg Brandl <georg@python.org>
parents: 35804
diff changeset
2333 return tarinfo
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2334
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2335 #--------------------------------------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2336 # Little helper methods:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2337
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2338 def _getmember(self, name, tarinfo=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2339 """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
2340 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
2341 """
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2342 # 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
2343 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
2344
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2345 if tarinfo is None:
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2346 end = len(members)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2347 else:
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2348 end = members.index(tarinfo)
27098
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 for i in xrange(end - 1, -1, -1):
33507
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2351 if name == members[i].name:
725c44421a42 Patch #1029061: Always extract member names from the tarinfo.
Martin v. Löwis <martin@v.loewis.de>
parents: 33263
diff changeset
2352 return members[i]
32604
08d90460ab4d [Patch 988444]
Andrew M. Kuchling <amk@amk.ca>
parents: 31314
diff changeset
2353
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2354 def _load(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2355 """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
2356 members.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2357 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2358 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2359 tarinfo = self.next()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2360 if tarinfo is None:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2361 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2362 self._loaded = True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2363
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2364 def _check(self, mode=None):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2365 """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
2366 corresponds to TarFile's mode.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2367 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2368 if self.closed:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2369 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
2370 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
2371 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
2372
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2373 def __iter__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2374 """Provide an iterator object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2375 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2376 if self._loaded:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2377 return iter(self.members)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2378 else:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2379 return TarIter(self)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2380
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2381 def _dbg(self, level, msg):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2382 """Write debugging output to sys.stderr.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2383 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2384 if level <= self.debug:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2385 print >> sys.stderr, msg
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2386 # class TarFile
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2387
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2388 class TarIter:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2389 """Iterator Class.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2390
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2391 for tarinfo in TarFile(...):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2392 suite...
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2393 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2394
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2395 def __init__(self, tarfile):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2396 """Construct a TarIter object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2397 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2398 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
2399 self.index = 0
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2400 def __iter__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2401 """Return iterator object.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2402 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2403 return self
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2404 def next(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2405 """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
2406 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
2407 """
34680
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2408 # 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
2409 # 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
2410 # 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
2411 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
2412 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
2413 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
2414 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
2415 raise StopIteration
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2416 else:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2417 try:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2418 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
2419 except IndexError:
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2420 raise StopIteration
481397683eac Patch #1103407: Properly deal with tarfile iterators when untarring
Martin v. Löwis <martin@v.loewis.de>
parents: 34649
diff changeset
2421 self.index += 1
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2422 return tarinfo
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 # Helper classes for sparse file support
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2425 class _section:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2426 """Base class for _data and _hole.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2427 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2428 def __init__(self, offset, size):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2429 self.offset = offset
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2430 self.size = size
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2431 def __contains__(self, offset):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2432 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
2433
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2434 class _data(_section):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2435 """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
2436 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2437 def __init__(self, offset, size, realpos):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2438 _section.__init__(self, offset, size)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2439 self.realpos = realpos
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2440
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2441 class _hole(_section):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2442 """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
2443 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2444 pass
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2445
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2446 class _ringbuffer(list):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2447 """Ringbuffer class which increases performance
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2448 over a regular list.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2449 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2450 def __init__(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2451 self.idx = 0
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2452 def find(self, offset):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2453 idx = self.idx
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2454 while True:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2455 item = self[idx]
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2456 if offset in item:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2457 break
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2458 idx += 1
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2459 if idx == len(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2460 idx = 0
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2461 if idx == self.idx:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2462 # End of File
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2463 return None
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2464 self.idx = idx
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2465 return item
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2466
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2467 #---------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2468 # zipfile compatible TarFile class
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2469 #---------------------------------------------
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2470 TAR_PLAIN = 0 # zipfile.ZIP_STORED
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2471 TAR_GZIPPED = 8 # zipfile.ZIP_DEFLATED
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2472 class TarFileCompat:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2473 """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
2474 ZipFile class.
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2475 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2476 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
2477 from warnings import warnpy3k
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2478 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
2479 stacklevel=2)
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2480 if compression == TAR_PLAIN:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2481 self.tarfile = TarFile.taropen(file, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2482 elif compression == TAR_GZIPPED:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2483 self.tarfile = TarFile.gzopen(file, mode)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2484 else:
38208
b286ed45439d Amendments to patch #1484695.
Georg Brandl <georg@python.org>
parents: 38185
diff changeset
2485 raise ValueError("unknown compression constant")
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2486 if mode[0:1] == "r":
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2487 members = self.tarfile.getmembers()
35532
d504a302bf53 Minor cleanup.
Raymond Hettinger <python@rcn.com>
parents: 35466
diff changeset
2488 for m in members:
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2489 m.filename = m.name
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2490 m.file_size = m.size
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2491 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
2492 def namelist(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2493 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
2494 def infolist(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2495 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
2496 self.tarfile.getmembers())
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2497 def printdir(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2498 self.tarfile.list()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2499 def testzip(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2500 return
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2501 def getinfo(self, name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2502 return self.tarfile.getmember(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2503 def read(self, name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2504 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
2505 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
2506 self.tarfile.add(filename, arcname)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2507 def writestr(self, zinfo, bytes):
34293
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2508 try:
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2509 from cStringIO import StringIO
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2510 except ImportError:
cd517701fd93 Use cStringIO where available.
Raymond Hettinger <python@rcn.com>
parents: 33810
diff changeset
2511 from StringIO import StringIO
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2512 import calendar
48138
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2513 tinfo = TarInfo(zinfo.filename)
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2514 tinfo.size = len(bytes)
feddaf21c2a4 Issue #3039: Fix TarFileCompat.writestr() which always raised an
Lars Gustäbel <lars@gustaebel.de>
parents: 47352
diff changeset
2515 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
2516 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
2517 def close(self):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2518 self.tarfile.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2519 #class TarFileCompat
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 # exported functions
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 def is_tarfile(name):
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2525 """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
2526 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
2527 """
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2528 try:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2529 t = open(name)
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2530 t.close()
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2531 return True
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2532 except TarError:
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2533 return False
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2534
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
2535 bltn_open = open
27098
f9a5ed092660 SF #651082, tarfile module implementation from Lars Gustäbel
Neal Norwitz <nnorwitz@gmail.com>
parents:
diff changeset
2536 open = TarFile.open