]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/xattr.c
Tweak add bstrerror output if snapshot fails
[bacula/bacula] / bacula / src / filed / xattr.c
index cf5a452f4318d5f6bcfedd9d45c88ccd16a91db1..a3e9410ffa164f9d7e847ddf526cb8d770d92094 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2008-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2008-2010 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.
@@ -145,6 +145,8 @@ static void xattr_drop_internal_table(alist *xattr_value_list)
 
       if (current_xattr->value_length > 0)
          free(current_xattr->value);
+
+      free(current_xattr);
    }
 
    delete xattr_value_list;
@@ -386,6 +388,7 @@ static bxattr_exit_code linux_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
     */
    bp = xattr_list;
    while ((bp - xattr_list) + 1 < xattr_list_len) {
+      int name_len;
       skip_xattr = false;
 
       /*
@@ -414,7 +417,8 @@ static bxattr_exit_code linux_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
          }
       }
 
-      if (skip_xattr) {
+      name_len = strlen(bp);
+      if (skip_xattr || name_len == 0) {
          bp = strchr(bp, '\0') + 1;
          continue;
       }
@@ -429,7 +433,7 @@ static bxattr_exit_code linux_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
       /*
        * Allocate space for storing the name.
        */
-      current_xattr->name_length = strlen(bp);
+      current_xattr->name_length = name_len;
       current_xattr->name = (char *)malloc(current_xattr->name_length);
       memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length);
 
@@ -538,10 +542,10 @@ static bxattr_exit_code linux_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt)
    }
 
 bail_out:
-   if (xattr_list) {
+   if (xattr_list != NULL) {
       free(xattr_list);
    }
-   if (xattr_value_list) {
+   if (xattr_value_list != NULL) {
       xattr_drop_internal_table(xattr_value_list);
    }
    return retval;
@@ -648,7 +652,8 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
    uint32_t expected_serialize_len = 0;
    unsigned int namespace_index;
    int attrnamespace;
-   char *current_attrnamespace, current_attrname[BUFSIZ], current_attrtuple[BUFSIZ];
+   char *current_attrnamespace = NULL;
+   char current_attrname[XATTR_BUFSIZ], current_attrtuple[XATTR_BUFSIZ];
    xattr_t *current_xattr;
    alist *xattr_value_list = NULL;
    bxattr_exit_code retval = bxattr_exit_error;
@@ -662,8 +667,24 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
    for (namespace_index = 0; namespace_index < sizeof(os_default_xattr_namespaces) / sizeof(int); namespace_index++) {
       attrnamespace = os_default_xattr_namespaces[namespace_index];
 
+      /*
+       * Convert the numeric attrnamespace into a string representation and make a private copy of that string.
+       * The extattr_namespace_to_string functions returns a strdupped string which we need to free.
+       */
+      if (extattr_namespace_to_string(attrnamespace, &current_attrnamespace) != 0) {
+         Mmsg2(jcr->errmsg, _("Failed to convert %d into namespace on file \"%s\"\n"),
+               attrnamespace, jcr->last_fname);
+         Dmsg2(100, "Failed to convert %d into namespace on file \"%s\"\n",
+               attrnamespace, jcr->last_fname);
+         goto bail_out;
+      }
+
       /*
        * First get the length of the available list with extended attributes.
+       * If we get EPERM on system namespace, don't return error.
+       * This is expected for normal users trying to archive the system
+       * namespace on FreeBSD 6.2 and later. On NetBSD 3.1 and later,
+       * they've decided to return EOPNOTSUPP instead.
        */
       xattr_list_len = extattr_list_link(jcr->last_fname, attrnamespace, NULL, 0);
       if (xattr_list_len < 0) {
@@ -671,6 +692,18 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
          case ENOENT:
             retval = bxattr_exit_ok;
             goto bail_out;
+#if defined(EOPNOTSUPP)
+         case EOPNOTSUPP:
+#endif
+         case EPERM:
+            if (attrnamespace == EXTATTR_NAMESPACE_SYSTEM) {
+               actuallyfree(current_attrnamespace);
+               current_attrnamespace = NULL;
+               continue;
+            }
+            /*
+             * FALLTHROUGH
+             */
          default:
             Mmsg2(jcr->errmsg, _("extattr_list_link error on file \"%s\": ERR=%s\n"),
                   jcr->last_fname, be.bstrerror());
@@ -715,27 +748,20 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
          skip_xattr = false;
 
          /*
-          * print the current name into the buffer as its not null terminated we need to
+          * Print the current name into the buffer as its not null terminated we need to
           * use the length encoded in the string for copying only the needed bytes.
           */
-         bsnprintf(current_attrname, sizeof(current_attrname), "%*.*s",
-                   xattr_list[index], xattr_list[index], xattr_list + (index + 1));
+         cnt = xattr_list[index];
+         if (cnt > ((int)sizeof(current_attrname) - 1)) {
+            cnt = ((int)sizeof(current_attrname) - 1);
+         }
+         strncpy(current_attrname, xattr_list + (index + 1), cnt);
+         current_attrname[cnt] = '\0';
 
          /*
           * First make a xattr tuple of the current namespace and the name of the xattr.
           * e.g. something like user.<attrname> or system.<attrname>
           */
-         if (extattr_namespace_to_string(attrnamespace, &current_attrnamespace) != 0) {
-            Mmsg2(jcr->errmsg, _("Failed to convert %d into namespace on file \"%s\"\n"),
-                  attrnamespace, jcr->last_fname);
-            Dmsg2(100, "Failed to convert %d into namespace on file \"%s\"\n",
-                  attrnamespace, jcr->last_fname);
-            goto bail_out;
-         }
-
-         /*
-          * Create a tupple of the current attrnamespace and attrname.
-          */
          bsnprintf(current_attrtuple, sizeof(current_attrtuple), "%s.%s", current_attrnamespace, current_attrname);
 
          /*
@@ -853,8 +879,15 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
 
          xattr_value_list->append(current_xattr);
          xattr_count++;
+
       }
 
+      /*
+       * Drop the local copy of the current_attrnamespace.
+       */
+      actuallyfree(current_attrnamespace);
+      current_attrnamespace = NULL;
+
       /*
        * We are done with this xattr list.
        */
@@ -892,10 +925,14 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
    }
 
 bail_out:
-   if (xattr_list) {
+   if (current_attrnamespace != NULL) {
+      actuallyfree(current_attrnamespace);
+      current_attrnamespace = NULL;
+   }
+   if (xattr_list != NULL) {
       free(xattr_list);
    }
-   if (xattr_value_list) {
+   if (xattr_value_list != NULL) {
       xattr_drop_internal_table(xattr_value_list);
       xattr_value_list = NULL;
    }
@@ -948,7 +985,7 @@ static bxattr_exit_code bsd_parse_xattr_streams(JCR *jcr, int stream)
        */
       cnt = extattr_set_link(jcr->last_fname, current_attrnamespace,
                              attrname, current_xattr->value, current_xattr->value_length);
-      if (cnt < 0 || cnt != current_xattr->value_length) {
+      if (cnt < 0 || cnt != (int)current_xattr->value_length) {
          switch (errno) {
          case ENOENT:
             goto bail_out;
@@ -1074,9 +1111,9 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = bsd_pa
 #include <sys/acl.h>
 #endif
 
-#if !defined(HAVE_OPENAT) ||
-    !defined(HAVE_UNKINKAT) ||
-    !defined(HAVE_FCHOWNAT) ||
+#if !defined(HAVE_OPENAT) || \
+    !defined(HAVE_UNLINKAT) || \
+    !defined(HAVE_FCHOWNAT) || \
     !defined(HAVE_FUTIMESAT)
 #error "Unable to compile code because of missing openat, unlinkat, fchownat or futimesat function"
 #endif
@@ -1352,7 +1389,7 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
    char link_source[PATH_MAX];
    char *acl_text = NULL;
    char attribs[MAXSTRING];
-   char buffer[BUFSIZ];
+   char buffer[XATTR_BUFSIZ];
    bxattr_exit_code retval = bxattr_exit_error;
    berrno be;
 
@@ -1624,7 +1661,7 @@ static bxattr_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_n
    }
 
 bail_out:
-   if (acl_text) {
+   if (acl_text != NULL) {
       free(acl_text);
    }
    if (attrfd != -1) {