]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/findlib/bfile.c
Update
[bacula/bacula] / bacula / src / findlib / bfile.c
index 4dc9df53925d2207a29d3227dbf86a064b4c9cc3..19ffcc39d61e2edc679e70a48fce4c9583a89e45 100644 (file)
    Copyright (C) 2003-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   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 along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -97,6 +92,99 @@ 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 stream.
+    * = 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
+
 
 
 /* ===============================================================
@@ -164,22 +252,29 @@ bool have_win32_api()
 
 
 /*
- * Return 1 if we support the stream
- *        0 if we do not support the stream
+ * Return true  if we support the stream
+ *        false if we do not support the stream
  */
 bool is_stream_supported(int stream)
 {
    /* No Win32 backup on this machine */
    switch (stream) {
+   case STREAM_WIN32_DATA:
+#ifdef HAVE_ZLIB
+   case STREAM_WIN32_GZIP_DATA:
+#endif
+#ifdef USE_WIN32STREAMEXTRACTION
+      return true;
+#else
+      return have_win32_api();      
+#endif
+
+/* Streams known not to be supported */
 #ifndef HAVE_LIBZ
    case STREAM_GZIP_DATA:
    case STREAM_SPARSE_GZIP_DATA:
-      return 0;
-#endif
-   case STREAM_WIN32_DATA:
    case STREAM_WIN32_GZIP_DATA:
-      return have_win32_api();
-
+#endif
    case STREAM_MACOS_FORK_DATA:
    case STREAM_HFSPLUS_ATTRIBUTES:
       return false;
@@ -214,7 +309,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 +428,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;
@@ -535,23 +634,32 @@ bool set_prog(BFILE *bfd, char *prog, JCR *jcr)
 bool is_stream_supported(int stream)
 {
    /* No Win32 backup on this machine */
-   switch (stream) {
+/*   switch (stream) {
 #ifndef HAVE_LIBZ
    case STREAM_GZIP_DATA:
    case STREAM_SPARSE_GZIP_DATA:
+   case STREAM_WIN32_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:
 #endif
       return false;
+*/
 
    /* Known streams */
 #ifdef HAVE_LIBZ
    case STREAM_GZIP_DATA:
    case STREAM_SPARSE_GZIP_DATA:
+#endif
+#ifdef USE_WIN32STREAMEXTRACTION
+   case STREAM_WIN32_DATA:
+# ifdef HAVE_LIBZ 
+   case STREAM_WIN32_GZIP_DATA:    
+# endif
 #endif
    case STREAM_UNIX_ATTRIBUTES:
    case STREAM_FILE_DATA:
@@ -565,43 +673,13 @@ bool is_stream_supported(int stream)
    case STREAM_MACOS_FORK_DATA:
    case STREAM_HFSPLUS_ATTRIBUTES:
 #endif
-   case 0:                            /* compatibility with old tapes */
+   case 0:   /* compatibility with old tapes */
       return true;
 
    }
-   return 0;
+   return false;
 }
 
-/* Old file reader code */
-#ifdef xxx
-   if (bfd->prog) {
-      POOLMEM *ecmd = get_pool_memory(PM_FNAME);
-      ecmd = edit_job_codes(bfd->jcr, ecmd, bfd->prog, fname);
-      const char *pmode;
-      if (flags & O_RDONLY) {
-         pmode = "r";
-      } else {
-         pmode = "w";
-      }
-      bfd->bpipe = open_bpipe(ecmd, 0, pmode);
-      if (bfd->bpipe == NULL) {
-         bfd->berrno = errno;
-         bfd->fid = -1;
-         free_pool_memory(ecmd);
-         return -1;
-      }
-      free_pool_memory(ecmd);
-      if (flags & O_RDONLY) {
-         bfd->fid = fileno(bfd->bpipe->rfd);
-      } else {
-         bfd->fid = fileno(bfd->bpipe->wfd);
-      }
-      errno = 0;
-      return bfd->fid;
-   }
-#endif
-
-
 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
 {
    /* Open reader/writer program */
@@ -615,6 +693,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;
 }