+ return bacl_exit_ok;
+}
+
+/*
+ * OS specific functions for handling different types of acl streams.
+ */
+#if defined(HAVE_DARWIN_OS)
+/*
+ * 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 bacl_exit_code darwin_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+#if defined(ACL_TYPE_EXTENDED)
+ /*
+ * On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS)
+ * and acl_get_file (name, ACL_TYPE_DEFAULT)
+ * always return NULL / EINVAL. There is no point in making
+ * these two useless calls. The real ACL is retrieved through
+ * acl_get_file (name, ACL_TYPE_EXTENDED).
+ *
+ * Read access ACLs for files, dirs and links
+ */
+ if (generic_get_acl_from_os(jcr, BACL_TYPE_EXTENDED) == bacl_exit_fatal)
+ return bacl_exit_fatal;
+#else
+ /*
+ * Read access ACLs for files, dirs and links
+ */
+ if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bacl_exit_fatal)
+ return bacl_exit_fatal;
+#endif
+
+ if (jcr->acl_data_len > 0) {
+ return send_acl_stream(jcr, STREAM_ACL_DARWIN_ACCESS_ACL);
+ }
+ return bacl_exit_ok;
+}
+
+static bacl_exit_code darwin_parse_acl_streams(JCR *jcr, int stream)
+{
+#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);
+#endif
+}
+
+/*
+ * For this OS setup the build and parse function pointer to the OS specific functions.
+ */
+static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = darwin_build_acl_streams;
+static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = darwin_parse_acl_streams;
+
+#elif defined(HAVE_FREEBSD_OS) || \
+ defined(HAVE_IRIX_OS) || \
+ defined(HAVE_LINUX_OS)
+
+/*
+ * 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 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 bacl_exit_code generic_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+ /*
+ * Read access ACLs for files, dirs and links
+ */
+ if (generic_get_acl_from_os(jcr, BACL_TYPE_ACCESS) == bacl_exit_fatal)
+ return bacl_exit_fatal;
+
+ if (jcr->acl_data_len > 0) {
+ if (send_acl_stream(jcr, os_access_acl_streams[0]) == bacl_exit_fatal)
+ return bacl_exit_fatal;
+ }
+
+ /*
+ * Directories can have default ACLs too
+ */
+ if (ff_pkt->type == FT_DIREND) {
+ if (generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT) == bacl_exit_fatal)
+ return bacl_exit_fatal;
+ if (jcr->acl_data_len > 0) {
+ if (send_acl_stream(jcr, os_default_acl_streams[0]) == bacl_exit_fatal)
+ return bacl_exit_fatal;
+ }
+ }
+ return bacl_exit_ok;
+}
+
+static bacl_exit_code generic_parse_acl_streams(JCR *jcr, int stream)
+{
+ unsigned int cnt;
+
+ switch (stream) {
+ case STREAM_UNIX_ACCESS_ACL:
+ return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
+ case STREAM_UNIX_DEFAULT_ACL:
+ return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
+ 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 bacl_exit_error;
+}
+
+/*
+ * For this OSes setup the build and parse function pointer to the OS specific functions.
+ */
+static bacl_exit_code (*os_build_acl_streams)(JCR *jcr, FF_PKT *ff_pkt) = generic_build_acl_streams;
+static bacl_exit_code (*os_parse_acl_streams)(JCR *jcr, int stream) = generic_parse_acl_streams;
+
+#elif defined(HAVE_OSF1_OS)
+
+/*
+ * 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 bacl_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 bacl_exit_error;
+ if (jcr->acl_data_len > 0) {
+ if (!send_acl_stream(jcr, STREAM_ACL_TRU64_ACCESS_ACL))
+ return bacl_exit_error;
+ }
+ /*
+ * 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 bacl_exit_error;
+ if (jcr->acl_data_len > 0) {
+ if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_ACL))
+ return bacl_exit_error;
+ }
+ /*
+ * Tru64 has next to BACL_TYPE_DEFAULT also BACL_TYPE_DEFAULT_DIR acls.
+ * This is an inherited acl for all subdirs.
+ * See http://www.helsinki.fi/atk/unix/dec_manuals/DOC_40D/AQ0R2DTE/DOCU_018.HTM
+ * Section 21.5 Default ACLs
+ */
+ if ((jcr->acl_data_len = generic_get_acl_from_os(jcr, BACL_TYPE_DEFAULT_DIR)) < 0)
+ return bacl_exit_error;
+ if (jcr->acl_data_len > 0) {
+ if (!send_acl_stream(jcr, STREAM_ACL_TRU64_DEFAULT_DIR_ACL))
+ return bacl_exit_error;
+ }
+ }
+ return bacl_exit_ok;
+}
+
+static bacl_exit_code tru64_parse_acl_streams(JCR *jcr, int stream)
+{
+ switch (stream) {
+ case STREAM_UNIX_ACCESS_ACL:
+ case STREAM_ACL_TRU64_ACCESS_ACL:
+ return generic_set_acl_on_os(jcr, BACL_TYPE_ACCESS);
+ case STREAM_UNIX_DEFAULT_ACL:
+ case STREAM_ACL_TRU64_DEFAULT_ACL:
+ return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT);
+ case STREAM_ACL_TRU64_DEFAULT_DIR_ACL:
+ return generic_set_acl_on_os(jcr, BACL_TYPE_DEFAULT_DIR);