]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/record.c
- Tweak install chapter of French manual to add new paragraph
[bacula/bacula] / bacula / src / stored / record.c
index e55a514997081303b52560a6624f477ae287057e..d3bb44eab6c35b45128c9ffb28bea864a7e15d52 100644 (file)
@@ -9,7 +9,7 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -41,7 +41,7 @@ extern int debug_level;
  *   record as a Label, otherwise it is simply
  *   the FileIndex of the current file.
  */
-char *FI_to_ascii(int fi)
+const char *FI_to_ascii(int fi)
 {
    static char buf[20];
    if (fi >= 0) {
@@ -80,7 +80,7 @@ char *FI_to_ascii(int fi)
  *   dealing with a Label, hence the
  *   stream is the JobId.
  */
-char *stream_to_ascii(int stream, int fi)
+const char *stream_to_ascii(int stream, int fi)
 {
     static char buf[20];
     if (fi < 0) {
@@ -92,12 +92,18 @@ char *stream_to_ascii(int stream, int fi)
        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_WIN32_ATTRIBUTES:
-       return "WIN32-ATTR";
+    case STREAM_UNIX_ATTRIBUTES_EX:
+       return "UNIX-ATTR-EX";
     case STREAM_SPARSE_DATA:
        return "SPARSE-DATA";
     case STREAM_SPARSE_GZIP_DATA:
@@ -110,12 +116,18 @@ char *stream_to_ascii(int stream, int fi)
        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_WIN32_ATTRIBUTES:
-       return "contWIN32-ATTR";
+    case -STREAM_UNIX_ATTRIBUTES_EX:
+       return "contUNIX-ATTR-EX";
     case -STREAM_SPARSE_DATA:
        return "contSPARSE-DATA";
     case -STREAM_SPARSE_GZIP_DATA:
@@ -137,12 +149,21 @@ DEV_RECORD *new_record(void)
 {
    DEV_RECORD *rec;
 
-   rec = (DEV_RECORD *) get_memory(sizeof(DEV_RECORD));
+   rec = (DEV_RECORD *)get_memory(sizeof(DEV_RECORD));
    memset(rec, 0, sizeof(DEV_RECORD));
    rec->data = get_pool_memory(PM_MESSAGE);
    return rec;
 }
 
+void empty_record(DEV_RECORD *rec)
+{
+   rec->File = rec->Block = 0;
+   rec->VolSessionId = rec->VolSessionTime = 0;
+   rec->FileIndex = rec->Stream = 0;
+   rec->data_len = rec->remainder = 0;
+   rec->state &= ~(REC_PARTIAL_RECORD|REC_BLOCK_EMPTY|REC_NO_MATCH|REC_CONTINUATION);
+}
+
 /*
  * Free the record entity 
  *
@@ -162,8 +183,8 @@ void free_record(DEV_RECORD *rec)
 /*
  * Write a Record to the block
  *
- *  Returns: 0 on failure (none or partially written)
- *          1 on success (all bytes written)
+ *  Returns: false on failure (none or partially written)
+ *          true  on success (all bytes written)
  *
  *  and remainder returned in packet.
  *
@@ -173,16 +194,15 @@ void free_record(DEV_RECORD *rec)
  *  non-zero), and 2. The remaining bytes to write may not
  *  all fit into the block.
  */
-int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
+bool write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
 {
    ser_declare;
    uint32_t remlen;
 
-   sm_check(__FILE__, __LINE__, False);
    remlen = block->buf_len - block->binbuf;
 
    ASSERT(block->binbuf == (uint32_t) (block->bufp - block->buf));
-   ASSERT(remlen >= 0);
+   ASSERT(block->buf_len >= block->binbuf);
 
    Dmsg6(190, "write_record_to_block() FI=%s SessId=%d Strm=%s len=%d\n\
 rem=%d remainder=%d\n",
@@ -200,8 +220,8 @@ rem=%d remainder=%d\n",
       if (remlen >= WRITE_RECHDR_LENGTH) {
         ser_begin(block->bufp, WRITE_RECHDR_LENGTH);
         if (BLOCK_VER == 1) {
-        ser_uint32(rec->VolSessionId);
-        ser_uint32(rec->VolSessionTime);
+           ser_uint32(rec->VolSessionId);
+           ser_uint32(rec->VolSessionTime);
         } else {
            block->VolSessionId = rec->VolSessionId;
            block->VolSessionTime = rec->VolSessionTime;
@@ -214,10 +234,16 @@ rem=%d remainder=%d\n",
         block->binbuf += WRITE_RECHDR_LENGTH;
         remlen -= WRITE_RECHDR_LENGTH;
         rec->remainder = rec->data_len;
+        if (rec->FileIndex > 0) {
+           /* If data record, update what we have in this block */
+           if (block->FirstIndex == 0) {
+              block->FirstIndex = rec->FileIndex;
+           }
+           block->LastIndex = rec->FileIndex;
+        }
       } else {
         rec->remainder = rec->data_len + WRITE_RECHDR_LENGTH;
-        sm_check(__FILE__, __LINE__, False);
-        return 0;
+        return false;
       }
    } else {
       /* 
@@ -237,8 +263,8 @@ rem=%d remainder=%d\n",
        */
       ser_begin(block->bufp, WRITE_RECHDR_LENGTH);
       if (BLOCK_VER == 1) {
-      ser_uint32(rec->VolSessionId);
-      ser_uint32(rec->VolSessionTime);
+        ser_uint32(rec->VolSessionId);
+        ser_uint32(rec->VolSessionTime);
       } else {
         block->VolSessionId = rec->VolSessionId;
         block->VolSessionTime = rec->VolSessionTime;
@@ -259,10 +285,16 @@ rem=%d remainder=%d\n",
       block->bufp += WRITE_RECHDR_LENGTH;
       block->binbuf += WRITE_RECHDR_LENGTH;
       remlen -= WRITE_RECHDR_LENGTH;
+      if (rec->FileIndex > 0) {
+        /* If data record, update what we have in this block */
+        if (block->FirstIndex == 0) {
+           block->FirstIndex = rec->FileIndex;
+        }
+        block->LastIndex = rec->FileIndex;
+      }
    }
    if (remlen == 0) {
-      sm_check(__FILE__, __LINE__, False);
-      return 0;                      /* partial transfer */
+      return false;                  /* partial transfer */
    }
 
    /*
@@ -280,7 +312,7 @@ rem=%d remainder=%d\n",
       } else {
         memcpy(block->bufp, rec->data+rec->data_len-rec->remainder, 
                remlen);
-#ifdef SMCHECK
+#ifdef xxxxxSMCHECK
         if (!sm_check_rtn(__FILE__, __LINE__, False)) {
            /* We damaged a buffer */
             Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n\
@@ -301,22 +333,21 @@ rem=%d remainder=%d\n",
         block->bufp += remlen;
         block->binbuf += remlen;
         rec->remainder -= remlen;
-        return 0;                    /* did partial transfer */
+        return false;                /* did partial transfer */
       }
    }
    rec->remainder = 0;               /* did whole transfer */
-   sm_check(__FILE__, __LINE__, False);
-   return 1;
+   return true;
 }
 
 
 /*
  * Test if we can write whole record to the block
  *
- *  Returns: 0 on failure 
- *          1 on success (all bytes can be written)
+ *  Returns: false on failure 
+ *          true  on success (all bytes can be written)
  */
-int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
+bool can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
 {
    uint32_t remlen;
 
@@ -326,27 +357,27 @@ int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec)
         remlen -= WRITE_RECHDR_LENGTH;
         rec->remainder = rec->data_len;
       } else {
-        return 0;
+        return false;
       }
    } else {
-      return 0;
+      return false;
    }
    if (rec->remainder > 0 && remlen < rec->remainder) {
-      return 0;
+      return false;
    }
-   return 1;
+   return true;
 }
 
 
 /*
  * Read a Record from the block
- *  Returns: 0 if nothing read or if the continuation record does not match.
- *            In both of these cases, a block read must be done.
- *          1 if at least the record header was read, this 
- *            routine may have to be called again with a new
- *            block if the entire record was not read.
+ *  Returns: false if nothing read or if the continuation record does not match.
+ *                In both of these cases, a block read must be done.
+ *          true  if at least the record header was read, this 
+ *                routine may have to be called again with a new
+ *                block if the entire record was not read.
  */
-int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
+bool read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
 {
    ser_declare;
    uint32_t remlen;
@@ -385,8 +416,8 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
 
       unser_begin(block->bufp, WRITE_RECHDR_LENGTH);
       if (block->BlockVer == 1) {
-      unser_uint32(VolSessionId);
-      unser_uint32(VolSessionTime);
+        unser_uint32(VolSessionId);
+        unser_uint32(VolSessionTime);
       } else {
         VolSessionId = block->VolSessionId;
         VolSessionTime = block->VolSessionTime;
@@ -405,7 +436,8 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
       if (rec->remainder && (rec->VolSessionId != VolSessionId || 
                             rec->VolSessionTime != VolSessionTime)) {
         rec->state |= REC_NO_MATCH;
-        return 0;                 /* This is from some other Session */
+         Dmsg0(500, "remainder and VolSession doesn't match\n");
+        return false;             /* This is from some other Session */
       }
 
       /* if Stream is negative, it means that this is a continuation
@@ -419,7 +451,7 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
            rec->data_len = 0;        /* return data as if no continuation */
         } else if (rec->Stream != -Stream) {
            rec->state |= REC_NO_MATCH;
-           return 0;                 /* This is from some other Session */
+           return false;             /* This is from some other Session */
         }
         rec->Stream = -Stream;       /* set correct Stream */
       } else {                       /* Regular record */
@@ -429,9 +461,15 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec)
       rec->VolSessionId = VolSessionId;
       rec->VolSessionTime = VolSessionTime;
       rec->FileIndex = FileIndex;
+      if (FileIndex > 0) {
+        if (block->FirstIndex == 0) {
+           block->FirstIndex = FileIndex;
+        }
+        block->LastIndex = FileIndex;
+      }
 
-      Dmsg6(100, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n\
-remlen=%d data_len=%d\n",
+      Dmsg6(100, "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, 
         rec->data_len);
@@ -452,7 +490,8 @@ remlen=%d data_len=%d\n",
       }
 #endif
       rec->state |= (REC_NO_HEADER | REC_BLOCK_EMPTY);
-      return 0;
+      empty_block(block);                     /* mark block empty */
+      return false;
    }
 
    ASSERT(data_bytes < MAX_BLOCK_LENGTH);      /* temp sanity check */
@@ -488,5 +527,5 @@ remlen=%d data_len=%d\n",
    Dmsg4(90, "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);
-   return 1;                         /* transferred full record */
+   return true;                      /* transferred full record */
 }