def add_abs_file(self, path, store_path): """ Read the given paths from disk and add them to the archive. """ write_p = self._pointer block_size = ffi.write_get_bytes_per_block(write_p) if block_size <= 0: block_size = 10240 # pragma: no cover with new_archive_entry() as entry_p: entry = ArchiveEntry(None, entry_p) with new_archive_read_disk(path) as read_p: while True: r = read_next_header2(read_p, entry_p) if r == ARCHIVE_EOF: break entry.pathname = store_path read_disk_descend(read_p) write_header(write_p, entry_p) try: with open(entry_sourcepath(entry_p), 'rb') as f: while True: data = f.read(block_size) if not data: break write_data(write_p, data, len(data)) except IOError as e: if e.errno != 21: raise # pragma: no cover write_finish_entry(write_p) entry_clear(entry_p) if os.path.isdir(path): break
def extract_entries(entries, flags=0, callback=None, totalsize=None, extractlist=None): """Extracts the given archive entries into the current directory. """ buff, size, offset = c_void_p(), c_size_t(), c_longlong() buff_p, size_p, offset_p = byref(buff), byref(size), byref(offset) sizedone = 0 printat = 0 with libarchive.extract.new_archive_write_disk(flags) as write_p: for entry in entries: if str(entry).endswith('TRANS.TBL'): continue if extractlist and str(entry) not in extractlist: continue write_header(write_p, entry._entry_p) read_p = entry._archive_p while 1: r = read_data_block(read_p, buff_p, size_p, offset_p) sizedone += size.value if callback and time.time() > printat: callback({'progress': float(sizedone) / float(totalsize)}) printat = time.time() + 0.5 if r == ARCHIVE_EOF: break write_data_block(write_p, buff, size, offset) write_finish_entry(write_p) if os.path.isdir(str(entry)): os.chmod(str(entry), 0o755) else: os.chmod(str(entry), 0o644) if callback: callback({'progress': float(sizedone) / float(totalsize)})
def test_entry_sparse_manual(tmpdir, sparse_map): """ Can we archive a partial non-sparse file as sparse """ fname = tmpdir.join('sparse1').strpath size = 8192 with open(fname, 'w') as testf: testf.write(generate_contents(8192)) buf = bytes(bytearray(1000000)) with memory_writer(buf, 'pax') as archive: with new_archive_entry_from_path(fname) as entry: assert len(entry.sparse_map) == 0 entry.sparse_map.extend(sparse_map) # not using archive.add_entries, that assumes the entry comes from # another archive and tries to use entry.get_blocks() write_p = archive._pointer ffi.write_header(write_p, entry.entry_p) with open(fname, 'rb') as testf: entry_data = testf.read() ffi.write_data(write_p, entry_data, len(entry_data)) ffi.write_finish_entry(write_p) with memory_reader(buf) as archive: for entry in archive: assert entry.name == fname.lstrip('/') assert entry.mode == stat(fname)[0] assert entry.size == size assert len(entry.sparse_map) == len(sparse_map) assert entry.sparse_map == sparse_map