]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/findlib/attribs.c
Update doc
[bacula/bacula] / bacula / src / findlib / attribs.c
index 9ee69f574a7e7621592eb89f9b2fe6912bfabde9..d73622e8219021ec98032db14a641b5cfd7b291f 100755 (executable)
@@ -9,7 +9,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 "find.h"
 
-#ifdef HAVE_CYGWIN
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
 
 /* Forward referenced subroutines */
-static
-int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd);
+static int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd);
 void unix_name_to_win32(POOLMEM **win32_name, char *name);
 void win_error(JCR *jcr, char *prefix, POOLMEM *ofile);
 HANDLE bget_handle(BFILE *bfd);
@@ -52,6 +51,36 @@ HANDLE bget_handle(BFILE *bfd);
 /*                                                            */
 /*=============================================================*/
 
+/*
+ * Return the data stream that will be used 
+ */
+int select_data_stream(FF_PKT *ff_pkt)
+{
+   int stream;
+
+   /* Note, no sparse option for win32_data */
+   if (!is_portable_backup(&ff_pkt->bfd)) {
+      stream = STREAM_WIN32_DATA;
+      ff_pkt->flags &= ~FO_SPARSE;
+   } else if (ff_pkt->flags & FO_SPARSE) {
+      stream = STREAM_SPARSE_DATA;
+   } else {
+      stream = STREAM_FILE_DATA;
+   }
+#ifdef HAVE_LIBZ
+   if (ff_pkt->flags & FO_GZIP) {
+      if (stream == STREAM_WIN32_DATA) {
+        stream = STREAM_WIN32_GZIP_DATA;
+      } else if (stream == STREAM_FILE_DATA) {
+        stream = STREAM_GZIP_DATA;
+      } else {
+        stream = STREAM_SPARSE_GZIP_DATA;
+      }
+   }
+#endif
+   return stream;
+}
+
 
 /* 
  * Encode a stat structure into a base64 character string   
@@ -64,15 +93,13 @@ HANDLE bget_handle(BFILE *bfd);
  *   them in the encode_attribsEx() subroutine, but this is
  *   not recommended.
  */
-void encode_stat(char *buf, struct stat *statp, uint32_t LinkFI)
+void encode_stat(char *buf, FF_PKT *ff_pkt, int data_stream)
 {
    char *p = buf;
+   struct stat *statp = &ff_pkt->statp;
    /*
-    * NOTE: we should use rdev as major and minor device if
-    * it is a block or char device (S_ISCHR(statp->st_mode)
-    * or S_ISBLK(statp->st_mode)).  In all other cases,
-    * it is not used.  
-    *
+    *  Encode a stat packet.  I should have done this more intelligently
+    *  with a length so that it could be easily expanded.
     */
    p += to_base64((int64_t)statp->st_dev, p);
    *p++ = ' ';                        /* separate fields with a space */
@@ -90,23 +117,34 @@ void encode_stat(char *buf, struct stat *statp, uint32_t LinkFI)
    *p++ = ' ';
    p += to_base64((int64_t)statp->st_size, p);
    *p++ = ' ';
+#ifndef HAVE_MINGW
    p += to_base64((int64_t)statp->st_blksize, p);
    *p++ = ' ';
    p += to_base64((int64_t)statp->st_blocks, p);
    *p++ = ' ';
+#else
+   p += to_base64((int64_t)0, p); /* output place holder */
+   *p++ = ' ';
+   p += to_base64((int64_t)0, p); /* output place holder */
+   *p++ = ' ';
+#endif
    p += to_base64((int64_t)statp->st_atime, p);
    *p++ = ' ';
    p += to_base64((int64_t)statp->st_mtime, p);
    *p++ = ' ';
    p += to_base64((int64_t)statp->st_ctime, p);
    *p++ = ' ';
-   p += to_base64((int64_t)LinkFI, p);
+   p += to_base64((int64_t)ff_pkt->LinkFI, p);
+   *p++ = ' ';
 
-/* FreeBSD function */
 #ifdef HAVE_CHFLAGS
-   *p++ = ' ';
-   p += to_base64((int64_t)statp->st_flags, p);
+   /* FreeBSD function */
+   p += to_base64((int64_t)statp->st_flags, p);  /* output st_flags */
+#else
+   p += to_base64((int64_t)0, p);     /* output place holder */
 #endif
+   *p++ = ' ';
+   p += to_base64((int64_t)data_stream, p);
    *p = 0;
    return;
 }
@@ -114,8 +152,7 @@ void encode_stat(char *buf, struct stat *statp, uint32_t LinkFI)
 
 
 /* Decode a stat packet from base64 characters */
-void
-decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI) 
+int decode_stat(char *buf, struct stat *statp, int32_t *LinkFI) 
 {
    char *p = buf;
    int64_t val;
@@ -144,12 +181,21 @@ decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI)
    p += from_base64(&val, p);
    statp->st_size = val;
    p++;
+#ifndef HAVE_MINGW
    p += from_base64(&val, p);
    statp->st_blksize = val;
    p++;
    p += from_base64(&val, p);
    statp->st_blocks = val;
    p++;
+#else
+   p += from_base64(&val, p);
+//   statp->st_blksize = val;
+   p++;
+   p += from_base64(&val, p);
+//   statp->st_blocks = val;
+   p++;
+#endif
    p += from_base64(&val, p);
    statp->st_atime = val;
    p++;
@@ -158,25 +204,78 @@ decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI)
    p++;
    p += from_base64(&val, p);
    statp->st_ctime = val;
+
    /* Optional FileIndex of hard linked file data */
    if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
       p++;
       p += from_base64(&val, p);
       *LinkFI = (uint32_t)val;
-  } else {
+   } else {
       *LinkFI = 0;
-  }
+      return 0;
+   }
 
-/* FreeBSD user flags */
-#ifdef HAVE_CHFLAGS
+   /* FreeBSD user flags */
    if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
       p++;
       p += from_base64(&val, p);
+#ifdef HAVE_CHFLAGS
       statp->st_flags = (uint32_t)val;
-  } else {
+   } else {
       statp->st_flags  = 0;
-  }
 #endif
+   }
+    
+   /* Look for data stream id */
+   if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
+      p++;
+      p += from_base64(&val, p);
+   } else {
+      val = 0;
+   }
+   return (int)val;
+}
+
+/* Decode a LinkFI field of encoded stat packet */
+int32_t decode_LinkFI(char *buf, struct stat *statp)
+{
+   char *p = buf;
+   int64_t val;
+
+   skip_nonspaces(&p);               /* st_dev */
+   p++;                              /* skip space */
+   skip_nonspaces(&p);               /* st_ino */
+   p++;
+   p += from_base64(&val, p);
+   statp->st_mode = val;             /* st_mode */
+   p++;
+   skip_nonspaces(&p);               /* st_nlink */
+   p++;
+   skip_nonspaces(&p);               /* st_uid */
+   p++;
+   skip_nonspaces(&p);               /* st_gid */
+   p++;
+   skip_nonspaces(&p);               /* st_rdev */
+   p++;
+   skip_nonspaces(&p);               /* st_size */
+   p++;
+   skip_nonspaces(&p);               /* st_blksize */
+   p++;
+   skip_nonspaces(&p);               /* st_blocks */
+   p++;
+   skip_nonspaces(&p);               /* st_atime */
+   p++;
+   skip_nonspaces(&p);               /* st_mtime */
+   p++;
+   skip_nonspaces(&p);               /* st_ctime */
+
+   /* Optional FileIndex of hard linked file data */
+   if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
+      p++;
+      p += from_base64(&val, p);
+      return (int32_t)val;
+   }
+   return 0;
 }
 
 /*
@@ -194,11 +293,25 @@ int set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    mode_t old_mask;
    int stat = 1;
 
-#ifdef HAVE_CYGWIN
-   if (stream == STREAM_UNIX_ATTRIBUTES_EX &&
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
+   if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
        set_win32_attributes(jcr, attr, ofd)) {
+       if (is_bopen(ofd)) {
+          bclose(ofd); 
+       }
+       pm_strcpy(&attr->ofname, "*none*");
+       return 1;
+   }
+   if (attr->data_stream == STREAM_WIN32_DATA ||
+       attr->data_stream == STREAM_WIN32_GZIP_DATA) {
+      if (is_bopen(ofd)) {
+        bclose(ofd); 
+      }
+      pm_strcpy(&attr->ofname, "*none*");
       return 1;
    }
+
+
    /*
     * If Windows stuff failed, e.g. attempt to restore Unix file
     *  to Windows, simply fall through and we will do it the    
@@ -222,18 +335,18 @@ int set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    if (attr->type == FT_LNK) {
       /* Change owner of link, not of real file */
       if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
-         Jmsg2(jcr, M_WARNING, 0, _("Unable to set file owner %s: ERR=%s\n"),
+         Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
            attr->ofname, strerror(errno));
         stat = 0;
       }
    } else {
       if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
-         Jmsg2(jcr, M_WARNING, 0, _("Unable to set file owner %s: ERR=%s\n"),
+         Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
            attr->ofname, strerror(errno));
         stat = 0;
       }
       if (chmod(attr->ofname, attr->statp.st_mode) < 0) {
-         Jmsg2(jcr, M_WARNING, 0, _("Unable to set file modes %s: ERR=%s\n"),
+         Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"),
            attr->ofname, strerror(errno));
         stat = 0;
       }
@@ -241,7 +354,7 @@ int set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
       /* FreeBSD user flags */
 #ifdef HAVE_CHFLAGS
       if (chflags(attr->ofname, attr->statp.st_flags) < 0) {
-         Jmsg2(jcr, M_WARNING, 0, _("Unable to set file flags %s: ERR=%s\n"),
+         Jmsg2(jcr, M_ERROR, 0, _("Unable to set file flags %s: ERR=%s\n"),
            attr->ofname, strerror(errno));
         stat = 0;
       }
@@ -255,6 +368,7 @@ int set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
         stat = 0;
       }
    }
+   pm_strcpy(&attr->ofname, "*none*");
    umask(old_mask);
    return stat;
 }
@@ -266,7 +380,7 @@ int set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
 /*                                                            */
 /*=============================================================*/
 
-#ifndef HAVE_CYGWIN
+#if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
     
 /*
  * It is possible to piggyback additional data e.g. ACLs on
@@ -293,7 +407,7 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
 /*                                                            */
 /*=============================================================*/
 
-#ifdef HAVE_CYGWIN
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
 
 int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
 {
@@ -303,7 +417,7 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
 
    attribsEx[0] = 0;                 /* no extended attributes */
 
-   if (!p_GetFileAttributesEx) {
+   if (!p_GetFileAttributesEx) {                                
       return STREAM_UNIX_ATTRIBUTES;
    }
 
@@ -311,7 +425,7 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
    if (!p_GetFileAttributesEx(ff_pkt->sys_fname, GetFileExInfoStandard,
                            (LPVOID)&atts)) {
       win_error(jcr, "GetFileAttributesEx:", ff_pkt->sys_fname);
-      return STREAM_UNIX_ATTRIBUTES_EX;
+      return STREAM_UNIX_ATTRIBUTES;
    }
 
    p += to_base64((uint64_t)atts.dwFileAttributes, p);
@@ -356,8 +470,7 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
  * Returns:  1 on success
  *          0 on failure
  */
-static
-int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
+static int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
 {
    char *p = attr->attrEx;
    int64_t val;
@@ -365,6 +478,10 @@ int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    ULARGE_INTEGER li;
    POOLMEM *win32_ofile;
 
+   if (!p_GetFileAttributesEx) {                                
+      return 0;
+   }
+
    if (!p || !*p) {                  /* we should have attributes */
       Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid);
       if (is_bopen(ofd)) {
@@ -407,7 +524,6 @@ int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
 
    /* At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */
 
-
    if (!is_bopen(ofd)) {
       Dmsg1(100, "File not open: %s\n", attr->ofname);
       bopen(ofd, attr->ofname, O_WRONLY|O_BINARY, 0);  /* attempt to open the file */
@@ -448,7 +564,7 @@ void win_error(JCR *jcr, char *prefix, POOLMEM *win32_ofile)
                 NULL);
    Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, win32_ofile, msg);
    strip_trailing_junk(msg);
-   Jmsg(jcr, M_INFO, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
+   Jmsg(jcr, M_ERROR, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
    LocalFree(msg);
 }
 
@@ -465,7 +581,7 @@ void win_error(JCR *jcr, char *prefix, DWORD lerror)
                 NULL);
    strip_trailing_junk(msg);
    if (jcr) {
-      Jmsg2(jcr, M_INFO, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
+      Jmsg2(jcr, M_ERROR, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
    } else {
       MessageBox(NULL, msg, prefix, MB_OK);
    }