]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/catreq.c
Start adding DeltaSeq
[bacula/bacula] / bacula / src / dird / catreq.c
index 7d9c2f452ddd745861e2467f47d2062699060b1b..db195635deeb7a14bda673fbc4c5437f83ada8bc 100644 (file)
@@ -6,7 +6,7 @@
    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 two of the GNU General Public
+   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.
 
@@ -15,7 +15,7 @@
    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 General Public License
+   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.
@@ -373,11 +373,11 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen)
    uint32_t VolSessionId, VolSessionTime;
    int32_t Stream;
    uint32_t FileIndex;
-   uint32_t data_len;
    char *p;
    int len;
    char *fname, *attr;
    ATTR_DBR *ar = NULL;
+   uint32_t reclen;
 
    /* Start transaction allocates jcr->attr and jcr->ar if needed */
    db_start_transaction(jcr, jcr->db);     /* start transaction if not already open */
@@ -393,24 +393,48 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen)
    skip_spaces(&p);
    skip_nonspaces(&p);                /* Job=nnn */
    skip_spaces(&p);
-   skip_nonspaces(&p);                /* FileAttributes */
+   skip_nonspaces(&p);                /* "FileAttributes" */
    p += 1;
+   /* The following "SD header" fields are serialized */
    unser_begin(p, 0);
    unser_uint32(VolSessionId);        /* VolSessionId */
    unser_uint32(VolSessionTime);      /* VolSessionTime */
    unser_int32(FileIndex);            /* FileIndex */
    unser_int32(Stream);               /* Stream */
-   unser_uint32(data_len);            /* Record length */
+   unser_uint32(reclen);              /* Record length */
    p += unser_length(p);              /* Raw record follows */
 
-   /*
+   /**
     * At this point p points to the raw record, which varies according
-    *  to what kind of a record (Stream) was sent
+    *  to what kind of a record (Stream) was sent.  Note, the integer
+    *  fields at the beginning of these "raw" records are in ASCII with
+    *  spaces between them so one can use scanf or manual scanning to
+    *  extract the fields.
+    *
+    * File Attributes
+    *   File_index
+    *   File type
+    *   Filename (full path)
+    *   Encoded attributes
+    *   Link name (if type==FT_LNK or FT_LNKSAVED)
+    *   Encoded extended-attributes (for Win32)
+    *   Delta sequence number (32 bit int)
+    *
+    * Restore Object
+    *   File_index
+    *   File_type
+    *   Object_index
+    *   Object_len (possibly compressed)
+    *   Object_full_len (not compressed)
+    *   Object_compression
+    *   Plugin_name
+    *   Object_name
+    *   Binary Object data
     */
 
    Dmsg1(400, "UpdCat msg=%s\n", msg);
-   Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d data_len=%d\n",
-      VolSessionId, VolSessionTime, FileIndex, Stream, data_len);
+   Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d reclen=%d\n",
+      VolSessionId, VolSessionTime, FileIndex, Stream, reclen);
 
    if (Stream == STREAM_UNIX_ATTRIBUTES || Stream == STREAM_UNIX_ATTRIBUTES_EX) {
       if (jcr->cached_attribute) {
@@ -424,14 +448,26 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen)
       jcr->attr = check_pool_memory_size(jcr->attr, msglen);
       memcpy(jcr->attr, msg, msglen);
       p = jcr->attr - msg + p;    /* point p into jcr->attr */
-      skip_nonspaces(&p);             /* skip FileIndex */
+      skip_nonspaces(&p);         /* skip FileIndex */
       skip_spaces(&p);
-      ar->FileType = str_to_int32(p);     /* TODO: choose between unserialize and str_to_int32 */
-      skip_nonspaces(&p);             /* skip FileType */
+      ar->FileType = str_to_int32(p); 
+      skip_nonspaces(&p);         /* skip FileType */
       skip_spaces(&p);
       fname = p;
       len = strlen(fname);        /* length before attributes */
       attr = &fname[len+1];
+      ar->DeltaSeq = 0;
+      if (ar->FileType == FT_REG) {
+         p = attr + strlen(attr) + 1;  /* point to link */
+         p = p + strlen(p) + 1;        /* point to extended attributes */
+         p = p + strlen(p) + 1;        /* point to delta sequence */
+         /*
+          * Older FDs don't have a delta sequence, so check if it is there 
+          */
+         if (p - jcr->attr < msglen) {
+            ar->DeltaSeq = str_to_int32(p);
+         }
+      }
 
       Dmsg2(400, "dird<stored: stream=%d %s\n", Stream, fname);
       Dmsg1(400, "dird<stored: attr=%s\n", attr);
@@ -449,44 +485,59 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen)
       } else {
          ar->JobId = jcr->JobId;
       }
-      /*
-       * Restore object */
-      if (ar->FileType == FT_RESTORE_FIRST) {
-         ROBJECT_DBR ro;
-         POOLMEM *attrEx = get_pool_memory(PM_MESSAGE);
-         char *p;
-         ro.full_fname = fname;
-         ro.Stream = Stream;
-         ro.FileType = ar->FileType;
-         ro.FileIndex = FileIndex;
-         ro.JobId = ar->JobId;
-         p = ar->attr;                   /* point to attributes */
-         while (*p++ != 0)               /* skip attributes */
-            { }
-         while (*p++ != 0)               /* skip link */
-            { }
-         /* We have an object, so do a binary copy */
-         ro.object_len = msglen + ar->attr - p;
-         attrEx = check_pool_memory_size(attrEx, ro.object_len + 1);
-         memcpy(attrEx, p, ro.object_len);  
-         ro.object = attrEx;
-         /* Add a EOS for those who attempt to print the object */
-         p = attrEx + ro.object_len;
-         *p = 0;
-         /* Send it */
-         if (!db_create_restore_object_record(jcr, jcr->db, &ro)) {
-            Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db));
-         }
-         free_pool_memory(attrEx);
-      } else {
-         ar->Digest = NULL;
-         ar->DigestType = CRYPTO_DIGEST_NONE;
-         jcr->cached_attribute = true;
-      }
+      ar->Digest = NULL;
+      ar->DigestType = CRYPTO_DIGEST_NONE;
+      jcr->cached_attribute = true;
 
       Dmsg2(400, "dird<filed: stream=%d %s\n", Stream, fname);
       Dmsg1(400, "dird<filed: attr=%s\n", attr);
 
+   } else if (Stream == STREAM_RESTORE_OBJECT) {
+      ROBJECT_DBR ro;
+
+      memset(&ro, 0, sizeof(ro));
+      ro.Stream = Stream;
+      ro.FileIndex = FileIndex;
+      if (jcr->mig_jcr) {
+         ro.JobId = jcr->mig_jcr->JobId;
+      } else {
+         ro.JobId = jcr->JobId;
+      }
+
+      Dmsg1(100, "Robj=%s\n", p);
+      
+      skip_nonspaces(&p);                  /* skip FileIndex */
+      skip_spaces(&p);
+      ro.FileType = str_to_int32(p);        /* FileType */
+      skip_nonspaces(&p);
+      skip_spaces(&p);
+      ro.object_index = str_to_int32(p);    /* Object Index */
+      skip_nonspaces(&p);
+      skip_spaces(&p);
+      ro.object_len = str_to_int32(p);      /* object length possibly compressed */
+      skip_nonspaces(&p);                  
+      skip_spaces(&p);
+      ro.object_full_len = str_to_int32(p); /* uncompressed object length */
+      skip_nonspaces(&p);
+      skip_spaces(&p);
+      ro.object_compression = str_to_int32(p); /* compression */
+      skip_nonspaces(&p);
+      skip_spaces(&p);
+
+      ro.plugin_name = p;                      /* point to plugin name */
+      len = strlen(ro.plugin_name);
+      ro.object_name = &ro.plugin_name[len+1]; /* point to object name */
+      len = strlen(ro.object_name);
+      ro.object = &ro.object_name[len+1];      /* point to object */
+      ro.object[ro.object_len] = 0;            /* add zero for those who attempt printing */
+      Dmsg7(100, "oname=%s stream=%d FT=%d FI=%d JobId=%d, obj_len=%d\nobj=\"%s\"\n",
+         ro.object_name, ro.Stream, ro.FileType, ro.FileIndex, ro.JobId,
+         ro.object_len, ro.object);
+      /* Send it */
+      if (!db_create_restore_object_record(jcr, jcr->db, &ro)) {
+         Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db));
+      }
+
    } else if (crypto_digest_stream_type(Stream) != CRYPTO_DIGEST_NONE) {
       fname = p;
       if (ar->FileIndex != FileIndex) {