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(jcr->acl_data, 0, sizeof(acl_data_t));
174 jcr->acl_data->u.build = (acl_build_data_t *)malloc(sizeof(acl_build_data_t));
175 memset(jcr->acl_data->u.build, 0, sizeof(acl_build_data_t));
176 jcr->acl_data->u.build->content = get_pool_memory(PM_MESSAGE);
180 jcr->xattr_data = (xattr_data_t *)malloc(sizeof(xattr_data_t));
181 memset(jcr->xattr_data, 0, sizeof(xattr_data_t));
182 jcr->xattr_data->u.build = (xattr_build_data_t *)malloc(sizeof(xattr_build_data_t));
183 memset(jcr->xattr_data->u.build, 0, sizeof(xattr_build_data_t));
184 jcr->xattr_data->u.build->content = get_pool_memory(PM_MESSAGE);
187 /** Subroutine save_file() is called for each file */
188 if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
189 ok = false; /* error */
190 jcr->setJobStatus(JS_ErrorTerminated);
193 if (have_acl && jcr->acl_data->u.build->nr_errors > 0) {
194 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld acl errors while doing backup\n"),
195 jcr->acl_data->u.build->nr_errors);
197 if (have_xattr && jcr->xattr_data->u.build->nr_errors > 0) {
198 Jmsg(jcr, M_WARNING, 0, _("Encountered %ld xattr errors while doing backup\n"),
199 jcr->xattr_data->u.build->nr_errors);
202 close_vss_backup_session(jcr);
204 accurate_finish(jcr); /* send deleted or base file list to SD */
206 stop_heartbeat_monitor(jcr);
208 sd->signal(BNET_EOD); /* end of sending data */
210 if (have_acl && jcr->acl_data) {
211 free_pool_memory(jcr->acl_data->u.build->content);
212 free(jcr->acl_data->u.build);
214 jcr->acl_data = NULL;
216 if (have_xattr && jcr->xattr_data) {
217 free_pool_memory(jcr->xattr_data->u.build->content);
218 free(jcr->xattr_data->u.build);
219 free(jcr->xattr_data);
220 jcr->xattr_data = NULL;
226 if (jcr->compress_buf) {
227 free_pool_memory(jcr->compress_buf);
228 jcr->compress_buf = NULL;
230 if (jcr->pZLIB_compress_workset) {
231 /* Free the zlib stream */
233 deflateEnd((z_stream *)jcr->pZLIB_compress_workset);
235 free (jcr->pZLIB_compress_workset);
236 jcr->pZLIB_compress_workset = NULL;
238 if (jcr->LZO_compress_workset) {
239 free (jcr->LZO_compress_workset);
240 jcr->LZO_compress_workset = NULL;
243 crypto_session_end(jcr);
246 Dmsg1(100, "end blast_data ok=%d\n", ok);
250 static bool crypto_session_start(JCR *jcr)
252 crypto_cipher_t cipher = CRYPTO_CIPHER_AES_128_CBC;
255 * Create encryption session data and a cached, DER-encoded session data
256 * structure. We use a single session key for each backup, so we'll encode
257 * the session data only once.
259 if (jcr->crypto.pki_encrypt) {
262 /** Create per-job session encryption context */
263 jcr->crypto.pki_session = crypto_session_new(cipher, jcr->crypto.pki_recipients);
265 /** Get the session data size */
266 if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)0, &size)) {
267 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
271 /** Allocate buffer */
272 jcr->crypto.pki_session_encoded = get_memory(size);
274 /** Encode session data */
275 if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)jcr->crypto.pki_session_encoded, &size)) {
276 Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
280 /** ... and store the encoded size */
281 jcr->crypto.pki_session_encoded_size = size;
283 /** Allocate the encryption/decryption buffer */
284 jcr->crypto.crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
289 static void crypto_session_end(JCR *jcr)
291 if (jcr->crypto.crypto_buf) {
292 free_pool_memory(jcr->crypto.crypto_buf);
293 jcr->crypto.crypto_buf = NULL;
295 if (jcr->crypto.pki_session) {
296 crypto_session_free(jcr->crypto.pki_session);
298 if (jcr->crypto.pki_session_encoded) {
299 free_pool_memory(jcr->crypto.pki_session_encoded);
300 jcr->crypto.pki_session_encoded = NULL;
304 static bool crypto_session_send(JCR *jcr, BSOCK *sd)
308 /** Send our header */
309 Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
310 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
313 sd->msg = jcr->crypto.pki_session_encoded;
314 sd->msglen = jcr->crypto.pki_session_encoded_size;
315 jcr->JobBytes += sd->msglen;
317 Dmsg1(100, "Send data len=%d\n", sd->msglen);
320 sd->signal(BNET_EOD);
326 * Called here by find() for each file included.
327 * This is a callback. The original is find_files() above.
329 * Send the file and its data to the Storage daemon.
333 * -1 to ignore file/directory (not used here)
335 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
337 bool do_read = false;
338 bool plugin_started = false;
339 bool do_plugin_set = false;
340 int stat, data_stream;
342 DIGEST *digest = NULL;
343 DIGEST *signing_digest = NULL;
344 int digest_stream = STREAM_NONE;
345 SIGNATURE *sig = NULL;
346 bool has_file_data = false;
347 struct save_pkt sp; /* use by option plugin */
348 // TODO landonf: Allow the user to specify the digest algorithm
350 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
352 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
354 BSOCK *sd = jcr->store_bsock;
356 if (jcr->is_canceled() || jcr->is_incomplete()) {
360 jcr->num_files_examined++; /* bump total file count */
362 switch (ff_pkt->type) {
363 case FT_LNKSAVED: /* Hard linked, file already saved */
364 Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
367 Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
368 has_file_data = true;
371 Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
372 has_file_data = true;
375 Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
377 case FT_RESTORE_FIRST:
378 Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname);
380 case FT_PLUGIN_CONFIG:
381 Dmsg1(100, "FT_PLUGIN_CONFIG saving: %s\n", ff_pkt->fname);
384 jcr->num_files_examined--; /* correct file count */
385 return 1; /* not used */
387 Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"),
388 ff_pkt->top_fname, ff_pkt->fname);
389 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
392 /* Suppress message for /dev filesystems */
393 if (!is_in_fileset(ff_pkt)) {
394 Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"),
395 ff_pkt->fname, ff_pkt->top_fname);
397 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
400 Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"),
401 ff_pkt->top_fname, ff_pkt->fname);
402 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
405 Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"),
411 Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
414 Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
415 if (S_ISSOCK(ff_pkt->statp.st_mode)) {
416 Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname);
421 Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
422 has_file_data = true;
425 Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
429 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
430 be.bstrerror(ff_pkt->ff_errno));
436 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"),
437 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
443 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
444 be.bstrerror(ff_pkt->ff_errno));
450 Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
453 Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
457 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"),
458 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
463 Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"),
464 ff_pkt->type, ff_pkt->fname);
469 Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
471 /** Digests and encryption are only useful if there's file data */
474 * Setup for digest handling. If this fails, the digest will be set to NULL
475 * and not used. Note, the digest (file hash) can be any one of the four
478 * The signing digest is a single algorithm depending on
479 * whether or not we have SHA2.
480 * ****FIXME**** the signing algoritm should really be
481 * determined a different way!!!!!! What happens if
482 * sha2 was available during backup but not restore?
484 if (ff_pkt->flags & FO_MD5) {
485 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
486 digest_stream = STREAM_MD5_DIGEST;
488 } else if (ff_pkt->flags & FO_SHA1) {
489 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
490 digest_stream = STREAM_SHA1_DIGEST;
492 } else if (ff_pkt->flags & FO_SHA256) {
493 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
494 digest_stream = STREAM_SHA256_DIGEST;
496 } else if (ff_pkt->flags & FO_SHA512) {
497 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
498 digest_stream = STREAM_SHA512_DIGEST;
501 /** Did digest initialization fail? */
502 if (digest_stream != STREAM_NONE && digest == NULL) {
503 Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
504 stream_to_ascii(digest_stream));
508 * Set up signature digest handling. If this fails, the signature digest
509 * will be set to NULL and not used.
511 /* TODO landonf: We should really only calculate the digest once, for
512 * both verification and signing.
514 if (jcr->crypto.pki_sign) {
515 signing_digest = crypto_digest_new(jcr, signing_algorithm);
517 /** Full-stop if a failure occurred initializing the signature digest */
518 if (signing_digest == NULL) {
519 Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
520 stream_to_ascii(signing_algorithm));
526 /** Enable encryption */
527 if (jcr->crypto.pki_encrypt) {
528 ff_pkt->flags |= FO_ENCRYPT;
532 /** Initialize the file descriptor we use for data and other streams. */
534 if (ff_pkt->flags & FO_PORTABLE) {
535 set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
538 if (ff_pkt->cmd_plugin && !ff_pkt->no_read) {
539 do_plugin_set = true;
541 /* option and cmd plugin are not compatible together */
542 } else if (ff_pkt->opt_plugin) {
544 /* ask the option plugin what to do with this file */
545 switch (plugin_option_handle_file(jcr, ff_pkt, &sp)) {
547 Dmsg2(10, "Option plugin %s will be used to backup %s\n",
548 ff_pkt->plugin, ff_pkt->fname);
549 do_plugin_set = true;
552 Dmsg2(10, "Option plugin %s decided to skip %s\n",
553 ff_pkt->plugin, ff_pkt->fname);
556 Dmsg2(10, "Option plugin %s decided to let bacula handle %s\n",
557 ff_pkt->plugin, ff_pkt->fname);
563 /* Tell bfile that it needs to call plugin */
564 if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
567 send_plugin_name(jcr, sd, true); /* signal start of plugin data */
568 plugin_started = true;
571 /** Send attributes -- must be done after binit() */
572 if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
575 /** Meta data only for restore object */
576 if (IS_FT_OBJECT(ff_pkt->type)) {
580 /** Set up the encryption context and send the session data to the SD */
581 if (has_file_data && jcr->crypto.pki_encrypt) {
582 if (!crypto_session_send(jcr, sd)) {
588 * Open any file with data that we intend to save, then save it.
590 * Note, if is_win32_backup, we must open the Directory so that
591 * the BackupRead will save its permissions and ownership streams.
593 if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
595 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
597 do_read = ff_pkt->statp.st_size > 0;
599 } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
600 ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION ||
601 (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
605 if (ff_pkt->cmd_plugin) {
609 Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read);
613 if (ff_pkt->type == FT_FIFO) {
614 tid = start_thread_timer(jcr, pthread_self(), 60);
618 int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
619 ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE ||
620 ff_pkt->type == FT_JUNCTION);
621 if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
622 ff_pkt->ff_errno = errno;
624 Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
628 stop_thread_timer(tid);
634 stop_thread_timer(tid);
638 stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
640 if (ff_pkt->flags & FO_CHKCHANGES) {
641 has_file_changed(jcr, ff_pkt);
644 bclose(&ff_pkt->bfd);
651 if (have_darwin_os) {
652 /** Regular files can have resource forks and Finder Info */
653 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
654 ff_pkt->flags & FO_HFSPLUS)) {
655 if (ff_pkt->hfsinfo.rsrclength > 0) {
658 if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
659 ff_pkt->ff_errno = errno;
661 Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"),
662 ff_pkt->fname, be.bstrerror());
664 if (is_bopen(&ff_pkt->bfd)) {
665 bclose(&ff_pkt->bfd);
669 flags = ff_pkt->flags;
670 ff_pkt->flags &= ~(FO_COMPRESS|FO_SPARSE|FO_OFFSETS);
671 if (flags & FO_ENCRYPT) {
672 rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
674 rsrc_stream = STREAM_MACOS_FORK_DATA;
676 stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
677 ff_pkt->flags = flags;
678 bclose(&ff_pkt->bfd);
684 Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
685 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
686 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
687 pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
690 crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
692 if (signing_digest) {
693 crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
696 sd->signal(BNET_EOD);
701 * Save ACLs when requested and available for anything not being a symlink
702 * and not being a plugin.
705 if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
706 switch (build_acl_streams(jcr, ff_pkt)) {
707 case bacl_exit_fatal:
709 case bacl_exit_error:
711 * Non-fatal errors, count them and when the number is under
712 * ACL_REPORT_ERR_MAX_PER_JOB print the error message set by the
713 * lower level routine in jcr->errmsg.
715 if (jcr->acl_data->u.build->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
716 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
718 jcr->acl_data->u.build->nr_errors++;
727 * Save Extended Attributes when requested and available for all files not
731 if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
732 switch (build_xattr_streams(jcr, ff_pkt)) {
733 case bxattr_exit_fatal:
735 case bxattr_exit_error:
737 * Non-fatal errors, count them and when the number is under
738 * XATTR_REPORT_ERR_MAX_PER_JOB print the error message set by the
739 * lower level routine in jcr->errmsg.
741 if (jcr->xattr_data->u.build->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
742 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
744 jcr->xattr_data->u.build->nr_errors++;
752 /** Terminate the signing digest and send it to the Storage daemon */
753 if (signing_digest) {
756 if ((sig = crypto_sign_new(jcr)) == NULL) {
757 Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
761 if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
762 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
766 /** Get signature size */
767 if (!crypto_sign_encode(sig, NULL, &size)) {
768 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
772 /** Grow the bsock buffer to fit our message if necessary */
773 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
774 sd->msg = realloc_pool_memory(sd->msg, size);
777 /** Send our header */
778 sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
779 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
781 /** Encode signature data */
782 if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
783 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
789 sd->signal(BNET_EOD); /* end of checksum */
792 /** Terminate any digest and send it to Storage daemon */
796 sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
797 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
799 size = CRYPTO_DIGEST_MAX_SIZE;
801 /** Grow the bsock buffer to fit our message if necessary */
802 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
803 sd->msg = realloc_pool_memory(sd->msg, size);
806 if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
807 Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
811 /* Keep the checksum if this file is a hardlink */
812 if (ff_pkt->linked) {
813 ff_pkt_set_link_digest(ff_pkt, digest_stream, sd->msg, size);
818 sd->signal(BNET_EOD); /* end of checksum */
821 /* Check if original file has a digest, and send it */
822 if (ff_pkt->type == FT_LNKSAVED && ff_pkt->digest) {
823 Dmsg2(300, "Link %s digest %d\n", ff_pkt->fname, ff_pkt->digest_len);
824 sd->fsend("%ld %d 0", jcr->JobFiles, ff_pkt->digest_stream);
826 sd->msg = check_pool_memory_size(sd->msg, ff_pkt->digest_len);
827 memcpy(sd->msg, ff_pkt->digest, ff_pkt->digest_len);
828 sd->msglen = ff_pkt->digest_len;
831 sd->signal(BNET_EOD); /* end of hardlink record */
835 rtnstat = jcr->is_canceled() ? 0 : 1; /* good return if not canceled */
838 if (jcr->is_incomplete() || jcr->is_canceled()) {
841 if (plugin_started) {
842 send_plugin_name(jcr, sd, false); /* signal end of plugin data */
844 if (ff_pkt->opt_plugin) {
845 jcr->plugin_sp = NULL; /* sp is local to this function */
846 jcr->plugin_ctx = NULL;
848 jcr->opt_plugin = false;
851 crypto_digest_free(digest);
853 if (signing_digest) {
854 crypto_digest_free(signing_digest);
857 crypto_sign_free(sig);
863 * Send data read from an already open file descriptor.
865 * We return 1 on sucess and 0 on errors.
868 * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
870 * Currently this is not a problem as the only other stream, resource forks,
871 * are not handled as sparse files.
873 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
874 DIGEST *signing_digest)
876 BSOCK *sd = jcr->store_bsock;
877 uint64_t fileAddr = 0; /* file address */
879 int32_t rsize = jcr->buf_size; /* read buffer size */
881 CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
882 const uint8_t *cipher_input;
883 uint32_t cipher_input_len;
884 uint32_t cipher_block_size;
885 uint32_t encrypted_len;
886 #ifdef FD_NO_SEND_TEST
891 rbuf = sd->msg; /* read buffer */
892 wbuf = sd->msg; /* write buffer */
893 cipher_input = (uint8_t *)rbuf; /* encrypt uncompressed data */
895 Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
897 #if defined(HAVE_LIBZ) || defined(HAVE_LZO)
898 uLong compress_len = 0;
899 uLong max_compress_len = 0;
900 const Bytef *cbuf = NULL;
904 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_GZIP) {
905 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
906 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
907 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
909 cbuf = (Bytef *)jcr->compress_buf;
910 max_compress_len = jcr->compress_buf_size; /* set max length */
912 wbuf = jcr->compress_buf; /* compressed output here */
913 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
916 * Only change zlib parameters if there is no pending operation.
917 * This should never happen as deflatereset is called after each
921 if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
922 /** set gzip compression level - must be done per file */
923 if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset,
924 ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
925 Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
926 jcr->setJobStatus(JS_ErrorTerminated);
935 comp_stream_header ch;
937 memset(&ch, 0, sizeof(comp_stream_header));
940 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_LZO1X) {
941 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
942 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
943 cbuf2 = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
944 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
946 cbuf = (Bytef *)jcr->compress_buf;
947 cbuf2 = (Bytef *)jcr->compress_buf + sizeof(comp_stream_header);
948 max_compress_len = jcr->compress_buf_size; /* set max length */
950 ch.magic = COMPRESS_LZO1X;
951 ch.version = COMP_HEAD_VERSION;
952 wbuf = jcr->compress_buf; /* compressed output here */
953 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
957 const uint32_t max_compress_len = 0;
960 if (ff_pkt->flags & FO_ENCRYPT) {
961 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
962 Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
965 /** Allocate the cipher context */
966 if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true,
967 &cipher_block_size)) == NULL) {
968 /* Shouldn't happen! */
969 Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
974 * Grow the crypto buffer, if necessary.
975 * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
976 * We grow crypto_buf to the maximum number of blocks that
977 * could be returned for the given read buffer size.
978 * (Using the larger of either rsize or max_compress_len)
980 jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf,
981 (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) +
982 cipher_block_size - 1) / cipher_block_size * cipher_block_size);
984 wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
988 * Send Data header to Storage daemon
989 * <file-index> <stream> <info>
991 if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
992 if (!jcr->is_job_canceled()) {
993 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
998 Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
1001 * Make space at beginning of buffer for fileAddr because this
1002 * same buffer will be used for writing if compression is off.
1004 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1005 rbuf += OFFSET_FADDR_SIZE;
1006 rsize -= OFFSET_FADDR_SIZE;
1007 #ifdef HAVE_FREEBSD_OS
1009 * To read FreeBSD partitions, the read size must be
1010 * a multiple of 512.
1012 rsize = (rsize/512) * 512;
1016 /** a RAW device read on win32 only works if the buffer is a multiple of 512 */
1018 if (S_ISBLK(ff_pkt->statp.st_mode))
1019 rsize = (rsize/512) * 512;
1023 * Read the file data
1025 while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
1027 /** Check for sparse blocks */
1028 if (ff_pkt->flags & FO_SPARSE) {
1030 bool allZeros = false;
1031 if ((sd->msglen == rsize &&
1032 fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
1033 ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
1034 (uint64_t)ff_pkt->statp.st_size == 0)) {
1035 allZeros = is_buf_zero(rbuf, rsize);
1038 /** Put file address as first data in buffer */
1039 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1040 ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
1042 fileAddr += sd->msglen; /* update file address */
1043 /** Skip block of all zeros */
1045 continue; /* skip block of zeros */
1047 } else if (ff_pkt->flags & FO_OFFSETS) {
1049 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1050 ser_uint64(ff_pkt->bfd.offset); /* store offset in begin of buffer */
1053 jcr->ReadBytes += sd->msglen; /* count bytes read */
1055 /** Uncompressed cipher input length */
1056 cipher_input_len = sd->msglen;
1058 /** Update checksum if requested */
1060 crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
1063 /** Update signing digest if requested */
1064 if (signing_digest) {
1065 crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
1069 /** Do compression if turned on */
1070 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_GZIP && jcr->pZLIB_compress_workset) {
1071 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1073 ((z_stream*)jcr->pZLIB_compress_workset)->next_in = (Bytef *)rbuf;
1074 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in = sd->msglen;
1075 ((z_stream*)jcr->pZLIB_compress_workset)->next_out = (Bytef *)cbuf;
1076 ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;
1078 if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
1079 Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
1080 jcr->setJobStatus(JS_ErrorTerminated);
1083 compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
1084 /** reset zlib stream to be able to begin from scratch again */
1085 if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
1086 Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
1087 jcr->setJobStatus(JS_ErrorTerminated);
1091 Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", compress_len,
1094 sd->msglen = compress_len; /* set compressed length */
1095 cipher_input_len = compress_len;
1099 /** Do compression if turned on */
1100 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_LZO1X && jcr->LZO_compress_workset) {
1102 ser_begin(cbuf, sizeof(comp_stream_header));
1104 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1106 lzores = lzo1x_1_compress((const unsigned char*)rbuf, sd->msglen, cbuf2, &compress_len, jcr->LZO_compress_workset);
1107 if (lzores == LZO_E_OK && compress_len <= max_compress_len)
1109 /* complete header */
1110 ser_uint32(COMPRESS_LZO1X);
1111 ser_uint32(compress_len);
1112 ser_uint16(ch.level);
1113 ser_uint16(ch.version);
1115 /** this should NEVER happen */
1116 Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores);
1117 jcr->setJobStatus(JS_ErrorTerminated);
1121 Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", compress_len,
1124 compress_len += sizeof(comp_stream_header); /* add size of header */
1125 sd->msglen = compress_len; /* set compressed length */
1126 cipher_input_len = compress_len;
1131 * Note, here we prepend the current record length to the beginning
1132 * of the encrypted data. This is because both sparse and compression
1133 * restore handling want records returned to them with exactly the
1134 * same number of bytes that were processed in the backup handling.
1135 * That is, both are block filters rather than a stream. When doing
1136 * compression, the compression routines may buffer data, so that for
1137 * any one record compressed, when it is decompressed the same size
1138 * will not be obtained. Of course, the buffered data eventually comes
1139 * out in subsequent crypto_cipher_update() calls or at least
1140 * when crypto_cipher_finalize() is called. Unfortunately, this
1141 * "feature" of encryption enormously complicates the restore code.
1143 if (ff_pkt->flags & FO_ENCRYPT) {
1144 uint32_t initial_len = 0;
1147 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1148 cipher_input_len += OFFSET_FADDR_SIZE;
1151 /** Encrypt the length of the input block */
1152 uint8_t packet_len[sizeof(uint32_t)];
1154 ser_begin(packet_len, sizeof(uint32_t));
1155 ser_uint32(cipher_input_len); /* store data len in begin of buffer */
1156 Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);
1158 if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
1159 (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
1160 /** Encryption failed. Shouldn't happen. */
1161 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1165 /** Encrypt the input block */
1166 if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len,
1167 (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
1168 if ((initial_len + encrypted_len) == 0) {
1169 /** No full block of data available, read more data */
1172 Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len,
1174 sd->msglen = initial_len + encrypted_len; /* set encrypted length */
1176 /** Encryption failed. Shouldn't happen. */
1177 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1182 /* Send the buffer to the Storage daemon */
1183 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1184 sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
1186 sd->msg = wbuf; /* set correct write buffer */
1188 if (!jcr->is_job_canceled()) {
1189 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1194 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1196 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1197 sd->msg = msgsave; /* restore read buffer */
1199 } /* end while read file data */
1201 if (sd->msglen < 0) { /* error */
1203 Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
1204 ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
1205 if (jcr->JobErrors++ > 1000) { /* insanity check */
1206 Jmsg(jcr, M_FATAL, 0, _("Too many errors. JobErrors=%d.\n"), jcr->JobErrors);
1208 } else if (ff_pkt->flags & FO_ENCRYPT) {
1210 * For encryption, we must call finalize to push out any
1213 if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf,
1215 /* Padding failed. Shouldn't happen. */
1216 Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
1220 /** Note, on SSL pre-0.9.7, there is always some output */
1221 if (encrypted_len > 0) {
1222 sd->msglen = encrypted_len; /* set encrypted length */
1223 sd->msg = jcr->crypto.crypto_buf; /* set correct write buffer */
1225 if (!jcr->is_job_canceled()) {
1226 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1231 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1232 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1233 sd->msg = msgsave; /* restore bnet buffer */
1237 if (!sd->signal(BNET_EOD)) { /* indicate end of file data */
1238 if (!jcr->is_job_canceled()) {
1239 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1245 /** Free the cipher context */
1247 crypto_cipher_free(cipher_ctx);
1252 /** Free the cipher context */
1254 crypto_cipher_free(cipher_ctx);
1257 sd->msg = msgsave; /* restore bnet buffer */
1262 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
1264 BSOCK *sd = jcr->store_bsock;
1265 char attribs[MAXSTRING];
1266 char attribsExBuf[MAXSTRING];
1267 char *attribsEx = NULL;
1271 int hangup = get_hangup();
1272 #ifdef FD_NO_SEND_TEST
1276 Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
1277 /** Find what data stream we will use, then encode the attributes */
1278 if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
1279 /* This should not happen */
1280 Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
1283 encode_stat(attribs, &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, data_stream);
1285 /** Now possibly extend the attributes */
1286 if (IS_FT_OBJECT(ff_pkt->type)) {
1287 attr_stream = STREAM_RESTORE_OBJECT;
1289 attribsEx = attribsExBuf;
1290 attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
1293 Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
1296 jcr->JobFiles++; /* increment number of files sent */
1297 ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
1298 pm_strcpy(jcr->last_fname, ff_pkt->fname);
1301 /* Debug code: check if we must hangup */
1302 if (hangup && (jcr->JobFiles > (uint32_t)hangup)) {
1303 jcr->setJobStatus(JS_Incomplete);
1304 Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
1310 * Send Attributes header to Storage daemon
1311 * <file-index> <stream> <info>
1313 if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
1314 if (!jcr->is_canceled() && !jcr->is_incomplete()) {
1315 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1320 Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
1323 * Send file attributes to Storage daemon
1326 * Filename (full path)
1327 * Encoded attributes
1328 * Link name (if type==FT_LNK or FT_LNKSAVED)
1329 * Encoded extended-attributes (for Win32)
1331 * or send Restore Object to Storage daemon
1335 * Object_len (possibly compressed)
1336 * Object_full_len (not compressed)
1337 * Object_compression
1340 * Binary Object data
1342 * For a directory, link is the same as fname, but with trailing
1343 * slash. For a linked file, link is the link.
1345 if (ff_pkt->type != FT_DELETED) { /* already stripped */
1348 switch (ff_pkt->type) {
1351 Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
1352 stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
1353 ff_pkt->type, ff_pkt->fname, 0, attribs, 0,
1354 ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
1359 /* Here link is the canonical filename (i.e. with trailing slash) */
1360 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1361 ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0,
1362 attribsEx, 0, ff_pkt->delta_seq, 0);
1364 case FT_PLUGIN_CONFIG:
1365 case FT_RESTORE_FIRST:
1366 comp_len = ff_pkt->object_len;
1367 ff_pkt->object_compression = 0;
1368 if (ff_pkt->object_len > 1000) {
1369 /* Big object, compress it */
1370 comp_len = ff_pkt->object_len + 1000;
1371 POOLMEM *comp_obj = get_memory(comp_len);
1372 /* *** FIXME *** check Zdeflate error */
1373 Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
1374 if (comp_len < ff_pkt->object_len) {
1375 ff_pkt->object = comp_obj;
1376 ff_pkt->object_compression = 1; /* zlib level 9 compression */
1378 /* Uncompressed object smaller, use it */
1379 comp_len = ff_pkt->object_len;
1381 Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
1383 sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
1384 jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
1385 comp_len, ff_pkt->object_len, ff_pkt->object_compression,
1386 ff_pkt->fname, 0, ff_pkt->object_name, 0);
1387 sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
1388 memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);
1389 /* Note we send one extra byte so Dir can store zero after object */
1390 sd->msglen += comp_len + 1;
1392 if (ff_pkt->object_compression) {
1393 free_and_null_pool_memory(ff_pkt->object);
1397 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
1398 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0,
1399 ff_pkt->delta_seq, 0);
1402 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1403 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0,
1404 attribsEx, 0, ff_pkt->delta_seq, 0);
1407 if (ff_pkt->type != FT_DELETED) {
1408 unstrip_path(ff_pkt);
1411 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1412 if (!stat && !jcr->is_job_canceled()) {
1413 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1416 sd->signal(BNET_EOD); /* indicate end of attributes data */
1421 * Do in place strip of path
1423 static bool do_strip(int count, char *in)
1429 /** Copy to first path separator -- Win32 might have c: ... */
1430 while (*in && !IsPathSeparator(*in)) {
1434 numsep++; /* one separator seen */
1435 for (stripped=0; stripped<count && *in; stripped++) {
1436 while (*in && !IsPathSeparator(*in)) {
1437 in++; /* skip chars */
1440 numsep++; /* count separators seen */
1441 in++; /* skip separator */
1445 while (*in) { /* copy to end */
1446 if (IsPathSeparator(*in)) {
1452 Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n",
1453 stripped, count, numsep, numsep>count);
1454 return stripped==count && numsep>count;
1458 * If requested strip leading components of the path so that we can
1459 * save file as if it came from a subdirectory. This is most useful
1460 * for dealing with snapshots, by removing the snapshot directory, or
1461 * in handling vendor migrations where files have been restored with
1462 * a vendor product into a subdirectory.
1464 void strip_path(FF_PKT *ff_pkt)
1466 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1467 Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1470 if (!ff_pkt->fname_save) {
1471 ff_pkt->fname_save = get_pool_memory(PM_FNAME);
1472 ff_pkt->link_save = get_pool_memory(PM_FNAME);
1474 pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1475 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1476 pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1477 Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1478 strlen(ff_pkt->link));
1483 * Strip path. If it doesn't succeed put it back. If
1484 * it does, and there is a different link string,
1485 * attempt to strip the link. If it fails, back them
1487 * Do not strip symlinks.
1488 * I.e. if either stripping fails don't strip anything.
1490 if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1491 unstrip_path(ff_pkt);
1494 /** Strip links but not symlinks */
1495 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1496 if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1497 unstrip_path(ff_pkt);
1502 Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
1506 void unstrip_path(FF_PKT *ff_pkt)
1508 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1511 strcpy(ff_pkt->fname, ff_pkt->fname_save);
1512 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1513 Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1515 strcpy(ff_pkt->link, ff_pkt->link_save);
1516 Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1517 strlen(ff_pkt->link_save));
1522 static void close_vss_backup_session(JCR *jcr)
1524 #if defined(WIN32_VSS)
1525 /* STOP VSS ON WIN32 */
1526 /* tell vss to close the backup session */
1528 if (g_pVSSClient->CloseBackup()) {
1529 /* inform user about writer states */
1530 for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1531 int msg_type = M_INFO;
1532 if (g_pVSSClient->GetWriterState(i) < 1) {
1533 msg_type = M_WARNING;
1536 Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1539 WCHAR *metadata = g_pVSSClient->GetMetadata();
1541 FF_PKT *ff_pkt = jcr->ff;
1542 ff_pkt->fname = (char *)"job";
1543 ff_pkt->type = FT_RESTORE_FIRST;
1545 ff_pkt->object_name = (char *)"job_metadata.xml";
1546 ff_pkt->object = (char *)metadata;
1547 ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR);
1548 ff_pkt->object_index = (int)time(NULL);
1549 save_file(jcr, ff_pkt, true);