]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/restore.c
More sanity checking
[bacula/bacula] / bacula / src / filed / restore.c
index 2fcf113bafeeeae20b175c61f74609629f12ef8f..b8435e132ae93c789deabf9e3c13605a089aa1aa 100644 (file)
@@ -62,6 +62,11 @@ const bool have_acl = false;
    const bool have_sha2 = false;
 #endif
 
+#if defined(HAVE_XATTR)
+const bool have_xattr = true;
+#else
+const bool have_xattr = false;
+#endif
 
 /* Data received from Storage Daemon */
 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
@@ -171,6 +176,7 @@ void do_restore(JCR *jcr)
    int non_support_acl = 0;
    int non_support_progname = 0;
    int non_support_crypto = 0;
+   int non_support_xattr = 0;
 
 #ifdef HAVE_DARWIN_OS
    struct attrlist attrList;
@@ -223,8 +229,9 @@ void do_restore(JCR *jcr)
     *        d. Alternate data stream (e.g. Resource Fork)
     *        e. Finder info
     *        f. ACLs
-    *        g. Possibly a cryptographic signature
-    *        h. Possibly MD5 or SHA1 record
+    *        g. XATTRs
+    *        h. Possibly a cryptographic signature
+    *        i. Possibly MD5 or SHA1 record
     *   3. Repeat step 1
     *
     * NOTE: We keep track of two bacula file descriptors:
@@ -243,9 +250,8 @@ void do_restore(JCR *jcr)
    binit(&rctx.bfd);
    binit(&rctx.forkbfd);
    attr = rctx.attr = new_attr(jcr);
-   jcr->acl_text = get_pool_memory(PM_MESSAGE);
-
-   
+   jcr->acl_data = get_pool_memory(PM_MESSAGE);
+   jcr->xattr_data = get_pool_memory(PM_MESSAGE);
 
    while (bget_msg(sd) >= 0 && !job_canceled(jcr)) {
       /* Remember previous stream type */
@@ -346,6 +352,8 @@ void do_restore(JCR *jcr)
          switch (stat) {
          case CF_ERROR:
          case CF_SKIP:
+            pm_strcpy(jcr->last_fname, attr->ofname);
+            jcr->last_type = attr->type;
             break;
          case CF_EXTRACT:        /* File created and we expect file data */
             rctx.extract = true;
@@ -571,26 +579,63 @@ void do_restore(JCR *jcr)
          break;
 
       case STREAM_UNIX_ACCESS_ACL:
+      case STREAM_UNIX_DEFAULT_ACL:
+      case STREAM_ACL_AIX_TEXT:
+      case STREAM_ACL_DARWIN_ACCESS_ACL:
+      case STREAM_ACL_FREEBSD_DEFAULT_ACL:
+      case STREAM_ACL_FREEBSD_ACCESS_ACL:
+      case STREAM_ACL_HPUX_ACL_ENTRY:
+      case STREAM_ACL_IRIX_DEFAULT_ACL:
+      case STREAM_ACL_IRIX_ACCESS_ACL:
+      case STREAM_ACL_LINUX_DEFAULT_ACL:
+      case STREAM_ACL_LINUX_ACCESS_ACL:
+      case STREAM_ACL_TRU64_DEFAULT_ACL:
+      case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
+      case STREAM_ACL_TRU64_ACCESS_ACL:
+      case STREAM_ACL_SOLARIS_ACLENT:
+      case STREAM_ACL_SOLARIS_ACE:
+         /*
+          * Do not restore ACLs when
+          * a) The current file is not extracted
+          * b)     and it is not a directory (they are never "extracted")
+          * c) or the file name is empty
+          */
+         if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
+            break;
+         }
          if (have_acl) {
-            pm_strcpy(jcr->acl_text, sd->msg);
-            Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_ACCESS, jcr->acl_text);
-            if (bacl_set(jcr, BACL_TYPE_ACCESS) != 0) {
-               Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACL of %s\n"), jcr->last_fname);
+            pm_memcpy(jcr->acl_data, sd->msg, sd->msglen);
+            jcr->acl_data_len = sd->msglen;
+            if (!parse_acl_stream(jcr, rctx.stream)) {
+               Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACLs of %s\n"), jcr->last_fname);
             }
          } else {
             non_support_acl++;
          }
          break;
 
-      case STREAM_UNIX_DEFAULT_ACL:
-         if (have_acl) {
-            pm_strcpy(jcr->acl_text, sd->msg);
-            Dmsg2(400, "Restoring ACL type 0x%2x <%s>\n", BACL_TYPE_DEFAULT, jcr->acl_text);
-            if (bacl_set(jcr, BACL_TYPE_DEFAULT) != 0) {
-               Qmsg1(jcr, M_WARNING, 0, _("Can't restore default ACL of %s\n"), jcr->last_fname);
+      case STREAM_XATTR_SOLARIS_SYS:
+      case STREAM_XATTR_SOLARIS:
+      case STREAM_XATTR_DARWIN:
+      case STREAM_XATTR_FREEBSD:
+      case STREAM_XATTR_LINUX:
+         /*
+          * Do not restore Extended Attributes when
+          * a) The current file is not extracted
+          * b)     and it is not a directory (they are never "extracted")
+          * c) or the file name is empty
+          */
+         if ((!rctx.extract && jcr->last_type != FT_DIREND) || (*jcr->last_fname == 0)) {
+            break;
+         }
+         if (have_xattr) {
+            pm_memcpy(jcr->xattr_data, sd->msg, sd->msglen);
+            jcr->xattr_data_len = sd->msglen;
+            if (!parse_xattr_stream(jcr, rctx.stream)) {
+               Qmsg1(jcr, M_WARNING, 0, _("Can't restore Extended Attributes of %s\n"), jcr->last_fname);
             }
          } else {
-            non_support_acl++;
+            non_support_xattr++;
          }
          break;
 
@@ -686,10 +731,19 @@ ok_out:
       jcr->compress_buf = NULL;
       jcr->compress_buf_size = 0;
    }
+
+   if (jcr->xattr_data) {
+      free_pool_memory(jcr->xattr_data);
+      jcr->xattr_data = NULL;
+   }
+   if (jcr->acl_data) {
+      free_pool_memory(jcr->acl_data);
+      jcr->acl_data = NULL;
+   }
+
    bclose(&rctx.forkbfd);
    bclose(&rctx.bfd);
    free_attr(rctx.attr);
-   free_pool_memory(jcr->acl_text);
    Dmsg2(10, "End Do Restore. Files=%d Bytes=%s\n", jcr->JobFiles,
       edit_uint64(jcr->JobBytes, ec1));
    if (non_support_data > 1 || non_support_attr > 1) {
@@ -708,6 +762,9 @@ ok_out:
    if (non_support_crypto) {
       Jmsg(jcr, M_INFO, 0, _("%d non-supported crypto streams ignored.\n"), non_support_acl);
    }
+   if (non_support_xattr) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported xattr streams ignored.\n"), non_support_xattr);
+   }
 
 }