]> git.sur5r.net Git - bacula/bacula/commitdiff
Imported patch from older git tree.
authorMarco van Wieringen <mvw@planets.elm.net>
Thu, 16 Jul 2009 05:42:21 +0000 (07:42 +0200)
committerMarco van Wieringen <mvw@planets.elm.net>
Sun, 9 Aug 2009 11:25:47 +0000 (13:25 +0200)
bacula/src/filed/acl.c
bacula/src/filed/backup.c
bacula/src/filed/filed.h
bacula/src/filed/protos.h
bacula/src/filed/restore.c
bacula/src/filed/xattr.c
bacula/src/filed/xattr.h

index feae14bc7b3070e985f958ba749b5f0b7e4baa9f..79fdbd6d57a268c48fae160853396953483c7718 100644 (file)
@@ -44,9 +44,6 @@
  * Its also interesting to see what the exact format of acl text is on
  * certain platforms and if they use they same encoding we might allow
  * different platform streams to be decoded on an other similar platform.
- * As we implement the decoding/restoring process as a big switch based
- * on the stream number being passed in extending the switching code is
- * easy.
  *
  *   Original written by Preben 'Peppe' Guldberg, December MMIV
  *   Major rewrite by Marco van Wieringen, November MMVIII
   
 #include "bacula.h"
 #include "filed.h"
+#include "acl.h"
   
 #if !defined(HAVE_ACL)
 /*
  * Entry points when compiled without support for ACLs or on an unsupported platform.
  */
-bool build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+bsub_exit_code build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   return false;
+   return bsub_exit_fatal;
 }
 
-bool parse_acl_stream(JCR *jcr, int stream)
+bsub_exit_code parse_acl_stream(JCR *jcr, int stream)
 {
-   return false;
+   return bsub_exit_fatal;
 }
 #else
 /*
  * Send an ACL stream to the SD.
  */
-static bool send_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code send_acl_stream(JCR *jcr, int stream)
 {
    BSOCK *sd = jcr->store_bsock;
    POOLMEM *msgsave;
 #ifdef FD_NO_SEND_TEST
-   return true;
+   return bsub_exit_ok;
 #endif
 
    /*
     * Sanity check
     */
    if (jcr->acl_data_len <= 0)
-      return true;
+      return bsub_exit_ok;
 
    /*
     * Send header
@@ -94,8 +92,7 @@ static bool send_acl_stream(JCR *jcr, int stream)
    if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
-
-      return false;
+      return bsub_exit_fatal;
    }
 
    /*
@@ -110,8 +107,7 @@ static bool send_acl_stream(JCR *jcr, int stream)
       sd->msglen = 0;
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
-
-      return false;
+      return bsub_exit_fatal;
    }
 
    jcr->JobBytes += sd->msglen;
@@ -119,42 +115,49 @@ static bool send_acl_stream(JCR *jcr, int stream)
    if (!sd->signal(BNET_EOD)) {
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
-
-      return false;
+      return bsub_exit_fatal;
    }
 
    Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
-
-   return true;
+   return bsub_exit_ok;
 }
 
 #if defined(HAVE_AIX_OS)
 
 #include <sys/access.h>
 
-static bool aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+/*
+ * Define the supported ACL streams for this OS
+ */
+static int os_access_acl_streams[1] = { STREAM_ACL_AIX_TEXT };
+static int os_default_acl_streams[1] = { -1 };
+
+static bsub_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    char *acl_text;
 
    if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
       jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
       actuallyfree(acl_text);
-
       return send_acl_stream(jcr, STREAM_ACL_AIX_TEXT);
    }
-
-   return false;
+   return bsub_exit_nok;
 }
 
-static bool aix_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code aix_parse_acl_streams(JCR *jcr, int stream)
 {
    if (acl_put(jcr->last_fname, jcr->acl_data, 0) != 0) {
-      return false;
+      return bsub_exit_nok;
    }
-
-   return true;
+   return bsub_exit_ok;
 }
 
+/*
+ * For this OS setup the build and parse function pointer to the OS specific functions.
+ */
+static bsub_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = aix_build_acl_streams;
+static bsub_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = aix_parse_acl_streams;
+
 #elif defined(HAVE_DARWIN_OS) \
    || defined(HAVE_FREEBSD_OS) \
    || defined(HAVE_IRIX_OS) \
@@ -222,13 +225,12 @@ static acl_type_t bac_to_os_acltype(bacl_type acltype)
 #endif
    default:
       /*
-       * This should never happen, as the per os version function only tries acl
+       * This should never happen, as the per OS version function only tries acl
        * types supported on a certain platform.
        */
       ostype = (acl_type_t)ACL_TYPE_NONE;
       break;
    }
-
    return ostype;
 }
 
@@ -257,8 +259,7 @@ static bool acl_is_trivial(acl_t acl)
        * If we fail to get the tagtype we call the acl non-trivial.
        */
       if (acl_get_tag_type(ace, &tag) < 0)
-         return false;
-
+         return true;
       /*
        * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell.
        */
@@ -266,10 +267,8 @@ static bool acl_is_trivial(acl_t acl)
           tag != ACL_GROUP_OBJ &&
           tag != ACL_OTHER)
          return false;
-
       entry_available = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
    }
-
    return true;
 #elif defined(HAVE_IRIX_OS)
    int n;
@@ -286,7 +285,6 @@ static bool acl_is_trivial(acl_t acl)
           tag != ACL_OTHER_OBJ)
          return false;
    }
-
    return true;
 #elif defined(HAVE_OSF1_OS)
    int count;
@@ -296,7 +294,6 @@ static bool acl_is_trivial(acl_t acl)
 
    while (count > 0) {
       tag = ace->entry->acl_type;
-
       /*
        * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell.
        */
@@ -304,18 +301,15 @@ static bool acl_is_trivial(acl_t acl)
           tag != ACL_GROUP_OBJ &&
           tag != ACL_OTHER)
          return false;
-
       /*
        * On Tru64, perm can also contain non-standard bits such as
        * PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ...
        */
       if ((ace->entry->acl_perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)))
          return false;
-
       ace = ace->next;
       count--;
    }
-
    return true;
 #endif
 }
@@ -324,10 +318,9 @@ static bool acl_is_trivial(acl_t acl)
 /*
  * Generic wrapper around acl_get_file call.
  */
-static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
+static bsub_exit_code generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
 {
    acl_t acl;
-   int len;
    acl_type_t ostype;
    char *acl_text;
 
@@ -349,8 +342,9 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
        */
       if (acl->acl_cnt <= 0) {
          pm_strcpy(jcr->acl_data, "");
+         jcr->acl_data_len = 0;
          acl_free(acl);
-         return 0;
+         return bsub_exit_ok;
       }
 #endif
 
@@ -364,17 +358,17 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
           * So we don't send an ACL stream to the SD.
           */
          pm_strcpy(jcr->acl_data, "");
+         jcr->acl_data_len = 0;
          acl_free(acl);
-         return 0;
+         return bsub_exit_ok;
       }
 #endif
 
       if ((acl_text = acl_to_text(acl, NULL)) != NULL) {
-         len = pm_strcpy(jcr->acl_data, acl_text);
+         jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
          acl_free(acl);
          acl_free(acl_text);
-
-         return len;
+         return bsub_exit_ok;
       }
 
       berrno be;
@@ -384,9 +378,9 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
          jcr->last_fname, be.bstrerror());
 
       pm_strcpy(jcr->acl_data, "");
+      jcr->acl_data_len = 0;
       acl_free(acl);
-
-      return 0;                       /* non-fatal error */
+      return bsub_exit_nok;
    }
 
    /*
@@ -398,6 +392,10 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
       case BACL_ENOTSUP:
          break;                       /* not supported */
 #endif
+      case ENOENT:
+         pm_strcpy(jcr->acl_data, "");
+         jcr->acl_data_len = 0;
+         return bsub_exit_ok;
       default:
          berrno be;
          /* Some real error */
@@ -407,20 +405,22 @@ static int generic_get_acl_from_os(JCR *jcr, bacl_type acltype)
             jcr->last_fname, be.bstrerror());
 
          pm_strcpy(jcr->acl_data, "");
-         return 0;                    /* non-fatal error */
+         jcr->acl_data_len = 0;
+         return bsub_exit_nok;
       }
    }
    /*
     * Not supported, just pretend there is nothing to see
     */
    pm_strcpy(jcr->acl_data, "");
-   return 0;
+   jcr->acl_data_len = 0;
+   return bsub_exit_ok;
 }
 
 /*
  * Generic wrapper around acl_set_file call.
  */
-static bool generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
+static bsub_exit_code generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
 {
    acl_t acl;
    acl_type_t ostype;
@@ -431,13 +431,17 @@ static bool generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
    ostype = bac_to_os_acltype(acltype);
    if (ostype == ACL_TYPE_DEFAULT && strlen(jcr->acl_data) == 0) {
       if (acl_delete_def_file(jcr->last_fname) == 0) {
-         return true;
+         return bsub_exit_ok;
+      }
+      switch (errno) {
+      case ENOENT:
+         return bsub_exit_ok;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("acl_delete_def_file error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         return bsub_exit_nok;
       }
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("acl_delete_def_file error on file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-
-      return false;
    }
 
    acl = acl_from_text(jcr->acl_data);
@@ -447,15 +451,14 @@ static bool generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
          jcr->last_fname, be.bstrerror());
       Dmsg3(100, "acl_from_text error acl=%s file=%s ERR=%s\n",  
          jcr->acl_data, jcr->last_fname, be.bstrerror());
-
-      return false;
+      return bsub_exit_nok;
    }
 
+#ifndef HAVE_FREEBSD_OS
    /*
     * FreeBSD always fails acl_valid() - at least on valid input...
     * As it does the right thing, given valid input, just ignore acl_valid().
     */
-#ifndef HAVE_FREEBSD_OS
    if (acl_valid(acl) != 0) {
       berrno be;
       Jmsg2(jcr, M_ERROR, 0, _("ac_valid error on file \"%s\": ERR=%s\n"),
@@ -463,8 +466,7 @@ static bool generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
       Dmsg3(100, "acl_valid error acl=%s file=%s ERR=%s\n",  
          jcr->acl_data, jcr->last_fname, be.bstrerror());
       acl_free(acl);
-
-      return false;
+      return bsub_exit_nok;
    }
 #endif
 
@@ -475,25 +477,35 @@ static bool generic_set_acl_on_os(JCR *jcr, bacl_type acltype)
     * don't save acls of symlinks (which cannot have acls anyhow)
     */
    if (acl_set_file(jcr->last_fname, ostype, acl) != 0 && jcr->last_type != FT_LNK) {
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("acl_set_file error on file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-      Dmsg3(100, "acl_set_file error acl=%s file=%s ERR=%s\n",  
-         jcr->acl_data, jcr->last_fname, be.bstrerror());
-      acl_free(acl);
-
-      return false;
+      switch (errno) {
+      case ENOENT:
+         acl_free(acl);
+         return bsub_exit_nok;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("acl_set_file error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg3(100, "acl_set_file error acl=%s file=%s ERR=%s\n",
+            jcr->acl_data, jcr->last_fname, be.bstrerror());
+         acl_free(acl);
+         return bsub_exit_nok;
+      }
    }
    acl_free(acl);
-
-   return true;
+   return bsub_exit_ok;
 }
 
 /*
  * OS specific functions for handling different types of acl streams.
  */
 #if defined(HAVE_DARWIN_OS)
-static bool darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+/*
+ * Define the supported ACL streams for this OS
+ */
+static int os_access_acl_streams[1] = { STREAM_ACL_DARWIN_ACCESS_ACL };
+static int os_default_acl_streams[1] = { -1 };
+
+static bsub_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
 #if defined(ACL_TYPE_EXTENDED)
    /*
@@ -505,189 +517,143 @@ static bool darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
     *
     * Read access ACLs for files, dirs and links
     */
-   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_EXTENDED)) < 0)
-      return false;
+   if (generic_get_acl_from_os(jcr, BACL_TYPE_EXTENDED) == bsub_exit_fatal)
+      return bsub_exit_fatal;
 #else
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
-      return false;
+   if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bsub_exit_fatal)
+      return bsub_exit_fatal;
 #endif
 
    if (jcr->acl_data_len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL))
-         return false;
+      return send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL);
    }
-
-   return true;
+   return bsub_exit_ok;
 }
 
-static bool darwin_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code darwin_parse_acl_streams(JCR *jcr, int stream)
 {
-   switch (stream) {
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_DARWIN_ACCESS_ACL:
+#if defined(ACL_TYPE_EXTENDED)
+      return generic_set_acl_on_os(jcr, BACL_TYPE_EXTENDED);
+#else
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
-   }
-
-   return false;
+#endif
 }
-#elif defined(HAVE_FREEBSD_OS)
-static bool freebsd_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   /*
-    * Read access ACLs for files, dirs and links
-    */
-   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
-      return false;
-
-   if (jcr->acl_data_len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_FREEBSD_ACCESS_ACL))
-         return false;
-   }
 
-   /*
-    * Directories can have default ACLs too
-    */
-   if (ff_pkt->type == FT_DIREND) {
-      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
-         return false;
-
-      if (jcr->acl_data_len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_FREEBSD_DEFAULT_ACL))
-            return false;
-      }
-   }
-
-   return true;
-}
+/*
+ * For this OS setup the build and parse function pointer to the OS specific functions.
+ */
+static bsub_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = darwin_build_acl_streams;
+static bsub_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = darwin_parse_acl_streams;
 
-static bool freebsd_parse_acl_stream(JCR *jcr, int stream)
-{
-   switch (stream) {
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_FREEBSD_ACCESS_ACL:
-      return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
-   case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_FREEBSD_DEFAULT_ACL:
-      return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
-   }
+#elif defined(HAVE_FREEBSD_OS) || defined(HAVE_IRIX_OS) || defined(HAVE_LINUX_OS)
 
-   return false;
-}
+/*
+ * Define the supported ACL streams for these OSes
+ */
+#if defined(HAVE_FREEBSD_OS)
+static int os_access_acl_streams[1] = { STREAM_ACL_FREEBSD_ACCESS_ACL };
+static int os_default_acl_streams[1] = { STREAM_ACL_FREEBSD_DEFAULT_ACL };
 #elif defined(HAVE_IRIX_OS)
-static bool irix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+static int os_access_acl_streams[1] = { STREAM_ACL_IRIX_ACCESS_ACL };
+static int os_default_acl_streams[1] = { STREAM_ACL_IRIX_DEFAULT_ACL };
+#elif defined(HAVE_LINUX_OS)
+static int os_access_acl_streams[1] = { STREAM_ACL_LINUX_ACCESS_ACL };
+static int os_default_acl_streams[1] = { STREAM_ACL_LINUX_DEFAULT_ACL };
+#endif
+
+static bsub_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    /*
     * Read access ACLs for files, dirs and links
     */
-   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
-      return false;
+   if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bsub_exit_fatal)
+      return bsub_exit_fatal;
 
    if (jcr->acl_data_len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_IRIX_ACCESS_ACL))
-         return false;
+      if (send_acl_stream(jcr, os_access_acl_streams[0]) == bsub_exit_fatal)
+         return bsub_exit_fatal;
    }
 
    /*
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
-      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
-         return false;
-
+      if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT) == bsub_exit_fatal)
+         return bsub_exit_fatal;
       if (jcr->acl_data_len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_IRIX_DEFAULT_ACL))
-            return false;
+         if (send_acl_stream(jcr, os_default_acl_streams[0]) == bsub_exit_fatal)
+            return bsub_exit_fatal;
       }
    }
-
-   return true;
+   return bsub_exit_ok;
 }
 
-static bool irix_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code generic_parse_acl_streams(JCR *jcr, int stream)
 {
+   int cnt;
+
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_IRIX_ACCESS_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_IRIX_DEFAULT_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
-   }
-
-   return false;
-}
-#elif defined(HAVE_LINUX_OS)
-static bool linux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   /*
-    * Read access ACLs for files, dirs and links
-    */
-   if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
-      return false;
-
-   if (jcr->acl_data_len > 0) {
-      if (!send_acl_stream(jcr, STREAM_ACL_LINUX_ACCESS_ACL))
-         return false;
-   }
-
-   /*
-    * Directories can have default ACLs too
-    */
-   if (ff_pkt->type == FT_DIREND) {
-      if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
-         return false;
-
-      if (jcr->acl_data_len > 0) {
-         if (!send_acl_stream(jcr, STREAM_ACL_LINUX_DEFAULT_ACL))
-            return false;
+   default:
+      /*
+       * See what type of acl it is.
+       */
+      for (cnt = 0; cnt < sizeof(os_access_acl_streams) / sizeof(int); cnt++) {
+         if (os_access_acl_streams[cnt] == stream) {
+            return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
+         }
+      }
+      for (cnt = 0; cnt < sizeof(os_default_acl_streams) / sizeof(int); cnt++) {
+         if (os_default_acl_streams[cnt] == stream) {
+            return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
+         }
       }
+      break;
    }
-
-   return true;
+   return bsub_exit_nok;
 }
 
-static bool linux_parse_acl_stream(JCR *jcr, int stream)
-{
-   switch (stream) {
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_LINUX_ACCESS_ACL:
-      return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
-   case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_LINUX_DEFAULT_ACL:
-      return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
-   }
+/*
+ * For this OSes setup the build and parse function pointer to the OS specific functions.
+ */
+static bsub_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = generic_build_acl_streams;
+static bsub_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = generic_parse_acl_streams;
 
-   return false;
-}
 #elif defined(HAVE_OSF1_OS)
-static bool tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+
+/*
+ * Define the supported ACL streams for this OS
+ */
+static int os_access_acl_streams[1] = { STREAM_ACL_TRU64_ACCESS_ACL };
+static int os_default_acl_streams[2] = { STREAM_ACL_TRU64_DEFAULT_ACL, STREAM_ACL_TRU64_DEFAULT_DIR_ACL };
+
+static bsub_exit_code tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    /*
     * Read access ACLs for files, dirs and links
     */
    if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS)) < 0)
-      return false;
-
+      return bsub_exit_nok;
    if (jcr->acl_data_len > 0) {
       if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL))
-         return false;
+         return bsub_exit_nok;
    }
-
    /*
     * Directories can have default ACLs too
     */
    if (ff_pkt->type == FT_DIREND) {
       if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT)) < 0)
-         return false;
-
+         return bsub_exit_nok;
       if (jcr->acl_data_len > 0) {
          if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL))
-            return false;
+            return bsub_exit_nok;
       }
-
       /*
        * Tru64 has next to BACL_TYPE_DEFAULT also BACL_TYPE_DEFAULT_DIR acls.
        * This is an inherited acl for all subdirs.
@@ -695,18 +661,16 @@ static bool tru64_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
        * Section 21.5 Default ACLs 
        */
       if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0)
-         return false;
-
+         return bsub_exit_nok;
       if (jcr->acl_data_len > 0) {
          if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL))
-            return false;
+            return bsub_exit_nok;
       }
    }
-
-   return true;
+   return bsub_exit_ok;
 }
 
-static bool tru64_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code tru64_parse_acl_streams(JCR *jcr, int stream)
 {
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
@@ -718,6 +682,13 @@ static bool tru64_parse_acl_stream(JCR *jcr, int stream)
    case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
       return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT_DIR);
 }
+
+/*
+ * For this OS setup the build and parse function pointer to the OS specific functions.
+ */
+static bsub_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = tru64_build_acl_streams;
+static bsub_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = tru64_parse_acl_streams;
+
 #endif
 
 #elif defined(HAVE_HPUX_OS)
@@ -729,6 +700,12 @@ static bool tru64_parse_acl_stream(JCR *jcr, int stream)
 
 #include <acllib.h>
 
+/*
+ * Define the supported ACL streams for this OS
+ */
+static int os_access_acl_streams[1] = { STREAM_ACL_HPUX_ACL_ENTRY };
+static int os_default_acl_streams[1] = { -1 };
+
 /*
  * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.)
  * There is no need to store those acls as we already store the stat bits too.
@@ -740,7 +717,6 @@ static bool acl_is_trivial(int count, struct acl_entry *entries, struct stat sb)
 
    for (n = 0; n < count; n++) {
       ace = entries[n];
-
       /*
        * See if this acl just is the stat mode in acl form.
        */
@@ -749,29 +725,33 @@ static bool acl_is_trivial(int count, struct acl_entry *entries, struct stat sb)
             (ace.uid == ACL_NSUSER && ace.gid == ACL_NSGROUP)))
          return false;
    }
-
    return true;
 }
 
 /*
  * OS specific functions for handling different types of acl streams.
  */
-static bool hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+static bsub_exit_code hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    int n;
    struct acl_entry acls[NACLENTRIES];
    char *acl_text;
 
    if ((n = getacl(jcr->last_fname, 0, acls)) < 0) {
-      switch(errno) {
+      switch (errno) {
 #if defined(BACL_ENOTSUP)
       case BACL_ENOTSUP:
          /*
           * Not supported, just pretend there is nothing to see
           */
          pm_strcpy(jcr->acl_data, "");
-         return true;
+         jcr->acl_data_len = 0;
+         return bsub_exit_ok;
 #endif
+      case ENOENT:
+         pm_strcpy(jcr->acl_data, "");
+         jcr->acl_data_len = 0;
+         return bsub_exit_ok;
       default:
          berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("getacl error on file \"%s\": ERR=%s\n"),
@@ -780,15 +760,15 @@ static bool hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
             jcr->last_fname, be.bstrerror());
 
          pm_strcpy(jcr->acl_data, "");
-         return false;
+         jcr->acl_data_len = 0;
+         return bsub_exit_nok;
       }
    }
-
    if (n == 0) {
       pm_strcpy(jcr->acl_data, "");
-      return true;
+      jcr->acl_data_len = 0;
+      return bsub_exit_ok;
    }
-
    if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
       if (acl_is_trivial(n, acls, ff_pkt->statp)) {
          /*
@@ -796,29 +776,26 @@ static bool hpux_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
           * So we don't send an ACL stream to the SD.
           */
          pm_strcpy(jcr->acl_data, "");
-         return true;
+         jcr->acl_data_len = 0;
+         return bsub_exit_ok;
       }
-
       if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
          jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
          actuallyfree(acl_text);
 
          return send_acl_stream(jcr, STREAM_ACL_HPUX_ACL_ENTRY);
       }
-
       berrno be;
       Jmsg2(jcr, M_ERROR, 0, _("acltostr error on file \"%s\": ERR=%s\n"),
          jcr->last_fname, be.bstrerror());
       Dmsg3(100, "acltostr error acl=%s file=%s ERR=%s\n",  
          jcr->acl_data, jcr->last_fname, be.bstrerror());
-
-      return false;
+      return bsub_exit_nok;
    }
-
-   return false;
+   return bsub_exit_nok;
 }
 
-static bool hpux_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code hpux_parse_acl_streams(JCR *jcr, int stream)
 {
    int n, stat;
    struct acl_entry acls[NACLENTRIES];
@@ -830,8 +807,7 @@ static bool hpux_parse_acl_stream(JCR *jcr, int stream)
          jcr->last_fname, be.bstrerror());
       Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n",  
          jcr->acl_data, jcr->last_fname, be.bstrerror());
-
-      return false;
+      return bsub_exit_nok;
    }
    if (strtoacl(jcr->acl_data, n, NACLENTRIES, acls, ACL_FILEOWNER, ACL_FILEGROUP) != n) {
       berrno be;
@@ -840,7 +816,7 @@ static bool hpux_parse_acl_stream(JCR *jcr, int stream)
       Dmsg3(100, "strtoacl error acl=%s file=%s ERR=%s\n",  
          jcr->acl_data, jcr->last_fname, be.bstrerror());
 
-      return false;
+      return bsub_exit_nok;
    }
    /*
     * Restore the ACLs, but don't complain about links which really should
@@ -849,18 +825,27 @@ static bool hpux_parse_acl_stream(JCR *jcr, int stream)
     * don't save acls of symlinks (which cannot have acls anyhow)
     */
    if (setacl(jcr->last_fname, n, acls) != 0 && jcr->last_type != FT_LNK) {
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("setacl error on file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-      Dmsg3(100, "setacl error acl=%s file=%s ERR=%s\n",  
-         jcr->acl_data, jcr->last_fname, be.bstrerror());
-
-      return false;
+      switch (errno) {
+      case ENOENT:
+         return bsub_exit_nok;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("setacl error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg3(100, "setacl error acl=%s file=%s ERR=%s\n",
+            jcr->acl_data, jcr->last_fname, be.bstrerror());
+         return bsub_exit_nok;
+      }
    }
-
-   return true;
+   return bsub_exit_ok;
 }
 
+/*
+ * For this OS setup the build and parse function pointer to the OS specific functions.
+ */
+static bsub_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = hpux_build_acl_streams;
+static bsub_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = hpux_parse_acl_streams;
+
 #elif defined(HAVE_SUN_OS)
 #ifdef HAVE_SYS_ACL_H
 #include <sys/acl.h>
@@ -876,7 +861,7 @@ static bool hpux_parse_acl_stream(JCR *jcr, int stream)
  * and versions of Solaris we need to expose some data to be able
  * to determine the type of acl used to stuff it into the correct
  * data stream. I know this is far from portable, but maybe the
- * propper interface is exposed later on and we can get ride of
+ * proper interface is exposed later on and we can get ride of
  * this kludge. Newer versions of Solaris include sys/acl_impl.h
  * which has implementation details of acls, if thats included we
  * don't have to define it ourself.
@@ -896,19 +881,24 @@ int acl_type(acl_t *);
 char *acl_strerror(int);
 }
 
+/*
+ * Define the supported ACL streams for this OS
+ */
+static int os_access_acl_streams[2] = { STREAM_ACL_SOLARIS_ACLENT, STREAM_ACL_SOLARIS_ACE };
+static int os_default_acl_streams[1] = { -1 };
+
 /*
  * As the new libsec interface with acl_totext and acl_fromtext also handles
  * the old format from acltotext we can use the new functions even
  * for acls retrieved and stored in the database with older fd versions. If the
  * new interface is not defined (Solaris 9 and older we fall back to the old code)
  */
-static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+static bsub_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    int acl_enabled, flags;
    acl_t *aclp;
    char *acl_text;
-   bool stream_status = false;
-   berrno be;
+   bsub_exit_code stream_status = bsub_exit_nok;
 
    /*
     * See if filesystem supports acls.
@@ -917,15 +907,15 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    switch (acl_enabled) {
    case 0:
       pm_strcpy(jcr->acl_data, "");
-
-      return true;
+      jcr->acl_data_len = 0;
+      return bsub_exit_ok;
    case -1:
+      berrno be;
       Jmsg2(jcr, M_ERROR, 0, _("pathconf error on file \"%s\": ERR=%s\n"),
          jcr->last_fname, be.bstrerror());
       Dmsg2(100, "pathconf error file=%s ERR=%s\n",  
          jcr->last_fname, be.bstrerror());
-
-      return false;
+      return bsub_exit_nok;
    default:
       break;
    }
@@ -938,8 +928,7 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
          jcr->last_fname, acl_strerror(errno));
       Dmsg2(100, "acl_get error file=%s ERR=%s\n",  
          jcr->last_fname, acl_strerror(errno));
-
-      return false;
+      return bsub_exit_nok;
    }
 
    if (!aclp) {
@@ -948,7 +937,8 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
        * So we don't send an ACL stream to the SD.
        */
       pm_strcpy(jcr->acl_data, "");
-      return true;
+      jcr->acl_data_len = 0;
+      return bsub_exit_ok;
    }
 
 #if defined(ACL_SID_FMT)
@@ -977,15 +967,13 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 
       acl_free(aclp);
    }
-
    return stream_status;
 }
 
-static bool solaris_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
 {
    acl_t *aclp;
    int acl_enabled, error;
-   berrno be;
 
    switch (stream) {
    case STREAM_UNIX_ACCESS_ACL:
@@ -999,15 +987,14 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
       case 0:
          Jmsg1(jcr, M_ERROR, 0, _("Trying to restore acl on file \"%s\" on filesystem without acl support\n"),
             jcr->last_fname);
-
-         return false;
+         return bsub_exit_nok;
       case -1:
+         berrno be;
          Jmsg2(jcr, M_ERROR, 0, _("pathconf error on file \"%s\": ERR=%s\n"),
             jcr->last_fname, be.bstrerror());
          Dmsg3(100, "pathconf error acl=%s file=%s ERR=%s\n",  
             jcr->acl_data, jcr->last_fname, be.bstrerror());
-
-         return false;
+         return bsub_exit_nok;
       default:
          /*
           * On a filesystem with ACL support make sure this particilar ACL type can be restored.
@@ -1020,7 +1007,7 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
             if ((acl_enabled & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED)) == 0) {
                Jmsg1(jcr, M_ERROR, 0, _("Trying to restore acl on file \"%s\" on filesystem without aclent acl support\n"),
                   jcr->last_fname);
-               return false;
+               return bsub_exit_nok;
             }
             break;
          case STREAM_ACL_SOLARIS_ACE:
@@ -1030,7 +1017,7 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
             if ((acl_enabled & _ACL_ACE_ENABLED) == 0) {
                Jmsg1(jcr, M_ERROR, 0, _("Trying to restore acl on file \"%s\" on filesystem without ace acl support\n"),
                   jcr->last_fname);
-               return false;
+               return bsub_exit_nok;
             }
             break;
          default:
@@ -1047,7 +1034,7 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
             jcr->last_fname, acl_strerror(error));
          Dmsg3(100, "acl_fromtext error acl=%s file=%s ERR=%s\n",  
             jcr->acl_data, jcr->last_fname, acl_strerror(error));
-         return false;
+         return bsub_exit_nok;
       }
 
       /*
@@ -1058,14 +1045,14 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
          if (acl_type(aclp) != ACLENT_T) {
             Jmsg1(jcr, M_ERROR, 0, _("wrong encoding of acl type in acl stream on file \"%s\"\n"),
                jcr->last_fname);
-            return false;
+            return bsub_exit_nok;
          }
          break;
       case STREAM_ACL_SOLARIS_ACE:
          if (acl_type(aclp) != ACE_T) {
             Jmsg1(jcr, M_ERROR, 0, _("wrong encoding of acl type in acl stream on file \"%s\"\n"),
                jcr->last_fname);
-            return false;
+            return bsub_exit_nok;
          }
          break;
       default:
@@ -1088,18 +1075,24 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
             jcr->acl_data, jcr->last_fname, acl_strerror(error));
 
          acl_free(aclp);
-         return false;
+         return bsub_exit_nok;
       }
 
       acl_free(aclp);
-      return true;
+      return bsub_exit_ok;
    default:
-      return false;
+      return bsub_exit_nok;
    } /* end switch (stream) */
 }
 
 #else /* HAVE_EXTENDED_ACL */
 
+/*
+ * Define the supported ACL streams for this OS
+ */
+static int os_access_acl_streams[2] = { STREAM_ACL_SOLARIS_ACLENT };
+static int os_default_acl_streams[1] = { -1 };
+
 /*
  * See if an acl is a trivial one (e.g. just the stat bits encoded as acl.)
  * There is no need to store those acls as we already store the stat bits too.
@@ -1118,14 +1111,13 @@ static bool acl_is_trivial(int count, aclent_t *entries)
             ace->a_type == CLASS_OBJ))
         return false;
    }
-
    return true;
 }
 
 /*
  * OS specific functions for handling different types of acl streams.
  */
-static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+static bsub_exit_code solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    int n;
    aclent_t *acls;
@@ -1133,7 +1125,7 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 
    n = acl(jcr->last_fname, GETACLCNT, 0, NULL);
    if (n < MIN_ACL_ENTRIES)
-      return false;
+      return bsub_exit_nok;
 
    acls = (aclent_t *)malloc(n * sizeof(aclent_t));
    if (acl(jcr->last_fname, GETACL, n, acls) == n) {
@@ -1144,14 +1136,14 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
           */
          free(acls);
          pm_strcpy(jcr->acl_data, "");
-         return true;
+         jcr->acl_data_len = 0;
+         return bsub_exit_ok;
       }
 
       if ((acl_text = acltotext(acls, n)) != NULL) {
          jcr->acl_data_len = pm_strcpy(jcr->acl_data, acl_text);
          actuallyfree(acl_text);
          free(acls);
-
          return send_acl_stream(jcr, STREAM_ACL_SOLARIS_ACLENT);
       }
 
@@ -1163,10 +1155,10 @@ static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
    }
 
    free(acls);
-   return false;
+   return bsub_exit_nok;
 }
 
-static bool solaris_parse_acl_stream(JCR *jcr, int stream)
+static bsub_exit_code solaris_parse_acl_streams(JCR *jcr, int stream)
 {
    int n;
    aclent_t *acls;
@@ -1178,8 +1170,7 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
          jcr->last_fname, be.bstrerror());
       Dmsg3(100, "aclfromtext error acl=%s file=%s ERR=%s\n",  
          jcr->acl_data, jcr->last_fname, be.bstrerror());
-
-      return false;
+      return bsub_exit_nok;
    }
 
    /*
@@ -1187,21 +1178,31 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
     * not have attributes, and the file it is linked to may not yet be restored.
     */
    if (acl(jcr->last_fname, SETACL, n, acls) == -1 && jcr->last_type != FT_LNK) {
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("acl(SETACL) error on file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-      Dmsg3(100, "acl(SETACL) error acl=%s file=%s ERR=%s\n",  
-         jcr->acl_data, jcr->last_fname, be.bstrerror());
-      actuallyfree(acls);
-
-      return false;
+      switch (errno) {
+      case ENOENT:
+         actuallyfree(acls);
+         return bsub_exit_nok;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("acl(SETACL) error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg3(100, "acl(SETACL) error acl=%s file=%s ERR=%s\n",
+            jcr->acl_data, jcr->last_fname, be.bstrerror());
+         actuallyfree(acls);
+         return bsub_exit_nok;
+      }
    }
-
    actuallyfree(acls);
-   return true;
+   return bsub_exit_ok;
 }
-
 #endif /* HAVE_EXTENDED_ACL */
+
+/*
+ * For this OS setup the build and parse function pointer to the OS specific functions.
+ */
+static bsub_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = solaris_build_acl_streams;
+static bsub_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = solaris_parse_acl_streams;
+
 #endif /* HAVE_SUN_OS */
 
 /*
@@ -1211,96 +1212,53 @@ static bool solaris_parse_acl_stream(JCR *jcr, int stream)
 /*
  * Read and send an ACL for the last encountered file.
  */
-bool build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+bsub_exit_code build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
    /*
-    * Call the appropriate function, the ifdefs make sure the proper code is compiled.
+    * Call the appropriate function.
     */
-#if defined(HAVE_AIX_OS)
-   return aix_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_DARWIN_OS)
-   return darwin_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_FREEBSD_OS)
-   return freebsd_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_HPUX_OS)
-   return hpux_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_IRIX_OS)
-   return irix_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_LINUX_OS)
-   return linux_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_OSF1_OS)
-   return tru64_build_acl_streams(jcr, ff_pkt);
-#elif defined(HAVE_SUN_OS)
-   return solaris_build_acl_streams(jcr, ff_pkt);
-#endif
+   if (os_build_acl_streams) {
+      return (*os_build_acl_streams)(jcr, ff_pkt);
+   }
+   return bsub_exit_nok;
 }
 
-bool parse_acl_stream(JCR *jcr, int stream)
+bsub_exit_code parse_acl_streams(JCR *jcr, int stream)
 {
-   /*
-    * Based on the stream being passed in dispatch to the right function
-    * for parsing and restoring a specific acl. The platform determines
-    * which streams are recognized and parsed and which are handled by
-    * the default case and ignored. The old STREAM_UNIX_ACCESS_ACL and
-    * STREAM_UNIX_DEFAULT_ACL is handled as a legacy stream by each function.
-    * As only one of the platform defines is true per compile we never end
-    * up with duplicate switch values.
-    */
    switch (stream) {
-#if defined(HAVE_AIX_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_AIX_TEXT:
-      return aix_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_DARWIN_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_DARWIN_ACCESS_ACL:
-      return darwin_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_FREEBSD_OS)
    case STREAM_UNIX_ACCESS_ACL:
    case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_FREEBSD_DEFAULT_ACL:
-   case STREAM_ACL_FREEBSD_ACCESS_ACL:
-      return freebsd_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_HPUX_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_HPUX_ACL_ENTRY:
-      return hpux_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_IRIX_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_IRIX_DEFAULT_ACL:
-   case STREAM_ACL_IRIX_ACCESS_ACL:
-      return irix_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_LINUX_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_LINUX_DEFAULT_ACL:
-   case STREAM_ACL_LINUX_ACCESS_ACL:
-      return linux_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_OSF1_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_UNIX_DEFAULT_ACL:
-   case STREAM_ACL_TRU64_DEFAULT_ACL:
-   case STREAM_ACL_TRU64_ACCESS_ACL:
-   case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
-      return tru64_parse_acl_stream(jcr, stream);
-#elif defined(HAVE_SUN_OS)
-   case STREAM_UNIX_ACCESS_ACL:
-   case STREAM_ACL_SOLARIS_ACLENT:
-#if defined(HAVE_EXTENDED_ACL)
-   case STREAM_ACL_SOLARIS_ACE:
-#endif
-      return solaris_parse_acl_stream(jcr, stream);
-#endif
-   default:
       /*
-       * Issue a warning and discard the message. But pretend the restore was ok.
+       * Handle legacy ACL streams.
        */
-      Qmsg2(jcr, M_WARNING, 0,
-         _("Can't restore ACLs of %s - incompatible acl stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;
-   } /* end switch (stream) */
+      if (os_parse_acl_streams) {
+         return (*os_parse_acl_streams)(jcr, stream);
+      }
+      break;
+   default:
+      if (os_parse_acl_streams) {
+         /*
+          * Walk the os_access_acl_streams array with the supported Access ACL streams for this OS.
+          */
+         for (cnt = 0; cnt < sizeof(os_access_acl_streams) / sizeof(int); cnt++) {
+            if (os_access_acl_streams[cnt] == stream) {
+               return (*os_parse_acl_streams)(jcr, stream);
+            }
+         }
+         /*
+          * Walk the os_default_acl_streams array with the supported Default ACL streams for this OS.
+          */
+         for (cnt = 0; cnt < sizeof(os_default_acl_streams) / sizeof(int); cnt++) {
+            if (os_default_acl_streams[cnt] == stream) {
+               return (*os_parse_acl_streams)(jcr, stream);
+            }
+         }
+      }
+      break;
+   }
+   Qmsg2(jcr, M_WARNING, 0,
+      _("Can't restore ACLs of %s - incompatible acl stream encountered - %d\n"),
+      jcr->last_fname, stream);
+   return bsub_exit_nok;
 }
 #endif
index f1818260c87c5dfe76d769e916b47ecce3482462..bdca4fac2d6c003c354ba546e30017e87609d7bf 100644 (file)
@@ -600,7 +600,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
     */
    if (have_acl) {
       if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
-         if (!build_acl_streams(jcr, ff_pkt))
+         if (build_acl_streams(jcr, ff_pkt) == bsub_exit_fatal)
             goto bail_out;
       }
    }
@@ -610,7 +610,7 @@ int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
     */
    if (have_xattr) {
       if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
-         if (!build_xattr_streams(jcr, ff_pkt))
+         if (build_xattr_streams(jcr, ff_pkt) == bsub_exit_fatal)
             goto bail_out;
       }
    }
index 3c3649be307f0c90a952f0af782dfcfdb9367076..eb2897256a4e7beb1cad4baad72039a7c1c37507 100644 (file)
@@ -40,7 +40,6 @@
 #include "fd_plugins.h"
 #include "findlib/find.h"
 #include "jcr.h"
-#include "acl.h"
 #include "protos.h"                   /* file daemon prototypes */
 #include "lib/runscript.h"
 #include "lib/breg.h"
@@ -51,3 +50,9 @@
 #endif
 
 extern CLIENT *me;                    /* "Global" Client resource */
+
+typedef enum {
+   bsub_exit_fatal = -1,
+   bsub_exit_nok = 0,
+   bsub_exit_ok = 1
+} bsub_exit_code;
index b5daaa8c1903a05a74e6c3d933d9864c409a7745..4a6d476e377dfe326332895e1b5687358e4eb3d5 100644 (file)
@@ -47,8 +47,8 @@ void start_dir_heartbeat(JCR *jcr);
 void stop_dir_heartbeat(JCR *jcr);
 
 /* From acl.c */
-bool build_acl_streams(JCR *jcr, FF_PKT *ff_pkt);
-bool parse_acl_stream(JCR *jcr, int stream);
+bsub_exit_code build_acl_streams(JCR *jcr, FF_PKT *ff_pkt);
+bsub_exit_code parse_acl_streams(JCR *jcr, int stream);
 
 /* from accurate.c */
 bool accurate_send_deleted_list(JCR *jcr);
@@ -62,5 +62,5 @@ void strip_path(FF_PKT *ff_pkt);
 void unstrip_path(FF_PKT *ff_pkt);
 
 /* from xattr.c */
-bool build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt);
-bool parse_xattr_stream(JCR *jcr, int stream);
+bsub_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt);
+bsub_exit_code parse_xattr_streams(JCR *jcr, int stream);
index e24abdf3f54a8aa30b43bd1470c5b4ab6d3ebd2a..4bbd5dbd14659d277e6bb4aa6a23157f1de135b5 100644 (file)
@@ -610,7 +610,7 @@ void do_restore(JCR *jcr)
          if (have_acl) {
             pm_memcpy(jcr->acl_data, sd->msg, sd->msglen);
             jcr->acl_data_len = sd->msglen;
-            if (!parse_acl_stream(jcr, rctx.stream)) {
+            if (parse_acl_streams(jcr, rctx.stream) != bsub_exit_ok) {
                Qmsg1(jcr, M_WARNING, 0, _("Can't restore ACLs of %s\n"), jcr->last_fname);
             }
          } else {
@@ -636,7 +636,7 @@ void do_restore(JCR *jcr)
          if (have_xattr) {
             pm_memcpy(jcr->xattr_data, sd->msg, sd->msglen);
             jcr->xattr_data_len = sd->msglen;
-            if (!parse_xattr_stream(jcr, rctx.stream)) {
+            if (parse_xattr_streams(jcr, rctx.stream) != bsub_exit_ok) {
                Qmsg1(jcr, M_WARNING, 0, _("Can't restore Extended Attributes of %s\n"), jcr->last_fname);
             }
          } else {
index 99f9bbb63b89b930f2df263a6d2fb6dd640c7eda..1bde9f8a1830755a5231a4645aeabf43d9520e2f 100644 (file)
 /*
  * Entry points when compiled without support for XATTRs or on an unsupported platform.
  */
-bool build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+bsub_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   return false;
+   return bsub_exit_fatal;
 }
 
-bool parse_xattr_stream(JCR *jcr, int stream)
+bsub_exit_code parse_xattr_streams(JCR *jcr, int stream)
 {
-   return false;
+   return bsub_exit_fatal;
 }
 #else
 /*
  * Send a XATTR stream to the SD.
  */
-static bool send_xattr_stream(JCR *jcr, int stream)
+static bsub_exit_code send_xattr_stream(JCR *jcr, int stream)
 {
    BSOCK *sd = jcr->store_bsock;
    POOLMEM *msgsave;
 #ifdef FD_NO_SEND_TEST
-   return true;
+   return bsub_exit_ok;
 #endif
 
    /*
     * Sanity check
     */
    if (jcr->xattr_data_len <= 0)
-      return true;
+      return bsub_exit_ok;
 
    /*
     * Send header
@@ -84,7 +84,7 @@ static bool send_xattr_stream(JCR *jcr, int stream)
    if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
-      return false;
+      return bsub_exit_fatal;
    }
 
    /*
@@ -99,7 +99,7 @@ static bool send_xattr_stream(JCR *jcr, int stream)
       sd->msglen = 0;
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
-      return false;
+      return bsub_exit_fatal;
    }
 
    jcr->JobBytes += sd->msglen;
@@ -107,11 +107,10 @@ static bool send_xattr_stream(JCR *jcr, int stream)
    if (!sd->signal(BNET_EOD)) {
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
             sd->bstrerror());
-      return false;
+      return bsub_exit_fatal;
    }
    Dmsg1(200, "XATTR of file: %s successfully backed up!\n", jcr->last_fname);
-
-   return true;
+   return bsub_exit_ok;
 }
 
 /*
@@ -226,11 +225,10 @@ static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len
 
    ser_end(jcr->xattr_data, expected_serialize_len + 10);
    jcr->xattr_data_len = ser_length(jcr->xattr_data);
-
    return jcr->xattr_data_len;
 }
 
-static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
+static bsub_exit_code generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int default_stream)
 {
    int count = 0;
    int32_t xattr_list_len,
@@ -244,14 +242,19 @@ static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
     */
    xattr_list_len = llistxattr(jcr->last_fname, NULL, 0);
    if (xattr_list_len < 0) {
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("llistxattr error on file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-      Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
-         jcr->last_fname, be.bstrerror());
-      return true;                       /* non-fatal return */
+      switch (errno) {
+      case ENOENT:
+         return bsub_exit_nok;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("llistxattr error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
+            jcr->last_fname, be.bstrerror());
+         return bsub_exit_nok;
+      }
    } else if (xattr_list_len == 0) {
-      return true;
+      return bsub_exit_ok;
    }
 
    /*
@@ -265,13 +268,19 @@ static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
     */
    xattr_list_len = llistxattr(jcr->last_fname, xattr_list, xattr_list_len);
    if (xattr_list_len < 0) {
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("llistxattr error on file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-      Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
-         jcr->last_fname, be.bstrerror());
-      free(xattr_list);
-      return true;                    /* non-fatal return */
+      switch (errno) {
+      case ENOENT:
+         free(xattr_list);
+         return bsub_exit_nok;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("llistxattr error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
+            jcr->last_fname, be.bstrerror());
+         free(xattr_list);
+         return bsub_exit_nok;
+      }
    }
    xattr_list[xattr_list_len] = '\0';
 
@@ -297,8 +306,7 @@ static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
 
    if (count == 0) {
       free(xattr_list);
-
-      return true;
+      return bsub_exit_ok;
    }
 
    /*
@@ -342,12 +350,17 @@ static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
        */
       xattr_value_len = lgetxattr(jcr->last_fname, bp, NULL, 0);
       if (xattr_value_len < 0) {
-         berrno be;
-         Jmsg2(jcr, M_ERROR, 0, _("lgetxattr error on file \"%s\": ERR=%s\n"),
-            jcr->last_fname, be.bstrerror());
-         Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
-            jcr->last_fname, be.bstrerror());
-         goto bail_out;
+         switch (errno) {
+         case ENOENT:
+            goto bail_out;
+         default:
+            berrno be;
+            Jmsg2(jcr, M_ERROR, 0, _("lgetxattr error on file \"%s\": ERR=%s\n"),
+               jcr->last_fname, be.bstrerror());
+            Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
+               jcr->last_fname, be.bstrerror());
+            goto bail_out;
+         }
       }
 
       /*
@@ -358,12 +371,17 @@ static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
 
       xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len);
       if (xattr_value_len < 0) {
-         berrno be;
-         Jmsg2(jcr, M_ERROR, 0, _("lgetxattr error on file \"%s\": ERR=%s\n"),
-            jcr->last_fname, be.bstrerror());
-         Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
-            jcr->last_fname, be.bstrerror());
-         goto bail_out;
+         switch (errno) {
+         case ENOENT:
+            goto bail_out;
+         default:
+            berrno be;
+            Jmsg2(jcr, M_ERROR, 0, _("lgetxattr error on file \"%s\": ERR=%s\n"),
+               jcr->last_fname, be.bstrerror());
+            Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
+               jcr->last_fname, be.bstrerror());
+            goto bail_out;
+         }
       }
 
       /*
@@ -405,19 +423,19 @@ static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
    /*
     * Send the datastream to the SD.
     */
-   return send_xattr_stream(jcr, stream);
+   return send_xattr_stream(jcr, default_stream);
 
 bail_out:
    xattr_drop_internal_table(xattr_value_list);
    free(xattr_list);
-   return true;                    /* non-fatal return */
+   return bsub_exit_nok;
 }
 
-static bool generic_xattr_parse_streams(JCR *jcr)
+static bsub_exit_code generic_xattr_parse_streams(JCR *jcr, int stream)
 {
    unser_declare;
    xattr_t current_xattr;
-   bool retval = true;                /* default non-fatal */
+   bsub_exit_code retval = bsub_exit_nok;
 
    /*
     * Parse the stream and perform the setxattr calls on the file.
@@ -437,7 +455,7 @@ static bool generic_xattr_parse_streams(JCR *jcr)
             jcr->last_fname);
          Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n",
             jcr->last_fname);
-         return true;                 /* non-fatal return */
+         return bsub_exit_nok;
       }
 
       /*
@@ -473,12 +491,18 @@ static bool generic_xattr_parse_streams(JCR *jcr)
        * we try to restore the other extended attributes too.
        */
       if (lsetxattr(jcr->last_fname, current_xattr.name, current_xattr.value,
-         current_xattr.value_length, 0) != 0) {
-         berrno be;
-         Jmsg2(jcr, M_ERROR, 0, _("lsetxattr error on file \"%s\": ERR=%s\n"),
-            jcr->last_fname, be.bstrerror());
-         Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
-            jcr->last_fname, be.bstrerror());
+         switch (errno) {
+         case ENOENT:
+            break;
+         default:
+            current_xattr.value_length, 0) != 0) {
+            berrno be;
+            Jmsg2(jcr, M_ERROR, 0, _("lsetxattr error on file \"%s\": ERR=%s\n"),
+               jcr->last_fname, be.bstrerror());
+            Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
+               jcr->last_fname, be.bstrerror());
+            break;
+         }
       }
 
       /*
@@ -492,79 +516,25 @@ static bool generic_xattr_parse_streams(JCR *jcr)
    return retval;
 }
 
-#if defined(HAVE_DARWIN_OS)
-static bool darwin_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_DARWIN);
-}
+/*
+ * For all these os-es setup the build and parse function pointer to the generic functions.
+ */
+static bsub_exit_code (*os_build_xattr_streams)(JCR *jcr, FF_PKT *ff_pkt, int default_stream) = generic_xattr_build_streams;
+static bsub_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = generic_xattr_parse_streams;
 
-static bool darwin_parse_xattr_stream(JCR *jcr, int stream)
-{
-   switch (stream) {
-   case STREAM_XATTR_DARWIN:
-      return generic_xattr_parse_streams(jcr);
-   default:
-      Jmsg2(jcr, M_WARNING, 0,
-         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;                    /* non-fatal error */
-   }
-}
+/*
+ * All these os-es have 1 xattr stream.
+ */
+#if defined(HAVE_DARWIN_OS)
+static int os_default_xattr_streams[1] = { STREAM_XATTR_DARWIN };
 #elif defined(HAVE_FREEBSD_OS)
-static bool freebsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_FREEBSD);
-}
-
-static bool freebsd_parse_xattr_stream(JCR *jcr, int stream)
-{
-   switch (stream) {
-   case STREAM_XATTR_FREEBSD:
-      return generic_xattr_parse_streams(jcr);
-   default:
-      Jmsg2(jcr, M_WARNING, 0, 
-         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;                    /* non-fatal error */
-   }
-}
+static int os_default_xattr_streams[1] = { STREAM_XATTR_FREEBSD };
 #elif defined(HAVE_LINUX_OS)
-static bool linux_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_LINUX);
-}
-
-static bool linux_parse_xattr_stream(JCR *jcr, int stream)
-{
-   switch (stream) {
-   case STREAM_XATTR_LINUX:
-      return generic_xattr_parse_streams(jcr);
-   default:
-      Jmsg2(jcr, M_WARNING, 0, 
-         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;                    /* non-fatal error */
-   }
-}
+static int os_default_xattr_streams[1] = { STREAM_XATTR_LINUX };
 #elif defined(HAVE_NETBSD_OS)
-static bool netbsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_NETBSD);
-}
-
-static bool netbsd_parse_xattr_stream(JCR *jcr, int stream)
-{
-   switch (stream) {
-   case STREAM_XATTR_NETBSD:
-      return generic_xattr_parse_streams(jcr);
-   default:
-      Jmsg2(jcr, M_WARNING, 0, 
-         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;                    /* non-fatal error */
-   }
-}
+static int os_default_xattr_streams[1] = { STREAM_XATTR_NETBSD };
 #endif
+
 #elif defined(HAVE_SUN_OS)
 /*
  * Solaris extended attributes were introduced in Solaris 9
@@ -675,15 +645,14 @@ static int toplevel_hidden_dir_xattr_data_len;
  * This code creates a temporary cache with entries for each xattr which has
  * a link count > 1 (which indicates it has one or more hard linked counterpart(s))
  */
-static xattr_link_cache_entry_t *xattr_link_cache_head = NULL,
-                                *xattr_link_cache_tail = NULL;
+static alist *xattr_link_cache = NULL;
 
 static struct xattr_link_cache_entry *find_xattr_link_cache_entry(ino_t inum)
 {
    xattr_link_cache_entry_t *ptr;
 
-   for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next) {
-      if (ptr->inum == inum) {
+   foreach_alist(ptr, xattr_link_cache) {
+      if (ptr && ptr->inum == inum) {
          return ptr;
       }
    }
@@ -698,24 +667,7 @@ static void add_xattr_link_cache_entry(ino_t inum, char *target)
    memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
    ptr->inum = inum;
    strncpy(ptr->target, target, sizeof(ptr->target));
-   if (xattr_link_cache_head == NULL) {
-      xattr_link_cache_head = ptr;
-   }
-   if (xattr_link_cache_tail != NULL) {
-      xattr_link_cache_tail->next = ptr;
-   }
-}
-
-static void drop_xattr_link_cache(void)
-{
-   xattr_link_cache_entry_t *ptr, *next;
-
-   for (ptr = xattr_link_cache_tail; ptr != NULL; ptr = next) {
-      next = ptr->next;
-      free(ptr);
-   }
-   xattr_link_cache_head = NULL;
-   xattr_link_cache_tail = NULL;
+   xattr_link_cache->append(ptr);
 }
 
 #if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
@@ -813,7 +765,7 @@ static bool acl_is_trivial(int count, aclent_t *entries)
 }
 #endif /* HAVE_ACL && !HAVE_EXTENDED_ACL */
 
-static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
+static bsub_exit_code solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
 {
 #ifdef HAVE_ACL
 #ifdef HAVE_EXTENDED_ACL
@@ -830,12 +782,17 @@ static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char
        */
       if ((fd != -1 && facl_get(fd, ACL_NO_TRIVIAL, &aclp) != 0) ||
            acl_get(attrname, ACL_NO_TRIVIAL, &aclp) != 0) {
-         berrno be;
-         Jmsg3(jcr, M_ERROR, 0, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
-            attrname, jcr->last_fname, be.bstrerror());
-         Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
-            attrname, jcr->last_fname, be.bstrerror());
-         return true;                    /* non-fatal */
+         switch (errno) {
+         case ENOENT:
+            return bsub_exit_nok;
+         default:
+            berrno be;
+            Jmsg3(jcr, M_ERROR, 0, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
+               attrname, jcr->last_fname, be.bstrerror());
+            Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
+               attrname, jcr->last_fname, be.bstrerror());
+            return bsub_exit_nok;
+         }
       }
 
       if (aclp != NULL) {
@@ -856,8 +813,7 @@ static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char
    } else {
       *acl_text = NULL;
    }
-
-   return true;
+   return bsub_exit_ok;
 #else /* HAVE_EXTENDED_ACL */
    int n;
    aclent_t *acls = NULL;
@@ -875,13 +831,19 @@ static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char
       acls = (aclent_t *)malloc(n * sizeof(aclent_t));
       if ((fd != -1 && facl(fd, GETACL, n, acls) != n) ||
           acl(attrname, GETACL, n, acls) != n) {
-         berrno be;
-         Jmsg3(jcr, M_ERROR, 0, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
-            attrname, jcr->last_fname, be.bstrerror());
-         Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
-            attrname, jcr->last_fname, be.bstrerror());
-         free(acls);
-         return true;                 /* non-fatal */
+         switch (errno) {
+         case ENOENT:
+            free(acls);
+            return bsub_exit_nok;
+         default:
+            berrno be;
+            Jmsg3(jcr, M_ERROR, 0, _("Unable to get acl on xattr %s on file \"%s\": ERR=%s\n"),
+               attrname, jcr->last_fname, be.bstrerror());
+            Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
+               attrname, jcr->last_fname, be.bstrerror());
+            free(acls);
+            return bsub_exit_nok;
+         }
       }
 
       /*
@@ -895,7 +857,7 @@ static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char
             Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n",
                attrname, jcr->last_fname, be.bstrerror());
             free(acls);
-            return true;                 /* non-fatal */
+            return bsub_exit_nok;
          }
       } else {
          *acl_text = NULL;
@@ -905,19 +867,18 @@ static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char
    } else {
       *acl_text = NULL;
    }
-
-   return true;
+   return bsub_exit_ok;
 #endif /* HAVE_EXTENDED_ACL */
 
 #else /* HAVE_ACL */
-   return false;                         /* fatal return */
+   return bsub_exit_ok;
 #endif /* HAVE_ACL */
 }
 
 /*
  * Forward declaration for recursive function call.
  */
-static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
+static bsub_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
 
 /*
  * Save an extended or extensible attribute.
@@ -934,8 +895,8 @@ static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const cha
  * acl_string is an acl text when a non trivial acl is set on the xattr.
  * actual_xattr_data is the content of the xattr file.
  */
-static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
-                                  const char *attrname, bool toplevel_hidden_dir, int stream)
+static bsub_exit_code solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
+                                         const char *attrname, bool toplevel_hidden_dir, int stream)
 {
    int cnt;
    int attrfd = -1;
@@ -946,7 +907,7 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
    char *acl_text = NULL;
    char attribs[MAXSTRING];
    char buffer[BUFSIZ];
-   bool retval = true;                /* default is non-fatal */
+   bsub_exit_code retval = bsub_exit_nok;
 
    snprintf(target_attrname, sizeof(target_attrname), "%s%s", xattr_namespace, attrname);
 
@@ -954,12 +915,17 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
     * Get the stats of the extended or extensible attribute.
     */
    if (fstatat(fd, attrname, &st, AT_SYMLINK_NOFOLLOW) < 0) {
-      berrno be;
-      Jmsg3(jcr, M_ERROR, 0, _("Unable to get status on xattr %s on file \"%s\": ERR=%s\n"),
-         target_attrname, jcr->last_fname, be.bstrerror());
-      Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n",
-         target_attrname, jcr->last_fname, be.bstrerror());
-      goto cleanup;
+      switch (errno) {
+      case ENOENT:
+         goto cleanup;
+      default:
+         berrno be;
+         Jmsg3(jcr, M_ERROR, 0, _("Unable to get status on xattr %s on file \"%s\": ERR=%s\n"),
+            target_attrname, jcr->last_fname, be.bstrerror());
+         Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n",
+            target_attrname, jcr->last_fname, be.bstrerror());
+         goto cleanup;
+      }
    }
 
    /*
@@ -974,7 +940,7 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
       /*
        * Get any acl on the xattr.
        */
-      if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
+      if (solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text) != bsub_exit_ok)
          goto cleanup;
 
       /*
@@ -990,7 +956,7 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
       /*
        * Get any acl on the xattr.
        */
-      if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
+      if (solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text) != bsub_exit_ok)
          goto cleanup;
 
       /*
@@ -1055,7 +1021,7 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
       /*
        * Get any acl on the xattr.
        */
-      if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text)) {
+      if (solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text) != bsub_exit_ok) {
          goto cleanup;
       }
 
@@ -1071,12 +1037,17 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
        * Open the extended or extensible attribute file.
        */
       if ((attrfd = openat(fd, attrname, O_RDONLY)) < 0) {
-         berrno be;
-         Jmsg3(jcr, M_ERROR, 0, _("Unable to open xattr %s on \"%s\": ERR=%s\n"),
-            target_attrname, jcr->last_fname, be.bstrerror());
-         Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n",
-            target_attrname, jcr->last_fname, be.bstrerror());
-         goto cleanup;
+         switch (errno) {
+         case ENOENT:
+            goto cleanup;
+         default:
+            berrno be;
+            Jmsg3(jcr, M_ERROR, 0, _("Unable to open xattr %s on \"%s\": ERR=%s\n"),
+               target_attrname, jcr->last_fname, be.bstrerror());
+            Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n",
+               target_attrname, jcr->last_fname, be.bstrerror());
+            goto cleanup;
+         }
       }
       break;
 
@@ -1086,12 +1057,17 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
        * Encode the stat struct into an ASCII representation.
        */
       if (readlink(attrname, link_source, sizeof(link_source)) < 0) {
-         berrno be;
-         Jmsg3(jcr, M_ERROR, 0, _("Unable to read symlin %s on \"%s\": ERR=%s\n"),
-            target_attrname, jcr->last_fname, be.bstrerror());
-         Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n",
-            target_attrname, jcr->last_fname, be.bstrerror());
-         goto cleanup;
+         switch (errno) {
+         case ENOENT:
+            goto cleanup;
+         default:
+            berrno be;
+            Jmsg3(jcr, M_ERROR, 0, _("Unable to read symlin %s on \"%s\": ERR=%s\n"),
+               target_attrname, jcr->last_fname, be.bstrerror());
+            Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n",
+               target_attrname, jcr->last_fname, be.bstrerror());
+            goto cleanup;
+         }
       }
 
       /*
@@ -1177,12 +1153,17 @@ static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
        * The recursive call could change our working dir so change back to the wanted workdir.
        */
       if (fchdir(fd) < 0) {
-         berrno be;
-         Jmsg2(jcr, M_ERROR, 0, _("Unable to chdir to xattr space of file \"%s\": ERR=%s\n"),
-            jcr->last_fname, be.bstrerror());
-         Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n",
-            jcr->last_fname, fd, be.bstrerror());
-         goto cleanup;
+         switch (errno) {
+         case ENOENT:
+            goto cleanup;
+         default:
+            berrno be;
+            Jmsg2(jcr, M_ERROR, 0, _("Unable to chdir to xattr space of file \"%s\": ERR=%s\n"),
+               jcr->last_fname, be.bstrerror());
+            Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n",
+               jcr->last_fname, fd, be.bstrerror());
+            goto cleanup;
+         }
       }
    }
 
@@ -1196,14 +1177,14 @@ cleanup:
    return retval;
 }
 
-static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
+static bsub_exit_code solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
 {
    const char *name;
    int fd, filefd = -1, attrdirfd = -1;
    DIR *dirp;
    struct dirent *dp;
    char current_xattr_namespace[PATH_MAX];
-   bool retval = true;                   /* default non-fatal error */
+   bsub_exit_code retval = bsub_exit_nok;
  
    /*
     * Determine what argument to use. Use attr_parent when set
@@ -1227,12 +1208,17 @@ static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const cha
     * Open the file on which to save the xattrs read-only.
     */
    if ((filefd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {
-      berrno be;
-      Jmsg2(jcr, M_ERROR, 0, _("Unable to open file \"%s\": ERR=%s\n"),
-         jcr->last_fname, be.bstrerror());
-      Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
-         jcr->last_fname, be.bstrerror());
-      goto cleanup;
+      switch (errno) {
+      case ENOENT:
+         goto cleanup;
+      default:
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("Unable to open file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
+            jcr->last_fname, be.bstrerror());
+         goto cleanup;
+      }
    }
 
    /*
@@ -1246,16 +1232,18 @@ static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const cha
           * Which is not problem we just forget about this this xattr.
           * But as this is not an error we return a positive return value.
           */
-         retval = true;
-         break;
+         retval = bsub_exit_ok;
+         goto cleanup;
+      case ENOENT:
+         goto cleanup;
       default:
          berrno be;
          Jmsg3(jcr, M_ERROR, 0, _("Unable to open xattr space %s on file \"%s\": ERR=%s\n"),
             name, jcr->last_fname, be.bstrerror());
          Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
             name, jcr->last_fname, be.bstrerror());
+         goto cleanup;
       }
-      goto cleanup;
    }
 
   /*
@@ -1353,7 +1341,7 @@ static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const cha
    }
 
    closedir(dirp);
-   retval = true;
+   retval = bsub_exit_ok;
 
 cleanup:
    if (attrdirfd != -1)
@@ -1364,7 +1352,7 @@ cleanup:
 }
 
 #ifdef HAVE_ACL
-static bool solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, char *acl_text)
+static bsub_exit_code solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, char *acl_text)
 {
 #ifdef HAVE_EXTENDED_ACL
    int error;
@@ -1372,8 +1360,8 @@ static bool solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, ch
 
    if ((error = acl_fromtext(acl_text, &aclp)) != 0) {
       Jmsg1(jcr, M_ERROR, 0, _("Unable to convert acl from text on file \"%s\"\n"),
-               jcr->last_fname);
-      return true;                    /* non-fatal */
+            jcr->last_fname);
+      return bsub_exit_nok;
    }
 
    if ((fd != -1 && facl_set(fd, aclp) != 0) ||
@@ -1383,13 +1371,13 @@ static bool solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, ch
          attrname, jcr->last_fname, be.bstrerror());
       Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
          attrname, jcr->last_fname, be.bstrerror());
-      return true;                    /* non-fatal */
+      return bsub_exit_nok;
    }
 
    if (aclp) {
       acl_free(aclp);
    }
-   return true;
+   return bsub_exit_ok;
 
 #else /* HAVE_EXTENDED_ACL */
    int n;
@@ -1404,21 +1392,21 @@ static bool solaris_restore_xattr_acl(JCR *jcr, int fd, const char *attrname, ch
             attrname, jcr->last_fname, be.bstrerror());
          Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
             attrname, jcr->last_fname, be.bstrerror());
-         return true;                   /* non-fatal */
+         return bsub_exit_nok;
       }
    }
 
    if (acls) {
       free(acls);
    }
-   return true;
+   return bsub_exit_ok;
 
 #endif /* HAVE_EXTENDED_ACL */
 
 }
 #endif /* HAVE_ACL */
 
-static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
+static bsub_exit_code solaris_restore_xattrs(JCR *jcr, bool is_extensible)
 {
    int fd, filefd = -1, attrdirfd = -1, attrfd = -1;
    int used_bytes, total_bytes, cnt;
@@ -1429,7 +1417,7 @@ static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
    int32_t inum;
    struct stat st;
    struct timeval times[2];
-   bool retval = true;             /* default non-fatal */
+   bsub_exit_code retval = bsub_exit_nok;
 
    /*
     * Parse the xattr stream. First the part that is the same for all xattrs.
@@ -1618,7 +1606,7 @@ static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
          /*
           * Successfully restored xattr.
           */
-         retval = true;
+         retval = bsub_exit_ok;
          goto cleanup;
       } else {
          if ((bp = strchr(acl_text, '\0')) == (char *)NULL ||
@@ -1700,7 +1688,7 @@ static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
       /*
        * Successfully restored xattr.
        */
-      retval = true;
+      retval = bsub_exit_ok;
       goto cleanup;
    default:
       goto cleanup;
@@ -1717,7 +1705,7 @@ static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
              * Gentile way of the system saying this type of xattr layering is not supported.
              * But as this is not an error we return a positive return value.
              */
-            retval = true;
+            retval = bsub_exit_ok;
             break;
          default:
             berrno be;
@@ -1732,7 +1720,7 @@ static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
 
 #ifdef HAVE_ACL
    if (acl_text && *acl_text)
-      if (!solaris_restore_xattr_acl(jcr, attrfd, target_attrname, acl_text))
+      if (solaris_restore_xattr_acl(jcr, attrfd, target_attrname, acl_text) != bsub_exit_ok)
          goto cleanup;
 #endif /* HAVE_ACL */
 
@@ -1758,7 +1746,7 @@ static bool solaris_restore_xattrs(JCR *jcr, bool is_extensible)
    /*
     * Successfully restored xattr.
     */
-   retval = true;
+   retval = bsub_exit_ok;
    goto cleanup;
 
 parse_error:
@@ -1780,11 +1768,37 @@ cleanup:
    return retval;
 }
 
-static bool solaris_extract_xattr(JCR *jcr, int stream)
+static bsub_exit_code solaris_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt, int default_stream)
+{
+   char cwd[PATH_MAX];
+   bsub_exit_code retval = bsub_exit_ok;
+
+   /*
+    * First see if extended attributes or extensible attributes are present.
+    * If not just pretend things went ok.
+    */
+   if (pathconf(jcr->last_fname, _PC_XATTR_EXISTS) > 0) {
+      nr_xattr_saved = 0;
+
+      /*
+       * As we change the cwd in the save function save the current cwd
+       * for restore after return from the solaris_save_xattrs function.
+       */
+      xattr_link_cache = New(alist(10, not_owned_by_alist));
+      getcwd(cwd, sizeof(cwd));
+      retval = solaris_save_xattrs(jcr, NULL, NULL);
+      chdir(cwd);
+      delete xattr_link_cache;
+      xattr_link_cache = NULL;
+   }
+   return retval;
+}
+
+static bsub_exit_code solaris_parse_xattr_streams(JCR *jcr, int stream)
 {
    char cwd[PATH_MAX];
    bool is_extensible = false;
-   bool retval;
+   bsub_exit_code retval;
 
    /*
     * First make sure we can restore xattr on the filesystem.
@@ -1798,7 +1812,7 @@ static bool solaris_extract_xattr(JCR *jcr, int stream)
                jcr->last_fname);
          Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n",
             jcr->last_fname);
-         return true;
+         return bsub_exit_nok;
       }
 
       is_extensible = true;
@@ -1811,11 +1825,11 @@ static bool solaris_extract_xattr(JCR *jcr, int stream)
                jcr->last_fname);
          Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n",
             jcr->last_fname);
-         return true;
+         return bsub_exit_nok;
       }
       break;
    default:
-      return true;
+      return bsub_exit_nok;
    }
 
    /*
@@ -1828,101 +1842,52 @@ static bool solaris_extract_xattr(JCR *jcr, int stream)
    return retval;
 }
 
-static int solaris_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
-{
-   char cwd[PATH_MAX];
-   bool retval = true;
 
-   /*
-    * First see if extended attributes or extensible attributes are present.
-    * If not just pretend things went ok.
-    */
-   if (pathconf(jcr->last_fname, _PC_XATTR_EXISTS) > 0) {
-      nr_xattr_saved = 0;
+/*
+ * Function pointers to the build and parse function to use for these xattrs.
+ */
+static bsub_exit_code (*os_build_xattr_streams)(JCR *jcr, FF_PKT *ff_pkt, int default_stream) = solaris_build_xattr_streams;
+static bsub_exit_code (*os_parse_xattr_streams)(JCR *jcr, int stream) = solaris_parse_xattr_streams;
 
-      /*
-       * As we change the cwd in the save function save the current cwd
-       * for restore after return from the solaris_save_xattrs function.
-       */
-      getcwd(cwd, sizeof(cwd));
-      retval = solaris_save_xattrs(jcr, NULL, NULL);
-      chdir(cwd);
-      drop_xattr_link_cache();
-   }
+/*
+ * Number of xattr streams this OS supports and an array with integers with the actual stream numbers.
+ */
+#if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
+static int os_default_xattr_streams[2] = { STREAM_XATTR_SOLARIS, STREAM_XATTR_SOLARIS_SYS};
+#else
+static int os_default_xattr_streams[1] = { STREAM_XATTR_SOLARIS };
+#endif /* defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED) */
 
-   return retval;
-}
+#endif /* defined(HAVE_SUN_OS) */
 
-static bool solaris_parse_xattr_stream(JCR *jcr, int stream)
+bsub_exit_code build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
 {
-   switch (stream) {
-#if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
-   case STREAM_XATTR_SOLARIS_SYS:
-#endif
-   case STREAM_XATTR_SOLARIS:
-      return solaris_extract_xattr(jcr, stream);
-   default:
-      Jmsg2(jcr, M_WARNING, 0,
-         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;                    /* non-fatal error */
+   if (os_build_xattr_streams) {
+      return (*os_build_xattr_streams)(jcr, ff_pkt, os_default_xattr_streams[0]);
    }
+   return bsub_exit_nok;
 }
-#endif
 
-bool build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+bsub_exit_code parse_xattr_streams(JCR *jcr, int stream)
 {
-#if defined(HAVE_SUN_OS)
-   return solaris_build_xattr_streams(jcr, ff_pkt);
-#elif defined(HAVE_DARWIN_OS)
-   return darwin_build_xattr_streams(jcr, ff_pkt);
-#elif defined(HAVE_FREEBSD_OS)
-   return freebsd_build_xattr_streams(jcr, ff_pkt);
-#elif defined(HAVE_LINUX_OS)
-   return linux_build_xattr_streams(jcr, ff_pkt);
-#elif defined(HAVE_NETBSD_OS)
-   return netbsd_build_xattr_streams(jcr, ff_pkt);
-#endif
-}
+   int cnt;
 
-bool parse_xattr_stream(JCR *jcr, int stream)
-{
-   /*
-    * Based on the stream being passed in dispatch to the right function
-    * for parsing and restoring a specific xattr. The platform determines
-    * which streams are recognized and parsed and which are handled by
-    * the default case and ignored. As only one of the platform defines
-    * is true per compile we never end up with duplicate switch values.
-    */
-   switch (stream) {
-#if defined(HAVE_SUN_OS)
-#if defined(HAVE_SYS_NVPAIR_H) && defined(_PC_SATTR_ENABLED)
-   case STREAM_XATTR_SOLARIS_SYS:
-#endif
-   case STREAM_XATTR_SOLARIS:
-      return solaris_parse_xattr_stream(jcr, stream);
-#elif defined(HAVE_DARWIN_OS)
-   case STREAM_XATTR_DARWIN:
-      return darwin_parse_xattr_stream(jcr, stream);
-#elif defined(HAVE_FREEBSD_OS)
-   case STREAM_XATTR_FREEBSD:
-      return freebsd_parse_xattr_stream(jcr, stream);
-#elif defined(HAVE_LINUX_OS)
-   case STREAM_XATTR_LINUX:
-      return linux_parse_xattr_stream(jcr, stream);
-#elif defined(HAVE_NETBSD_OS)
-   case STREAM_XATTR_NETBSD:
-      return netbsd_parse_xattr_stream(jcr, stream);
-#endif
-   default:
+   if (os_parse_xattr_streams) {
       /*
-       * Issue a warning and discard the message. But pretend the restore was ok.
+       * See if we can parse this stream, and ifso give it a try.
        */
-      Qmsg2(jcr, M_WARNING, 0,
-         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-         jcr->last_fname, stream);
-      return true;
-   } /* end switch (stream) */
+      for (cnt = 0; cnt < sizeof(os_default_xattr_streams) / sizeof(int); cnt++) {
+         if (os_default_xattr_streams[cnt] == stream) {
+            return (*os_parse_xattr_streams)(jcr, stream);
+         }
+      }
+   }
+   /*
+    * Issue a warning and discard the message. But pretend the restore was ok.
+    */
+   Jmsg2(jcr, M_WARNING, 0,
+      _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
+      jcr->last_fname, stream);
+   return bsub_exit_nok;
 }
-
 #endif
index 2adec4fb97462e2fcc9c2e2a56c4ada46ab94054..ba66e1de4f87791ac7e589ffc65d104682ad9be6 100644 (file)
@@ -52,7 +52,6 @@ typedef struct xattr {
 typedef struct xattr_link_cache_entry {
    uint32_t inum;
    char target[PATH_MAX];
-   struct xattr_link_cache_entry *next;
 } xattr_link_cache_entry_t;
 
 /*