2 * Bacula File Daemon backup.c send file attributes and data
3 * to the Storage daemon.
5 * Kern Sibbald, March MM
11 Copyright (C) 2000-2005 Kern Sibbald
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License
15 version 2 as amended with additional clauses defined in the
16 file LICENSE in the main source directory.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 the file LICENSE for additional details.
28 /* Forward referenced functions */
29 static int save_file(FF_PKT *ff_pkt, void *pkt, bool top_level);
30 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
31 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
32 static bool read_and_send_acl(JCR *jcr, int acltype, int stream);
35 * Find all the requested files and send them
36 * to the Storage daemon.
38 * Note, we normally carry on a one-way
39 * conversation from this point on with the SD, simply blasting
40 * data to him. To properly know what is going on, we
41 * also run a "heartbeat" monitor which reads the socket and
42 * reacts accordingly (at the moment it has nothing to do
43 * except echo the heartbeat to the Director).
46 bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
51 sd = jcr->store_bsock;
53 set_jcr_job_status(jcr, JS_Running);
55 Dmsg1(300, "bfiled: opened data connection %d to stored\n", sd->fd);
58 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
62 buf_size = client->max_network_buffer_size;
64 buf_size = 0; /* use default */
66 if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
67 set_jcr_job_status(jcr, JS_ErrorTerminated);
68 Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
72 jcr->buf_size = sd->msglen;
73 /* Adjust for compression so that output buffer is
74 * 12 bytes + 0.1% larger than input buffer plus 18 bytes.
75 * This gives a bit extra plus room for the sparse addr if any.
76 * Note, we adjust the read size to be smaller so that the
77 * same output buffer can be used without growing it.
79 jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
80 jcr->compress_buf = get_memory(jcr->compress_buf_size);
82 Dmsg1(300, "set_find_options ff=%p\n", jcr->ff);
83 set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
84 Dmsg0(300, "start find files\n");
86 start_heartbeat_monitor(jcr);
88 jcr->acl_text = get_pool_memory(PM_MESSAGE);
90 /* Subroutine save_file() is called for each file */
91 if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, (void *)jcr)) {
92 ok = false; /* error */
93 set_jcr_job_status(jcr, JS_ErrorTerminated);
94 // Jmsg(jcr, M_FATAL, 0, _("Find files error.\n"));
97 free_pool_memory(jcr->acl_text);
99 stop_heartbeat_monitor(jcr);
101 bnet_sig(sd, BNET_EOD); /* end of sending data */
107 if (jcr->compress_buf) {
108 free_pool_memory(jcr->compress_buf);
109 jcr->compress_buf = NULL;
111 Dmsg1(100, "end blast_data ok=%d\n", ok);
116 * Called here by find() for each file included.
117 * This is a callback. The original is find_files() above.
119 * Send the file and its data to the Storage daemon.
123 * -1 to ignore file/directory (not used here)
125 static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
127 int stat, data_stream;
128 DIGEST *digest = NULL;
129 DIGEST *signing_digest = NULL;
130 int digest_stream = STREAM_NONE;
131 // TODO landonf: Allow the user to specify the digest algorithm
133 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
135 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
138 JCR *jcr = (JCR *)vjcr;
140 if (job_canceled(jcr)) {
144 sd = jcr->store_bsock;
145 jcr->num_files_examined++; /* bump total file count */
147 switch (ff_pkt->type) {
148 case FT_LNKSAVED: /* Hard linked, file already saved */
149 Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
152 Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
155 Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
158 Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
161 return 1; /* not used */
163 Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend into %s\n"),
165 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
168 /* Suppress message for /dev filesystems */
169 if (strncmp(ff_pkt->fname, "/dev/", 5) != 0) {
170 Jmsg(jcr, M_INFO, 1, _(" Filesystem change prohibited. Will not descend into %s\n"),
173 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
176 Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend into %s\n"),
178 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
181 Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
184 Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
187 Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
190 Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
194 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname,
195 be.strerror(ff_pkt->ff_errno));
201 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link %s: ERR=%s\n"), ff_pkt->fname,
202 be.strerror(ff_pkt->ff_errno));
208 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname,
209 be.strerror(ff_pkt->ff_errno));
215 Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
218 Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
222 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory %s: ERR=%s\n"), ff_pkt->fname,
223 be.strerror(ff_pkt->ff_errno));
228 Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname);
233 Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
236 * Setup for digest handling. If this fails, the digest will be set to NULL
239 if (ff_pkt->flags & FO_MD5) {
240 digest = crypto_digest_new(CRYPTO_DIGEST_MD5);
241 digest_stream = STREAM_MD5_DIGEST;
243 } else if (ff_pkt->flags & FO_SHA1) {
244 digest = crypto_digest_new(CRYPTO_DIGEST_SHA1);
245 digest_stream = STREAM_SHA1_DIGEST;
247 } else if (ff_pkt->flags & FO_SHA256) {
248 digest = crypto_digest_new(CRYPTO_DIGEST_SHA256);
249 digest_stream = STREAM_SHA256_DIGEST;
251 } else if (ff_pkt->flags & FO_SHA512) {
252 digest = crypto_digest_new(CRYPTO_DIGEST_SHA512);
253 digest_stream = STREAM_SHA512_DIGEST;
256 /* Did digest initialization fail? */
257 if (digest_stream != STREAM_NONE && digest == NULL) {
258 Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
259 stream_to_ascii(digest_stream));
263 * Set up signature digest handling. If this fails, the signature digest will be set to
266 // TODO landonf: We should really only calculate the digest once, for both verification and signing.
268 signing_digest = crypto_digest_new(signing_algorithm);
271 /* Full-stop if a failure occured initializing the signature digest */
272 if (jcr->pki_sign && signing_digest == NULL) {
273 Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
274 stream_to_ascii(signing_algorithm));
279 /* Initialise the file descriptor we use for data and other streams. */
281 if (ff_pkt->flags & FO_PORTABLE) {
282 set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
284 if (ff_pkt->reader) {
285 if (!set_prog(&ff_pkt->bfd, ff_pkt->reader, jcr)) {
286 Jmsg(jcr, M_FATAL, 0, _("Python reader program \"%s\" not found.\n"),
292 /* Send attributes -- must be done after binit() */
293 if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
298 * Open any file with data that we intend to save, then save it.
300 * Note, if is_win32_backup, we must open the Directory so that
301 * the BackupRead will save its permissions and ownership streams.
303 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
304 ff_pkt->statp.st_size > 0) ||
305 ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
306 (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
308 if (ff_pkt->type == FT_FIFO) {
309 tid = start_thread_timer(pthread_self(), 60);
313 if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
314 ff_pkt->ff_errno = errno;
316 Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname,
320 stop_thread_timer(tid);
326 stop_thread_timer(tid);
329 stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
330 bclose(&ff_pkt->bfd);
336 #ifdef HAVE_DARWIN_OS
337 /* Regular files can have resource forks and Finder Info */
338 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
339 ff_pkt->flags & FO_HFSPLUS)) {
340 if (ff_pkt->hfsinfo.rsrclength > 0) {
342 if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
343 ff_pkt->ff_errno = errno;
345 Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname,
348 if (is_bopen(&ff_pkt->bfd)) {
349 bclose(&ff_pkt->bfd);
353 flags = ff_pkt->flags;
354 ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
355 stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, digest);
356 ff_pkt->flags = flags;
357 bclose(&ff_pkt->bfd);
363 Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
364 bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
365 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
366 memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
369 crypto_digest_update(digest, sd->msg, sd->msglen);
371 if (signature_digest) {
372 crypto_digest_update(signature_digest, sd->msg, sd->msglen);
375 bnet_sig(sd, BNET_EOD);
379 if (ff_pkt->flags & FO_ACL) {
380 /* Read access ACLs for files, dirs and links */
381 if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) {
384 /* Directories can have default ACLs too */
385 if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
386 if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) {
392 /* Terminate the signing digest and send it to the Storage daemon */
393 if (signing_digest) {
398 if ((sig = crypto_sign_new()) == NULL) {
399 Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for stream signature.\n"));
403 if (crypto_sign_add_signer(sig, signing_digest, jcr->pki_keypair) == false) {
404 Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
408 /* Get signature size */
409 if (crypto_sign_encode(sig, NULL, &size) == false) {
410 Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
414 /* Allocate signature data buffer */
421 /* Encode signature data */
422 if (crypto_sign_encode(sig, buf, &size) == false) {
423 Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
427 /* Send our header */
428 bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
429 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
431 /* Grow the bsock buffer to fit our message if necessary */
432 if ((size_t) sizeof_pool_memory(sd->msg) < size) {
433 sd->msg = realloc_pool_memory(sd->msg, size);
436 /* Copy our message over and send it */
437 memcpy(sd->msg, buf, size);
440 bnet_sig(sd, BNET_EOD); /* end of checksum */
442 crypto_digest_free(signing_digest);
443 crypto_sign_free(sig);
447 /* Terminate any digest and send it to Storage daemon and the Director */
449 char md[CRYPTO_DIGEST_MAX_SIZE];
454 if (crypto_digest_finalize(digest, &md, &size)) {
455 bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, digest_stream);
456 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
457 memcpy(sd->msg, md, size);
460 bnet_sig(sd, BNET_EOD); /* end of checksum */
463 crypto_digest_free(digest);
470 * Send data read from an already open file descriptor.
472 * We return 1 on sucess and 0 on errors.
475 * We use ff_pkt->statp.st_size when FO_SPARSE.
476 * Currently this is not a problem as the only other stream, resource forks,
477 * are not handled as sparse files.
479 int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signing_digest)
481 BSOCK *sd = jcr->store_bsock;
482 uint64_t fileAddr = 0; /* file address */
484 int rsize = jcr->buf_size; /* read buffer size */
486 #ifdef FD_NO_SEND_TEST
491 rbuf = sd->msg; /* read buffer */
492 wbuf = sd->msg; /* write buffer */
495 Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
499 uLong compress_len, max_compress_len = 0;
500 const Bytef *cbuf = NULL;
502 if (ff_pkt->flags & FO_GZIP) {
503 if (ff_pkt->flags & FO_SPARSE) {
504 cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
505 max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
507 cbuf = (Bytef *)jcr->compress_buf;
508 max_compress_len = jcr->compress_buf_size; /* set max length */
510 wbuf = jcr->compress_buf; /* compressed output here */
515 * Send Data header to Storage daemon
516 * <file-index> <stream> <info>
518 if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
519 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
523 Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
526 * Make space at beginning of buffer for fileAddr because this
527 * same buffer will be used for writing if compression if off.
529 if (ff_pkt->flags & FO_SPARSE) {
530 rbuf += SPARSE_FADDR_SIZE;
531 rsize -= SPARSE_FADDR_SIZE;
532 #ifdef HAVE_FREEBSD_OS
534 * To read FreeBSD partitions, the read size must be
537 rsize = (rsize/512) * 512;
541 /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
543 if (S_ISBLK(ff_pkt->statp.st_mode))
544 rsize = (rsize/512) * 512;
550 while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
553 /* Check for sparse blocks */
554 if (ff_pkt->flags & FO_SPARSE) {
556 if (sd->msglen == rsize &&
557 fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size ||
558 ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
559 (uint64_t)ff_pkt->statp.st_size == 0)) {
560 sparseBlock = is_buf_zero(rbuf, rsize);
563 ser_begin(wbuf, SPARSE_FADDR_SIZE);
564 ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
567 jcr->ReadBytes += sd->msglen; /* count bytes read */
568 fileAddr += sd->msglen;
570 /* Update checksum if requested */
572 crypto_digest_update(digest, rbuf, sd->msglen);
575 /* Update signing digest if requested */
576 if (signing_digest) {
577 crypto_digest_update(signing_digest, rbuf, sd->msglen);
581 /* Do compression if turned on */
582 if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
584 compress_len = max_compress_len;
585 Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
587 /* NOTE! This call modifies compress_len !!! */
588 if ((zstat=compress2((Bytef *)cbuf, &compress_len,
589 (const Bytef *)rbuf, (uLong)sd->msglen,
590 ff_pkt->GZIP_level)) != Z_OK) {
591 Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
594 set_jcr_job_status(jcr, JS_ErrorTerminated);
597 Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
598 compress_len, sd->msglen);
600 sd->msglen = compress_len; /* set compressed length */
604 /* Send the buffer to the Storage daemon */
606 if (ff_pkt->flags & FO_SPARSE) {
607 sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
609 sd->msg = wbuf; /* set correct write buffer */
610 if (!bnet_send(sd)) {
611 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
613 sd->msg = msgsave; /* restore bnet buffer */
618 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
620 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed */
621 sd->msg = msgsave; /* restore read buffer */
623 } /* end while read file data */
626 if (sd->msglen < 0) {
628 Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
629 ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
630 if (jcr->Errors++ > 1000) { /* insanity check */
631 Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
636 if (!bnet_sig(sd, BNET_EOD)) { /* indicate end of file data */
637 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
646 * Read and send an ACL for the last encountered file.
648 static bool read_and_send_acl(JCR *jcr, int acltype, int stream)
651 BSOCK *sd = jcr->store_bsock;
654 #ifdef FD_NO_SEND_TEST
658 len = bacl_get(jcr, acltype);
660 Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
664 return true; /* no ACL */
668 if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
669 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
674 /* Send the buffer to the storage deamon */
675 Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
677 sd->msg = jcr->acl_text;
678 sd->msglen = len + 1;
679 if (!bnet_send(sd)) {
682 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
687 jcr->JobBytes += sd->msglen;
689 if (!bnet_sig(sd, BNET_EOD)) {
690 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
695 Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
700 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
702 BSOCK *sd = jcr->store_bsock;
703 char attribs[MAXSTRING];
704 char attribsEx[MAXSTRING];
707 #ifdef FD_NO_SEND_TEST
711 /* Find what data stream we will use, then encode the attributes */
712 data_stream = select_data_stream(ff_pkt);
713 encode_stat(attribs, ff_pkt, data_stream);
715 /* Now possibly extend the attributes */
716 attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
718 Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
721 jcr->JobFiles++; /* increment number of files sent */
722 ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
723 pm_strcpy(jcr->last_fname, ff_pkt->fname);
727 * Send Attributes header to Storage daemon
728 * <file-index> <stream> <info>
730 if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
731 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
735 Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
738 * Send file attributes to Storage daemon
741 * Filename (full path)
743 * Link name (if type==FT_LNK or FT_LNKSAVED)
744 * Encoded extended-attributes (for Win32)
746 * For a directory, link is the same as fname, but with trailing
747 * slash. For a linked file, link is the link.
749 if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
750 Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
751 stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
752 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
754 } else if (ff_pkt->type == FT_DIREND) {
755 /* Here link is the canonical filename (i.e. with trailing slash) */
756 stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
757 ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
759 stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
760 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
763 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
765 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
769 bnet_sig(sd, BNET_EOD); /* indicate end of attributes data */