-/*
- *
- * Bacula Director -- fd_cmds.c -- send commands to File daemon
- *
- * Kern Sibbald, October MM
- *
- * This routine is run as a separate thread. There may be more
- * work to be done to make it totally reentrant!!!!
- *
- * Utility functions for sending info to File Daemon.
- * These functions are used by both backup and verify.
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ *
+ * Bacula Director -- fd_cmds.c -- send commands to File daemon
+ *
+ * Kern Sibbald, October MM
+ *
+ * This routine is run as a separate thread. There may be more
+ * work to be done to make it totally reentrant!!!!
+ *
+ * Utility functions for sending info to File Daemon.
+ * These functions are used by both backup and verify.
+ *
+ * Version $Id$
+ */
#include "bacula.h"
#include "dird.h"
if (!decompress_data(jcr, &wbuf, &wsize)) {
return -1;
}
- } else {
- Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
}
if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
return -1;
}
-
jcr->JobBytes += wsize;
*addr += wsize;
+ Dmsg2(30, "Write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
/* Clean up crypto buffers */
if (flags & FO_ENCRYPT) {
char *wbuf; /* write buffer */
uint32_t wsize; /* write size */
char ec1[50]; /* Buffer printing huge values */
+ bool second_pass = false;
+again:
/* Write out the remaining block and free the cipher context */
cipher_ctx->buf = check_pool_memory_size(cipher_ctx->buf, cipher_ctx->buf_len +
cipher_ctx->block_size);
Jmsg1(jcr, M_FATAL, 0, _("Decryption error for %s\n"), jcr->last_fname);
}
+ Dmsg2(30, "Flush decrypt len=%d buf_len=%d\n", decrypted_len, cipher_ctx->buf_len);
/* If nothing new was decrypted, and our output buffer is empty, return */
if (decrypted_len == 0 && cipher_ctx->buf_len == 0) {
return true;
Dmsg1(500, "Crypto unser block size=%d\n", cipher_ctx->packet_len - CRYPTO_LEN_SIZE);
wsize = cipher_ctx->packet_len - CRYPTO_LEN_SIZE;
wbuf = &cipher_ctx->buf[CRYPTO_LEN_SIZE]; /* Decrypted, possibly decompressed output here. */
+ cipher_ctx->buf_len -= cipher_ctx->packet_len;
+ Dmsg2(30, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
- if (cipher_ctx->buf_len != cipher_ctx->packet_len) {
+#ifdef xxx
+ Dmsg2(30, "check buf_len=%d pkt_len=%d\n", cipher_ctx->buf_len, cipher_ctx->packet_len);
+ if (second_pass && cipher_ctx->buf_len != cipher_ctx->packet_len) {
Jmsg2(jcr, M_FATAL, 0,
_("Unexpected number of bytes remaining at end of file, received %u, expected %u\n"),
cipher_ctx->packet_len, cipher_ctx->buf_len);
return false;
}
-
- cipher_ctx->buf_len = 0;
- cipher_ctx->packet_len = 0;
+#endif
if (flags & FO_SPARSE) {
if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
}
if (flags & FO_GZIP) {
- decompress_data(jcr, &wbuf, &wsize);
- } else {
- Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
+ if (!decompress_data(jcr, &wbuf, &wsize)) {
+ return false;
+ }
}
+ Dmsg0(30, "Call store_data\n");
if (!store_data(jcr, bfd, wbuf, wsize, (flags & FO_WIN32DECOMP) != 0)) {
return false;
}
-
jcr->JobBytes += wsize;
+ Dmsg2(30, "Flush write %u bytes, JobBytes=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
+
+ /* Move any remaining data to start of buffer */
+ if (cipher_ctx->buf_len > 0) {
+ Dmsg1(30, "Moving %u buffered bytes to start of buffer\n", cipher_ctx->buf_len);
+ memmove(cipher_ctx->buf, &cipher_ctx->buf[cipher_ctx->packet_len],
+ cipher_ctx->buf_len);
+ }
+ /* The packet was successfully written, reset the length so that the next
+ * packet length may be re-read by unser_crypto_packet_len() */
+ cipher_ctx->packet_len = 0;
+
+ if (cipher_ctx->buf_len >0 && !second_pass) {
+ second_pass = true;
+ goto again;
+ }
+
+ /* Stop decryption */
+ cipher_ctx->buf_len = 0;
+ cipher_ctx->packet_len = 0;
return true;
}