tarfile.py 69 KB

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