* 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
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;
}
/*
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;
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) \
#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;
}
* 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.
*/
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;
tag != ACL_OTHER_OBJ)
return false;
}
-
return true;
#elif defined(HAVE_OSF1_OS)
int count;
while (count > 0) {
tag = ace->entry->acl_type;
-
/*
* Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ or ACL_OTHER breaks the spell.
*/
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
}
/*
* 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;
*/
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
* 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;
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;
}
/*
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 */
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;
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);
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"),
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
* 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)
/*
*
* 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.
* 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:
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)
#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.
for (n = 0; n < count; n++) {
ace = entries[n];
-
/*
* See if this acl just is the stat mode in acl form.
*/
(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"),
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)) {
/*
* 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];
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;
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
* 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>
* 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.
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.
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;
}
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) {
* 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)
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:
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.
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:
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:
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;
}
/*
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:
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.
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;
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) {
*/
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);
}
}
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;
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;
}
/*
* 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 */
/*
/*
* 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
*/
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;
}
}
*/
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;
}
}
#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"
#endif
extern CLIENT *me; /* "Global" Client resource */
+
+typedef enum {
+ bsub_exit_fatal = -1,
+ bsub_exit_nok = 0,
+ bsub_exit_ok = 1
+} bsub_exit_code;
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);
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);
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 {
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 {
/*
* 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
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;
}
/*
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;
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;
}
/*
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,
*/
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;
}
/*
*/
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';
if (count == 0) {
free(xattr_list);
-
- return true;
+ return bsub_exit_ok;
}
/*
*/
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;
+ }
}
/*
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;
+ }
}
/*
/*
* 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.
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;
}
/*
* 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;
+ }
}
/*
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
* 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;
}
}
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)
}
#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
*/
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) {
} else {
*acl_text = NULL;
}
-
- return true;
+ return bsub_exit_ok;
#else /* HAVE_EXTENDED_ACL */
int n;
aclent_t *acls = NULL;
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;
+ }
}
/*
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;
} 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.
* 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;
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);
* 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;
+ }
}
/*
/*
* 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;
/*
/*
* 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;
/*
/*
* 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;
}
* 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;
* 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;
+ }
}
/*
* 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;
+ }
}
}
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
* 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;
+ }
}
/*
* 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;
}
/*
}
closedir(dirp);
- retval = true;
+ retval = bsub_exit_ok;
cleanup:
if (attrdirfd != -1)
}
#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;
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) ||
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;
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;
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.
/*
* Successfully restored xattr.
*/
- retval = true;
+ retval = bsub_exit_ok;
goto cleanup;
} else {
if ((bp = strchr(acl_text, '\0')) == (char *)NULL ||
/*
* Successfully restored xattr.
*/
- retval = true;
+ retval = bsub_exit_ok;
goto cleanup;
default:
goto cleanup;
* 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;
#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 */
/*
* Successfully restored xattr.
*/
- retval = true;
+ retval = bsub_exit_ok;
goto cleanup;
parse_error:
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.
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;
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;
}
/*
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
typedef struct xattr_link_cache_entry {
uint32_t inum;
char target[PATH_MAX];
- struct xattr_link_cache_entry *next;
} xattr_link_cache_entry_t;
/*