*
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2000-2004 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "filed.h"
+#ifdef HAVE_ACL
+#include <sys/acl.h>
+#include <acl/libacl.h>
+#endif
+
/* Data received from Storage Daemon */
static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
uint64_t fileAddr = 0; /* file write address */
int non_support_data = 0;
int non_support_attr = 0;
+ int non_support_acl = 0;
int prog_name_msg = 0;
ATTR *attr;
-
+#ifdef HAVE_ACL
+ acl_t acl;
+#endif
binit(&bfd);
sd = jcr->store_bsock;
switch (stream) {
case STREAM_UNIX_ATTRIBUTES:
case STREAM_UNIX_ATTRIBUTES_EX:
-
Dmsg1(30, "Stream=Unix Attributes. extract=%d\n", extract);
/* If extracting, it was from previous stream, so
* close the output file.
case CF_EXTRACT:
extract = true;
P(jcr->mutex);
- pm_strcpy(&jcr->last_fname, attr->ofname);
+ pm_strcpy(jcr->last_fname, attr->ofname);
V(jcr->mutex);
jcr->JobFiles++;
fileAddr = 0;
break;
case CF_CREATED:
P(jcr->mutex);
- pm_strcpy(&jcr->last_fname, attr->ofname);
+ pm_strcpy(jcr->last_fname, attr->ofname);
V(jcr->mutex);
jcr->JobFiles++;
fileAddr = 0;
case STREAM_FILE_DATA:
case STREAM_SPARSE_DATA:
case STREAM_WIN32_DATA:
-
if (extract) {
if (stream == STREAM_SPARSE_DATA) {
ser_declare;
if (fileAddr != faddr) {
fileAddr = faddr;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+ berrno be;
+ be.set_errno(bfd.berrno);
Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
- edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
+ edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
extract = false;
bclose(&bfd);
continue;
Dmsg2(30, "Write %u bytes, total before write=%u\n", wsize, total);
if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
Dmsg0(0, "===Write error===\n");
- Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: ERR=%s\n"), attr->ofname, berror(&bfd));
+ berrno be;
+ be.set_errno(bfd.berrno);
+ Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: ERR=%s\n"), attr->ofname,
+ be.strerror());
extract = false;
bclose(&bfd);
continue;
if (fileAddr != faddr) {
fileAddr = faddr;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+ berrno be;
+ be.set_errno(bfd.berrno);
Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
- edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
+ edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
extract = false;
bclose(&bfd);
continue;
Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
if ((uLong)bwrite(&bfd, jcr->compress_buf, compress_len) != compress_len) {
Dmsg0(0, "===Write error===\n");
- Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), attr->ofname, berror(&bfd));
+ berrno be;
+ be.set_errno(bfd.berrno);
+ Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), attr->ofname, be.strerror());
extract = false;
bclose(&bfd);
continue;
#endif
break;
+ case STREAM_UNIX_ATTRIBUTES_ACL:
+#ifdef HAVE_ACL
+ /* Recover ACL from stream and check it */
+ acl = acl_from_text(sd->msg);
+ if (acl_valid(acl) != 0) {
+ Jmsg1(jcr, M_WARNING, 0, "Failure in the ACL of %s! FD is not able to restore it!\n", jcr->last_fname);
+ acl_free(acl);
+ }
+
+ /* Try to restore ACL */
+ if (attr->type == FT_DIREND) {
+ /* Directory */
+ if (acl_set_file(jcr->last_fname, ACL_TYPE_DEFAULT, acl) != 0 &&
+ acl_set_file(jcr->last_fname, ACL_TYPE_ACCESS, acl) != 0) {
+ Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore ACL of directory: %s! Maybe system does not support ACLs!\n", jcr->last_fname);
+ }
+ /* File or Link */
+ } else if (acl_set_file(jcr->last_fname, ACL_TYPE_ACCESS, acl) != 0) {
+ Jmsg1(jcr, M_WARNING, 0, "Error! Can't restore ACL of file: %s! Maybe system does not support ACLs!\n", jcr->last_fname);
+ }
+ acl_free(acl);
+ Dmsg1(200, "ACL of file: %s successfully restored!", jcr->last_fname);
+ break;
+#else
+ non_support_acl++;
+ break; /* unconfigured, ignore */
+#endif
+
case STREAM_MD5_SIGNATURE:
case STREAM_SHA1_SIGNATURE:
break;
Jmsg(jcr, M_ERROR, 0, _("%d non-supported data streams and %d non-supported attrib streams ignored.\n"),
non_support_data, non_support_attr);
}
+ if (non_support_acl) {
+ Jmsg(jcr, M_INFO, 0, _("%d non-supported acl streams ignored.\n"), non_support_acl);
+ }
+
}
#ifdef HAVE_LIBZ