From: Philipp Gesang Date: Fri, 28 Apr 2017 16:06:27 +0000 (+0200) Subject: encode operation modes X-Git-Tag: v2.2~7^2~138 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=d1c38f40ba08825586661868fafac5771bb4b597;p=python-delta-tar encode operation modes Introduce the “arcmode” to comprehensively switch modes to supplant the pervasive ad-hoc string parsing and attribute queries. Encodes the triple encryption, compression, concat. --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index 180745c..b7cf6ad 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -130,6 +130,7 @@ class DeltaTar(object): '#gz': '.gz', '#gz.pdtcrypt': '.gz', '#pdtcrypt': '', + '#': '', } # valid index modes and their corresponding default file extension @@ -232,7 +233,6 @@ class DeltaTar(object): if crypto_paramversion is not None: self.crypto_paramversion = crypto_paramversion - # generate index_mode if index_mode is None: index_mode = '' @@ -685,7 +685,7 @@ class DeltaTar(object): tarobj = tarfile.TarFile.open(tarfile_path, mode='w' + self.mode, format=tarfile.GNU_FORMAT, - concat_compression='#gz' in self.mode, + concat='#' in self.mode, encryption=self.encryptor, max_volume_size=max_volume_size, new_volume_handler=new_volume_handler, @@ -848,7 +848,7 @@ class DeltaTar(object): tarobj = tarfile.TarFile.open(tarfile_path, mode='w' + self.mode, format=tarfile.GNU_FORMAT, - concat_compression='#gz' in self.mode, + concat='#' in self.mode, encryption=self.encryptor, max_volume_size=max_volume_size, new_volume_handler=new_volume_handler, @@ -1067,7 +1067,7 @@ class DeltaTar(object): self.tar_obj = tarfile.TarFile.open(self.tar_path, mode='r' + self.delta_tar.mode, format=tarfile.GNU_FORMAT, - concat_compression='#gz' in self.delta_tar.mode, + concat='#' in self.delta_tar.mode, encryption=self.delta_tar.decryptor, new_volume_handler=self.new_volume_handler, save_to_members=False, @@ -1245,7 +1245,7 @@ class DeltaTar(object): tarobj = tarfile.TarFile.open(backup_tar_path, mode='r' + self.mode, format=tarfile.GNU_FORMAT, - concat_compression='#gz' in self.mode, + concat='#' in self.mode, encryption=self.decryptor, new_volume_handler=new_volume_handler, save_to_members=False, @@ -1754,7 +1754,7 @@ class RestoreHelper(object): index_data['tarobj'] = tarfile.open(mode="r" + self._deltatar.mode, fileobj=index_data['vol_fd'], format=tarfile.GNU_FORMAT, - concat_compression='#gz' in self._deltatar.mode, + concat='#' in self._deltatar.mode, encryption=self._deltatar.decryptor, new_volume_handler=index_data['new_volume_handler'], save_to_members=False) diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index 59f9c9e..6e7517d 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -126,6 +126,44 @@ GZ_MAGIC_DEFLATE = struct.pack ("= 0 if self.remainder > 0: self.remainder = 0 @@ -867,13 +933,14 @@ class _Stream: # happens at the end of the file # _init_read_gz failed in the previous iteration so # self.cmp.decompress fails here - if self.concat_stream: + if self.arcmode & ARCMODE_CONCAT: pass else: raise ReadError("invalid compressed data") - if self.comptype == "gz" and hasattr(self, "crc"): + if self.arcmode & ARCMODE_COMPRESS and hasattr(self, "crc"): self.crc = self.zlib.crc32(buf, self.crc) & 0xFFFFffff - if self.concat_stream and len(self.cmp.unused_data) != 0: + if self.arcmode & ARCMODE_CONCAT \ + and len(self.cmp.unused_data) != 0: self.buf = self.cmp.unused_data + self.buf self.close(close_fileobj=False) try: @@ -898,7 +965,7 @@ class _Stream: t = [self.buf] while c < size: todo = size - if self.encryption is not None: + if self.arcmode & ARCMODE_ENCRYPT: if self.remainder <= 0: # prepare next object if self._init_read_encrypt () is False: # EOF @@ -908,7 +975,7 @@ class _Stream: # only read up to the end of the encrypted object todo = min (size, self.remainder) buf = self.fileobj.read(todo) - if self.encryption is not None: + if self.arcmode & ARCMODE_ENCRYPT: # decrypt the thing buf = self.encryption.process (buf) if todo == self.remainder: @@ -1806,8 +1873,8 @@ class TarFile(object): fileobject = ExFileObject # The file-object for extractfile(). - concat_compression = False # Used to separate in different zip members each - # file, used for robustness. + arcmode = ARCMODE_PLAIN # Object processing mode (“concat”, encryption, + # compression) save_to_members = True # If new members are saved. This can be disabled # if you manage lots of files and don't want @@ -1820,7 +1887,7 @@ class TarFile(object): tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None, max_volume_size=None, new_volume_handler=None, - concat_compression=False, nacl=None, + concat=False, nacl=None, save_to_members=True): """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to read from an existing archive, 'a' to append data to an existing @@ -1833,7 +1900,7 @@ class TarFile(object): if len(mode) > 1 or mode not in "raw": raise ValueError("mode must be 'r', 'a' or 'w'") self.mode = mode - self.concat_compression = concat_compression + self.arcmode = arcmode_set (concat) self.nacl = nacl self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] @@ -2039,10 +2106,9 @@ class TarFile(object): raise ValueError("mode must be 'r' or 'w'") stream = _Stream(name, filemode, comptype, fileobj, bufsize, - concat_stream=True, encryption=encryption, + concat=True, encryption=encryption, compresslevel=compresslevel) - if comptype != "tar": - kwargs ["concat_compression"] = True + kwargs ["concat"] = True try: t = cls(name, filemode, stream, **kwargs) except: # XXX except what? @@ -2441,16 +2507,8 @@ class TarFile(object): tarinfo = copy.copy(tarinfo) - if self.concat_compression is True: - if getattr (self.fileobj, "cmp", None) is not None: - self.fileobj._finalize_write_gz () - encrypt = getattr (self.fileobj, "encryption", None) is not None - if encrypt is True: - self.fileobj._finalize_write_encrypt () - self.fileobj._init_write_encrypt (tarinfo.name, - set_last_block_offset=True) - self.fileobj._init_write_gz (set_last_block_offset=not encrypt) - self.last_block_offset = self.fileobj.last_block_offset + if self.arcmode & ARCMODE_CONCAT: + self.last_block_offset = self.fileobj.next (tarinfo.name) else: self.last_block_offset = self.fileobj.tell() @@ -2528,15 +2586,8 @@ class TarFile(object): self.volume_tarinfo = None - if self.concat_compression is True: - # with non-concat modes, this is taken care by the _Stream - # ctor as invoked by the newvol handler - if getattr (self.fileobj, "cmp", None) is not None: - # e. g. compressed PAX header written - self.fileobj._finalize_write_gz () - if getattr (self.fileobj, "encryption", None) is not None: - self.fileobj._init_write_encrypt (tarinfo.name) - self.fileobj._init_write_gz () + if self.arcmode & ARCMODE_CONCAT: + self.fileobj.next_volume (tarinfo.name) # write new volume header buf = tarinfo.tobuf(self.format, self.encoding, self.errors) @@ -2579,7 +2630,7 @@ class TarFile(object): fileobj=None, bufsize=self.fileobj.bufsize, encryption=encryption, - concat_stream=self.fileobj.concat_stream) + concat=self.fileobj.arcmode & ARCMODE_CONCAT) else: # here, we lose information about compression/encryption! self._dbg(3, 'open_volume: builtin open') diff --git a/testing/test_concat_compress.py b/testing/test_concat_compress.py index 2359bec..84f47ba 100644 --- a/testing/test_concat_compress.py +++ b/testing/test_concat_compress.py @@ -39,8 +39,7 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", mode="w#gz", - format=GNU_FORMAT, - concat_compression=True) + format=GNU_FORMAT) tarobj.add("big") tarobj.close() os.unlink("big") @@ -62,8 +61,7 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + mode="w#gz") tarobj.add("big") tarobj.close() os.unlink("big") @@ -86,8 +84,7 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + mode="w#gz") tarobj.add("big") pos = tarobj.get_last_member_offset() tarobj.close() @@ -115,8 +112,7 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + mode="w#gz") tarobj.add("big") tarobj.add("small") pos = tarobj.get_last_member_offset() @@ -157,7 +153,6 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", mode="w#gz", - concat_compression=True, max_volume_size=1000000, new_volume_handler=new_volume_handler) tarobj.add("small") @@ -182,7 +177,6 @@ class ConcatCompressTest(BaseTest): fo = open("sample.tar.gz", 'rb') fo.seek(pos) tarobj = TarFile.open(mode="r#gz", fileobj=fo, - concat_compression=True, new_volume_handler=new_volume_handler_fo) tarobj.extract(tarobj.next()) tarobj.close() @@ -206,8 +200,7 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + mode="w#gz") tarobj.add("big") tarobj.add("small") tarobj.add("small2") @@ -243,9 +236,7 @@ class ConcatCompressTest(BaseTest): hash["small2"] = self.create_file("small2", 354) # create the tar file with volumes - tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + tarobj = TarFile.open("sample.tar.gz", mode="w#gz") tarobj.add("big") tarobj.add("small") tarobj.add("small2") @@ -282,7 +273,6 @@ class ConcatCompressTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", mode="w#gz", - concat_compression=True, max_volume_size=20000, new_volume_handler=new_volume_handler) tarobj.add("big") @@ -322,9 +312,7 @@ class ConcatCompressTest(BaseTest): hash["small2"] = self.create_file("small2", 354) # create the tar file with volumes - tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + tarobj = TarFile.open("sample.tar.gz", mode="w#gz") tarobj.add("big") tarobj.add("small") tarobj.add("small2") @@ -369,9 +357,7 @@ class ConcatCompressTest(BaseTest): hash["small2"] = self.create_file("small2", 354) # create the tar file with volumes - tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + tarobj = TarFile.open("sample.tar.gz", mode="w#gz") tarobj.add("big") tarobj.add("small") tarobj.add("small2") @@ -415,9 +401,7 @@ class ConcatCompressTest(BaseTest): hash["small2"] = self.create_file("small2", 354) # create the tar file with volumes - tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + tarobj = TarFile.open("sample.tar.gz", mode="w#gz") tarobj.add("big") tarobj.add("small") tarobj.add("small2") diff --git a/testing/test_deltatar.py b/testing/test_deltatar.py index f6e8095..a8dd8cc 100644 --- a/testing/test_deltatar.py +++ b/testing/test_deltatar.py @@ -1672,6 +1672,7 @@ class DeltaTarAes128ConcatTest(DeltaTarTest): ''' Same as DeltaTar but with specific aes128 concat stream mode ''' + MODE = '#' ENCRYPTION = ('some magic key', 1) diff --git a/testing/test_encryption.py b/testing/test_encryption.py index 9dafdc1..25cc1ae 100644 --- a/testing/test_encryption.py +++ b/testing/test_encryption.py @@ -62,7 +62,6 @@ class EncryptionTest(BaseTest): tarobj = TarFile.open("sample.tar.gz.pdtcrypt", mode="w#gz", format=GNU_FORMAT, - concat_compression=True, encryption=encryptor) tarobj.add("big") tarobj.close() @@ -104,7 +103,6 @@ class EncryptionTest(BaseTest): tarobj = TarFile.open("sample.tar.gz.pdtcrypt", mode="w#gz", format=GNU_FORMAT, - concat_compression=True, encryption=encryptor) for k in hash: @@ -148,7 +146,6 @@ class EncryptionTest(BaseTest): tarobj = TarFile.open("sample.tar.gz.pdtcrypt", mode="w#gz", format=GNU_FORMAT, - concat_compression=True, encryption=encryptor) tarobj.add("big") tarobj.close() @@ -184,7 +181,6 @@ class EncryptionTest(BaseTest): tarobj = TarFile.open("sample.tar.gz.pdtcrypt", mode="w#gz", format=GNU_FORMAT, - concat_compression=True, encryption=encryptor) for k in hash: @@ -233,7 +229,6 @@ class EncryptionTest(BaseTest): # entropy tarobj = TarFile.open("sample.tar.gz.pdtcrypt", mode="w#gz", - concat_compression=True, max_volume_size=20000, compresslevel=0, new_volume_handler=encrypt_volume, diff --git a/testing/test_rescue_tar.py b/testing/test_rescue_tar.py index cb0764f..854caab 100644 --- a/testing/test_rescue_tar.py +++ b/testing/test_rescue_tar.py @@ -43,8 +43,7 @@ class RescueTarTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + mode="w#gz") tarobj.add("big") tarobj.add("big2") tarobj.add("small") @@ -82,8 +81,7 @@ class RescueTarTest(BaseTest): # create the tar file with volumes tarobj = TarFile.open("sample.tar.gz", - mode="w#gz", - concat_compression=True) + mode="w#gz") tarobj.add("big") tarobj.add("big2") tarobj.add("small")