+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2001-2010 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.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version three of the GNU Affero General Public
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of Kern Sibbald.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
/*
*
* record.c -- tape record handling functions
* Kern Sibbald, April MMI
* added BB02 format October MMII
*
- * Version $Id$
- *
- */
-/*
- Copyright (C) 2001-2005 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as amended with additional clauses defined in the
- file LICENSE in the main source directory.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- the file LICENSE for additional details.
-
*/
#include "bacula.h"
#include "stored.h"
-extern int debug_level;
-
/*
* Convert a FileIndex into a printable
* ASCII string. Not reentrant.
* record as a Label, otherwise it is simply
* the FileIndex of the current file.
*/
-const char *FI_to_ascii(int fi)
+const char *FI_to_ascii(char *buf, int fi)
{
- static char buf[20];
if (fi >= 0) {
sprintf(buf, "%d", fi);
return buf;
case EOT_LABEL:
return "EOT_LABEL";
break;
+ case SOB_LABEL:
+ return "SOB_LABEL";
+ break;
+ case EOB_LABEL:
+ return "EOB_LABEL";
+ break;
default:
sprintf(buf, _("unknown: %d"), fi);
return buf;
* dealing with a Label, hence the
* stream is the JobId.
*/
-const char *stream_to_ascii(int stream, int fi)
+const char *stream_to_ascii(char *buf, int stream, int fi)
{
- static char buf[20];
- if (fi < 0) {
- sprintf(buf, "%d", stream);
- return buf;
- }
- switch (stream) {
- case STREAM_UNIX_ATTRIBUTES:
- return "UATTR";
- case STREAM_FILE_DATA:
- return "DATA";
- case STREAM_WIN32_DATA:
- return "WIN32-DATA";
- case STREAM_WIN32_GZIP_DATA:
- return "WIN32-GZIP";
- case STREAM_MD5_SIGNATURE:
- return "MD5";
- case STREAM_SHA1_SIGNATURE:
- return "SHA1";
- case STREAM_GZIP_DATA:
- return "GZIP";
- case STREAM_UNIX_ATTRIBUTES_EX:
- return "UNIX-ATTR-EX";
- case STREAM_SPARSE_DATA:
- return "SPARSE-DATA";
- case STREAM_SPARSE_GZIP_DATA:
- return "SPARSE-GZIP";
- case STREAM_PROGRAM_NAMES:
- return "PROG-NAMES";
- case STREAM_PROGRAM_DATA:
- return "PROG-DATA";
- case STREAM_MACOS_FORK_DATA:
- return "MACOS-RSRC";
- case STREAM_HFSPLUS_ATTRIBUTES:
- return "HFSPLUS-ATTR";
- case -STREAM_UNIX_ATTRIBUTES:
- return "contUATTR";
- case -STREAM_FILE_DATA:
- return "contDATA";
- case -STREAM_WIN32_DATA:
- return "contWIN32-DATA";
- case -STREAM_WIN32_GZIP_DATA:
- return "contWIN32-GZIP";
- case -STREAM_MD5_SIGNATURE:
- return "contMD5";
- case -STREAM_SHA1_SIGNATURE:
- return "contSHA1";
- case -STREAM_GZIP_DATA:
- return "contGZIP";
- case -STREAM_UNIX_ATTRIBUTES_EX:
- return "contUNIX-ATTR-EX";
- case -STREAM_SPARSE_DATA:
- return "contSPARSE-DATA";
- case -STREAM_SPARSE_GZIP_DATA:
- return "contSPARSE-GZIP";
- case -STREAM_PROGRAM_NAMES:
- return "contPROG-NAMES";
- case -STREAM_PROGRAM_DATA:
- return "contPROG-DATA";
- case -STREAM_MACOS_FORK_DATA:
- return "contMACOS-RSRC";
- case -STREAM_HFSPLUS_ATTRIBUTES:
- return "contHFSPLUS-ATTR";
- default:
- sprintf(buf, "%d", stream);
- return buf;
- }
+
+ if (fi < 0) {
+ sprintf(buf, "%d", stream);
+ return buf;
+ }
+ if (stream < 0) {
+ stream = -stream;
+ stream &= STREAMMASK_TYPE;
+ /* Stream was negative => all are continuation items */
+ switch (stream) {
+ case STREAM_UNIX_ATTRIBUTES:
+ return "contUATTR";
+ case STREAM_FILE_DATA:
+ return "contDATA";
+ case STREAM_WIN32_DATA:
+ return "contWIN32-DATA";
+ case STREAM_WIN32_GZIP_DATA:
+ return "contWIN32-GZIP";
+ case STREAM_WIN32_COMPRESSED_DATA:
+ return "contWIN32-COMPRESSED";
+ case STREAM_MD5_DIGEST:
+ return "contMD5";
+ case STREAM_SHA1_DIGEST:
+ return "contSHA1";
+ case STREAM_GZIP_DATA:
+ return "contGZIP";
+ case STREAM_COMPRESSED_DATA:
+ return "contCOMPRESSED";
+ case STREAM_UNIX_ATTRIBUTES_EX:
+ return "contUNIX-ATTR-EX";
+ case STREAM_RESTORE_OBJECT:
+ return "contRESTORE-OBJECT";
+ case STREAM_SPARSE_DATA:
+ return "contSPARSE-DATA";
+ case STREAM_SPARSE_GZIP_DATA:
+ return "contSPARSE-GZIP";
+ case STREAM_SPARSE_COMPRESSED_DATA:
+ return "contSPARSE-COMPRESSED";
+ case STREAM_PROGRAM_NAMES:
+ return "contPROG-NAMES";
+ case STREAM_PROGRAM_DATA:
+ return "contPROG-DATA";
+ case STREAM_MACOS_FORK_DATA:
+ return "contMACOS-RSRC";
+ case STREAM_HFSPLUS_ATTRIBUTES:
+ return "contHFSPLUS-ATTR";
+ case STREAM_SHA256_DIGEST:
+ return "contSHA256";
+ case STREAM_SHA512_DIGEST:
+ return "contSHA512";
+ case STREAM_SIGNED_DIGEST:
+ return "contSIGNED-DIGEST";
+ case STREAM_ENCRYPTED_SESSION_DATA:
+ return "contENCRYPTED-SESSION-DATA";
+ case STREAM_ENCRYPTED_FILE_DATA:
+ return "contENCRYPTED-FILE";
+ case STREAM_ENCRYPTED_FILE_GZIP_DATA:
+ return "contENCRYPTED-GZIP";
+ case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
+ return "contENCRYPTED-COMPRESSED";
+ case STREAM_ENCRYPTED_WIN32_DATA:
+ return "contENCRYPTED-WIN32-DATA";
+ case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
+ return "contENCRYPTED-WIN32-GZIP";
+ case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
+ return "contENCRYPTED-WIN32-COMPRESSED";
+ case STREAM_ENCRYPTED_MACOS_FORK_DATA:
+ return "contENCRYPTED-MACOS-RSRC";
+ case STREAM_PLUGIN_NAME:
+ return "contPLUGIN-NAME";
+
+ default:
+ sprintf(buf, "%d", -stream);
+ return buf;
+ }
+ }
+
+ switch (stream & STREAMMASK_TYPE) {
+ case STREAM_UNIX_ATTRIBUTES:
+ return "UATTR";
+ case STREAM_FILE_DATA:
+ return "DATA";
+ case STREAM_WIN32_DATA:
+ return "WIN32-DATA";
+ case STREAM_WIN32_GZIP_DATA:
+ return "WIN32-GZIP";
+ case STREAM_WIN32_COMPRESSED_DATA:
+ return "WIN32-COMPRESSED";
+ case STREAM_MD5_DIGEST:
+ return "MD5";
+ case STREAM_SHA1_DIGEST:
+ return "SHA1";
+ case STREAM_GZIP_DATA:
+ return "GZIP";
+ case STREAM_COMPRESSED_DATA:
+ return "COMPRESSED";
+ case STREAM_UNIX_ATTRIBUTES_EX:
+ return "UNIX-ATTR-EX";
+ case STREAM_RESTORE_OBJECT:
+ return "RESTORE-OBJECT";
+ case STREAM_SPARSE_DATA:
+ return "SPARSE-DATA";
+ case STREAM_SPARSE_GZIP_DATA:
+ return "SPARSE-GZIP";
+ case STREAM_SPARSE_COMPRESSED_DATA:
+ return "SPARSE-COMPRESSED";
+ case STREAM_PROGRAM_NAMES:
+ return "PROG-NAMES";
+ case STREAM_PROGRAM_DATA:
+ return "PROG-DATA";
+ case STREAM_PLUGIN_NAME:
+ return "PLUGIN-NAME";
+ case STREAM_MACOS_FORK_DATA:
+ return "MACOS-RSRC";
+ case STREAM_HFSPLUS_ATTRIBUTES:
+ return "HFSPLUS-ATTR";
+ case STREAM_SHA256_DIGEST:
+ return "SHA256";
+ case STREAM_SHA512_DIGEST:
+ return "SHA512";
+ case STREAM_SIGNED_DIGEST:
+ return "SIGNED-DIGEST";
+ case STREAM_ENCRYPTED_SESSION_DATA:
+ return "ENCRYPTED-SESSION-DATA";
+ case STREAM_ENCRYPTED_FILE_DATA:
+ return "ENCRYPTED-FILE";
+ case STREAM_ENCRYPTED_FILE_GZIP_DATA:
+ return "ENCRYPTED-GZIP";
+ case STREAM_ENCRYPTED_FILE_COMPRESSED_DATA:
+ return "ENCRYPTED-COMPRESSED";
+ case STREAM_ENCRYPTED_WIN32_DATA:
+ return "ENCRYPTED-WIN32-DATA";
+ case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
+ return "ENCRYPTED-WIN32-GZIP";
+ case STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA:
+ return "ENCRYPTED-WIN32-COMPRESSED";
+ case STREAM_ENCRYPTED_MACOS_FORK_DATA:
+ return "ENCRYPTED-MACOS-RSRC";
+
+ default:
+ sprintf(buf, "%d", stream);
+ return buf;
+ }
}
/*
{
ser_declare;
uint32_t remlen;
+ char buf1[100], buf2[100];
remlen = block->buf_len - block->binbuf;
ASSERT(block->buf_len >= block->binbuf);
Dmsg6(890, "write_record_to_block() FI=%s SessId=%d Strm=%s len=%d\n"
-"rem=%d remainder=%d\n",
- FI_to_ascii(rec->FileIndex), rec->VolSessionId,
- stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
+ "rem=%d remainder=%d\n",
+ FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+ stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
remlen, rec->remainder);
/*
if (!sm_check_rtn(__FILE__, __LINE__, False)) {
/* We damaged a buffer */
Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n"
-"rem=%d remainder=%d\n",
- FI_to_ascii(rec->FileIndex), rec->VolSessionId,
- stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
+ "rem=%d remainder=%d\n",
+ FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+ stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
remlen, rec->remainder);
Dmsg5(0, "Damaged block: bufp=%x binbuf=%d buf_len=%d rem=%d moved=%d\n",
block->bufp, block->binbuf, block->buf_len, block->buf_len-block->binbuf,
return true;
}
+uint64_t get_record_address(DEV_RECORD *rec)
+{
+ return ((uint64_t)rec->File)<<32 | rec->Block;
+}
/*
* Read a Record from the block
* routine may have to be called again with a new
* block if the entire record was not read.
*/
-bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
+bool read_record_from_block(DCR *dcr, DEV_BLOCK *block, DEV_RECORD *rec)
{
ser_declare;
uint32_t remlen;
int32_t Stream;
uint32_t data_bytes;
uint32_t rhl;
+ char buf1[100], buf2[100];
remlen = block->binbuf;
- rec->Block = block->BlockNumber;
- rec->File = ((DEVICE *)block->dev)->file;
/* Clear state flags */
rec->state = 0;
if (block->dev->is_tape()) {
rec->state |= REC_ISTAPE;
}
-
+ rec->Block = ((DEVICE *)block->dev)->EndBlock;
+ rec->File = ((DEVICE *)block->dev)->EndFile;
/*
* Get the header. There is always a full header,
return false; /* This is from some other Session */
}
rec->Stream = -Stream; /* set correct Stream */
+ rec->maskedStream = rec->Stream & STREAMMASK_TYPE;
} else { /* Regular record */
rec->Stream = Stream;
+ rec->maskedStream = rec->Stream & STREAMMASK_TYPE;
rec->data_len = 0; /* transfer to beginning of data */
}
rec->VolSessionId = VolSessionId;
Dmsg6(450, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n"
"remlen=%d data_len=%d\n",
- FI_to_ascii(rec->FileIndex), rec->VolSessionId,
- stream_to_ascii(rec->Stream, rec->FileIndex), data_bytes, remlen,
+ FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+ stream_to_ascii(buf2, rec->Stream, rec->FileIndex), data_bytes, remlen,
rec->data_len);
} else {
/*
return false;
}
- ASSERT(data_bytes < MAX_BLOCK_LENGTH); /* temp sanity check */
+ /* Sanity check */
+ if (data_bytes >= MAX_BLOCK_LENGTH) {
+ /*
+ * Something is wrong, force read of next block, abort
+ * continuing with this block.
+ */
+ rec->state |= (REC_NO_HEADER | REC_BLOCK_EMPTY);
+ empty_block(block);
+ Jmsg2(dcr->jcr, M_WARNING, 0, _("Sanity check failed. maxlen=%d datalen=%d. Block discarded.\n"),
+ MAX_BLOCK_LENGTH, data_bytes);
+ return false;
+ }
rec->data = check_pool_memory_size(rec->data, rec->data_len+data_bytes);
rec->remainder = 1; /* partial record transferred */
Dmsg1(450, "read_record_block: partial xfered=%d\n", rec->data_len);
rec->state |= (REC_PARTIAL_RECORD | REC_BLOCK_EMPTY);
- return 1;
+ return true;
}
rec->remainder = 0;
Dmsg4(450, "Rtn full rd_rec_blk FI=%s SessId=%d Strm=%s len=%d\n",
- FI_to_ascii(rec->FileIndex), rec->VolSessionId,
- stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
+ FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+ stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
return true; /* transferred full record */
}