summaryrefslogtreecommitdiffstats
path: root/contrib/python/python-libarchive/py3/libarchive
diff options
context:
space:
mode:
authorsay <[email protected]>2023-12-08 17:40:48 +0300
committersay <[email protected]>2023-12-08 19:58:59 +0300
commit914f57e3243f53dd89dd3adb4d8b6d35c47f46ce (patch)
tree98a1f1f1f5e2c38db3a78da10aeb7eb7d4e952e0 /contrib/python/python-libarchive/py3/libarchive
parente61293d91ee7c923944f627d8e1138bcb17cacad (diff)
Make support_retries() and get_type() methods of object instead of class ones. Reduce get_type_name() usage.
Diffstat (limited to 'contrib/python/python-libarchive/py3/libarchive')
-rw-r--r--contrib/python/python-libarchive/py3/libarchive/__init__.py800
-rw-r--r--contrib/python/python-libarchive/py3/libarchive/_libarchive.swg339
-rw-r--r--contrib/python/python-libarchive/py3/libarchive/tar.py135
-rw-r--r--contrib/python/python-libarchive/py3/libarchive/zip.py151
4 files changed, 0 insertions, 1425 deletions
diff --git a/contrib/python/python-libarchive/py3/libarchive/__init__.py b/contrib/python/python-libarchive/py3/libarchive/__init__.py
deleted file mode 100644
index 0c0c63359a3..00000000000
--- a/contrib/python/python-libarchive/py3/libarchive/__init__.py
+++ /dev/null
@@ -1,800 +0,0 @@
-# Copyright (c) 2011, SmartFile <[email protected]>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the organization nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os
-import stat
-import sys
-import math
-import time
-import logging
-import warnings
-
-import contextlib2
-
-from libarchive import _libarchive
-import six
-
-logger = logging.getLogger(__name__)
-
-# Suggested block size for libarchive. Libarchive may adjust it.
-BLOCK_SIZE = 10240
-
-MTIME_FORMAT = ''
-
-# Default encoding scheme.
-ENCODING = 'utf-8'
-
-if six.PY2:
- def encode(value, encoding):
- if type(value) == str:
- value = value.decode(encoding, errors='ignore')
- return value.encode(encoding)
-else:
- def encode(value, encoding):
- return value.encode(encoding)
-
-
-# Functions to initialize read/write for various libarchive supported formats and filters.
-FORMATS = {
- None: (_libarchive.archive_read_support_format_all, None),
- 'tar': (_libarchive.archive_read_support_format_tar, _libarchive.archive_write_set_format_ustar),
- 'pax': (_libarchive.archive_read_support_format_tar, _libarchive.archive_write_set_format_pax),
- 'gnu': (_libarchive.archive_read_support_format_gnutar, _libarchive.archive_write_set_format_gnutar),
- 'zip': (_libarchive.archive_read_support_format_zip, _libarchive.archive_write_set_format_zip),
- 'rar': (_libarchive.archive_read_support_format_rar, None),
- '7zip': (_libarchive.archive_read_support_format_7zip, None),
- 'ar': (_libarchive.archive_read_support_format_ar, None),
- 'cab': (_libarchive.archive_read_support_format_cab, None),
- 'cpio': (_libarchive.archive_read_support_format_cpio, _libarchive.archive_write_set_format_cpio_newc),
- 'iso': (_libarchive.archive_read_support_format_iso9660, _libarchive.archive_write_set_format_iso9660),
- 'lha': (_libarchive.archive_read_support_format_lha, None),
- 'xar': (_libarchive.archive_read_support_format_xar, _libarchive.archive_write_set_format_xar),
-}
-
-FILTERS = {
- None: (_libarchive.archive_read_support_filter_all, _libarchive.archive_write_add_filter_none),
- 'bzip2': (_libarchive.archive_read_support_filter_bzip2, _libarchive.archive_write_add_filter_bzip2),
- 'gzip': (_libarchive.archive_read_support_filter_gzip, _libarchive.archive_write_add_filter_gzip),
- 'zstd': (_libarchive.archive_read_support_filter_zstd, _libarchive.archive_write_add_filter_zstd),
-}
-
-# Map file extensions to formats and filters. To support quick detection.
-FORMAT_EXTENSIONS = {
- '.tar': 'tar',
- '.zip': 'zip',
- '.rar': 'rar',
- '.7z': '7zip',
- '.ar': 'ar',
- '.cab': 'cab',
- '.rpm': 'cpio',
- '.cpio': 'cpio',
- '.iso': 'iso',
- '.lha': 'lha',
- '.xar': 'xar',
-}
-FILTER_EXTENSIONS = {
- '.bz2': 'bzip2',
- '.gz': 'gzip',
- '.zst': 'zstd',
-}
-
-
-class EOF(Exception):
- '''Raised by ArchiveInfo.from_archive() when unable to read the next
- archive header.'''
- pass
-
-
-def get_error(archive):
- '''Retrieves the last error description for the given archive instance.'''
- return _libarchive.archive_error_string(archive)
-
-
-def call_and_check(func, archive, *args):
- '''Executes a libarchive function and raises an exception when appropriate.'''
- ret = func(*args)
- if ret == _libarchive.ARCHIVE_OK:
- return
- elif ret == _libarchive.ARCHIVE_WARN:
- warnings.warn('Warning executing function: %s.' % get_error(archive), RuntimeWarning)
- elif ret == _libarchive.ARCHIVE_EOF:
- raise EOF()
- else:
- raise Exception('Fatal error executing function, message is: %s.' % get_error(archive))
-
-
-def get_func(name, items, index):
- item = items.get(name, None)
- if item is None:
- return None
- return item[index]
-
-
-def guess_format(filename):
- filename, ext = os.path.splitext(filename)
- filter = FILTER_EXTENSIONS.get(ext)
- if filter:
- filename, ext = os.path.splitext(filename)
- format = FORMAT_EXTENSIONS.get(ext)
- return format, filter
-
-
-def is_archive_name(filename, formats=None):
- '''Quick check to see if the given file has an extension indiciating that it is
- an archive. The format parameter can be used to limit what archive format is acceptable.
- If omitted, all supported archive formats will be checked.
-
- This function will return the name of the most likely archive format, None if the file is
- unlikely to be an archive.'''
- if formats is None:
- formats = FORMAT_EXTENSIONS.values()
- format, filter = guess_format(filename)
- if format in formats:
- return format
-
-
-def is_archive(f, formats=(None, ), filters=(None, )):
- '''Check to see if the given file is actually an archive. The format parameter
- can be used to specify which archive format is acceptable. If ommitted, all supported
- archive formats will be checked. It opens the file using libarchive. If no error is
- received, the file was successfully detected by the libarchive bidding process.
-
- This procedure is quite costly, so you should avoid calling it unless you are reasonably
- sure that the given file is an archive. In other words, you may wish to filter large
- numbers of file names using is_archive_name() before double-checking the positives with
- this function.
-
- This function will return True if the file can be opened as an archive using the given
- format(s)/filter(s).'''
- with contextlib2.ExitStack() as exit_stack:
- if isinstance(f, six.string_types):
- f = exit_stack.enter_context(open(f, 'rb'))
- a = _libarchive.archive_read_new()
- for format in formats:
- format = get_func(format, FORMATS, 0)
- if format is None:
- return False
- format(a)
- for filter in filters:
- filter = get_func(filter, FILTERS, 0)
- if filter is None:
- return False
- filter(a)
- try:
- try:
- call_and_check(_libarchive.archive_read_open_fd, a, a, f.fileno(), BLOCK_SIZE)
- return True
- except:
- return False
- finally:
- _libarchive.archive_read_close(a)
- _libarchive.archive_read_free(a)
-
-
-def get_archive_filter_names(filename):
- with open(filename, 'rb') as afile:
- a = _libarchive.archive_read_new()
- try:
- format_func = get_func(None, FORMATS, 0)
- format_func(a)
- filter_func = get_func(None, FILTERS, 0)
- filter_func(a)
- if _libarchive.archive_read_open_fd(a, afile.fileno(), BLOCK_SIZE) == _libarchive.ARCHIVE_OK:
- try:
- nfilter = _libarchive.archive_filter_count(a)
- return [_libarchive.archive_filter_name(a, i).decode(ENCODING) for i in range(nfilter)]
- finally:
- _libarchive.archive_read_close(a)
- finally:
- _libarchive.archive_read_free(a)
- return []
-
-
-class EntryReadStream(object):
- '''A file-like object for reading an entry from the archive.'''
- def __init__(self, archive, size):
- self.archive = archive
- self.closed = False
- self.size = size
- self.bytes = 0
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- return
-
- def __iter__(self):
- if self.closed:
- return
- while True:
- data = self.read(BLOCK_SIZE)
- if not data:
- break
- yield data
-
- def __len__(self):
- return self.size
-
- def tell(self):
- return self.bytes
-
- def read(self, bytes=-1):
- if self.closed:
- return
- if self.bytes == self.size:
- # EOF already reached.
- return
- if bytes < 0:
- bytes = self.size - self.bytes
- elif self.bytes + bytes > self.size:
- # Limit read to remaining bytes
- bytes = self.size - self.bytes
- # Read requested bytes
- data = _libarchive.archive_read_data_into_str(self.archive._a, bytes)
- self.bytes += len(data)
- return data
-
- def close(self):
- if self.closed:
- return
- # Call archive.close() with _defer True to let it know we have been
- # closed and it is now safe to actually close.
- self.archive.close(_defer=True)
- self.archive = None
- self.closed = True
-
-
-class EntryWriteStream(object):
- '''A file-like object for writing an entry to an archive.
-
- If the size is known ahead of time and provided, then the file contents
- are not buffered but flushed directly to the archive. If size is omitted,
- then the file contents are buffered and flushed in the close() method.'''
- def __init__(self, archive, pathname, size=None):
- self.archive = archive
- self.entry = Entry(pathname=pathname, mtime=time.time(), mode=stat.S_IFREG)
- if size is None:
- self.buffer = six.StringIO()
- else:
- self.buffer = None
- self.entry.size = size
- self.entry.to_archive(self.archive)
- self.bytes = 0
- self.closed = False
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- self.close()
-
- def __del__(self):
- self.close()
-
- def __len__(self):
- return self.bytes
-
- def tell(self):
- return self.bytes
-
- def write(self, data):
- if self.closed:
- raise Exception('Cannot write to closed stream.')
- if self.buffer:
- self.buffer.write(data)
- else:
- _libarchive.archive_write_data_from_str(self.archive._a, data)
- self.bytes += len(data)
-
- def close(self):
- if self.closed:
- return
- if self.buffer:
- self.entry.size = self.buffer.tell()
- self.entry.to_archive(self.archive)
- _libarchive.archive_write_data_from_str(self.archive._a, self.buffer.getvalue())
- _libarchive.archive_write_finish_entry(self.archive._a)
-
- # Call archive.close() with _defer True to let it know we have been
- # closed and it is now safe to actually close.
- self.archive.close(_defer=True)
- self.archive = None
- self.closed = True
-
-
-class Entry(object):
- '''An entry within an archive. Represents the header data and it's location within the archive.'''
- def __init__(self, pathname=None, size=None, mtime=None, mode=None, hpos=None, encoding=ENCODING):
- self.pathname = pathname
- self.size = size
- self.mtime = mtime
- self.mode = mode
- self.hpos = hpos
- self.encoding = encoding
- self.linkname = None
- self.id = None
- self.hardlink = None
-
- @property
- def header_position(self):
- return self.hpos
-
- @classmethod
- def from_archive(cls, archive, encoding=ENCODING):
- '''Instantiates an Entry class and sets all the properties from an archive header.'''
- e = _libarchive.archive_entry_new()
- try:
- call_and_check(_libarchive.archive_read_next_header2, archive._a, archive._a, e)
- mode = _libarchive.archive_entry_filetype(e)
- mode |= _libarchive.archive_entry_perm(e)
- mtime = _libarchive.archive_entry_mtime(e) + _libarchive.archive_entry_mtime_nsec(e) / 1000000000.0
- # use current time as mtime if stored mtime is equal to 0
- mtime = mtime or time.time()
- entry = cls(
- pathname=_libarchive.archive_entry_pathname(e).decode(encoding),
- size=_libarchive.archive_entry_size(e),
- mtime=mtime,
- mode=mode,
- hpos=archive.header_position,
- )
- # check hardlinkness first to processes hardlinks to the symlinks correctly
- hardlink = _libarchive.archive_entry_hardlink(e)
- if hardlink:
- entry.hardlink = hardlink
- elif entry.issym():
- entry.linkname = _libarchive.archive_entry_symlink(e)
- finally:
- _libarchive.archive_entry_free(e)
- return entry
-
- @classmethod
- def from_file(cls, f, entry=None, encoding=ENCODING, mtime=None):
- '''Instantiates an Entry class and sets all the properties from a file on the file system.
- f can be a file-like object or a path.'''
- if entry is None:
- entry = cls(encoding=encoding)
- if entry.pathname is None:
- if isinstance(f, six.string_types):
- st = os.lstat(f)
- entry.pathname = f
- entry.size = st.st_size
- entry.mtime = st.st_mtime if mtime is None else mtime
- entry.mode = st.st_mode
- entry.id = cls.get_entry_id(st)
- if entry.issym():
- entry.linkname = os.readlink(f)
- elif hasattr(f, 'fileno'):
- st = os.fstat(f.fileno())
- entry.pathname = getattr(f, 'name', None)
- entry.size = st.st_size
- entry.mtime = st.st_mtime if mtime is None else mtime
- entry.mode = st.st_mode
- entry.id = cls.get_entry_id(st)
- else:
- entry.pathname = getattr(f, 'pathname', None)
- entry.size = getattr(f, 'size', 0)
- entry.mtime = getattr(f, 'mtime', time.time()) if mtime is None else mtime
- entry.mode = getattr(f, 'mode', stat.S_IFREG)
- return entry
-
- @staticmethod
- def get_entry_id(st):
- # windows doesn't have such information
- if st.st_ino and st.st_dev:
- return (st.st_dev, st.st_ino)
- return None
-
- def to_archive(self, archive):
- '''Creates an archive header and writes it to the given archive.'''
- e = _libarchive.archive_entry_new()
- try:
- _libarchive.archive_entry_set_pathname(e, encode(self.pathname, self.encoding))
- _libarchive.archive_entry_set_filetype(e, stat.S_IFMT(self.mode))
- _libarchive.archive_entry_set_perm(e, stat.S_IMODE(self.mode))
-
- nsec, sec = math.modf(self.mtime)
- nsec *= 1000000000
- _libarchive.archive_entry_set_mtime(e, int(sec), int(nsec))
-
- if self.ishardlink():
- _libarchive.archive_entry_set_size(e, 0)
- _libarchive.archive_entry_set_hardlink(e, encode(self.hardlink, self.encoding))
- elif self.issym():
- _libarchive.archive_entry_set_size(e, 0)
- _libarchive.archive_entry_set_symlink(e, encode(self.linkname, self.encoding))
- else:
- _libarchive.archive_entry_set_size(e, self.size)
- call_and_check(_libarchive.archive_write_header, archive._a, archive._a, e)
- #self.hpos = archive.header_position
- finally:
- _libarchive.archive_entry_free(e)
-
- def isdir(self):
- return stat.S_ISDIR(self.mode)
-
- def isfile(self):
- return stat.S_ISREG(self.mode)
-
- def issym(self):
- return stat.S_ISLNK(self.mode)
-
- def isfifo(self):
- return stat.S_ISFIFO(self.mode)
-
- def ischr(self):
- return stat.S_ISCHR(self.mode)
-
- def isblk(self):
- return stat.S_ISBLK(self.mode)
-
- def ishardlink(self):
- return bool(self.hardlink)
-
-
-class Archive(object):
- '''A low-level archive reader which provides forward-only iteration. Consider
- this a light-weight pythonic libarchive wrapper.'''
- def __init__(self, f, mode='rb', format=None, filter=None, entry_class=Entry, encoding=ENCODING, blocksize=BLOCK_SIZE, filter_opts=None, format_opts=None, fsync=False, fixed_mtime=None):
- if six.PY2:
- assert mode in ('r', 'rb', 'w', 'wb', 'a', 'ab'), 'Mode should be "r[b]", "w[b]" or "a[b]".'
- else:
- assert mode in ('rb', 'wb', 'ab'), 'Mode should be "rb", "wb", or "ab".'
- self._stream = None
- self.encoding = encoding
- self.blocksize = blocksize
- self.file_handle = None
- self.fd = None
- self.filename = None
- self.fsync = fsync
- if isinstance(f, six.string_types):
- self.filename = f
- self.file_handle = open(f, mode)
- self.fd = self.file_handle.fileno()
- # Only close it if we opened it...
- self._defer_close = True
- elif hasattr(f, 'fileno'):
- self.filename = getattr(f, 'name', None)
- self.file_handle = f
- self.fd = self.file_handle.fileno()
- # Leave the fd alone, caller should manage it...
- self._defer_close = False
- elif isinstance(f, int):
- assert f >= 0, f
- self.fd = f
- # Leave the fd alone, caller should manage it...
- self._defer_close = False
- else:
- raise Exception('Provided file is not path or open file.')
- self.mode = mode
- # Guess the format/filter from file name (if not provided)
- if self.filename:
- if format is None:
- format = guess_format(self.filename)[0]
- if filter is None:
- filter = guess_format(self.filename)[1]
- self.format = format
- self.filter = filter
- # The class to use for entries.
- self.entry_class = entry_class
- self.fixed_mtime = fixed_mtime
- # Select filter/format functions.
- if self.mode.startswith('r'):
- self.format_func = get_func(self.format, FORMATS, 0)
- if self.format_func is None:
- raise Exception('Unsupported format %s' % format)
- self.filter_func = get_func(self.filter, FILTERS, 0)
- if self.filter_func is None:
- raise Exception('Unsupported filter %s' % filter)
- else:
- # TODO: how to support appending?
- if self.format is None:
- raise Exception('You must specify a format for writing.')
- self.format_func = get_func(self.format, FORMATS, 1)
- if self.format_func is None:
- raise Exception('Unsupported format %s' % format)
- self.filter_func = get_func(self.filter, FILTERS, 1)
- if self.filter_func is None:
- raise Exception('Unsupported filter %s' % filter)
- # Open the archive, apply filter/format functions.
- self.filter_opts = filter_opts
- self.format_opts = format_opts
- # Stores every added entry's id to handle hardlinks properly
- self.members = {}
- self.init()
-
- def __iter__(self):
- while True:
- try:
- yield self.entry_class.from_archive(self, encoding=self.encoding)
- except EOF:
- break
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def __del__(self):
- self.close()
-
- def init(self):
- def _apply_opts(f, opts):
- if opts:
- for opt_name, opt_val in opts.items():
- call_and_check(f, self._a, self._a, None, encode(opt_name, self.encoding), encode(opt_val, self.encoding))
-
- if self.mode.startswith('r'):
- self._a = _libarchive.archive_read_new()
- else:
- self._a = _libarchive.archive_write_new()
- self.format_func(self._a)
- self.filter_func(self._a)
- if self.mode.startswith('r'):
- _apply_opts(_libarchive.archive_read_set_format_option, self.format_opts)
- _apply_opts(_libarchive.archive_read_set_filter_option, self.filter_opts)
- call_and_check(_libarchive.archive_read_open_fd, self._a, self._a, self.fd, self.blocksize)
- else:
- _apply_opts(_libarchive.archive_write_set_format_option, self.format_opts)
- _apply_opts(_libarchive.archive_write_set_filter_option, self.filter_opts)
- call_and_check(_libarchive.archive_write_open_fd, self._a, self._a, self.fd)
- # XXX Don't pad the last block to avoid badly formed archive with zstd filter
- call_and_check(_libarchive.archive_write_set_bytes_in_last_block, self._a, self._a, 1)
-
- def denit(self):
- '''Closes and deallocates the archive reader/writer.'''
- if getattr(self, '_a', None) is None:
- return
- try:
- if self.mode.startswith('r'):
- _libarchive.archive_read_close(self._a)
- _libarchive.archive_read_free(self._a)
- else:
- _libarchive.archive_write_close(self._a)
- _libarchive.archive_write_free(self._a)
- finally:
- # We only want one try at this...
- self._a = None
-
- def close(self, _defer=False):
- # _defer == True is how a stream can notify Archive that the stream is
- # now closed. Calling it directly in not recommended.
- if _defer:
- # This call came from our open stream.
- self._stream = None
- if not self._defer_close:
- # We are not yet ready to close.
- return
- if self._stream is not None:
- # We have a stream open! don't close, but remember we were asked to.
- self._defer_close = True
- return
- self.denit()
- # If there is a file attached...
- if getattr(self, 'file_handle', None):
- # Make sure it is not already closed...
- if getattr(self.file_handle, 'closed', False):
- return
- # Flush it if not read-only...
- if not self.file_handle.mode.startswith('r'):
- self.file_handle.flush()
- if self.fsync:
- os.fsync(self.fd)
- # and then close it, if we opened it...
- if getattr(self, 'close', None):
- self.file_handle.close()
-
- @property
- def header_position(self):
- '''The position within the file.'''
- return _libarchive.archive_read_header_position(self._a)
-
- def iterpaths(self):
- for entry in self:
- yield entry.pathname
-
- def read(self, size):
- '''Read current archive entry contents into string.'''
- return _libarchive.archive_read_data_into_str(self._a, size)
-
- def readpath(self, f):
- '''Write current archive entry contents to file. f can be a file-like object or
- a path.'''
- with contextlib2.ExitStack() as exit_stack:
- if isinstance(f, six.string_types):
- basedir = os.path.basename(f)
- if not os.path.exists(basedir):
- os.makedirs(basedir)
- f = exit_stack.enter_context(open(f, 'wb'))
- return _libarchive.archive_read_data_into_fd(self._a, f.fileno())
-
- def readstream(self, size):
- '''Returns a file-like object for reading current archive entry contents.'''
- self._stream = EntryReadStream(self, size)
- return self._stream
-
- def write(self, member, data=None):
- '''Writes a string buffer to the archive as the given entry.'''
- if isinstance(member, six.string_types):
- if self.fixed_mtime is None:
- mtime = time.time()
- else:
- mtime = self.fixed_mtime
- # Use default mode
- member = self.entry_class(pathname=member, encoding=self.encoding, mtime=mtime, mode=stat.S_IFREG | 0o755)
- if data:
- member.size = len(data)
- member.to_archive(self)
- if data:
- _libarchive.archive_write_data_from_str(self._a, data)
- _libarchive.archive_write_finish_entry(self._a)
-
- def writepath(self, f, pathname=None):
- '''Writes a file to the archive. f can be a file-like object or a path. Uses
- write() to do the actual writing.'''
- member = self.entry_class.from_file(f, encoding=self.encoding, mtime=self.fixed_mtime)
-
- with contextlib2.ExitStack() as exit_stack:
- if isinstance(f, six.string_types):
- if os.path.isfile(f):
- f = exit_stack.enter_context(open(f, 'rb'))
- if pathname:
- member.pathname = pathname
-
- # hardlinks and symlink has no data to be written
- if member.id in self.members:
- member.hardlink = self.members[member.id]
- self.write(member)
- return
- elif member.issym():
- self.write(member)
- elif hasattr(f, 'read') and hasattr(f, 'seek') and hasattr(f, 'tell'):
- self.write_from_file_object(member, f)
- elif hasattr(f, 'read'):
- # TODO: optimize this to write directly from f to archive.
- self.write(member, data=f.read())
- else:
- self.write(member)
-
- if member.id:
- self.members[member.id] = member.pathname
-
- def write_from_file_object(self, member, fileobj):
- if isinstance(member, six.string_types):
- member = self.entry_class(pathname=member, encoding=self.encoding, mtime=self.fixed_mtime)
-
- start = fileobj.tell()
- fileobj.seek(0, os.SEEK_END)
- size = fileobj.tell() - start
- fileobj.seek(start, os.SEEK_SET)
-
- if size:
- member.size = size
- member.to_archive(self)
-
- while size:
- data = fileobj.read(BLOCK_SIZE)
- if not data:
- break
-
- size -= len(data)
- if size < 0:
- msg = "File ({}) size has changed. Can't write more data than was declared in the tar header ({}). " \
- "(probably file was changed during archiving)".format(member.pathname, member.size)
- logger.warning(msg)
- # write rest expected data (size is negative)
- _libarchive.archive_write_data_from_str(self._a, data[:size])
- break
-
- _libarchive.archive_write_data_from_str(self._a, data)
-
- _libarchive.archive_write_finish_entry(self._a)
-
- def writestream(self, pathname, size=None):
- '''Returns a file-like object for writing a new entry.'''
- self._stream = EntryWriteStream(self, pathname, size)
- return self._stream
-
- def printlist(self, s=sys.stdout):
- for entry in self:
- s.write(entry.size)
- s.write('\t')
- s.write(entry.mtime.strftime(MTIME_FORMAT))
- s.write('\t')
- s.write(entry.pathname)
- s.flush()
-
-
-class SeekableArchive(Archive):
- '''A class that provides random-access to archive entries. It does this by using one
- or many Archive instances to seek to the correct location. The best performance will
- occur when reading archive entries in the order in which they appear in the archive.
- Reading out of order will cause the archive to be closed and opened each time a
- reverse seek is needed.'''
- def __init__(self, f, **kwargs):
- self._stream = None
- # Convert file to open file. We need this to reopen the archive.
- mode = kwargs.setdefault('mode', 'rb')
- if isinstance(f, six.string_types):
- f = open(f, mode)
- super(SeekableArchive, self).__init__(f, **kwargs)
- self.entries = []
- self.eof = False
-
- def __iter__(self):
- for entry in self.entries:
- yield entry
- if not self.eof:
- try:
- for entry in super(SeekableArchive, self).__iter__():
- self.entries.append(entry)
- yield entry
- except StopIteration:
- self.eof = True
-
- def reopen(self):
- '''Seeks the underlying fd to 0 position, then opens the archive. If the archive
- is already open, this will effectively re-open it (rewind to the beginning).'''
- self.denit()
- self.file_handle.seek(0)
- self.init()
-
- def getentry(self, pathname):
- '''Take a name or entry object and returns an entry object.'''
- for entry in self:
- if entry.pathname == pathname:
- return entry
- raise KeyError(pathname)
-
- def seek(self, entry):
- '''Seeks the archive to the requested entry. Will reopen if necessary.'''
- move = entry.header_position - self.header_position
- if move != 0:
- if move < 0:
- # can't move back, re-open archive:
- self.reopen()
- # move to proper position in stream
- for curr in super(SeekableArchive, self).__iter__():
- if curr.header_position == entry.header_position:
- break
-
- def read(self, member):
- '''Return the requested archive entry contents as a string.'''
- entry = self.getentry(member)
- self.seek(entry)
- return super(SeekableArchive, self).read(entry.size)
-
- def readpath(self, member, f):
- entry = self.getentry(member)
- self.seek(entry)
- return super(SeekableArchive, self).readpath(f)
-
- def readstream(self, member):
- '''Returns a file-like object for reading requested archive entry contents.'''
- entry = self.getentry(member)
- self.seek(entry)
- self._stream = EntryReadStream(self, entry.size)
- return self._stream
diff --git a/contrib/python/python-libarchive/py3/libarchive/_libarchive.swg b/contrib/python/python-libarchive/py3/libarchive/_libarchive.swg
deleted file mode 100644
index 2fcb05420e4..00000000000
--- a/contrib/python/python-libarchive/py3/libarchive/_libarchive.swg
+++ /dev/null
@@ -1,339 +0,0 @@
-/* Copyright (c) 2011, SmartFile <[email protected]>
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the organization nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-%module _libarchive
-
-%{
-#define SWIG_PYTHON_STRICT_BYTE_CHAR
-
-#include <archive.h>
-#include <archive_entry.h>
-%}
-
-%include "typemaps.i"
-
-%typemap(in) time_t
-{
- if (PyLong_Check($input))
- $1 = (time_t) PyLong_AsLong($input);
- else if (PyInt_Check($input))
- $1 = (time_t) PyInt_AsLong($input);
- else if (PyFloat_Check($input))
- $1 = (time_t) PyFloat_AsDouble($input);
- else {
- PyErr_SetString(PyExc_TypeError,"Expected a large number");
- return NULL;
- }
-}
-
-%typemap(out) time_t
-{
- $result = PyLong_FromLong((long)$1);
-}
-
-%typemap(in) int64_t
-{
- if (PyLong_Check($input))
- $1 = (int64_t) PyLong_AsLong($input);
- else if (PyInt_Check($input))
- $1 = (int64_t) PyInt_AsLong($input);
- else if (PyFloat_Check($input))
- $1 = (int64_t) PyFloat_AsDouble($input);
- else {
- PyErr_SetString(PyExc_TypeError,"Expected a large number");
- return NULL;
- }
-}
-
-%typemap(out) int64_t
-{
- $result = PyLong_FromLong((long)$1);
-}
-
-#define __LA_INT64_T long long
-#define __LA_MODE_T int
-
-/* STRUCTURES */
-struct archive;
-struct archive_entry;
-
-/* ARCHIVE READING */
-extern struct archive *archive_read_new(void);
-extern int archive_read_free(struct archive *);
-
-/* opening */
-extern int archive_read_open_filename(struct archive *,
- const char *_filename, size_t _block_size);
-extern int archive_read_open_memory(struct archive *,
- void * buff, size_t size);
-extern int archive_read_open_memory2(struct archive *a, void *buff,
- size_t size, size_t read_size);
-extern int archive_read_open_fd(struct archive *, int _fd,
- size_t _block_size);
-
-/* closing */
-extern int archive_read_close(struct archive *);
-extern int archive_format(struct archive *);
-
-/* headers */
-extern int archive_read_next_header2(struct archive *,
- struct archive_entry *);
-extern const struct stat *archive_entry_stat(struct archive_entry *);
-extern __LA_INT64_T archive_read_header_position(struct archive *);
-
-/* data */
-extern int archive_read_data_skip(struct archive *);
-extern int archive_read_data_into_fd(struct archive *, int fd);
-
-/* FILTERS */
-extern int archive_read_support_filter_all(struct archive *);
-extern int archive_read_support_filter_bzip2(struct archive *);
-extern int archive_read_support_filter_compress(struct archive *);
-extern int archive_read_support_filter_gzip(struct archive *);
-extern int archive_read_support_filter_lzip(struct archive *);
-extern int archive_read_support_filter_lzma(struct archive *);
-extern int archive_read_support_filter_none(struct archive *);
-extern int archive_read_support_filter_rpm(struct archive *);
-extern int archive_read_support_filter_uu(struct archive *);
-extern int archive_read_support_filter_xz(struct archive *);
-extern int archive_read_support_filter_zstd(struct archive *);
-
-extern int archive_filter_count(struct archive *);
-extern const char * archive_filter_name(struct archive *, int);
-
-/* FORMATS */
-extern int archive_read_support_format_all(struct archive *);
-extern int archive_read_support_format_7zip(struct archive *);
-extern int archive_read_support_format_ar(struct archive *);
-extern int archive_read_support_format_cab(struct archive *);
-extern int archive_read_support_format_cpio(struct archive *);
-extern int archive_read_support_format_empty(struct archive *);
-extern int archive_read_support_format_gnutar(struct archive *);
-extern int archive_read_support_format_iso9660(struct archive *);
-extern int archive_read_support_format_lha(struct archive *);
-/*extern int archive_read_support_format_mtree(struct archive *);*/
-extern int archive_read_support_format_rar(struct archive *);
-extern int archive_read_support_format_raw(struct archive *);
-extern int archive_read_support_format_tar(struct archive *);
-extern int archive_read_support_format_xar(struct archive *);
-extern int archive_read_support_format_zip(struct archive *);
-/*extern int archive_read_support_format_by_code(struct archive *, int);*/
-
-/* OPTIONS */
-extern int archive_write_set_bytes_in_last_block(struct archive *_a, int bytes_in_last_block);
-extern int archive_write_set_filter_option(struct archive *_a, const char *m, const char *o, const char *v);
-extern int archive_write_zip_set_compression_deflate(struct archive *_a);
-extern int archive_write_set_format_option(struct archive *_a, const char *m, const char *o, const char *v);
-extern int archive_read_set_filter_option(struct archive *_a, const char *m, const char *o, const char *v);
-extern int archive_read_set_format_option(struct archive *_a, const char *m, const char *o, const char *v);
-
-/* ARCHIVE WRITING */
-extern struct archive *archive_write_new(void);
-extern int archive_write_free(struct archive *);
-
-/* opening */
-extern int archive_write_open(struct archive *, void *,
- archive_open_callback *, archive_write_callback *,
- archive_close_callback *);
-extern int archive_write_open_fd(struct archive *, int _fd);
-extern int archive_write_open_filename(struct archive *, const char *_file);
-extern int archive_write_open_filename_w(struct archive *,
- const wchar_t *_file);
-extern int archive_write_open_memory(struct archive *,
- void *_buffer, size_t _buffSize, size_t *_used);
-
-/* closing */
-extern int archive_write_close(struct archive *);
-
-/* headers */
-extern int archive_write_header(struct archive *,
- struct archive_entry *);
-
-/* data */
-
-/* commit */
-extern int archive_write_finish_entry(struct archive *);
-
-/* FILTERS */
-extern int archive_write_add_filter_bzip2(struct archive *);
-extern int archive_write_add_filter_compress(struct archive *);
-extern int archive_write_add_filter_gzip(struct archive *);
-extern int archive_write_add_filter_lzip(struct archive *);
-extern int archive_write_add_filter_lzma(struct archive *);
-extern int archive_write_add_filter_none(struct archive *);
-extern int archive_write_add_filter_xz(struct archive *);
-extern int archive_write_add_filter_zstd(struct archive *);
-
-
-/* FORMATS */
-/* A convenience function to set the format based on the code or name. */
-extern int archive_write_set_format(struct archive *, int format_code);
-extern int archive_write_set_format_by_name(struct archive *,
- const char *name);
-/* To minimize link pollution, use one or more of the following. */
-extern int archive_write_set_format_ar_bsd(struct archive *);
-extern int archive_write_set_format_ar_svr4(struct archive *);
-extern int archive_write_set_format_cpio(struct archive *);
-extern int archive_write_set_format_cpio_newc(struct archive *);
-extern int archive_write_set_format_gnutar(struct archive *);
-extern int archive_write_set_format_iso9660(struct archive *);
-/*extern int archive_write_set_format_mtree(struct archive *);*/
-/* TODO: int archive_write_set_format_old_tar(struct archive *); */
-extern int archive_write_set_format_pax(struct archive *);
-extern int archive_write_set_format_pax_restricted(struct archive *);
-extern int archive_write_set_format_shar(struct archive *);
-extern int archive_write_set_format_shar_dump(struct archive *);
-extern int archive_write_set_format_ustar(struct archive *);
-extern int archive_write_set_format_xar(struct archive *);
-extern int archive_write_set_format_zip(struct archive *);
-
-/* ARCHIVE ENTRY */
-extern struct archive_entry *archive_entry_new(void);
-extern void archive_entry_free(struct archive_entry *);
-extern const char *archive_entry_symlink(struct archive_entry *);
-extern void archive_entry_set_symlink(struct archive_entry *, const char *);
-extern const char *archive_entry_hardlink(struct archive_entry *);
-extern void archive_entry_set_hardlink(struct archive_entry *, const char *);
-
-/* ARCHIVE ENTRY PROPERTY ACCESS */
-/* reading */
-extern const char *archive_entry_pathname(struct archive_entry *);
-extern const wchar_t *archive_entry_pathname_w(struct archive_entry *);
-extern __LA_INT64_T archive_entry_size(struct archive_entry *);
-extern time_t archive_entry_mtime(struct archive_entry *);
-extern time_t archive_entry_mtime_nsec(struct archive_entry *);
-extern __LA_MODE_T archive_entry_filetype(struct archive_entry *);
-extern __LA_MODE_T archive_entry_perm(struct archive_entry *);
-
-/* writing */
-extern void archive_entry_set_pathname(struct archive_entry *, const char *);
-extern void archive_entry_set_size(struct archive_entry *, __LA_INT64_T);
-extern void archive_entry_set_mtime(struct archive_entry *, time_t, long);
-extern void archive_entry_set_filetype(struct archive_entry *, unsigned int);
-extern void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
-
-
-/* ERROR HANDLING */
-extern int archive_errno(struct archive *);
-extern const char *archive_error_string(struct archive *);
-
-
-/* CONSTANTS */
-#define ARCHIVE_VERSION_NUMBER 3000001
-#define ARCHIVE_VERSION_STRING "libarchive 3.0.1b"
-#define ARCHIVE_EOF 1 /* Found end of archive. */
-#define ARCHIVE_OK 0 /* Operation was successful. */
-#define ARCHIVE_RETRY (-10) /* Retry might succeed. */
-#define ARCHIVE_WARN (-20) /* Partial success. */
-#define ARCHIVE_FAILED (-25) /* Current operation cannot complete. */
-#define ARCHIVE_FATAL (-30) /* No more operations are possible. */
-
-#define ARCHIVE_FILTER_NONE 0
-#define ARCHIVE_FILTER_GZIP 1
-#define ARCHIVE_FILTER_BZIP2 2
-#define ARCHIVE_FILTER_COMPRESS 3
-#define ARCHIVE_FILTER_PROGRAM 4
-#define ARCHIVE_FILTER_LZMA 5
-#define ARCHIVE_FILTER_XZ 6
-#define ARCHIVE_FILTER_UU 7
-#define ARCHIVE_FILTER_RPM 8
-#define ARCHIVE_FILTER_LZIP 9
-
-#define ARCHIVE_FORMAT_BASE_MASK 0xff0000
-#define ARCHIVE_FORMAT_CPIO 0x10000
-#define ARCHIVE_FORMAT_CPIO_POSIX (ARCHIVE_FORMAT_CPIO | 1)
-#define ARCHIVE_FORMAT_CPIO_BIN_LE (ARCHIVE_FORMAT_CPIO | 2)
-#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3)
-#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4)
-#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5)
-#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6)
-#define ARCHIVE_FORMAT_SHAR 0x20000
-#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1)
-#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2)
-#define ARCHIVE_FORMAT_TAR 0x30000
-#define ARCHIVE_FORMAT_TAR_USTAR (ARCHIVE_FORMAT_TAR | 1)
-#define ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE (ARCHIVE_FORMAT_TAR | 2)
-#define ARCHIVE_FORMAT_TAR_PAX_RESTRICTED (ARCHIVE_FORMAT_TAR | 3)
-#define ARCHIVE_FORMAT_TAR_GNUTAR (ARCHIVE_FORMAT_TAR | 4)
-#define ARCHIVE_FORMAT_ISO9660 0x40000
-#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1)
-#define ARCHIVE_FORMAT_ZIP 0x50000
-#define ARCHIVE_FORMAT_EMPTY 0x60000
-#define ARCHIVE_FORMAT_AR 0x70000
-#define ARCHIVE_FORMAT_AR_GNU (ARCHIVE_FORMAT_AR | 1)
-#define ARCHIVE_FORMAT_AR_BSD (ARCHIVE_FORMAT_AR | 2)
-#define ARCHIVE_FORMAT_MTREE 0x80000
-#define ARCHIVE_FORMAT_RAW 0x90000
-#define ARCHIVE_FORMAT_XAR 0xA0000
-#define ARCHIVE_FORMAT_LHA 0xB0000
-#define ARCHIVE_FORMAT_CAB 0xC0000
-#define ARCHIVE_FORMAT_RAR 0xD0000
-#define ARCHIVE_FORMAT_7ZIP 0xE0000
-
-#define ARCHIVE_EXTRACT_OWNER (0x0001)
-#define ARCHIVE_EXTRACT_PERM (0x0002)
-#define ARCHIVE_EXTRACT_TIME (0x0004)
-#define ARCHIVE_EXTRACT_NO_OVERWRITE (0x0008)
-#define ARCHIVE_EXTRACT_UNLINK (0x0010)
-#define ARCHIVE_EXTRACT_ACL (0x0020)
-#define ARCHIVE_EXTRACT_FFLAGS (0x0040)
-#define ARCHIVE_EXTRACT_XATTR (0x0080)
-#define ARCHIVE_EXTRACT_SECURE_SYMLINKS (0x0100)
-#define ARCHIVE_EXTRACT_SECURE_NODOTDOT (0x0200)
-#define ARCHIVE_EXTRACT_NO_AUTODIR (0x0400)
-#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800)
-#define ARCHIVE_EXTRACT_SPARSE (0x1000)
-#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
-
-%inline %{
-PyObject *archive_read_data_into_str(struct archive *archive, int len) {
- PyObject *str = NULL;
- if (!(str = PyBytes_FromStringAndSize(NULL, len))) {
- PyErr_SetString(PyExc_MemoryError, "could not allocate string.");
- return NULL;
- }
- if (len != archive_read_data(archive, PyBytes_AS_STRING(str), len)) {
- PyErr_SetString(PyExc_RuntimeError, "could not read requested data.");
- return NULL;
- }
- return str;
-}
-
-PyObject *archive_write_data_from_str(struct archive *archive, PyObject *str) {
- int len = PyBytes_Size(str);
- if (len == 0)
- return PyInt_FromLong(len);
- int ret = archive_write_data(archive, PyBytes_AS_STRING(str), len);
- if (ret == ARCHIVE_FATAL) {
- PyErr_Format(PyExc_RuntimeError, "Could not write requested data - most likely no space left on device (error code: %d)", ret);
- return NULL;
- }
- else if (ret <= 0) {
- PyErr_Format(PyExc_RuntimeError, "Could not write requested data (error code: %d)", ret);
- return NULL;
- }
- return PyInt_FromLong(len);
-}
-%}
diff --git a/contrib/python/python-libarchive/py3/libarchive/tar.py b/contrib/python/python-libarchive/py3/libarchive/tar.py
deleted file mode 100644
index f14149804b9..00000000000
--- a/contrib/python/python-libarchive/py3/libarchive/tar.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# Copyright (c) 2011, SmartFile <[email protected]>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the organization nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import time
-from libarchive import is_archive, Entry, SeekableArchive
-from tarfile import DEFAULT_FORMAT, USTAR_FORMAT, GNU_FORMAT, PAX_FORMAT, ENCODING
-from tarfile import REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE
-
-FORMAT_CONVERSION = {
- USTAR_FORMAT: 'tar',
- GNU_FORMAT: 'gnu',
- PAX_FORMAT: 'pax',
-}
-
-
-def is_tarfile(filename):
- return is_archive(filename, formats=('tar', 'gnu', 'pax'))
-
-
-def open(**kwargs):
- return TarFile(**kwargs)
-
-
-class TarInfo(Entry):
- def __init__(self, name):
- super(TarInfo, self).__init__(pathname=name)
-
- fromtarfile = Entry.from_archive
-
- def get_name(self):
- return self.pathname
-
- def set_name(self, value):
- self.pathname = value
-
- name = property(get_name, set_name)
-
- @property
- def get_type(self):
- for attr, type in (
- ('isdir', DIRTYPE), ('isfile', REGTYPE), ('issym', SYMTYPE),
- ('isfifo', FIFOTYPE), ('ischr', CHRTYPE), ('isblk', BLKTYPE),
- ):
- if getattr(self, attr)():
- return type
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- pax_headers = property(_get_missing, _set_missing)
-
-
-class TarFile(SeekableArchive):
- def __init__(self, name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, encoding=ENCODING):
- if name:
- f = name
- elif fileobj:
- f = fileobj
- try:
- format = FORMAT_CONVERSON.get(format)
- except KeyError:
- raise Exception('Invalid tar format: %s' % format)
- super(TarFile, self).__init__(f, mode=mode, format=format, entry_class=tarinfo, encoding=encoding)
-
- getmember = SeekableArchive.getentry
- list = SeekableArchive.printlist
- extract = SeekableArchive.readpath
- extractfile = SeekableArchive.readstream
-
- def getmembers(self):
- return list(self)
-
- def getnames(self):
- return list(self.iterpaths)
-
- def next(self):
- pass # TODO: how to do this?
-
- def extract(self, member, path=None):
- if path is None:
- path = os.getcwd()
- if isinstance(member, basestring):
- f = os.path.join(path, member)
- else:
- f = os.path.join(path, member.pathname)
- return self.readpath(member, f)
-
- def add(self, name, arcname, recursive=True, exclude=None, filter=None):
- pass # TODO: implement this.
-
- def addfile(tarinfo, fileobj):
- return self.writepath(fileobj, tarinfo)
-
- def gettarinfo(name=None, arcname=None, fileobj=None):
- if name:
- f = name
- elif fileobj:
- f = fileobj
- entry = self.entry_class.from_file(f)
- if arcname:
- entry.pathname = arcname
- return entry
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- pax_headers = property(_get_missing, _set_missing)
diff --git a/contrib/python/python-libarchive/py3/libarchive/zip.py b/contrib/python/python-libarchive/py3/libarchive/zip.py
deleted file mode 100644
index 539f6dbcc49..00000000000
--- a/contrib/python/python-libarchive/py3/libarchive/zip.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (c) 2011, SmartFile <[email protected]>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the organization nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os, time
-from libarchive import is_archive, Entry, SeekableArchive
-from zipfile import ZIP_STORED, ZIP_DEFLATED
-
-
-def is_zipfile(filename):
- return is_archive(filename, formats=('zip', ))
-
-
-class ZipEntry(Entry):
- def __init__(self, *args, **kwargs):
- super(ZipEntry, self).__init__(*args, **kwargs)
-
- def get_filename(self):
- return self.pathname
-
- def set_filename(self, value):
- self.pathname = value
-
- filename = property(get_filename, set_filename)
-
- def get_file_size(self):
- return self.size
-
- def set_file_size(self, value):
- assert isinstance(size, (int, long)), 'Please provide size as int or long.'
- self.size = value
-
- file_size = property(get_file_size, set_file_size)
-
- def get_date_time(self):
- return time.localtime(self.mtime)[0:6]
-
- def set_date_time(self, value):
- assert isinstance(value, tuple), 'mtime should be tuple (year, month, day, hour, minute, second).'
- assert len(value) == 6, 'mtime should be tuple (year, month, day, hour, minute, second).'
- self.mtime = time.mktime(value + (0, 0, 0))
-
- date_time = property(get_date_time, set_date_time)
-
- header_offset = Entry.header_position
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- compress_type = property(_get_missing, _set_missing)
- comment = property(_get_missing, _set_missing)
- extra = property(_get_missing, _set_missing)
- create_system = property(_get_missing, _set_missing)
- create_version = property(_get_missing, _set_missing)
- extract_version = property(_get_missing, _set_missing)
- reserved = property(_get_missing, _set_missing)
- flag_bits = property(_get_missing, _set_missing)
- volume = property(_get_missing, _set_missing)
- internal_attr = property(_get_missing, _set_missing)
- external_attr = property(_get_missing, _set_missing)
- CRC = property(_get_missing, _set_missing)
- compress_size = property(_get_missing, _set_missing)
-
-
-class ZipFile(SeekableArchive):
- def __init__(self, f, mode='r', compression=ZIP_DEFLATED, allowZip64=False):
- super(ZipFile, self).__init__(f, mode=mode, format='zip', entry_class=ZipEntry, encoding='CP437')
- if mode == 'w' and compression == ZIP_STORED:
- # Disable compression for writing.
- _libarchive.archive_write_set_format_option(self.archive._a, "zip", "compression", "store")
- self.compression = compression
-
- getinfo = SeekableArchive.getentry
-
- def namelist(self):
- return list(self.iterpaths)
-
- def infolist(self):
- return list(self)
-
- def open(self, name, mode, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- if mode == 'r':
- return self.readstream(name)
- else:
- return self.writestream(name)
-
- def extract(self, name, path=None, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- if not path:
- path = os.getcwd()
- return self.readpath(name, os.path.join(path, name))
-
- def extractall(self, path, names=None, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- if not names:
- names = self.namelist()
- if names:
- for name in names:
- self.extract(name, path)
-
- def read(self, name, pwd=None):
- if pwd:
- raise NotImplemented('Encryption not supported.')
- return self.read(name)
-
- def writestr(self, member, data, compress_type=None):
- if compress_type != self.compression:
- raise Exception('Cannot change compression type for individual entries.')
- return self.write(member, data)
-
- def setpassword(self, pwd):
- raise NotImplemented('Encryption not supported.')
-
- def testzip(self):
- raise NotImplemented()
-
- def _get_missing(self):
- raise NotImplemented()
-
- def _set_missing(self, value):
- raise NotImplemented()
-
- comment = property(_get_missing, _set_missing)