2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Bacula File Daemon backup.c send file attributes and data
30 * to the Storage daemon.
32 * Kern Sibbald, March MM
41 const bool have_darwin_os = true;
43 const bool have_darwin_os = false;
47 const bool have_acl = true;
49 const bool have_acl = false;
52 #if defined(HAVE_XATTR)
53 const bool have_xattr = true;
55 const bool have_xattr = false;
58 /* Forward referenced functions */
59 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level);
60 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
61 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
62 static bool crypto_session_start(JCR *jcr);
63 static void crypto_session_end(JCR *jcr);
64 static bool crypto_session_send(JCR *jcr, BSOCK *sd);
65 static void close_vss_backup_session(JCR *jcr);
68 * Find all the requested files and send them
69 * to the Storage daemon.
71 * Note, we normally carry on a one-way
72 * conversation from this point on with the SD, simply blasting
73 * data to him. To properly know what is going on, we
74 * also run a "heartbeat" monitor which reads the socket and
75 * reacts accordingly (at the moment it has nothing to do
76 * except echo the heartbeat to the Director).
79 bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
83 // TODO landonf: Allow user to specify encryption algorithm
85 sd = jcr->store_bsock;
87 jcr->setJobStatus(JS_Running);
89 Dmsg1(300, "bfiled: opened data connection %d to stored\n", sd->m_fd);
92 CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
96 buf_size = client->max_network_buffer_size;
98 buf_size = 0; /* use default */
100 if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) {
101 jcr->setJobStatus(JS_ErrorTerminated);
102 Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
106 jcr->buf_size = sd->msglen;
108 * Adjust for compression so that output buffer is
109 * 12 bytes + 0.1% larger than input buffer plus 18 bytes.
110 * This gives a bit extra plus room for the sparse addr if any.
111 * Note, we adjust the read size to be smaller so that the
112 * same output buffer can be used without growing it.
114 * For LZO1X compression the recommended value is :
115 * output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + sizeof(comp_stream_header)
117 * The zlib compression workset is initialized here to minimize
118 * the "per file" load. The jcr member is only set, if the init
121 * For the same reason, lzo compression is initialized here.
124 jcr->compress_buf_size = MAX(jcr->buf_size + (jcr->buf_size / 16) + 67 + (int)sizeof(comp_stream_header), jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30);
125 jcr->compress_buf = get_memory(jcr->compress_buf_size);
127 jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
128 jcr->compress_buf = get_memory(jcr->compress_buf_size);
132 z_stream *pZlibStream = (z_stream*)malloc(sizeof(z_stream));
134 pZlibStream->zalloc = Z_NULL;
135 pZlibStream->zfree = Z_NULL;
136 pZlibStream->opaque = Z_NULL;
137 pZlibStream->state = Z_NULL;
139 if (deflateInit(pZlibStream, Z_DEFAULT_COMPRESSION) == Z_OK) {
140 jcr->pZLIB_compress_workset = pZlibStream;
148 lzo_voidp pLzoMem = (lzo_voidp) malloc(LZO1X_1_MEM_COMPRESS);
150 if (lzo_init() == LZO_E_OK) {
151 jcr->LZO_compress_workset = pLzoMem;
158 if (!crypto_session_start(jcr)) {
162 set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
164 /** in accurate mode, we overload the find_one check function */
166 set_find_changed_function((FF_PKT *)jcr->ff, accurate_check_file);
169 start_heartbeat_monitor(jcr);
172 jcr->acl_data = (acl_data_t *)malloc(sizeof(acl_data_t));
173 memset((caddr_t)jcr->acl_data, 0, sizeof(acl_data_t));
174 jcr->acl_data->content = get_pool_memory(PM_MESSAGE);
178 jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
179 memset((caddr_t)jcr->xattr_data, 0, sizeof(xattr_data_t));
180 jcr->xattr_data->content = get_pool_memory(PM_MESSAGE);
183 /** Subroutine save_file() is called for each file */
184 if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
185 ok = false; /* error */
186 jcr->setJobStatus(JS_ErrorTerminated);
189 if (have_acl && jcr->acl_data->nr_errors > 0) {
190 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing backup\n"),
191 jcr->acl_data->nr_errors);
193 if (have_xattr && jcr->xattr_data->nr_errors > 0) {
194 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing backup\n"),
195 jcr->xattr_data->nr_errors);
198 close_vss_backup_session(jcr);
200 accurate_finish(jcr); /* send deleted or base file list to SD */
202 stop_heartbeat_monitor(jcr);
204 sd->signal(BNET_EOD); /* end of sending data */
206 if (have_acl && jcr->acl_data) {
207 free_pool_memory(jcr->acl_data->content);
209 jcr->acl_data = NULL;
211 if (have_xattr && jcr->xattr_data) {
212 free_pool_memory(jcr->xattr_data->content);
213 free(jcr->xattr_data);
214 jcr->xattr_data = NULL;
220 if (jcr->compress_buf) {
221 free_pool_memory(jcr->compress_buf);
222 jcr->compress_buf = NULL;
224 if (jcr->pZLIB_compress_workset) {
225 /* Free the zlib stream */
227 deflateEnd((z_stream *)jcr->pZLIB_compress_workset);
229 free (jcr->pZLIB_compress_workset);
230 jcr->pZLIB_compress_workset = NULL;
232 if (jcr->LZO_compress_workset) {
233 free (jcr->LZO_compress_workset);
234 jcr->LZO_compress_workset = NULL;
237 crypto_session_end(jcr);
240 Dmsg1(100, "end blast_data ok=%d\n", ok);
244 static bool crypto_session_start(JCR *jcr)
246 crypto_cipher_t cipher = CRYPTO_CIPHER_AES_128_CBC;
249 * Create encryption session data and a cached, DER-encoded session data
250 * structure. We use a single session key for each backup, so we'll encode
251 * the session data only once.
253 if (jcr->crypto.pki_encrypt) {
256 /** Create per-job session encryption context */
257 jcr->crypto.pki_session = crypto_session_new(cipher, jcr->crypto.pki_recipients);
259 /** Get the session data size */
260 if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)0, &size)) {
261 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
265 /** Allocate buffer */
266 jcr->crypto.pki_session_encoded = get_memory(size);
268 /** Encode session data */
269 if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)jcr->crypto.pki_session_encoded, &size)) {
270 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
274 /** ... and store the encoded size */
275 jcr->crypto.pki_session_encoded_size = size;
277 /** Allocate the encryption/decryption buffer */
278 jcr->crypto.crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
283 static void crypto_session_end(JCR *jcr)
285 if (jcr->crypto.crypto_buf) {
286 free_pool_memory(jcr->crypto.crypto_buf);
287 jcr->crypto.crypto_buf = NULL;
289 if (jcr->crypto.pki_session) {
290 crypto_session_free(jcr->crypto.pki_session);
292 if (jcr->crypto.pki_session_encoded) {
293 free_pool_memory(jcr->crypto.pki_session_encoded);
294 jcr->crypto.pki_session_encoded = NULL;
298 static bool crypto_session_send(JCR *jcr, BSOCK *sd)
302 /** Send our header */
303 Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
304 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
307 sd->msg = jcr->crypto.pki_session_encoded;
308 sd->msglen = jcr->crypto.pki_session_encoded_size;
309 jcr->JobBytes += sd->msglen;
311 Dmsg1(100, "Send data len=%d\n", sd->msglen);
314 sd->signal(BNET_EOD);
320 * Called here by find() for each file included.
321 * This is a callback. The original is find_files() above.
323 * Send the file and its data to the Storage daemon.
327 * -1 to ignore file/directory (not used here)
329 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
331 bool do_read = false;
332 bool plugin_started = false;
333 bool do_plugin_set = false;
334 int stat, data_stream;
336 DIGEST *digest = NULL;
337 DIGEST *signing_digest = NULL;
338 int digest_stream = STREAM_NONE;
339 SIGNATURE *sig = NULL;
340 bool has_file_data = false;
341 struct save_pkt sp; /* use by option plugin */
342 // TODO landonf: Allow the user to specify the digest algorithm
344 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
346 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
348 BSOCK *sd = jcr->store_bsock;
350 if (jcr->is_canceled() || jcr->is_incomplete()) {
354 jcr->num_files_examined++; /* bump total file count */
356 switch (ff_pkt->type) {
357 case FT_LNKSAVED: /* Hard linked, file already saved */
358 Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
361 Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
362 has_file_data = true;
365 Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
366 has_file_data = true;
369 Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
371 case FT_RESTORE_FIRST:
372 Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname);
374 case FT_PLUGIN_CONFIG:
375 Dmsg1(100, "FT_PLUGIN_CONFIG saving: %s\n", ff_pkt->fname);
378 jcr->num_files_examined--; /* correct file count */
379 return 1; /* not used */
381 Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"),
382 ff_pkt->top_fname, ff_pkt->fname);
383 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
386 /* Suppress message for /dev filesystems */
387 if (!is_in_fileset(ff_pkt)) {
388 Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"),
389 ff_pkt->fname, ff_pkt->top_fname);
391 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
394 Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"),
395 ff_pkt->top_fname, ff_pkt->fname);
396 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
399 Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"),
405 Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
408 Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
409 if (S_ISSOCK(ff_pkt->statp.st_mode)) {
410 Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname);
415 Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
416 has_file_data = true;
419 Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
423 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
424 be.bstrerror(ff_pkt->ff_errno));
430 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"),
431 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
437 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
438 be.bstrerror(ff_pkt->ff_errno));
444 Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
447 Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
451 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"),
452 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
457 Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"),
458 ff_pkt->type, ff_pkt->fname);
463 Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
465 /** Digests and encryption are only useful if there's file data */
468 * Setup for digest handling. If this fails, the digest will be set to NULL
469 * and not used. Note, the digest (file hash) can be any one of the four
472 * The signing digest is a single algorithm depending on
473 * whether or not we have SHA2.
474 * ****FIXME**** the signing algoritm should really be
475 * determined a different way!!!!!! What happens if
476 * sha2 was available during backup but not restore?
478 if (ff_pkt->flags & FO_MD5) {
479 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
480 digest_stream = STREAM_MD5_DIGEST;
482 } else if (ff_pkt->flags & FO_SHA1) {
483 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
484 digest_stream = STREAM_SHA1_DIGEST;
486 } else if (ff_pkt->flags & FO_SHA256) {
487 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
488 digest_stream = STREAM_SHA256_DIGEST;
490 } else if (ff_pkt->flags & FO_SHA512) {
491 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
492 digest_stream = STREAM_SHA512_DIGEST;
495 /** Did digest initialization fail? */
496 if (digest_stream != STREAM_NONE && digest == NULL) {
497 Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
498 stream_to_ascii(digest_stream));
502 * Set up signature digest handling. If this fails, the signature digest
503 * will be set to NULL and not used.
505 /* TODO landonf: We should really only calculate the digest once, for
506 * both verification and signing.
508 if (jcr->crypto.pki_sign) {
509 signing_digest = crypto_digest_new(jcr, signing_algorithm);
511 /** Full-stop if a failure occurred initializing the signature digest */
512 if (signing_digest == NULL) {
513 Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
514 stream_to_ascii(signing_algorithm));
520 /** Enable encryption */
521 if (jcr->crypto.pki_encrypt) {
522 ff_pkt->flags |= FO_ENCRYPT;
526 /** Initialize the file descriptor we use for data and other streams. */
528 if (ff_pkt->flags & FO_PORTABLE) {
529 set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
532 if (ff_pkt->cmd_plugin) {
533 do_plugin_set = true;
535 /* option and cmd plugin are not compatible together */
536 } else if (ff_pkt->opt_plugin) {
538 /* ask the option plugin what to do with this file */
539 switch (plugin_option_handle_file(jcr, ff_pkt, &sp)) {
541 Dmsg2(10, "Option plugin %s will be used to backup %s\n",
542 ff_pkt->plugin, ff_pkt->fname);
543 do_plugin_set = true;
546 Dmsg2(10, "Option plugin %s decided to skip %s\n",
547 ff_pkt->plugin, ff_pkt->fname);
550 Dmsg2(10, "Option plugin %s decided to let bacula handle %s\n",
551 ff_pkt->plugin, ff_pkt->fname);
557 /* Tell bfile that it needs to call plugin */
558 if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
561 send_plugin_name(jcr, sd, true); /* signal start of plugin data */
562 plugin_started = true;
565 /** Send attributes -- must be done after binit() */
566 if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
569 /** Meta data only for restore object */
570 if (IS_FT_OBJECT(ff_pkt->type)) {
574 /** Set up the encryption context and send the session data to the SD */
575 if (has_file_data && jcr->crypto.pki_encrypt) {
576 if (!crypto_session_send(jcr, sd)) {
582 * Open any file with data that we intend to save, then save it.
584 * Note, if is_win32_backup, we must open the Directory so that
585 * the BackupRead will save its permissions and ownership streams.
587 if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
589 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
591 do_read = ff_pkt->statp.st_size > 0;
593 } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
594 ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION ||
595 (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
599 if (ff_pkt->cmd_plugin) {
603 Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read);
607 if (ff_pkt->type == FT_FIFO) {
608 tid = start_thread_timer(jcr, pthread_self(), 60);
612 int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
613 ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE ||
614 ff_pkt->type == FT_JUNCTION);
615 if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
616 ff_pkt->ff_errno = errno;
618 Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
622 stop_thread_timer(tid);
628 stop_thread_timer(tid);
632 stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
634 if (ff_pkt->flags & FO_CHKCHANGES) {
635 has_file_changed(jcr, ff_pkt);
638 bclose(&ff_pkt->bfd);
645 if (have_darwin_os) {
646 /** Regular files can have resource forks and Finder Info */
647 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
648 ff_pkt->flags & FO_HFSPLUS)) {
649 if (ff_pkt->hfsinfo.rsrclength > 0) {
652 if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
653 ff_pkt->ff_errno = errno;
655 Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"),
656 ff_pkt->fname, be.bstrerror());
658 if (is_bopen(&ff_pkt->bfd)) {
659 bclose(&ff_pkt->bfd);
663 flags = ff_pkt->flags;
664 ff_pkt->flags &= ~(FO_COMPRESS|FO_SPARSE|FO_OFFSETS);
665 if (flags & FO_ENCRYPT) {
666 rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
668 rsrc_stream = STREAM_MACOS_FORK_DATA;
670 stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
671 ff_pkt->flags = flags;
672 bclose(&ff_pkt->bfd);
678 Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
679 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
680 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
681 pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
684 crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
686 if (signing_digest) {
687 crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
690 sd->signal(BNET_EOD);
695 * Save ACLs when requested and available for anything not being a symlink
696 * and not being a plugin.
699 if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
700 switch (build_acl_streams(jcr, ff_pkt)) {
701 case bacl_exit_fatal:
703 case bacl_exit_error:
705 * Non-fatal errors, count them and when the number is under
706 * ACL_REPORT_ERR_MAX_PER_JOB print the error message set by the
707 * lower level routine in jcr->errmsg.
709 if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
710 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
712 jcr->acl_data->nr_errors++;
721 * Save Extended Attributes when requested and available for all files not
725 if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
726 switch (build_xattr_streams(jcr, ff_pkt)) {
727 case bxattr_exit_fatal:
729 case bxattr_exit_error:
731 * Non-fatal errors, count them and when the number is under
732 * XATTR_REPORT_ERR_MAX_PER_JOB print the error message set by the
733 * lower level routine in jcr->errmsg.
735 if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
736 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
738 jcr->xattr_data->nr_errors++;
746 /** Terminate the signing digest and send it to the Storage daemon */
747 if (signing_digest) {
750 if ((sig = crypto_sign_new(jcr)) == NULL) {
751 Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
755 if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
756 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
760 /** Get signature size */
761 if (!crypto_sign_encode(sig, NULL, &size)) {
762 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
766 /** Grow the bsock buffer to fit our message if necessary */
767 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
768 sd->msg = realloc_pool_memory(sd->msg, size);
771 /** Send our header */
772 sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
773 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
775 /** Encode signature data */
776 if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
777 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
783 sd->signal(BNET_EOD); /* end of checksum */
786 /** Terminate any digest and send it to Storage daemon */
790 sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
791 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
793 size = CRYPTO_DIGEST_MAX_SIZE;
795 /** Grow the bsock buffer to fit our message if necessary */
796 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
797 sd->msg = realloc_pool_memory(sd->msg, size);
800 if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
801 Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
805 /* Keep the checksum if this file is a hardlink */
806 if (ff_pkt->linked) {
807 ff_pkt_set_link_digest(ff_pkt, digest_stream, sd->msg, size);
812 sd->signal(BNET_EOD); /* end of checksum */
815 /* Check if original file has a digest, and send it */
816 if (ff_pkt->type == FT_LNKSAVED && ff_pkt->digest) {
817 Dmsg2(300, "Link %s digest %d\n", ff_pkt->fname, ff_pkt->digest_len);
818 sd->fsend("%ld %d 0", jcr->JobFiles, ff_pkt->digest_stream);
820 sd->msg = check_pool_memory_size(sd->msg, ff_pkt->digest_len);
821 memcpy(sd->msg, ff_pkt->digest, ff_pkt->digest_len);
822 sd->msglen = ff_pkt->digest_len;
825 sd->signal(BNET_EOD); /* end of hardlink record */
829 rtnstat = jcr->is_canceled() ? 0 : 1; /* good return if not canceled */
832 if (jcr->is_incomplete() || jcr->is_canceled()) {
835 if (plugin_started) {
836 send_plugin_name(jcr, sd, false); /* signal end of plugin data */
838 if (ff_pkt->opt_plugin) {
839 jcr->plugin_sp = NULL; /* sp is local to this function */
840 jcr->plugin_ctx = NULL;
842 jcr->opt_plugin = false;
845 crypto_digest_free(digest);
847 if (signing_digest) {
848 crypto_digest_free(signing_digest);
851 crypto_sign_free(sig);
857 * Send data read from an already open file descriptor.
859 * We return 1 on sucess and 0 on errors.
862 * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
864 * Currently this is not a problem as the only other stream, resource forks,
865 * are not handled as sparse files.
867 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
868 DIGEST *signing_digest)
870 BSOCK *sd = jcr->store_bsock;
871 uint64_t fileAddr = 0; /* file address */
873 int32_t rsize = jcr->buf_size; /* read buffer size */
875 CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
876 const uint8_t *cipher_input;
877 uint32_t cipher_input_len;
878 uint32_t cipher_block_size;
879 uint32_t encrypted_len;
880 #ifdef FD_NO_SEND_TEST
885 rbuf = sd->msg; /* read buffer */
886 wbuf = sd->msg; /* write buffer */
887 cipher_input = (uint8_t *)rbuf; /* encrypt uncompressed data */
889 Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
891 #if defined(HAVE_LIBZ) || defined(HAVE_LZO)
892 uLong compress_len = 0;
893 uLong max_compress_len = 0;
894 const Bytef *cbuf = NULL;
898 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_GZIP) {
899 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
900 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
901 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
903 cbuf = (Bytef *)jcr->compress_buf;
904 max_compress_len = jcr->compress_buf_size; /* set max length */
906 wbuf = jcr->compress_buf; /* compressed output here */
907 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
910 * Only change zlib parameters if there is no pending operation.
911 * This should never happen as deflatereset is called after each
915 if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
916 /** set gzip compression level - must be done per file */
917 if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset,
918 ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
919 Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
920 jcr->setJobStatus(JS_ErrorTerminated);
929 comp_stream_header ch;
931 memset(&ch, 0, sizeof(comp_stream_header));
934 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_LZO1X) {
935 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
936 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
937 cbuf2 = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
938 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
940 cbuf = (Bytef *)jcr->compress_buf;
941 cbuf2 = (Bytef *)jcr->compress_buf + sizeof(comp_stream_header);
942 max_compress_len = jcr->compress_buf_size; /* set max length */
944 ch.magic = COMPRESS_LZO1X;
945 ch.version = COMP_HEAD_VERSION;
946 wbuf = jcr->compress_buf; /* compressed output here */
947 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
951 const uint32_t max_compress_len = 0;
954 if (ff_pkt->flags & FO_ENCRYPT) {
955 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
956 Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
959 /** Allocate the cipher context */
960 if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true,
961 &cipher_block_size)) == NULL) {
962 /* Shouldn't happen! */
963 Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
968 * Grow the crypto buffer, if necessary.
969 * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
970 * We grow crypto_buf to the maximum number of blocks that
971 * could be returned for the given read buffer size.
972 * (Using the larger of either rsize or max_compress_len)
974 jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf,
975 (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) +
976 cipher_block_size - 1) / cipher_block_size * cipher_block_size);
978 wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
982 * Send Data header to Storage daemon
983 * <file-index> <stream> <info>
985 if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
986 if (!jcr->is_job_canceled()) {
987 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
992 Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
995 * Make space at beginning of buffer for fileAddr because this
996 * same buffer will be used for writing if compression is off.
998 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
999 rbuf += OFFSET_FADDR_SIZE;
1000 rsize -= OFFSET_FADDR_SIZE;
1001 #ifdef HAVE_FREEBSD_OS
1003 * To read FreeBSD partitions, the read size must be
1004 * a multiple of 512.
1006 rsize = (rsize/512) * 512;
1010 /** a RAW device read on win32 only works if the buffer is a multiple of 512 */
1012 if (S_ISBLK(ff_pkt->statp.st_mode))
1013 rsize = (rsize/512) * 512;
1017 * Read the file data
1019 while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
1021 /** Check for sparse blocks */
1022 if (ff_pkt->flags & FO_SPARSE) {
1024 bool allZeros = false;
1025 if ((sd->msglen == rsize &&
1026 fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
1027 ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
1028 (uint64_t)ff_pkt->statp.st_size == 0)) {
1029 allZeros = is_buf_zero(rbuf, rsize);
1032 /** Put file address as first data in buffer */
1033 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1034 ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
1036 fileAddr += sd->msglen; /* update file address */
1037 /** Skip block of all zeros */
1039 continue; /* skip block of zeros */
1041 } else if (ff_pkt->flags & FO_OFFSETS) {
1043 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1044 ser_uint64(ff_pkt->bfd.offset); /* store offset in begin of buffer */
1047 jcr->ReadBytes += sd->msglen; /* count bytes read */
1049 /** Uncompressed cipher input length */
1050 cipher_input_len = sd->msglen;
1052 /** Update checksum if requested */
1054 crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
1057 /** Update signing digest if requested */
1058 if (signing_digest) {
1059 crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
1063 /** Do compression if turned on */
1064 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_GZIP && jcr->pZLIB_compress_workset) {
1065 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1067 ((z_stream*)jcr->pZLIB_compress_workset)->next_in = (Bytef *)rbuf;
1068 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in = sd->msglen;
1069 ((z_stream*)jcr->pZLIB_compress_workset)->next_out = (Bytef *)cbuf;
1070 ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;
1072 if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
1073 Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
1074 jcr->setJobStatus(JS_ErrorTerminated);
1077 compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
1078 /** reset zlib stream to be able to begin from scratch again */
1079 if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
1080 Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
1081 jcr->setJobStatus(JS_ErrorTerminated);
1085 Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", compress_len,
1088 sd->msglen = compress_len; /* set compressed length */
1089 cipher_input_len = compress_len;
1093 /** Do compression if turned on */
1094 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_LZO1X && jcr->LZO_compress_workset) {
1096 ser_begin(cbuf, sizeof(comp_stream_header));
1098 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1100 lzores = lzo1x_1_compress((const unsigned char*)rbuf, sd->msglen, cbuf2, &compress_len, jcr->LZO_compress_workset);
1101 if (lzores == LZO_E_OK && compress_len <= max_compress_len)
1103 /* complete header */
1104 ser_uint32(COMPRESS_LZO1X);
1105 ser_uint32(compress_len);
1106 ser_uint16(ch.level);
1107 ser_uint16(ch.version);
1109 /** this should NEVER happen */
1110 Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores);
1111 jcr->setJobStatus(JS_ErrorTerminated);
1115 Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", compress_len,
1118 compress_len += sizeof(comp_stream_header); /* add size of header */
1119 sd->msglen = compress_len; /* set compressed length */
1120 cipher_input_len = compress_len;
1125 * Note, here we prepend the current record length to the beginning
1126 * of the encrypted data. This is because both sparse and compression
1127 * restore handling want records returned to them with exactly the
1128 * same number of bytes that were processed in the backup handling.
1129 * That is, both are block filters rather than a stream. When doing
1130 * compression, the compression routines may buffer data, so that for
1131 * any one record compressed, when it is decompressed the same size
1132 * will not be obtained. Of course, the buffered data eventually comes
1133 * out in subsequent crypto_cipher_update() calls or at least
1134 * when crypto_cipher_finalize() is called. Unfortunately, this
1135 * "feature" of encryption enormously complicates the restore code.
1137 if (ff_pkt->flags & FO_ENCRYPT) {
1138 uint32_t initial_len = 0;
1141 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1142 cipher_input_len += OFFSET_FADDR_SIZE;
1145 /** Encrypt the length of the input block */
1146 uint8_t packet_len[sizeof(uint32_t)];
1148 ser_begin(packet_len, sizeof(uint32_t));
1149 ser_uint32(cipher_input_len); /* store data len in begin of buffer */
1150 Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);
1152 if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
1153 (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
1154 /** Encryption failed. Shouldn't happen. */
1155 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1159 /** Encrypt the input block */
1160 if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len,
1161 (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
1162 if ((initial_len + encrypted_len) == 0) {
1163 /** No full block of data available, read more data */
1166 Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len,
1168 sd->msglen = initial_len + encrypted_len; /* set encrypted length */
1170 /** Encryption failed. Shouldn't happen. */
1171 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1176 /* Send the buffer to the Storage daemon */
1177 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1178 sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
1180 sd->msg = wbuf; /* set correct write buffer */
1182 if (!jcr->is_job_canceled()) {
1183 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1188 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1190 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1191 sd->msg = msgsave; /* restore read buffer */
1193 } /* end while read file data */
1195 if (sd->msglen < 0) { /* error */
1197 Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
1198 ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
1199 if (jcr->JobErrors++ > 1000) { /* insanity check */
1200 Jmsg(jcr, M_FATAL, 0, _("Too many errors. JobErrors=%d.\n"), jcr->JobErrors);
1202 } else if (ff_pkt->flags & FO_ENCRYPT) {
1204 * For encryption, we must call finalize to push out any
1207 if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf,
1209 /* Padding failed. Shouldn't happen. */
1210 Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
1214 /** Note, on SSL pre-0.9.7, there is always some output */
1215 if (encrypted_len > 0) {
1216 sd->msglen = encrypted_len; /* set encrypted length */
1217 sd->msg = jcr->crypto.crypto_buf; /* set correct write buffer */
1219 if (!jcr->is_job_canceled()) {
1220 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1225 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1226 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1227 sd->msg = msgsave; /* restore bnet buffer */
1231 if (!sd->signal(BNET_EOD)) { /* indicate end of file data */
1232 if (!jcr->is_job_canceled()) {
1233 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1239 /** Free the cipher context */
1241 crypto_cipher_free(cipher_ctx);
1246 /** Free the cipher context */
1248 crypto_cipher_free(cipher_ctx);
1251 sd->msg = msgsave; /* restore bnet buffer */
1256 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
1258 BSOCK *sd = jcr->store_bsock;
1259 char attribs[MAXSTRING];
1260 char attribsExBuf[MAXSTRING];
1261 char *attribsEx = NULL;
1265 int hangup = get_hangup();
1266 #ifdef FD_NO_SEND_TEST
1270 Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
1271 /** Find what data stream we will use, then encode the attributes */
1272 if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
1273 /* This should not happen */
1274 Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
1277 encode_stat(attribs, &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, data_stream);
1279 /** Now possibly extend the attributes */
1280 if (IS_FT_OBJECT(ff_pkt->type)) {
1281 attr_stream = STREAM_RESTORE_OBJECT;
1283 attribsEx = attribsExBuf;
1284 attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
1287 Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
1290 jcr->JobFiles++; /* increment number of files sent */
1291 ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
1292 pm_strcpy(jcr->last_fname, ff_pkt->fname);
1295 /* Debug code: check if we must hangup */
1296 if (hangup && (jcr->JobFiles > (uint32_t)hangup)) {
1297 jcr->setJobStatus(JS_Incomplete);
1298 Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
1304 * Send Attributes header to Storage daemon
1305 * <file-index> <stream> <info>
1307 if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
1308 if (!jcr->is_canceled() && !jcr->is_incomplete()) {
1309 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1314 Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
1317 * Send file attributes to Storage daemon
1320 * Filename (full path)
1321 * Encoded attributes
1322 * Link name (if type==FT_LNK or FT_LNKSAVED)
1323 * Encoded extended-attributes (for Win32)
1325 * or send Restore Object to Storage daemon
1329 * Object_len (possibly compressed)
1330 * Object_full_len (not compressed)
1331 * Object_compression
1334 * Binary Object data
1336 * For a directory, link is the same as fname, but with trailing
1337 * slash. For a linked file, link is the link.
1339 if (ff_pkt->type != FT_DELETED) { /* already stripped */
1342 switch (ff_pkt->type) {
1345 Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
1346 stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
1347 ff_pkt->type, ff_pkt->fname, 0, attribs, 0,
1348 ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
1353 /* Here link is the canonical filename (i.e. with trailing slash) */
1354 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1355 ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0,
1356 attribsEx, 0, ff_pkt->delta_seq, 0);
1358 case FT_PLUGIN_CONFIG:
1359 case FT_RESTORE_FIRST:
1360 comp_len = ff_pkt->object_len;
1361 ff_pkt->object_compression = 0;
1362 if (ff_pkt->object_len > 1000) {
1363 /* Big object, compress it */
1364 comp_len = ff_pkt->object_len + 1000;
1365 POOLMEM *comp_obj = get_memory(comp_len);
1366 /* *** FIXME *** check Zdeflate error */
1367 Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
1368 if (comp_len < ff_pkt->object_len) {
1369 ff_pkt->object = comp_obj;
1370 ff_pkt->object_compression = 1; /* zlib level 9 compression */
1372 /* Uncompressed object smaller, use it */
1373 comp_len = ff_pkt->object_len;
1375 Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
1377 sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
1378 jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
1379 comp_len, ff_pkt->object_len, ff_pkt->object_compression,
1380 ff_pkt->fname, 0, ff_pkt->object_name, 0);
1381 sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
1382 memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);
1383 /* Note we send one extra byte so Dir can store zero after object */
1384 sd->msglen += comp_len + 1;
1386 if (ff_pkt->object_compression) {
1387 free_and_null_pool_memory(ff_pkt->object);
1391 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
1392 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0,
1393 ff_pkt->delta_seq, 0);
1396 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1397 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0,
1398 attribsEx, 0, ff_pkt->delta_seq, 0);
1401 if (ff_pkt->type != FT_DELETED) {
1402 unstrip_path(ff_pkt);
1405 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1406 if (!stat && !jcr->is_job_canceled()) {
1407 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1410 sd->signal(BNET_EOD); /* indicate end of attributes data */
1415 * Do in place strip of path
1417 static bool do_strip(int count, char *in)
1423 /** Copy to first path separator -- Win32 might have c: ... */
1424 while (*in && !IsPathSeparator(*in)) {
1428 numsep++; /* one separator seen */
1429 for (stripped=0; stripped<count && *in; stripped++) {
1430 while (*in && !IsPathSeparator(*in)) {
1431 in++; /* skip chars */
1434 numsep++; /* count separators seen */
1435 in++; /* skip separator */
1439 while (*in) { /* copy to end */
1440 if (IsPathSeparator(*in)) {
1446 Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n",
1447 stripped, count, numsep, numsep>count);
1448 return stripped==count && numsep>count;
1452 * If requested strip leading components of the path so that we can
1453 * save file as if it came from a subdirectory. This is most useful
1454 * for dealing with snapshots, by removing the snapshot directory, or
1455 * in handling vendor migrations where files have been restored with
1456 * a vendor product into a subdirectory.
1458 void strip_path(FF_PKT *ff_pkt)
1460 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1461 Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1464 if (!ff_pkt->fname_save) {
1465 ff_pkt->fname_save = get_pool_memory(PM_FNAME);
1466 ff_pkt->link_save = get_pool_memory(PM_FNAME);
1468 pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1469 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1470 pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1471 Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1472 strlen(ff_pkt->link));
1477 * Strip path. If it doesn't succeed put it back. If
1478 * it does, and there is a different link string,
1479 * attempt to strip the link. If it fails, back them
1481 * Do not strip symlinks.
1482 * I.e. if either stripping fails don't strip anything.
1484 if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1485 unstrip_path(ff_pkt);
1488 /** Strip links but not symlinks */
1489 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1490 if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1491 unstrip_path(ff_pkt);
1496 Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
1500 void unstrip_path(FF_PKT *ff_pkt)
1502 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1505 strcpy(ff_pkt->fname, ff_pkt->fname_save);
1506 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1507 Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1509 strcpy(ff_pkt->link, ff_pkt->link_save);
1510 Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1511 strlen(ff_pkt->link_save));
1516 static void close_vss_backup_session(JCR *jcr)
1518 #if defined(WIN32_VSS)
1519 /* STOP VSS ON WIN32 */
1520 /* tell vss to close the backup session */
1522 if (g_pVSSClient->CloseBackup()) {
1523 /* inform user about writer states */
1524 for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1525 int msg_type = M_INFO;
1526 if (g_pVSSClient->GetWriterState(i) < 1) {
1527 msg_type = M_WARNING;
1530 Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1533 WCHAR *metadata = g_pVSSClient->GetMetadata();
1535 FF_PKT *ff_pkt = jcr->ff;
1536 ff_pkt->fname = (char *)"job";
1537 ff_pkt->type = FT_RESTORE_FIRST;
1539 ff_pkt->object_name = (char *)"job_metadata.xml";
1540 ff_pkt->object = (char *)metadata;
1541 ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR);
1542 ff_pkt->object_index = (int)time(NULL);
1543 save_file(jcr, ff_pkt, true);