]> git.sur5r.net Git - bacula/bacula/commitdiff
support for WIN32 backup stream restores on platforms without win32 backup api
authorThorsten Engel <thorsten.engel@matrix-computer.com>
Wed, 2 Nov 2005 15:11:08 +0000 (15:11 +0000)
committerThorsten Engel <thorsten.engel@matrix-computer.com>
Wed, 2 Nov 2005 15:11:08 +0000 (15:11 +0000)
PRELIMINARY!

must define USE_WIN32STREAMEXTRACTION for enabling

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2522 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/filed/restore.c
bacula/src/findlib/bfile.c
bacula/src/findlib/bfile.h
bacula/src/findlib/find.h

index e2686298d22fcd9035ef25fa837ccabf02337dd2..cfda593a2c5a5a95e4b8a009d8f4cfec9fa197e0 100644 (file)
@@ -290,6 +290,15 @@ void do_restore(JCR *jcr)
                   || stream == STREAM_WIN32_GZIP_DATA) {
                flags |= FO_GZIP;
             }
+
+#ifdef USE_WIN32STREAMEXTRACTION
+/* THIS DETERMINES IF WE USE THE WIN32 BACKUPSTREAM DECOMPOSITION */
+            if (is_win32_stream(stream) && !have_win32_api()) {
+               set_portable_backup(&bfd);
+               flags |= FO_WIN32DECOMP;
+            }
+#endif
+
             if (extract_data(jcr, &bfd, sd->msg, sd->msglen, &fileAddr, flags) < 0) {
                extract = false;
                bclose(&bfd);
@@ -534,6 +543,17 @@ int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
       Dmsg2(30, "Write %u bytes, total before write=%s\n", wsize, edit_uint64(jcr->JobBytes, ec1));
    }
 
+#ifdef USE_WIN32STREAMEXTRACTION
+   if (flags & FO_WIN32DECOMP) {
+      if (!processWin32BackupAPIBlock(bfd, wbuf, wsize)) {
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("Write error in Win32 Block Decomposition on %s: %s\n"), 
+               jcr->last_fname, be.strerror(bfd->berrno));
+         return -1;
+      }
+   }
+   else
+#endif
    if (bwrite(bfd, wbuf, wsize) != (ssize_t)wsize) {
       berrno be;
       Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), 
index 4dc9df53925d2207a29d3227dbf86a064b4c9cc3..6b740f88b9b1046a672586bcf88e5079a2cafb47 100644 (file)
@@ -97,6 +97,94 @@ const char *stream_to_ascii(int stream)
    }
 }
 
+#ifdef USE_WIN32STREAMEXTRACTION
+BOOL processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, size_t dwSize)
+{   
+   /* pByte contains the buffer 
+      dwSize the len to be processed. function assumes to be called in successive
+      incremental order over the complete BackupRead stream beginning at pos 0 and
+      ending at the end. */
+
+   PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT* pContext = &(bfd->win32DecompContext);
+   BOOL bContinue = FALSE;
+   LONGLONG dwDataOffset = 0;
+   LONGLONG dwDataLen;
+
+   /* Win32 Stream Header size without name of strem.
+      = sizeof (WIN32_STREAM_ID)- sizeof(WCHAR*); */
+   DWORD dwSizeHeader = 20; 
+
+   do {               
+      if (pContext->liNextHeader >= dwSize) {                        
+         dwDataLen = dwSize-dwDataOffset;
+         bContinue = FALSE; /* 1 iteration is enough */
+      }
+      else {                        
+         dwDataLen = pContext->liNextHeader-dwDataOffset;
+         bContinue = TRUE; /* multiple iterations may be necessary */
+      }
+
+      /* flush */
+      /* copy block of real DATA */
+      if (pContext->bIsInData) {
+         if (bwrite(bfd, ((LPBYTE)pBuffer)+dwDataOffset, dwDataLen) != (ssize_t)dwDataLen)            
+            return FALSE;         
+      }
+
+      if (pContext->liNextHeader < dwSize) {/* is a header in this block ? */
+         DWORD dwOffsetTarget;
+         DWORD dwOffsetSource;
+            
+         if (pContext->liNextHeader < 0) {
+            /* start of header was before this block,
+               so we continue with the part in the current block */                                   
+            dwOffsetTarget = abs (pContext->liNextHeader);
+            dwOffsetSource = 0;                            
+         }
+         else {
+            /* start of header is inside of this block */
+            dwOffsetTarget = 0;
+            dwOffsetSource = pContext->liNextHeader;                        
+         }
+
+         DWORD dwHeaderPartLen = dwSizeHeader-dwOffsetTarget;
+         BOOL bHeaderIsComplete;
+
+         if (dwHeaderPartLen <= dwSize-dwOffsetSource) 
+            /* header (or rest of header) is completely available in current block */
+            bHeaderIsComplete = TRUE;                                                        
+         else  {
+            /* header will continue in next block */
+            bHeaderIsComplete = FALSE;
+            dwHeaderPartLen = dwSize-dwOffsetSource;
+         }
+
+         /* copy the available portion of header to persistent copy */
+         memcpy (((LPBYTE) &pContext->header_stream)+dwOffsetTarget, ((LPBYTE) pBuffer)+dwOffsetSource, dwHeaderPartLen);
+
+         /* recalculate position of next header */
+         if (bHeaderIsComplete) {
+            dwDataOffset = pContext->liNextHeader+dwSizeHeader+pContext->header_stream.dwStreamNameSize;
+            pContext->liNextHeader = dwDataOffset+pContext->header_stream.Size.QuadPart;
+            pContext->bIsInData = pContext->header_stream.dwStreamId == BACKUP_DATA;
+            if (dwDataOffset == dwSize)
+                  bContinue = FALSE;
+         }
+         else {
+            /* stop and continue with next block */
+            bContinue = FALSE;
+            pContext->bIsInData = FALSE;
+         }
+      }                
+   } while (bContinue);    
+
+   /* set "NextHeader" relative to the beginning of the next block */
+   pContext->liNextHeader-= dwSize;
+
+   return TRUE;
+}
+#endif
+
 
 
 /* ===============================================================
@@ -178,7 +266,12 @@ bool is_stream_supported(int stream)
 #endif
    case STREAM_WIN32_DATA:
    case STREAM_WIN32_GZIP_DATA:
-      return have_win32_api();
+#ifdef USE_WIN32STREAMEXTRACTION
+      return true;
+#else
+      return have_win32_api();      
+#endif
+
 
    case STREAM_MACOS_FORK_DATA:
    case STREAM_HFSPLUS_ATTRIBUTES:
@@ -214,7 +307,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    POOLMEM *win32_fname_wchar;
 
    DWORD dwaccess, dwflags, dwshare;
-   
+
    /* Convert to Windows path format */
    win32_fname = get_pool_memory(PM_FNAME);
    win32_fname_wchar = get_pool_memory(PM_FNAME);
@@ -333,6 +426,10 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    }
    bfd->errmsg = NULL;
    bfd->lpContext = NULL;
+#ifdef USE_WIN32STREAMEXTRACTION
+   bfd->win32DecompContext.bIsInData = FALSE;
+   bfd->win32DecompContext.liNextHeader = 0;
+#endif
    free_pool_memory(win32_fname_wchar);
    free_pool_memory(win32_fname);
    return bfd->mode == BF_CLOSED ? -1 : 1;
@@ -540,8 +637,10 @@ bool is_stream_supported(int stream)
    case STREAM_GZIP_DATA:
    case STREAM_SPARSE_GZIP_DATA:
 #endif
+#ifndef USE_WIN32STREAMEXTRACTION
    case STREAM_WIN32_DATA:
    case STREAM_WIN32_GZIP_DATA:
+#endif
 #ifndef HAVE_DARWIN_OS
    case STREAM_MACOS_FORK_DATA:
    case STREAM_HFSPLUS_ATTRIBUTES:
@@ -552,6 +651,12 @@ bool is_stream_supported(int stream)
 #ifdef HAVE_LIBZ
    case STREAM_GZIP_DATA:
    case STREAM_SPARSE_GZIP_DATA:
+#endif
+#ifdef USE_WIN32STREAMEXTRACTION
+   case STREAM_WIN32_DATA:
+#endif
+#if defined(USE_WIN32STREAMEXTRACTION) && defined(HAVE_LIBZ)
+   case STREAM_WIN32_GZIP_DATA:    
 #endif
    case STREAM_UNIX_ATTRIBUTES:
    case STREAM_FILE_DATA:
@@ -615,6 +720,12 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    bfd->berrno = errno;
    Dmsg1(400, "Open file %d\n", bfd->fid);
    errno = bfd->berrno;
+
+#ifdef USE_WIN32STREAMEXTRACTION
+   bfd->win32DecompContext.bIsInData = FALSE;
+   bfd->win32DecompContext.liNextHeader = 0;
+#endif
+
    return bfd->fid;
 }
 
index a38e53c1c1d2463c1ece075b1b4130ae2811d6cc..de60b4f23f68c8f9f2f8d545df3c5978dc51530e 100644 (file)
@@ -41,6 +41,14 @@ struct Python_IO {
 };
 #endif
 
+#ifdef USE_WIN32STREAMEXTRACTION
+typedef struct _PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT {
+        LONGLONG        liNextHeader;
+        BOOL            bIsInData;
+        WIN32_STREAM_ID header_stream;        
+} PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT;
+#endif
+
 /*  =======================================================
  *
  *   W I N D O W S
@@ -74,6 +82,10 @@ struct BFILE {
    char *prog;                        /* reader/writer program if any */
    JCR *jcr;                          /* jcr for editing job codes */
    Python_IO pio;                     /* Python I/O routines */
+#ifdef USE_WIN32STREAMEXTRACTION
+   PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */
+   int use_backup_decomp;             /* set if using BackupRead Stream Decomposition */
+#endif
 };
 
 HANDLE bget_handle(BFILE *bfd);
@@ -94,6 +106,10 @@ struct BFILE {
    char *prog;                        /* reader/writer program if any */
    JCR *jcr;                          /* jcr for editing job codes */
    Python_IO pio;                     /* Python I/O routines */
+#ifdef USE_WIN32STREAMEXTRACTION
+   PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */
+   int use_backup_decomp;             /* set if using BackupRead Stream Decomposition */
+#endif
 };
 
 #endif
@@ -118,4 +134,8 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count);
 off_t   blseek(BFILE *bfd, off_t offset, int whence);
 const char   *stream_to_ascii(int stream);
 
+#ifdef USE_WIN32STREAMEXTRACTION
+BOOL processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, size_t dwSize);
+#endif
+
 #endif /* __BFILE_H */
index 798fa25940dec7dc39ba153e6bd41d2a25c444fc..9e4c0b9bbd6fe24909ffac7c48e43773f301e9cb 100755 (executable)
@@ -90,6 +90,9 @@ enum {
 #define FO_NO_HARDLINK  (1<<15)       /* don't handle hard links */
 #define FO_IGNORECASE   (1<<16)       /* Ignore file name case */
 #define FO_HFSPLUS      (1<<17)       /* Resource forks and Finder Info */
+#ifdef USE_WIN32STREAMEXTRACTION
+#define FO_WIN32DECOMP  (1<<18)       /* Use BackupRead decomposition */
+#endif
 
 struct s_included_file {
    struct s_included_file *next;