- /* ACL stream */
- if (ff_pkt->flags & FO_ACL) {
- char *acl_text;
- /* Read ACLs for files, dirs and links */
- if (ff_pkt->type == FT_DIREND) {
- /* Directory: Try for default ACL*/
- acl_t myAcl = acl_get_file(ff_pkt->fname, ACL_TYPE_DEFAULT);
- if (!myAcl) {
- Dmsg1(200, "No default ACL defined for directory: %s!\n", ff_pkt->fname);
- /* If there is no default ACL get standard ACL */
- myAcl = acl_get_file(ff_pkt->fname, ACL_TYPE_ACCESS);
- if (!myAcl) {
- Emsg1(M_WARNING, 0, "Error while trying to get ACL of directory: %s!\n", ff_pkt->fname);
- }
- }
- acl_text = acl_to_any_text(myAcl, NULL, ',', TEXT_ABBREVIATE);
- /* Free memory */
- acl_free(myAcl);
- } else {
- /* Files or links */
- acl_t myAcl = acl_get_file(ff_pkt->fname, ACL_TYPE_ACCESS);
- if (!myAcl) {
- Emsg1(M_WARNING, 0, "Error while trying to get ACL of file: %s!\n", ff_pkt->fname);
- acl_free(myAcl);
- }
- acl_text = acl_to_any_text(myAcl, NULL, ',', TEXT_ABBREVIATE);
- acl_free(myAcl);
+ BSOCK *sd = jcr->store_bsock;
+ POOLMEM *msgsave;
+ int len;
+#ifdef FD_NO_SEND_TEST
+ return true;
+#endif
+
+ len = bacl_get(jcr, acltype);
+ if (len < 0) {
+ Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
+ return true;
+ }
+ if (len == 0) {
+ return true; /* no ACL */
+ }
+
+ /* 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;
+ }
+
+ /* Send the buffer to the storage deamon */
+ Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
+ msgsave = sd->msg;
+ sd->msg = jcr->acl_text;
+ sd->msglen = len + 1;
+ if (!sd->send()) {
+ sd->msg = msgsave;
+ sd->msglen = 0;
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+ return false;
+ }
+
+ jcr->JobBytes += sd->msglen;
+ sd->msg = msgsave;
+ if (!sd->signal(BNET_EOD)) {
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+ return false;
+ }
+
+ Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
+#endif
+ return true;
+}
+
+static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
+{
+ BSOCK *sd = jcr->store_bsock;
+ char attribs[MAXSTRING];
+ char attribsEx[MAXSTRING];
+ int attr_stream;
+ int stat;
+#ifdef FD_NO_SEND_TEST
+ return true;
+#endif
+
+ Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
+ /* Find what data stream we will use, then encode the attributes */
+ if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
+ /* This should not happen */
+ Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
+ return false;
+ }
+ encode_stat(attribs, ff_pkt, data_stream);
+
+ /* Now possibly extend the attributes */
+ attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
+
+ Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
+
+ jcr->lock();
+ jcr->JobFiles++; /* increment number of files sent */
+ ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
+ pm_strcpy(jcr->last_fname, ff_pkt->fname);
+ jcr->unlock();
+
+ /*
+ * Send Attributes header to Storage daemon
+ * <file-index> <stream> <info>
+ */
+ if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+ return false;
+ }
+ Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
+
+ /*
+ * Send file attributes to Storage daemon
+ * File_index
+ * File type
+ * Filename (full path)
+ * Encoded attributes
+ * Link name (if type==FT_LNK or FT_LNKSAVED)
+ * Encoded extended-attributes (for Win32)
+ *
+ * For a directory, link is the same as fname, but with trailing
+ * slash. For a linked file, link is the link.
+ */
+ if (ff_pkt->type != FT_DELETED) { /* already stripped */
+ strip_path(ff_pkt);
+ }
+ if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
+ Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
+ stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
+ ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
+ attribsEx, 0);
+ } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) {
+ /* Here link is the canonical filename (i.e. with trailing slash) */
+ stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
+ ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
+ } else {
+ stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
+ ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
+ }
+ if (ff_pkt->type != FT_DELETED) {
+ unstrip_path(ff_pkt);
+ }
+
+ Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
+ if (!stat) {
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+ return false;
+ }
+ sd->signal(BNET_EOD); /* indicate end of attributes data */
+ return true;
+}
+
+/*
+ * Do in place strip of path
+ */
+static bool do_strip(int count, char *in)
+{
+ char *out = in;
+ int stripped;
+ int numsep = 0;
+
+ /* Copy to first path separator -- Win32 might have c: ... */
+ while (*in && !IsPathSeparator(*in)) {
+ *out++ = *in++;
+ }
+ *out++ = *in++;
+ numsep++; /* one separator seen */
+ for (stripped=0; stripped<count && *in; stripped++) {
+ while (*in && !IsPathSeparator(*in)) {
+ in++; /* skip chars */