]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/restore.c
- Fix backspace to first character in conio.c
[bacula/bacula] / bacula / src / filed / restore.c
index fc356f09dc3e65a32c9a5a936d4e08cb107438cc..3ad0006cf8922ed92d8234d001e2e85897c62fff 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 /*
-   Copyright (C) 2000-2003 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
 #include "bacula.h"
 #include "filed.h"
 
+#ifdef HAVE_ACL
+#include <sys/acl.h>
+#include <acl/libacl.h>
+#endif
+
 /* Data received from Storage Daemon */
 static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
 
 /* Forward referenced functions */
+#ifdef HAVE_LIBZ
+static const char *zlib_strerror(int stat);
+#endif
 
 #define RETRY 10                     /* retry wait time */
 
@@ -42,13 +50,12 @@ static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
  */
 void do_restore(JCR *jcr)
 {
-   int wherelen;
    BSOCK *sd;
    int32_t stream;
    uint32_t size;
    uint32_t VolSessionId, VolSessionTime;
    int32_t file_index;
-   int extract = FALSE;
+   bool extract = false;
    BFILE bfd;
    int stat;
    uint32_t total = 0;               /* Job total but only 32 bits for debug */
@@ -57,16 +64,27 @@ void do_restore(JCR *jcr)
    uint64_t fileAddr = 0;            /* file write address */
    int non_support_data = 0;
    int non_support_attr = 0;
+   int non_support_acl = 0;
    int prog_name_msg = 0;
    ATTR *attr;
-   
-   wherelen = strlen(jcr->where);
+#ifdef HAVE_ACL
+   acl_t acl;
+#endif
 
    binit(&bfd);
    sd = jcr->store_bsock;
    set_jcr_job_status(jcr, JS_Running);
 
-   if (!bnet_set_buffer_size(sd, MAX_NETWORK_BUFFER_SIZE, BNET_SETBUF_READ)) {
+   LockRes();
+   CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
+   UnlockRes();
+   uint32_t buf_size;
+   if (client) {
+      buf_size = client->max_network_buffer_size;
+   } else {
+      buf_size = 0;                  /* use default */
+   }
+   if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       return;
    }
@@ -117,7 +135,6 @@ void do_restore(JCR *jcr)
       switch (stream) {
       case STREAM_UNIX_ATTRIBUTES:
       case STREAM_UNIX_ATTRIBUTES_EX:
-
          Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
         /* If extracting, it was from previous stream, so
          * close the output file.
@@ -127,7 +144,7 @@ void do_restore(JCR *jcr)
                Jmsg0(jcr, M_ERROR, 0, _("Logic error output file should be open\n"));
            }
            set_attributes(jcr, attr, &bfd);
-           extract = FALSE;
+           extract = false;
             Dmsg0(30, "Stop extracting.\n");
         }
 
@@ -159,16 +176,16 @@ void do_restore(JCR *jcr)
         jcr->num_files_examined++;
 
          Dmsg1(30, "Outfile=%s\n", attr->ofname);
-        extract = FALSE;
+        extract = false;
         stat = create_file(jcr, attr, &bfd, jcr->replace);
         switch (stat) {
         case CF_ERROR:
         case CF_SKIP:
            break;
         case CF_EXTRACT:
-           extract = TRUE;
+           extract = true;
            P(jcr->mutex);
-           pm_strcpy(&jcr->last_fname, attr->ofname);
+           pm_strcpy(jcr->last_fname, attr->ofname);
            V(jcr->mutex);
            jcr->JobFiles++;
            fileAddr = 0;
@@ -177,7 +194,7 @@ void do_restore(JCR *jcr)
            break;
         case CF_CREATED:
            P(jcr->mutex);
-           pm_strcpy(&jcr->last_fname, attr->ofname);
+           pm_strcpy(jcr->last_fname, attr->ofname);
            V(jcr->mutex);
            jcr->JobFiles++;
            fileAddr = 0;
@@ -188,24 +205,10 @@ void do_restore(JCR *jcr)
         }  
         break;
 
-      /* Windows Backup data stream */
-      case STREAM_WIN32_DATA:  
-        if (!is_win32_backup()) {
-           if (!non_support_data) {
-               Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
-                 stream_to_ascii(stream));
-           }
-           extract = FALSE;
-           non_support_data++;
-           continue;
-        }
-        goto extract_data;
-
       /* Data stream */
       case STREAM_FILE_DATA:
       case STREAM_SPARSE_DATA: 
-
-extract_data:
+      case STREAM_WIN32_DATA:  
         if (extract) {
            if (stream == STREAM_SPARSE_DATA) {
               ser_declare;
@@ -219,9 +222,12 @@ extract_data:
               if (fileAddr != faddr) {
                  fileAddr = faddr;
                  if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+                    berrno be;
+                    be.set_errno(bfd.berrno);
                      Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
-                        edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
-                    extract = FALSE;
+                        edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
+                    extract = false;
+                    bclose(&bfd);
                     continue;
                  }
               }
@@ -232,8 +238,12 @@ extract_data:
             Dmsg2(30, "Write %u bytes, total before write=%u\n", wsize, total);
            if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
                Dmsg0(0, "===Write error===\n");
-               Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: ERR=%s\n"), attr->ofname, berror(&bfd));
-              extract = FALSE;
+              berrno be;
+              be.set_errno(bfd.berrno);
+               Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: ERR=%s\n"), attr->ofname, 
+                    be.strerror());
+              extract = false;
+              bclose(&bfd);
               continue;
            } 
            total += wsize;
@@ -243,31 +253,19 @@ extract_data:
         }
         break;
 
-      /* Windows Backup GZIP data stream */
-      case STREAM_WIN32_GZIP_DATA:  
-        if (!is_win32_backup()) {
-           if (!non_support_attr) {
-               Jmsg(jcr, M_ERROR, 0, _("%s stream not supported on this Client.\n"),
-                 stream_to_ascii(stream));
-           }
-           extract = FALSE;
-           non_support_attr++;
-           continue;
-        }
-        /* Fall through desired */
-
       /* GZIP data stream */
       case STREAM_GZIP_DATA:
       case STREAM_SPARSE_GZIP_DATA:  
+      case STREAM_WIN32_GZIP_DATA:  
 #ifdef HAVE_LIBZ
         if (extract) {
-           ser_declare;
            uLong compress_len;
-           uint64_t faddr;
-           char ec1[50];
            int stat;
 
            if (stream == STREAM_SPARSE_GZIP_DATA) {
+              ser_declare;
+              uint64_t faddr;
+              char ec1[50];
               wbuf = sd->msg + SPARSE_FADDR_SIZE;
               wsize = sd->msglen - SPARSE_FADDR_SIZE;
               ser_begin(sd->msg, SPARSE_FADDR_SIZE);
@@ -275,9 +273,12 @@ extract_data:
               if (fileAddr != faddr) {
                  fileAddr = faddr;
                  if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+                    berrno be;
+                    be.set_errno(bfd.berrno);
                      Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
-                        edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
-                    extract = FALSE;
+                        edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
+                    extract = false;
+                    bclose(&bfd);
                     continue;
                  }
               }
@@ -289,16 +290,21 @@ extract_data:
             Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
            if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len, 
                  (const Byte *)wbuf, (uLong)wsize)) != Z_OK) {
-               Jmsg(jcr, M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
-              extract = FALSE;
+               Jmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"), 
+                 attr->ofname, zlib_strerror(stat));
+              extract = false;
+              bclose(&bfd);
               continue;
            }
 
             Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
            if ((uLong)bwrite(&bfd, jcr->compress_buf, compress_len) != compress_len) {
                Dmsg0(0, "===Write error===\n");
-               Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), attr->ofname, berror(&bfd));
-              extract = FALSE;
+              berrno be;
+              be.set_errno(bfd.berrno);
+               Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), attr->ofname, be.strerror());
+              extract = false;
+              bclose(&bfd);
               continue;
            }
            total += compress_len;
@@ -309,12 +315,41 @@ extract_data:
 #else
         if (extract) {
             Jmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
-           extract = FALSE;
+           extract = false;
+           bclose(&bfd);
            continue;
         }
 #endif
         break;
 
+      case STREAM_UNIX_ATTRIBUTES_ACL:  
+#ifdef HAVE_ACL
+        /* Recover ACL from stream and check it */
+        acl = acl_from_text(sd->msg);
+        if (acl_valid(acl) != 0) {
+            Jmsg1(jcr, M_WARNING, 0, "Failure in the ACL of %s! FD is not able to restore it!\n", jcr->last_fname);
+           acl_free(acl);
+        }
+        
+        /* Try to restore ACL */
+        if (attr->type == FT_DIREND) {
+           /* Directory */
+           if (acl_set_file(jcr->last_fname, ACL_TYPE_DEFAULT, acl) != 0 &&
+               acl_set_file(jcr->last_fname, ACL_TYPE_ACCESS, acl) != 0) {
+               Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore ACL of directory: %s! Maybe system does not support ACLs!\n", jcr->last_fname);
+           }
+        /* File or Link */
+        } else if (acl_set_file(jcr->last_fname, ACL_TYPE_ACCESS, acl) != 0) {
+            Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore ACL of file: %s! Maybe system does not support ACLs!\n", jcr->last_fname);
+        }
+        acl_free(acl);
+         Dmsg1(200, "ACL of file: %s successfully restored!", jcr->last_fname);
+        break;
+#else 
+        non_support_acl++;
+        break;                       /* unconfigured, ignore */
+#endif  
+        
       case STREAM_MD5_SIGNATURE:
       case STREAM_SHA1_SIGNATURE:
         break;
@@ -335,7 +370,7 @@ extract_data:
                Jmsg0(jcr, M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
            }
            set_attributes(jcr, attr, &bfd);
-           extract = FALSE;
+           extract = false;
         }
          Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
          Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
@@ -360,6 +395,7 @@ ok_out:
       free(jcr->compress_buf);
       jcr->compress_buf = NULL;
    }
+   bclose(&bfd);
    free_attr(attr);
    Dmsg2(10, "End Do Restore. Files=%d Bytes=%" lld "\n", jcr->JobFiles,
       jcr->JobBytes);
@@ -367,4 +403,36 @@ ok_out:
       Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
         non_support_data, non_support_attr);
    }
+   if (non_support_acl) {
+      Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
+   }
+
 }         
+
+#ifdef HAVE_LIBZ
+/*
+ * Convert ZLIB error code into an ASCII message
+ */
+static const char *zlib_strerror(int stat)
+{
+   if (stat >= 0) {
+      return "None";
+   }
+   switch (stat) {
+   case Z_ERRNO:
+      return "Zlib errno";
+   case Z_STREAM_ERROR:
+      return "Zlib stream error";
+   case Z_DATA_ERROR:
+      return "Zlib data error";
+   case Z_MEM_ERROR:
+      return "Zlib memory error";
+   case Z_BUF_ERROR:
+      return "Zlib buffer error";
+   case Z_VERSION_ERROR:
+      return "Zlib version error";
+   default:
+      return "*none*";
+   }
+}
+#endif