def checkFile(cache, crypt, checksum, size, basis, compressed, encrypted, added, authCond): fsize = cache.size(checksum) if not cache.exists(checksum): #print(f"{checksum}: does not exist") missing.append(checksum) elif fsize == 0: print(f"{checksum} is empty") zero.append(checksum) else: authenticate = (authCond == 'all') if fsize != size: print( f"{checksum}: size mismatch Expected: {size}, found {fsize} ({fsize - size})-- {added} -- {basis is not None} " ) mismatch.append((checksum, size, fsize)) sizes.setdefault((fsize - size), []).append(checksum) if authCond != 'none': authenticate = True elif basis: #print(f"{checksum} -- {compressed} {encrypted}", flush=True) instream = decryptHeader(crypt, cache.open(checksum, "rb")) uc = CompressedBuffer.UncompressedBufferedReader( instream, compressor=compressed) data = uc.read(256) kind = magic.from_buffer(data) if kind != 'rdiff network-delta data': print(f"{checksum}: Not a delta: {kind}") notdelta.append((checksum, kind)) if authenticate: with cache.open(checksum, "rb") as f: if not authenticateFile(f, fsize, crypt): print(f"{checksum} did not authenticate") notauth.append(checksum)
def recoverChecksum(self, cksum, authenticate=True, chain=None, basisFile=None): self.logger.debug("Recovering checksum: %s", cksum) cksInfo = None if not chain: chain = self.db.getChecksumInfoChain(cksum) if chain: cksInfo = chain.pop(0) if cksInfo['checksum'] != cksum: self.logger.error("Unexpected checksum: %s. Expected: %s", cksInfo['checksum'], cksum) return None else: cksInfo = self.db.getChecksumInfo(cksum) if cksInfo is None: self.logger.error("Checksum %s not found", cksum) return None #self.logger.debug(" %s: %s", cksum, str(cksInfo)) try: if not cksInfo['isfile']: raise RegenerateException("{} is not a file".format(cksum)) if cksInfo['basis']: if basisFile: basis = basisFile basis.seek(0) else: basis = self.recoverChecksum(cksInfo['basis'], authenticate, chain) if cksInfo['encrypted']: patchfile = self.decryptFile(cksum, cksInfo['disksize'], authenticate) else: patchfile = self.cacheDir.open(cksum, 'rb') if cksInfo['compressed']: self.logger.debug("Uncompressing %s", cksum) temp = tempfile.TemporaryFile() buf = CompressedBuffer.UncompressedBufferedReader(patchfile, compressor=cksInfo['compressed']) shutil.copyfileobj(buf, temp) temp.seek(0) patchfile = temp try: output = librsync.patch(basis, patchfile) #output.seek(0) return output except librsync.LibrsyncError as e: self.logger.error("Recovering checksum: %s : %s", cksum, e) raise RegenerateException("Checksum: {}: Error: {}".format(cksum, e)) else: if cksInfo['encrypted']: output = self.decryptFile(cksum, cksInfo['disksize']) else: output = self.cacheDir.open(cksum, "rb") if cksInfo['compressed'] is not None and cksInfo['compressed'].lower() != 'none': self.logger.debug("Uncompressing %s", cksum) temp = tempfile.TemporaryFile() buf = CompressedBuffer.UncompressedBufferedReader(output, compressor=cksInfo['compressed']) shutil.copyfileobj(buf, temp) temp.seek(0) output = temp return output except RegenerateException: raise except Exception as e: self.logger.error("Unable to recover checksum %s: %s", cksum, e) #self.logger.exception(e) raise RegenerateException("Checksum: {}: Error: {}".format(cksum, e))