]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/findlib/bfile.c
Update
[bacula/bacula] / bacula / src / findlib / bfile.c
index 64231a5594ec526924020e6c167b33bdf8feddc4..19ffcc39d61e2edc679e70a48fce4c9583a89e45 100644 (file)
@@ -9,29 +9,28 @@
  *
  */
 /*
-   Copyright (C) 2003-2004 Kern Sibbald and John Walker
+   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.
 
  */
 
 #include "bacula.h"
 #include "find.h"
 
-extern int generate_job_event(JCR *jcr, const char *event);
+bool    (*python_set_prog)(JCR *jcr, const char *prog) = NULL;
+int     (*python_open)(BFILE *bfd, const char *fname, int flags, mode_t mode) = NULL;
+int     (*python_close)(BFILE *bfd) = NULL;
+ssize_t (*python_read)(BFILE *bfd, void *buf, size_t count) = NULL;
+ssize_t (*python_write)(BFILE *bfd, void *buf, size_t count) = NULL;
 
 #ifdef HAVE_DARWIN_OS
 #include <sys/paths.h>
@@ -60,39 +59,132 @@ const char *stream_to_ascii(int stream)
 
    switch (stream) {
    case STREAM_GZIP_DATA:
-      return "GZIP data";
+      return _("GZIP data");
    case STREAM_SPARSE_GZIP_DATA:
-      return "GZIP sparse data";
+      return _("GZIP sparse data");
    case STREAM_WIN32_DATA:
-      return "Win32 data";
+      return _("Win32 data");
    case STREAM_WIN32_GZIP_DATA:
-      return "Win32 GZIP data";
+      return _("Win32 GZIP data");
    case STREAM_UNIX_ATTRIBUTES:
-      return "File attributes";
+      return _("File attributes");
    case STREAM_FILE_DATA:
-      return "File data";
+      return _("File data");
    case STREAM_MD5_SIGNATURE:
-      return "MD5 signature";
+      return _("MD5 signature");
    case STREAM_UNIX_ATTRIBUTES_EX:
-      return "Extended attributes";
+      return _("Extended attributes");
    case STREAM_SPARSE_DATA:
-      return "Sparse data";
+      return _("Sparse data");
    case STREAM_PROGRAM_NAMES:
-      return "Program names";
+      return _("Program names");
    case STREAM_PROGRAM_DATA:
-      return "Program data";
+      return _("Program data");
    case STREAM_SHA1_SIGNATURE:
-      return "SHA1 signature";
+      return _("SHA1 signature");
    case STREAM_MACOS_FORK_DATA:
-      return "HFS+ resource fork";
+      return _("HFS+ resource fork");
    case STREAM_HFSPLUS_ATTRIBUTES:
-      return "HFS+ Finder Info";
+      return _("HFS+ Finder Info");
    default:
       sprintf(buf, "%d", stream);
       return (const char *)buf;
    }
 }
 
+#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
+
 
 
 /* ===============================================================
@@ -160,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;
@@ -207,12 +306,22 @@ HANDLE bget_handle(BFILE *bfd)
 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
 {
    POOLMEM *win32_fname;
+   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);
+   
    unix_name_to_win32(&win32_fname, (char *)fname);
 
+   if (!(p_CreateFileA || p_CreateFileW))
+      return 0;
+
+   if (p_CreateFileW && p_MultiByteToWideChar)               
+      UTF8_2_wchar(&win32_fname_wchar, win32_fname);
+
    if (flags & O_CREAT) {             /* Create */
       if (bfd->use_backup_api) {
          dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
@@ -221,13 +330,28 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
          dwaccess = GENERIC_WRITE;
          dwflags = 0;
       }
-      bfd->fh = CreateFile(win32_fname,
+
+   // unicode or ansii open for create write
+   if (p_CreateFileW && p_MultiByteToWideChar) {   
+      bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
+             dwaccess,                /* Requested access */
+             0,                       /* Shared mode */
+             NULL,                    /* SecurityAttributes */
+             CREATE_ALWAYS,           /* CreationDisposition */
+             dwflags,                 /* Flags and attributes */
+             NULL);                   /* TemplateFile */
+   }
+   else {
+      bfd->fh = p_CreateFileA(win32_fname,
              dwaccess,                /* Requested access */
              0,                       /* Shared mode */
              NULL,                    /* SecurityAttributes */
              CREATE_ALWAYS,           /* CreationDisposition */
              dwflags,                 /* Flags and attributes */
              NULL);                   /* TemplateFile */
+   }
+
+
       bfd->mode = BF_WRITE;
 
    } else if (flags & O_WRONLY) {     /* Open existing for write */
@@ -238,13 +362,28 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
          dwaccess = GENERIC_WRITE;
          dwflags = 0;
       }
-      bfd->fh = CreateFile(win32_fname,
+
+   // unicode or ansii open for open existing write
+   if (p_CreateFileW && p_MultiByteToWideChar) {   
+      bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
              dwaccess,                /* Requested access */
              0,                       /* Shared mode */
              NULL,                    /* SecurityAttributes */
              OPEN_EXISTING,           /* CreationDisposition */
              dwflags,                 /* Flags and attributes */
              NULL);                   /* TemplateFile */
+   }
+   else {
+      bfd->fh = p_CreateFileA(win32_fname,
+             dwaccess,                /* Requested access */
+             0,                       /* Shared mode */
+             NULL,                    /* SecurityAttributes */
+             OPEN_EXISTING,           /* CreationDisposition */
+             dwflags,                 /* Flags and attributes */
+             NULL);                   /* TemplateFile */
+
+   }
+
       bfd->mode = BF_WRITE;
 
    } else {                           /* Read */
@@ -257,13 +396,27 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
          dwflags = 0;
          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE;
       }
-      bfd->fh = CreateFile(win32_fname,
+
+      // unicode or ansii open for open existing read
+   if (p_CreateFileW && p_MultiByteToWideChar) {   
+      bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
              dwaccess,                /* Requested access */
              dwshare,                 /* Share modes */
              NULL,                    /* SecurityAttributes */
              OPEN_EXISTING,           /* CreationDisposition */
              dwflags,                 /* Flags and attributes */
              NULL);                   /* TemplateFile */
+   }
+   else {
+      bfd->fh = p_CreateFileA(win32_fname,
+             dwaccess,                /* Requested access */
+             dwshare,                 /* Share modes */
+             NULL,                    /* SecurityAttributes */
+             OPEN_EXISTING,           /* CreationDisposition */
+             dwflags,                 /* Flags and attributes */
+             NULL);                   /* TemplateFile */
+   }
+
       bfd->mode = BF_READ;
    }
 
@@ -275,6 +428,11 @@ 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;
 }
@@ -459,13 +617,14 @@ bool set_prog(BFILE *bfd, char *prog, JCR *jcr)
       return true;                    /* already setup */
    }
 
-   int stat = generate_job_event(jcr, "Reader");
-   if (stat == 1 && bfd->pio.fo && bfd->pio.fr && bfd->pio.fc) {
+   if (python_set_prog(jcr, prog)) {
+      Dmsg1(000, "Set prog=%s\n", prog);
       bfd->prog = prog;
       bfd->jcr = jcr;
       return true;
    }
 #endif
+   Dmsg0(000, "No prog set\n");
    bfd->prog = NULL;
    return false;
 
@@ -475,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:
@@ -505,49 +673,19 @@ 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 */
    if (bfd->prog) {
-      errno = 0;
-      return 1;
+      Dmsg1(000, "Open file %d\n", bfd->fid);
+      return python_open(bfd, fname, flags, mode);
    }
 
    /* Normal file open */
@@ -555,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;
 }
 
@@ -576,27 +720,19 @@ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
 }
 #endif
 
-/* Old prog close code */
-#ifdef xxx
-   if (bfd->prog && bfd->bpipe) {
-      stat = close_bpipe(bfd->bpipe);
-      bfd->berrno = errno;
-      bfd->fid = -1;
-      bfd->bpipe = NULL;
-      return stat;
-   }
-#endif
-
 
 int bclose(BFILE *bfd)
 {
    int stat;
+
    Dmsg1(400, "Close file %d\n", bfd->fid);
-   if (bfd->fid == -1) {
-      return 0;
-   }
+
    /* Close reader/writer program */
    if (bfd->prog) {
+      return python_close(bfd);
+   }
+
+   if (bfd->fid == -1) {
       return 0;
    }
 
@@ -610,6 +746,10 @@ int bclose(BFILE *bfd)
 ssize_t bread(BFILE *bfd, void *buf, size_t count)
 {
    ssize_t stat;
+
+   if (bfd->prog) {
+      return python_read(bfd, buf, count);
+   }
    stat = read(bfd->fid, buf, count);
    bfd->berrno = errno;
    return stat;
@@ -618,6 +758,10 @@ ssize_t bread(BFILE *bfd, void *buf, size_t count)
 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
 {
    ssize_t stat;
+
+   if (bfd->prog) {
+      return python_write(bfd, buf, count);
+   }
    stat = write(bfd->fid, buf, count);
    bfd->berrno = errno;
    return stat;