]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/findlib/attribs.c
kes Apply doc fix from bug #1062.
[bacula/bacula] / bacula / src / findlib / attribs.c
old mode 100755 (executable)
new mode 100644 (file)
index 3e4f7cd..2869444
@@ -1,3 +1,30 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 /*
  *  Encode and decode standard Unix attributes and
  *   Extended attributes for Win32 and
  *   Version $Id$
  *
  */
-/*
-   Copyright (C) 2000-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
-   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 
-   the file LICENSE for additional details.
-
- */
 
 #include "bacula.h"
 #include "find.h"
 
-#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
-
-#include "../lib/winapi.h"
+static uid_t my_uid = 1;
+static gid_t my_gid = 1;                        
+static bool uid_set = false;
 
 
+#if defined(HAVE_WIN32)
 /* Forward referenced subroutines */
 static bool 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);
-#endif
+#endif /* HAVE_WIN32 */
 
 /* For old systems that don't have lchown() use chown() */
 #ifndef HAVE_LCHOWN
@@ -104,7 +118,7 @@ int select_data_stream(FF_PKT *ff_pkt)
       default:
          /* All stream types that do not support gzip should clear out
           * FO_GZIP above, and this code block should be unreachable. */
-         ASSERT(!ff_pkt->flags & FO_GZIP);
+         ASSERT(!(ff_pkt->flags & FO_GZIP));
          return STREAM_NONE;
       }
    }
@@ -127,7 +141,7 @@ int select_data_stream(FF_PKT *ff_pkt)
       default:
          /* All stream types that do not support encryption should clear out
           * FO_ENCRYPT above, and this code block should be unreachable. */
-         ASSERT(!ff_pkt->flags & FO_ENCRYPT);
+         ASSERT(!(ff_pkt->flags & FO_ENCRYPT));
          return STREAM_NONE;
       }
    }
@@ -206,11 +220,17 @@ void encode_stat(char *buf, FF_PKT *ff_pkt, int data_stream)
 
 
 /* Do casting according to unknown type to keep compiler happy */
-#if !HAVE_GCC & HAVE_SUN_OS
-#define plug(st, val) st = val        /* brain damaged compiler */
+#ifdef HAVE_TYPEOF
+  #define plug(st, val) st = (typeof st)val
 #else
-template <class T> void plug(T &st, uint64_t val)
-    { st = static_cast<T>(val); }
+  #if !HAVE_GCC & HAVE_SUN_OS
+    /* Sun compiler does not handle templates correctly */
+    #define plug(st, val) st = val
+  #else
+    /* Use templates to do the casting */
+    template <class T> void plug(T &st, uint64_t val)
+      { st = static_cast<T>(val); }
+  #endif
 #endif
 
 
@@ -355,9 +375,15 @@ bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    struct utimbuf ut;
    mode_t old_mask;
    bool ok = true;
-   off_t fsize;
+   boffset_t fsize;
+   if (uid_set) {
+      my_uid = getuid();
+      my_gid = getgid();
+      uid_set = true;
+   }
 
-#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
+#if defined(HAVE_WIN32)
    if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
        set_win32_attributes(jcr, attr, ofd)) {
        if (is_bopen(ofd)) {
@@ -388,13 +414,22 @@ bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
       char ec1[50], ec2[50];
       fsize = blseek(ofd, 0, SEEK_END);
       bclose(ofd);                    /* first close file */
-      if (fsize > 0 && fsize != (off_t)attr->statp.st_size) {
+      if (attr->type == FT_REG && fsize > 0 && attr->statp.st_size > 0 && 
+                        fsize != (boffset_t)attr->statp.st_size) {
          Jmsg3(jcr, M_ERROR, 0, _("File size of restored file %s not correct. Original %s, restored %s.\n"),
             attr->ofname, edit_uint64(attr->statp.st_size, ec1),
             edit_uint64(fsize, ec2));
       }
    }
 
+   /*
+    * We do not restore sockets, so skip trying to restore their
+    *   attributes.
+    */
+   if (attr->type == FT_SPEC && S_ISSOCK(attr->statp.st_mode)) {
+      goto bail_out;
+   }
+
    ut.actime = attr->statp.st_atime;
    ut.modtime = attr->statp.st_mtime;
 
@@ -405,33 +440,33 @@ bool 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) {
+      if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && my_uid == 0) {
          berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
-            attr->ofname, be.strerror());
+            attr->ofname, be.bstrerror());
          ok = false;
       }
    } else {
-      if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
+      if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && my_uid == 0) {
          berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
-            attr->ofname, be.strerror());
+            attr->ofname, be.bstrerror());
          ok = false;
       }
-      if (chmod(attr->ofname, attr->statp.st_mode) < 0) {
+      if (chmod(attr->ofname, attr->statp.st_mode) < 0 && my_uid == 0) {
          berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"),
-            attr->ofname, be.strerror());
+            attr->ofname, be.bstrerror());
          ok = false;
       }
 
       /*
        * Reset file times.
        */
-      if (utime(attr->ofname, &ut) < 0) {
+      if (utime(attr->ofname, &ut) < 0 && my_uid == 0) {
          berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"),
-            attr->ofname, be.strerror());
+            attr->ofname, be.bstrerror());
          ok = false;
       }
 #ifdef HAVE_CHFLAGS
@@ -442,14 +477,16 @@ bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
        *  but if the immutable bit is set, it will make the utimes()
        *  fail.
        */
-      if (chflags(attr->ofname, attr->statp.st_flags) < 0) {
+      if (chflags(attr->ofname, attr->statp.st_flags) < 0 && my_uid == 0) {
          berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file flags %s: ERR=%s\n"),
-            attr->ofname, be.strerror());
+            attr->ofname, be.bstrerror());
          ok = false;
       }
 #endif
    }
+
+bail_out:
    pm_strcpy(attr->ofname, "*none*");
    umask(old_mask);
    return ok;
@@ -462,7 +499,7 @@ bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
 /*                                                             */
 /*=============================================================*/
 
-#if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
+#if !defined(HAVE_WIN32)
 
 /*
  * It is possible to piggyback additional data e.g. ACLs on
@@ -502,7 +539,7 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
 /*                                                             */
 /*=============================================================*/
 
-#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
+#if defined(HAVE_WIN32)
 
 int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
 {
@@ -512,12 +549,12 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
 
    attribsEx[0] = 0;                  /* no extended attributes */
 
+   unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname);
+
    // try unicode version
    if (p_GetFileAttributesExW)  {
-      unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname);
-
       POOLMEM* pwszBuf = get_pool_memory (PM_FNAME);   
-      UTF8_2_wchar(&pwszBuf, ff_pkt->sys_fname);
+      make_win32_path_UTF8_2_wchar(&pwszBuf, ff_pkt->fname);
 
       BOOL b=p_GetFileAttributesExW((LPCWSTR) pwszBuf, GetFileExInfoStandard, (LPVOID)&atts);
       free_pool_memory(pwszBuf);
@@ -529,9 +566,7 @@ int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
    }
    else {
       if (!p_GetFileAttributesExA)
-         return STREAM_UNIX_ATTRIBUTES;
-
-      unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname);
+         return STREAM_UNIX_ATTRIBUTES;      
 
       if (!p_GetFileAttributesExA(ff_pkt->sys_fname, GetFileExInfoStandard,
                               (LPVOID)&atts)) {
@@ -591,8 +626,9 @@ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    POOLMEM *win32_ofile;
 
    // if we have neither ansi nor wchar version, we leave
-   if (!(p_SetFileAttributesW || p_SetFileAttributesA))
+   if (!(p_SetFileAttributesW || p_SetFileAttributesA)) {
       return false;
+   }
 
    if (!p || !*p) {                   /* we should have attributes */
       Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid);
@@ -632,8 +668,6 @@ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    win32_ofile = get_pool_memory(PM_FNAME);
    unix_name_to_win32(&win32_ofile, attr->ofname);
 
-
-
    /* At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */
 
    if (!is_bopen(ofd)) {
@@ -653,11 +687,10 @@ static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    }
 
    Dmsg1(100, "SetFileAtts %s\n", attr->ofname);
-   if (!(atts.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
-   {
+   if (!(atts.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
       if (p_SetFileAttributesW) {
-         POOLMEM* pwszBuf = get_pool_memory (PM_FNAME);   
-         UTF8_2_wchar(&pwszBuf, win32_ofile);
+         POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);   
+         make_win32_path_UTF8_2_wchar(&pwszBuf, attr->ofname);
 
          BOOL b=p_SetFileAttributesW((LPCWSTR)pwszBuf, atts.dwFileAttributes & SET_ATTRS);
          free_pool_memory(pwszBuf);
@@ -712,17 +745,4 @@ void win_error(JCR *jcr, char *prefix, DWORD lerror)
    }
    LocalFree(msg);
 }
-
-
-/* Conversion of a Unix filename to a Win32 filename */
-extern void conv_unix_to_win32_path(const char *path, char *win32_path, DWORD dwSize);
-void unix_name_to_win32(POOLMEM **win32_name, char *name)
-{
-   /* One extra byte should suffice, but we double it */
-   /* add MAX_PATH bytes for VSS shadow copy name */
-   DWORD dwSize = 2*strlen(name)+MAX_PATH;
-   *win32_name = check_pool_memory_size(*win32_name, dwSize);
-   conv_unix_to_win32_path(name, *win32_name, dwSize);
-}
-
-#endif  /* HAVE_CYGWIN */
+#endif  /* HAVE_WIN32 */