]> 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 dc645faef1189c0287d91cacbd2507c067ad225f..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 = NULL, 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;
@@ -664,6 +669,7 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
 
       /*
        * 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"),
@@ -673,10 +679,12 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
          goto bail_out;
       }
 
-      current_attrnamespace = bstrdup(current_attrnamespace);
-
       /*
        * 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) {
@@ -684,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());
@@ -731,7 +751,10 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
           * 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.
           */
-         cnt = MIN((sizeof(current_attrname) - 1), xattr_list[index]);
+         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';
 
@@ -862,7 +885,8 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
       /*
        * Drop the local copy of the current_attrnamespace.
        */
-      bfree_and_null(current_attrnamespace);
+      actuallyfree(current_attrnamespace);
+      current_attrnamespace = NULL;
 
       /*
        * We are done with this xattr list.
@@ -901,13 +925,14 @@ static bxattr_exit_code bsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
    }
 
 bail_out:
-   if (current_attrnamespace) {
-      free(current_attrnamespace);
+   if (current_attrnamespace != NULL) {
+      actuallyfree(current_attrnamespace);
+      current_attrnamespace = NULL;
    }
-   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);
       xattr_value_list = NULL;
    }
@@ -960,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;
@@ -1087,7 +1112,7 @@ static bxattr_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = bsd_pa
 #endif
 
 #if !defined(HAVE_OPENAT) || \
-    !defined(HAVE_UNKINKAT) || \
+    !defined(HAVE_UNLINKAT) || \
     !defined(HAVE_FCHOWNAT) || \
     !defined(HAVE_FUTIMESAT)
 #error "Unable to compile code because of missing openat, unlinkat, fchownat or futimesat function"
@@ -1364,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;
 
@@ -1636,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) {