From 69e63fe55678587a8d9648bc35609fba9a495616 Mon Sep 17 00:00:00 2001 From: Steve Randall Date: Tue, 5 Jun 2018 10:55:06 -0500 Subject: [PATCH 1/4] Set options for writing archive. Set uid/gid lookup for reading disk. --- libarchive/ffi.py | 1 + libarchive/write.py | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/libarchive/ffi.py b/libarchive/ffi.py index 03c81d3..28a1c41 100644 --- a/libarchive/ffi.py +++ b/libarchive/ffi.py @@ -209,6 +209,7 @@ def ffi(name, argtypes, restype, errcheck=None): # archive_write ffi('write_new', [], c_archive_p, check_null) +ffi('write_set_options', [c_archive_p, c_char_p], c_int, check_int) ffi('write_disk_new', [], c_archive_p, check_null) ffi('write_disk_set_options', [c_archive_p, c_int], c_int, check_int) diff --git a/libarchive/write.py b/libarchive/write.py index 2c06f0d..0ad801c 100644 --- a/libarchive/write.py +++ b/libarchive/write.py @@ -15,8 +15,10 @@ @contextmanager -def new_archive_read_disk(path): +def new_archive_read_disk(path, lookup=False): archive_p = read_disk_new() + if lookup: + ffi.read_disk_set_standard_lookup(archive_p) read_disk_open_w(archive_p, path) try: yield archive_p @@ -39,7 +41,7 @@ def add_entries(self, entries): write_data(write_p, block, len(block)) write_finish_entry(write_p) - def add_files(self, *paths): + def add_files(self, *paths, **kw): """Read the given paths from disk and add them to the archive. """ write_p = self._pointer @@ -51,7 +53,7 @@ def add_files(self, *paths): with new_archive_entry() as entry_p: entry = ArchiveEntry(None, entry_p) for path in paths: - with new_archive_read_disk(path) as read_p: + with new_archive_read_disk(path, **kw) as read_p: while 1: r = read_next_header2(read_p, entry_p) if r == ARCHIVE_EOF: @@ -109,11 +111,15 @@ def add_file_from_memory( @contextmanager -def new_archive_write(format_name, filter_name=None): +def new_archive_write(format_name, filter_name=None, options=''): archive_p = ffi.write_new() getattr(ffi, 'write_set_format_'+format_name)(archive_p) if filter_name: getattr(ffi, 'write_add_filter_'+filter_name)(archive_p) + if options: + if not isinstance(options, bytes): + options = options.encode('utf-8') + ffi.write_set_options(archive_p, options) try: yield archive_p ffi.write_close(archive_p) @@ -128,7 +134,7 @@ def new_archive_write(format_name, filter_name=None): def custom_writer( write_func, format_name, filter_name=None, open_func=VOID_CB, close_func=VOID_CB, block_size=page_size, - archive_write_class=ArchiveWrite + archive_write_class=ArchiveWrite, options='' ): def write_cb_internal(archive_p, context, buffer_, length): @@ -139,7 +145,7 @@ def write_cb_internal(archive_p, context, buffer_, length): write_cb = WRITE_CALLBACK(write_cb_internal) close_cb = CLOSE_CALLBACK(close_func) - with new_archive_write(format_name, filter_name) as archive_p: + with new_archive_write(format_name, filter_name, options) as archive_p: ffi.write_set_bytes_in_last_block(archive_p, 1) ffi.write_set_bytes_per_block(archive_p, block_size) ffi.write_open(archive_p, None, open_cb, write_cb, close_cb) @@ -148,9 +154,10 @@ def write_cb_internal(archive_p, context, buffer_, length): @contextmanager def fd_writer( - fd, format_name, filter_name=None, archive_write_class=ArchiveWrite + fd, format_name, filter_name=None, + archive_write_class=ArchiveWrite, options='' ): - with new_archive_write(format_name, filter_name) as archive_p: + with new_archive_write(format_name, filter_name, options) as archive_p: ffi.write_open_fd(archive_p, fd) yield archive_write_class(archive_p) @@ -158,18 +165,19 @@ def fd_writer( @contextmanager def file_writer( filepath, format_name, filter_name=None, - archive_write_class=ArchiveWrite + archive_write_class=ArchiveWrite, options='' ): - with new_archive_write(format_name, filter_name) as archive_p: + with new_archive_write(format_name, filter_name, options) as archive_p: ffi.write_open_filename_w(archive_p, filepath) yield archive_write_class(archive_p) @contextmanager def memory_writer( - buf, format_name, filter_name=None, archive_write_class=ArchiveWrite + buf, format_name, filter_name=None, + archive_write_class=ArchiveWrite, options='' ): - with new_archive_write(format_name, filter_name) as archive_p: + with new_archive_write(format_name, filter_name, options) as archive_p: used = byref(c_size_t()) buf_p = cast(buf, c_void_p) ffi.write_open_memory(archive_p, buf_p, len(buf), used) From 8ce3dd3d9bd4bf46c1cb528bafa0608629a31d42 Mon Sep 17 00:00:00 2001 From: Steve Randall Date: Fri, 8 Jun 2018 06:50:09 -0500 Subject: [PATCH 2/4] Add support for "read disk" flags for adding files to archive. --- libarchive/ffi.py | 1 + libarchive/write.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libarchive/ffi.py b/libarchive/ffi.py index 28a1c41..755eb71 100644 --- a/libarchive/ffi.py +++ b/libarchive/ffi.py @@ -193,6 +193,7 @@ def ffi(name, argtypes, restype, errcheck=None): # archive_read_disk ffi('read_disk_new', [], c_archive_p, check_null) +ffi('read_disk_set_behavior', [c_archive_p, c_int], c_int, check_int) ffi('read_disk_set_standard_lookup', [c_archive_p], c_int, check_int) ffi('read_disk_open', [c_archive_p, c_char_p], c_int, check_int) ffi('read_disk_open_w', [c_archive_p, c_wchar_p], c_int, check_int) diff --git a/libarchive/write.py b/libarchive/write.py index 0ad801c..8648063 100644 --- a/libarchive/write.py +++ b/libarchive/write.py @@ -10,13 +10,24 @@ DEFAULT_UNIX_PERMISSION, ARCHIVE_EOF, page_size, entry_sourcepath, entry_clear, read_disk_new, read_disk_open_w, read_next_header2, read_disk_descend, read_free, write_header, write_data, - write_finish_entry, entry_set_size, entry_set_filetype, entry_set_perm + write_finish_entry, entry_set_size, entry_set_filetype, entry_set_perm, + read_disk_set_behavior ) +READDISK_RESTORE_ATIME = 0x0001 +READDISK_HONOR_NODUMP = 0x0002 +READDISK_MAC_COPYFILE = 0x0004 +READDISK_NO_TRAVERSE_MOUNTS = 0x0008 +READDISK_NO_XATTR = 0x0010 +READDISK_NO_ACL = 0x0020 +READDISK_NO_FFLAGS = 0x0040 + + @contextmanager -def new_archive_read_disk(path, lookup=False): +def new_archive_read_disk(path, flags=0, lookup=False): archive_p = read_disk_new() + read_disk_set_behavior(archive_p, flags) if lookup: ffi.read_disk_set_standard_lookup(archive_p) read_disk_open_w(archive_p, path) From 191577a935fe40ff83c08b0b604a42de2d695187 Mon Sep 17 00:00:00 2001 From: Changaco Date: Sun, 10 Jun 2018 15:15:04 +0200 Subject: [PATCH 3/4] move `READDISK_*` constants to new `flags` module --- libarchive/flags.py | 7 +++++++ libarchive/write.py | 9 --------- 2 files changed, 7 insertions(+), 9 deletions(-) create mode 100644 libarchive/flags.py diff --git a/libarchive/flags.py b/libarchive/flags.py new file mode 100644 index 0000000..6c5b304 --- /dev/null +++ b/libarchive/flags.py @@ -0,0 +1,7 @@ +READDISK_RESTORE_ATIME = 0x0001 +READDISK_HONOR_NODUMP = 0x0002 +READDISK_MAC_COPYFILE = 0x0004 +READDISK_NO_TRAVERSE_MOUNTS = 0x0008 +READDISK_NO_XATTR = 0x0010 +READDISK_NO_ACL = 0x0020 +READDISK_NO_FFLAGS = 0x0040 diff --git a/libarchive/write.py b/libarchive/write.py index 8648063..f547105 100644 --- a/libarchive/write.py +++ b/libarchive/write.py @@ -15,15 +15,6 @@ ) -READDISK_RESTORE_ATIME = 0x0001 -READDISK_HONOR_NODUMP = 0x0002 -READDISK_MAC_COPYFILE = 0x0004 -READDISK_NO_TRAVERSE_MOUNTS = 0x0008 -READDISK_NO_XATTR = 0x0010 -READDISK_NO_ACL = 0x0020 -READDISK_NO_FFLAGS = 0x0040 - - @contextmanager def new_archive_read_disk(path, flags=0, lookup=False): archive_p = read_disk_new() From 3d59828d358f72b8fe5fee530d739e16a8856043 Mon Sep 17 00:00:00 2001 From: Changaco Date: Sun, 10 Jun 2018 15:18:47 +0200 Subject: [PATCH 4/4] update docstring of `ArchiveWrite.add_files()` --- libarchive/write.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libarchive/write.py b/libarchive/write.py index f547105..c2ff9af 100644 --- a/libarchive/write.py +++ b/libarchive/write.py @@ -45,6 +45,8 @@ def add_entries(self, entries): def add_files(self, *paths, **kw): """Read the given paths from disk and add them to the archive. + + The keyword arguments (`**kw`) are passed to `new_archive_read_disk`. """ write_p = self._pointer