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);
235 if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
240 * Setup for digest handling. If this fails, the digest will be set to NULL
243 if (ff_pkt->flags & FO_MD5) {
244 digest = crypto_digest_new(CRYPTO_DIGEST_MD5);
245 digest_stream = STREAM_MD5_DIGEST;
247 } else if (ff_pkt->flags & FO_SHA1) {
248 digest = crypto_digest_new(CRYPTO_DIGEST_SHA1);
249 digest_stream = STREAM_SHA1_DIGEST;
251 } else if (ff_pkt->flags & FO_SHA256) {
252 digest = crypto_digest_new(CRYPTO_DIGEST_SHA256);
253 digest_stream = STREAM_SHA256_DIGEST;
255 } else if (ff_pkt->flags & FO_SHA512) {
256 digest = crypto_digest_new(CRYPTO_DIGEST_SHA512);
257 digest_stream = STREAM_SHA512_DIGEST;
260 /* Did digest initialization fail? */
261 if (digest_stream != STREAM_NONE && digest == NULL) {
262 Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
263 stream_to_ascii(digest_stream));
267 * Set up signature digest handling. If this fails, the signature digest will be set to
270 // TODO landonf: We should really only calculate the digest once, for both verification and signing.
272 signing_digest = crypto_digest_new(signing_algorithm);
275 /* Full-stop if a failure occured initializing the signature digest */
276 if (jcr->pki_sign && signing_digest == NULL) {
277 Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
278 stream_to_ascii(signing_algorithm));
283 /* Initialise the file descriptor we use for data and other streams. */
285 if (ff_pkt->flags & FO_PORTABLE) {
286 set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
288 if (ff_pkt->reader) {
289 if (!set_prog(&ff_pkt->bfd, ff_pkt->reader, jcr)) {
290 Jmsg(jcr, M_FATAL, 0, _("Python reader program \"%s\" not found.\n"),
297 * Open any file with data that we intend to save, then save it.
299 * Note, if is_win32_backup, we must open the Directory so that
300 * the BackupRead will save its permissions and ownership streams.
302 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
303 ff_pkt->statp.st_size > 0) ||
304 ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
305 (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
307 if (ff_pkt->type == FT_FIFO) {
308 tid = start_thread_timer(pthread_self(), 60);
312 if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
313 ff_pkt->ff_errno = errno;
315 Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname,
319 stop_thread_timer(tid);
325 stop_thread_timer(tid);
328 stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
329 bclose(&ff_pkt->bfd);
335 #ifdef HAVE_DARWIN_OS
336 /* Regular files can have resource forks and Finder Info */
337 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
338 ff_pkt->flags & FO_HFSPLUS)) {
339 if (ff_pkt->hfsinfo.rsrclength > 0) {
341 if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
342 ff_pkt->ff_errno = errno;
344 Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname,
347 if (is_bopen(&ff_pkt->bfd)) {
348 bclose(&ff_pkt->bfd);
352 flags = ff_pkt->flags;
353 ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
354 stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, digest);
355 ff_pkt->flags = flags;
356 bclose(&ff_pkt->bfd);
362 Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
363 bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
364 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
365 memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
368 crypto_digest_update(digest, sd->msg, sd->msglen);
370 if (signature_digest) {
371 crypto_digest_update(signature_digest, sd->msg, sd->msglen);
374 bnet_sig(sd, BNET_EOD);
378 if (ff_pkt->flags & FO_ACL) {
379 /* Read access ACLs for files, dirs and links */
380 if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) {
383 /* Directories can have default ACLs too */
384 if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
385 if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) {
391 /* Terminate the signing digest and send it to the Storage daemon */
392 if (signing_digest) {
397 if ((sig = crypto_sign_new()) == NULL) {
398 Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for stream signature.\n"));
402 if (crypto_sign_add_signer(sig, signing_digest, jcr->pki_keypair) == false) {
403 Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
407 /* Get signature size */
408 if (crypto_sign_encode(sig, NULL, &size) == false) {
409 Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
413 /* Allocate signature data buffer */
420 /* Encode signature data */
421 if (crypto_sign_encode(sig, buf, &size) == false) {
422 Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
426 /* Send our header */
427 bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
428 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
430 /* Grow the bsock buffer to fit our message if necessary */
431 if ((size_t) sizeof_pool_memory(sd->msg) < size) {
432 sd->msg = realloc_pool_memory(sd->msg, size);
435 /* Copy our message over and send it */
436 memcpy(sd->msg, buf, size);
439 bnet_sig(sd, BNET_EOD); /* end of checksum */
441 crypto_digest_free(signing_digest);
442 crypto_sign_free(sig);
446 /* Terminate any digest and send it to Storage daemon and the Director */
448 char md[CRYPTO_DIGEST_MAX_SIZE];
453 if (crypto_digest_finalize(digest, &md, &size) == true) {
454 bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, digest_stream);
455 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
456 memcpy(sd->msg, md, size);
459 bnet_sig(sd, BNET_EOD); /* end of checksum */
462 crypto_digest_free(digest);
469 * Send data read from an already open file descriptor.
471 * We return 1 on sucess and 0 on errors.
474 * We use ff_pkt->statp.st_size when FO_SPARSE.
475 * Currently this is not a problem as the only other stream, resource forks,
476 * are not handled as sparse files.
478 int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signing_digest)
480 BSOCK *sd = jcr->store_bsock;
481 uint64_t fileAddr = 0; /* file address */
483 int rsize = jcr->buf_size; /* read buffer size */
485 #ifdef FD_NO_SEND_TEST
490 rbuf = sd->msg; /* read buffer */
491 wbuf = sd->msg; /* write buffer */
494 Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
498 uLong compress_len, max_compress_len = 0;
499 const Bytef *cbuf = NULL;
501 if (ff_pkt->flags & FO_GZIP) {
502 if (ff_pkt->flags & FO_SPARSE) {
503 cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
504 max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
506 cbuf = (Bytef *)jcr->compress_buf;
507 max_compress_len = jcr->compress_buf_size; /* set max length */
509 wbuf = jcr->compress_buf; /* compressed output here */
514 * Send Data header to Storage daemon
515 * <file-index> <stream> <info>
517 if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
518 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
522 Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
525 * Make space at beginning of buffer for fileAddr because this
526 * same buffer will be used for writing if compression if off.
528 if (ff_pkt->flags & FO_SPARSE) {
529 rbuf += SPARSE_FADDR_SIZE;
530 rsize -= SPARSE_FADDR_SIZE;
531 #ifdef HAVE_FREEBSD_OS
533 * To read FreeBSD partitions, the read size must be
536 rsize = (rsize/512) * 512;
540 /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
542 if (S_ISBLK(ff_pkt->statp.st_mode))
543 rsize = (rsize/512) * 512;
549 while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
552 /* Check for sparse blocks */
553 if (ff_pkt->flags & FO_SPARSE) {
555 if (sd->msglen == rsize &&
556 fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size ||
557 ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
558 (uint64_t)ff_pkt->statp.st_size == 0)) {
559 sparseBlock = is_buf_zero(rbuf, rsize);
562 ser_begin(wbuf, SPARSE_FADDR_SIZE);
563 ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
566 jcr->ReadBytes += sd->msglen; /* count bytes read */
567 fileAddr += sd->msglen;
569 /* Update checksum if requested */
571 crypto_digest_update(digest, rbuf, sd->msglen);
574 /* Update signing digest if requested */
575 if (signing_digest) {
576 crypto_digest_update(signing_digest, rbuf, sd->msglen);
580 /* Do compression if turned on */
581 if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
583 compress_len = max_compress_len;
584 Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
586 /* NOTE! This call modifies compress_len !!! */
587 if ((zstat=compress2((Bytef *)cbuf, &compress_len,
588 (const Bytef *)rbuf, (uLong)sd->msglen,
589 ff_pkt->GZIP_level)) != Z_OK) {
590 Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
593 set_jcr_job_status(jcr, JS_ErrorTerminated);
596 Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
597 compress_len, sd->msglen);
599 sd->msglen = compress_len; /* set compressed length */
603 /* Send the buffer to the Storage daemon */
605 if (ff_pkt->flags & FO_SPARSE) {
606 sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
608 sd->msg = wbuf; /* set correct write buffer */
609 if (!bnet_send(sd)) {
610 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
612 sd->msg = msgsave; /* restore bnet buffer */
617 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
619 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed */
620 sd->msg = msgsave; /* restore read buffer */
622 } /* end while read file data */
625 if (sd->msglen < 0) {
627 Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
628 ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
629 if (jcr->Errors++ > 1000) { /* insanity check */
630 Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
635 if (!bnet_sig(sd, BNET_EOD)) { /* indicate end of file data */
636 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
645 * Read and send an ACL for the last encountered file.
647 static bool read_and_send_acl(JCR *jcr, int acltype, int stream)
650 BSOCK *sd = jcr->store_bsock;
653 #ifdef FD_NO_SEND_TEST
657 len = bacl_get(jcr, acltype);
659 Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
663 return true; /* no ACL */
667 if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
668 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
673 /* Send the buffer to the storage deamon */
674 Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
676 sd->msg = jcr->acl_text;
677 sd->msglen = len + 1;
678 if (!bnet_send(sd)) {
681 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
686 jcr->JobBytes += sd->msglen;
688 if (!bnet_sig(sd, BNET_EOD)) {
689 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
694 Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
699 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
701 BSOCK *sd = jcr->store_bsock;
702 char attribs[MAXSTRING];
703 char attribsEx[MAXSTRING];
706 #ifdef FD_NO_SEND_TEST
710 /* Find what data stream we will use, then encode the attributes */
711 data_stream = select_data_stream(ff_pkt);
712 encode_stat(attribs, ff_pkt, data_stream);
714 /* Now possibly extend the attributes */
715 attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
717 Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
720 jcr->JobFiles++; /* increment number of files sent */
721 ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
722 pm_strcpy(jcr->last_fname, ff_pkt->fname);
726 * Send Attributes header to Storage daemon
727 * <file-index> <stream> <info>
729 if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
730 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
734 Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
737 * Send file attributes to Storage daemon
740 * Filename (full path)
742 * Link name (if type==FT_LNK or FT_LNKSAVED)
743 * Encoded extended-attributes (for Win32)
745 * For a directory, link is the same as fname, but with trailing
746 * slash. For a linked file, link is the link.
748 if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
749 Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
750 stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
751 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
753 } else if (ff_pkt->type == FT_DIREND) {
754 /* Here link is the canonical filename (i.e. with trailing slash) */
755 stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
756 ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
758 stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
759 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
762 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
764 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
768 bnet_sig(sd, BNET_EOD); /* indicate end of attributes data */