extend tarfile API for rescue mode
[python-delta-tar] / deltatar / tarfile.py
index a57983f..cc74e92 100644 (file)
@@ -126,6 +126,10 @@ GZ_MAGIC_BYTES       = struct.pack ("<BB", GZ_MAGIC [0], GZ_MAGIC [1])
 GZ_MAGIC_DEFLATE     = struct.pack ("<BBB", GZ_MAGIC [0], GZ_MAGIC [1],
                                     GZ_METHOD_DEFLATE)
 
+TOLERANCE_STRICT  = 0
+TOLERANCE_RECOVER = 1 # rely on offsets in index
+TOLERANCE_RESCUE  = 2 # deduce metadata from archive contents
+
 #---------------------------------------------------------
 # archive handling mode
 #---------------------------------------------------------
@@ -466,15 +470,15 @@ class _Stream:
     """
 
     remainder = -1 # track size in encrypted entries
-    tolerant  = False
+    tolerance = TOLERANCE_STRICT
 
     def __init__(self, name, mode, comptype, fileobj, bufsize,
                  concat=False, encryption=None, enccounter=None,
-                 compresslevel=9, tolerant=False):
+                 compresslevel=9, tolerance=TOLERANCE_STRICT):
         """Construct a _Stream object.
         """
         self.arcmode = arcmode_set (concat, encryption, comptype)
-        self.tolerant = tolerant
+        self.tolerance = tolerance
 
         self._extfileobj = True
         if fileobj is None:
@@ -891,7 +895,7 @@ class _Stream:
         try:
             return self.encryption.process (buf)
         except RuntimeError as exn:
-            if self.tolerant is True:
+            if self.tolerance != TOLERANCE_STRICT:
                 raise DecryptionError (exn)
             raise
 
@@ -1008,7 +1012,7 @@ class _Stream:
                     try:
                         self._init_read_gz()
                     except DecryptionError:
-                        if self.tolerant is True:
+                        if self.tolerance != TOLERANCE_STRICT:
                             # return whatever data was processed successfully
                             if len (buf) > 0:
                                 t.append (buf)
@@ -1067,7 +1071,7 @@ class _Stream:
                     else:
                         self.remainder -= todo
             except DecryptionError:
-                if self.tolerant is False:
+                if self.tolerance == TOLERANCE_STRICT:
                     raise
                 self.encryption.drop ()
                 if good_crypto == 0:
@@ -2101,7 +2105,8 @@ class TarFile(object):
 
     @classmethod
     def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE,
-             encryption=None, compresslevel=9, tolerant=False, **kwargs):
+             encryption=None, compresslevel=9, tolerance=TOLERANCE_STRICT,
+             **kwargs):
         """Open a tar archive for reading, writing or appending. Return
            an appropriate TarFile class.
 
@@ -2198,7 +2203,7 @@ class TarFile(object):
 
             stream = _Stream(name, filemode, comptype, fileobj, bufsize,
                              concat=True, encryption=encryption,
-                             compresslevel=compresslevel, tolerant=tolerant)
+                             compresslevel=compresslevel, tolerance=tolerance)
             kwargs ["concat"] = True
             try:
                 t = cls(name, filemode, stream, **kwargs)