+bool sparse_data(JCR *jcr, BFILE *bfd, uint64_t *addr, char **data, uint32_t *length)
+{
+ unser_declare;
+ uint64_t faddr;
+ char ec1[50];
+ unser_begin(*data, SPARSE_FADDR_SIZE);
+ unser_uint64(faddr);
+ if (*addr != faddr) {
+ *addr = faddr;
+ if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
+ berrno be;
+ Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
+ edit_uint64(*addr, ec1), jcr->last_fname,
+ be.bstrerror(bfd->berrno));
+ return false;
+ }
+ }
+ *data += SPARSE_FADDR_SIZE;
+ *length -= SPARSE_FADDR_SIZE;
+ return true;
+}
+
+bool decompress_data(JCR *jcr, char **data, uint32_t *length)
+{
+#ifdef HAVE_LIBZ
+ uLong compress_len;
+ int stat;
+ char ec1[50]; /* Buffer printing huge values */
+
+ /*
+ * NOTE! We only use uLong and Byte because they are
+ * needed by the zlib routines, they should not otherwise
+ * be used in Bacula.
+ */
+ compress_len = jcr->compress_buf_size;
+ Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, *length);
+ if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
+ (const Byte *)*data, (uLong)*length)) != Z_OK) {
+ Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
+ jcr->last_fname, zlib_strerror(stat));
+ return false;
+ }
+ *data = jcr->compress_buf;
+ *length = compress_len;
+ Dmsg2(100, "Write uncompressed %d bytes, total before write=%s\n", compress_len, edit_uint64(jcr->JobBytes, ec1));
+ return true;
+#else
+ Qmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
+ return false;
+#endif
+}
+
+static void unser_crypto_packet_len(RESTORE_CIPHER_CTX *ctx)
+{
+ unser_declare;
+ if (ctx->packet_len == 0 && ctx->buf_len >= CRYPTO_LEN_SIZE) {
+ unser_begin(&ctx->buf[0], CRYPTO_LEN_SIZE);
+ unser_uint32(ctx->packet_len);
+ ctx->packet_len += CRYPTO_LEN_SIZE;
+ }
+}
+
+bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win32_decomp)
+{
+ if (jcr->crypto.digest) {
+ crypto_digest_update(jcr->crypto.digest, (uint8_t *)data, length);
+ }
+ if (win32_decomp) {
+ if (!processWin32BackupAPIBlock(bfd, data, length)) {
+ berrno be;
+ Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"),
+ jcr->last_fname, be.bstrerror(bfd->berrno));
+ return false;
+ }
+ } else if (bwrite(bfd, data, length) != (ssize_t)length) {
+ berrno be;
+ Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"),
+ jcr->last_fname, be.bstrerror(bfd->berrno));
+ return false;
+ }
+
+ return true;
+}
+