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 + 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 int stat, data_stream;
335 DIGEST *digest = NULL;
336 DIGEST *signing_digest = NULL;
337 int digest_stream = STREAM_NONE;
338 SIGNATURE *sig = NULL;
339 bool has_file_data = false;
340 // TODO landonf: Allow the user to specify the digest algorithm
342 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
344 crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
346 BSOCK *sd = jcr->store_bsock;
348 if (jcr->is_canceled() || jcr->is_incomplete()) {
352 jcr->num_files_examined++; /* bump total file count */
354 switch (ff_pkt->type) {
355 case FT_LNKSAVED: /* Hard linked, file already saved */
356 Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
359 Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
360 has_file_data = true;
363 Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
364 has_file_data = true;
367 Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
369 case FT_RESTORE_FIRST:
370 Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname);
373 jcr->num_files_examined--; /* correct file count */
374 return 1; /* not used */
376 Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend from %s into %s\n"),
377 ff_pkt->top_fname, ff_pkt->fname);
378 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
381 /* Suppress message for /dev filesystems */
382 if (!is_in_fileset(ff_pkt)) {
383 Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into it.\n"),
384 ff_pkt->fname, ff_pkt->top_fname);
386 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
389 Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend from %s into %s\n"),
390 ff_pkt->top_fname, ff_pkt->fname);
391 ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
394 Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"),
400 Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
403 Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
404 if (S_ISSOCK(ff_pkt->statp.st_mode)) {
405 Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname);
410 Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
411 has_file_data = true;
414 Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
418 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
419 be.bstrerror(ff_pkt->ff_errno));
425 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"),
426 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
432 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
433 be.bstrerror(ff_pkt->ff_errno));
439 Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
442 Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
446 Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"),
447 ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
452 Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"),
453 ff_pkt->type, ff_pkt->fname);
458 Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
460 /** Digests and encryption are only useful if there's file data */
463 * Setup for digest handling. If this fails, the digest will be set to NULL
464 * and not used. Note, the digest (file hash) can be any one of the four
467 * The signing digest is a single algorithm depending on
468 * whether or not we have SHA2.
469 * ****FIXME**** the signing algoritm should really be
470 * determined a different way!!!!!! What happens if
471 * sha2 was available during backup but not restore?
473 if (ff_pkt->flags & FO_MD5) {
474 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
475 digest_stream = STREAM_MD5_DIGEST;
477 } else if (ff_pkt->flags & FO_SHA1) {
478 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
479 digest_stream = STREAM_SHA1_DIGEST;
481 } else if (ff_pkt->flags & FO_SHA256) {
482 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
483 digest_stream = STREAM_SHA256_DIGEST;
485 } else if (ff_pkt->flags & FO_SHA512) {
486 digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
487 digest_stream = STREAM_SHA512_DIGEST;
490 /** Did digest initialization fail? */
491 if (digest_stream != STREAM_NONE && digest == NULL) {
492 Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
493 stream_to_ascii(digest_stream));
497 * Set up signature digest handling. If this fails, the signature digest
498 * will be set to NULL and not used.
500 /* TODO landonf: We should really only calculate the digest once, for
501 * both verification and signing.
503 if (jcr->crypto.pki_sign) {
504 signing_digest = crypto_digest_new(jcr, signing_algorithm);
506 /** Full-stop if a failure occurred initializing the signature digest */
507 if (signing_digest == NULL) {
508 Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
509 stream_to_ascii(signing_algorithm));
515 /** Enable encryption */
516 if (jcr->crypto.pki_encrypt) {
517 ff_pkt->flags |= FO_ENCRYPT;
521 /** Initialize the file descriptor we use for data and other streams. */
523 if (ff_pkt->flags & FO_PORTABLE) {
524 set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
526 if (ff_pkt->cmd_plugin) {
527 /* Tell bfile that it needs to call plugin */
528 if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
531 send_plugin_name(jcr, sd, true); /* signal start of plugin data */
532 plugin_started = true;
535 /** Send attributes -- must be done after binit() */
536 if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
539 /** Meta data only for restore object */
540 if (ff_pkt->type == FT_RESTORE_FIRST) {
544 /** Set up the encryption context and send the session data to the SD */
545 if (has_file_data && jcr->crypto.pki_encrypt) {
546 if (!crypto_session_send(jcr, sd)) {
552 * Open any file with data that we intend to save, then save it.
554 * Note, if is_win32_backup, we must open the Directory so that
555 * the BackupRead will save its permissions and ownership streams.
557 if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
559 do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
561 do_read = ff_pkt->statp.st_size > 0;
563 } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
564 ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION ||
565 (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
569 if (ff_pkt->cmd_plugin) {
573 Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read);
577 if (ff_pkt->type == FT_FIFO) {
578 tid = start_thread_timer(jcr, pthread_self(), 60);
582 int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
583 ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE ||
584 ff_pkt->type == FT_JUNCTION);
585 if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
586 ff_pkt->ff_errno = errno;
588 Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
592 stop_thread_timer(tid);
598 stop_thread_timer(tid);
602 stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
604 if (ff_pkt->flags & FO_CHKCHANGES) {
605 has_file_changed(jcr, ff_pkt);
608 bclose(&ff_pkt->bfd);
615 if (have_darwin_os) {
616 /** Regular files can have resource forks and Finder Info */
617 if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
618 ff_pkt->flags & FO_HFSPLUS)) {
619 if (ff_pkt->hfsinfo.rsrclength > 0) {
622 if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
623 ff_pkt->ff_errno = errno;
625 Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"),
626 ff_pkt->fname, be.bstrerror());
628 if (is_bopen(&ff_pkt->bfd)) {
629 bclose(&ff_pkt->bfd);
633 flags = ff_pkt->flags;
634 ff_pkt->flags &= ~(FO_COMPRESS|FO_SPARSE|FO_OFFSETS);
635 if (flags & FO_ENCRYPT) {
636 rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
638 rsrc_stream = STREAM_MACOS_FORK_DATA;
640 stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
641 ff_pkt->flags = flags;
642 bclose(&ff_pkt->bfd);
648 Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
649 sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
650 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
651 pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
654 crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
656 if (signing_digest) {
657 crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
660 sd->signal(BNET_EOD);
665 * Save ACLs when requested and available for anything not being a symlink and not being a plugin.
668 if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
669 switch (build_acl_streams(jcr, ff_pkt)) {
670 case bacl_exit_fatal:
672 case bacl_exit_error:
674 * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
675 * print the error message set by the lower level routine in jcr->errmsg.
677 if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
678 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
680 jcr->acl_data->nr_errors++;
689 * Save Extended Attributes when requested and available for all files not being a plugin.
692 if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
693 switch (build_xattr_streams(jcr, ff_pkt)) {
694 case bxattr_exit_fatal:
696 case bxattr_exit_error:
698 * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
699 * print the error message set by the lower level routine in jcr->errmsg.
701 if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
702 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
704 jcr->xattr_data->nr_errors++;
712 /** Terminate the signing digest and send it to the Storage daemon */
713 if (signing_digest) {
716 if ((sig = crypto_sign_new(jcr)) == NULL) {
717 Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
721 if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
722 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
726 /** Get signature size */
727 if (!crypto_sign_encode(sig, NULL, &size)) {
728 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
732 /** Grow the bsock buffer to fit our message if necessary */
733 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
734 sd->msg = realloc_pool_memory(sd->msg, size);
737 /** Send our header */
738 sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
739 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
741 /** Encode signature data */
742 if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
743 Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
749 sd->signal(BNET_EOD); /* end of checksum */
752 /** Terminate any digest and send it to Storage daemon */
756 sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
757 Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
759 size = CRYPTO_DIGEST_MAX_SIZE;
761 /** Grow the bsock buffer to fit our message if necessary */
762 if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
763 sd->msg = realloc_pool_memory(sd->msg, size);
766 if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
767 Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
771 /* Keep the checksum if this file is a hardlink */
772 if (ff_pkt->linked) {
773 ff_pkt_set_link_digest(ff_pkt, digest_stream, sd->msg, size);
778 sd->signal(BNET_EOD); /* end of checksum */
781 /* Check if original file has a digest, and send it */
782 if (ff_pkt->type == FT_LNKSAVED && ff_pkt->digest) {
783 Dmsg2(300, "Link %s digest %d\n", ff_pkt->fname, ff_pkt->digest_len);
784 sd->fsend("%ld %d 0", jcr->JobFiles, ff_pkt->digest_stream);
786 sd->msg = check_pool_memory_size(sd->msg, ff_pkt->digest_len);
787 memcpy(sd->msg, ff_pkt->digest, ff_pkt->digest_len);
788 sd->msglen = ff_pkt->digest_len;
791 sd->signal(BNET_EOD); /* end of hardlink record */
795 rtnstat = jcr->is_canceled() ? 0 : 1; /* good return if not canceled */
798 if (jcr->is_incomplete()) {
801 if (ff_pkt->cmd_plugin && plugin_started) {
802 send_plugin_name(jcr, sd, false); /* signal end of plugin data */
805 crypto_digest_free(digest);
807 if (signing_digest) {
808 crypto_digest_free(signing_digest);
811 crypto_sign_free(sig);
817 * Send data read from an already open file descriptor.
819 * We return 1 on sucess and 0 on errors.
822 * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
824 * Currently this is not a problem as the only other stream, resource forks,
825 * are not handled as sparse files.
827 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
828 DIGEST *signing_digest)
830 BSOCK *sd = jcr->store_bsock;
831 uint64_t fileAddr = 0; /* file address */
833 int32_t rsize = jcr->buf_size; /* read buffer size */
835 CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
836 const uint8_t *cipher_input;
837 uint32_t cipher_input_len;
838 uint32_t cipher_block_size;
839 uint32_t encrypted_len;
840 #ifdef FD_NO_SEND_TEST
845 rbuf = sd->msg; /* read buffer */
846 wbuf = sd->msg; /* write buffer */
847 cipher_input = (uint8_t *)rbuf; /* encrypt uncompressed data */
849 Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
851 #if defined(HAVE_LIBZ) || defined(HAVE_LZO)
852 uLong compress_len = 0;
853 uLong max_compress_len = 0;
854 const Bytef *cbuf = NULL;
858 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_GZIP) {
859 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
860 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
861 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
863 cbuf = (Bytef *)jcr->compress_buf;
864 max_compress_len = jcr->compress_buf_size; /* set max length */
866 wbuf = jcr->compress_buf; /* compressed output here */
867 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
870 * Only change zlib parameters if there is no pending operation.
871 * This should never happen as deflatereset is called after each
875 if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
876 /** set gzip compression level - must be done per file */
877 if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset,
878 ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
879 Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
880 jcr->setJobStatus(JS_ErrorTerminated);
889 comp_stream_header ch;
891 memset(&ch, 0, sizeof(comp_stream_header));
894 if ((ff_pkt->flags & FO_COMPRESS) && ff_pkt->Compress_algo == COMPRESS_LZO1X) {
895 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
896 cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
897 cbuf2 = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
898 max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
900 cbuf = (Bytef *)jcr->compress_buf;
901 cbuf2 = (Bytef *)jcr->compress_buf + sizeof(comp_stream_header);
902 max_compress_len = jcr->compress_buf_size; /* set max length */
904 ch.magic = COMPRESS_LZO1X;
905 ch.version = COMP_HEAD_VERSION;
906 wbuf = jcr->compress_buf; /* compressed output here */
907 cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
911 const uint32_t max_compress_len = 0;
914 if (ff_pkt->flags & FO_ENCRYPT) {
915 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
916 Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
919 /** Allocate the cipher context */
920 if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true,
921 &cipher_block_size)) == NULL) {
922 /* Shouldn't happen! */
923 Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
928 * Grow the crypto buffer, if necessary.
929 * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
930 * We grow crypto_buf to the maximum number of blocks that
931 * could be returned for the given read buffer size.
932 * (Using the larger of either rsize or max_compress_len)
934 jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf,
935 (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) +
936 cipher_block_size - 1) / cipher_block_size * cipher_block_size);
938 wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
942 * Send Data header to Storage daemon
943 * <file-index> <stream> <info>
945 if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
946 if (!jcr->is_job_canceled()) {
947 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
952 Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
955 * Make space at beginning of buffer for fileAddr because this
956 * same buffer will be used for writing if compression is off.
958 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
959 rbuf += OFFSET_FADDR_SIZE;
960 rsize -= OFFSET_FADDR_SIZE;
961 #ifdef HAVE_FREEBSD_OS
963 * To read FreeBSD partitions, the read size must be
966 rsize = (rsize/512) * 512;
970 /** a RAW device read on win32 only works if the buffer is a multiple of 512 */
972 if (S_ISBLK(ff_pkt->statp.st_mode))
973 rsize = (rsize/512) * 512;
979 while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
981 /** Check for sparse blocks */
982 if (ff_pkt->flags & FO_SPARSE) {
984 bool allZeros = false;
985 if ((sd->msglen == rsize &&
986 fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
987 ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
988 (uint64_t)ff_pkt->statp.st_size == 0)) {
989 allZeros = is_buf_zero(rbuf, rsize);
992 /** Put file address as first data in buffer */
993 ser_begin(wbuf, OFFSET_FADDR_SIZE);
994 ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
996 fileAddr += sd->msglen; /* update file address */
997 /** Skip block of all zeros */
999 continue; /* skip block of zeros */
1001 } else if (ff_pkt->flags & FO_OFFSETS) {
1003 ser_begin(wbuf, OFFSET_FADDR_SIZE);
1004 ser_uint64(ff_pkt->bfd.offset); /* store offset in begin of buffer */
1007 jcr->ReadBytes += sd->msglen; /* count bytes read */
1009 /** Uncompressed cipher input length */
1010 cipher_input_len = sd->msglen;
1012 /** Update checksum if requested */
1014 crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
1017 /** Update signing digest if requested */
1018 if (signing_digest) {
1019 crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
1023 /** Do compression if turned on */
1024 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_GZIP && jcr->pZLIB_compress_workset) {
1025 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1027 ((z_stream*)jcr->pZLIB_compress_workset)->next_in = (Bytef *)rbuf;
1028 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in = sd->msglen;
1029 ((z_stream*)jcr->pZLIB_compress_workset)->next_out = (Bytef *)cbuf;
1030 ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;
1032 if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
1033 Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
1034 jcr->setJobStatus(JS_ErrorTerminated);
1037 compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
1038 /** reset zlib stream to be able to begin from scratch again */
1039 if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
1040 Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
1041 jcr->setJobStatus(JS_ErrorTerminated);
1045 Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", compress_len,
1048 sd->msglen = compress_len; /* set compressed length */
1049 cipher_input_len = compress_len;
1053 /** Do compression if turned on */
1054 if (ff_pkt->flags & FO_COMPRESS && ff_pkt->Compress_algo == COMPRESS_LZO1X && jcr->LZO_compress_workset) {
1056 ser_begin(cbuf, sizeof(comp_stream_header));
1058 Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
1060 lzores = lzo1x_1_compress((const unsigned char*)rbuf, sd->msglen, cbuf2, &compress_len, jcr->LZO_compress_workset);
1061 if (lzores == LZO_E_OK && compress_len <= max_compress_len)
1063 /* complete header */
1064 ser_uint32(COMPRESS_LZO1X);
1065 ser_uint32(compress_len);
1066 ser_uint16(ch.level);
1067 ser_uint16(ch.version);
1069 /** this should NEVER happen */
1070 Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores);
1071 jcr->setJobStatus(JS_ErrorTerminated);
1075 Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", compress_len,
1078 compress_len += sizeof(comp_stream_header); /* add size of header */
1079 sd->msglen = compress_len; /* set compressed length */
1080 cipher_input_len = compress_len;
1085 * Note, here we prepend the current record length to the beginning
1086 * of the encrypted data. This is because both sparse and compression
1087 * restore handling want records returned to them with exactly the
1088 * same number of bytes that were processed in the backup handling.
1089 * That is, both are block filters rather than a stream. When doing
1090 * compression, the compression routines may buffer data, so that for
1091 * any one record compressed, when it is decompressed the same size
1092 * will not be obtained. Of course, the buffered data eventually comes
1093 * out in subsequent crypto_cipher_update() calls or at least
1094 * when crypto_cipher_finalize() is called. Unfortunately, this
1095 * "feature" of encryption enormously complicates the restore code.
1097 if (ff_pkt->flags & FO_ENCRYPT) {
1098 uint32_t initial_len = 0;
1101 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1102 cipher_input_len += OFFSET_FADDR_SIZE;
1105 /** Encrypt the length of the input block */
1106 uint8_t packet_len[sizeof(uint32_t)];
1108 ser_begin(packet_len, sizeof(uint32_t));
1109 ser_uint32(cipher_input_len); /* store data len in begin of buffer */
1110 Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);
1112 if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
1113 (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
1114 /** Encryption failed. Shouldn't happen. */
1115 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1119 /** Encrypt the input block */
1120 if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len,
1121 (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
1122 if ((initial_len + encrypted_len) == 0) {
1123 /** No full block of data available, read more data */
1126 Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len,
1128 sd->msglen = initial_len + encrypted_len; /* set encrypted length */
1130 /** Encryption failed. Shouldn't happen. */
1131 Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1136 /* Send the buffer to the Storage daemon */
1137 if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
1138 sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
1140 sd->msg = wbuf; /* set correct write buffer */
1142 if (!jcr->is_job_canceled()) {
1143 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1148 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1150 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1151 sd->msg = msgsave; /* restore read buffer */
1153 } /* end while read file data */
1155 if (sd->msglen < 0) { /* error */
1157 Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
1158 ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
1159 if (jcr->JobErrors++ > 1000) { /* insanity check */
1160 Jmsg(jcr, M_FATAL, 0, _("Too many errors. JobErrors=%d.\n"), jcr->JobErrors);
1162 } else if (ff_pkt->flags & FO_ENCRYPT) {
1164 * For encryption, we must call finalize to push out any
1167 if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf,
1169 /* Padding failed. Shouldn't happen. */
1170 Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
1174 /** Note, on SSL pre-0.9.7, there is always some output */
1175 if (encrypted_len > 0) {
1176 sd->msglen = encrypted_len; /* set encrypted length */
1177 sd->msg = jcr->crypto.crypto_buf; /* set correct write buffer */
1179 if (!jcr->is_job_canceled()) {
1180 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1185 Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1186 jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed/encrypted */
1187 sd->msg = msgsave; /* restore bnet buffer */
1191 if (!sd->signal(BNET_EOD)) { /* indicate end of file data */
1192 if (!jcr->is_job_canceled()) {
1193 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1199 /** Free the cipher context */
1201 crypto_cipher_free(cipher_ctx);
1206 /** Free the cipher context */
1208 crypto_cipher_free(cipher_ctx);
1211 sd->msg = msgsave; /* restore bnet buffer */
1216 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
1218 BSOCK *sd = jcr->store_bsock;
1219 char attribs[MAXSTRING];
1220 char attribsExBuf[MAXSTRING];
1221 char *attribsEx = NULL;
1225 int hangup = get_hangup();
1226 #ifdef FD_NO_SEND_TEST
1230 Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
1231 /** Find what data stream we will use, then encode the attributes */
1232 if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
1233 /* This should not happen */
1234 Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
1237 encode_stat(attribs, &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, data_stream);
1239 /** Now possibly extend the attributes */
1240 if (ff_pkt->type == FT_RESTORE_FIRST) {
1241 attr_stream = STREAM_RESTORE_OBJECT;
1243 attribsEx = attribsExBuf;
1244 attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
1247 Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
1250 jcr->JobFiles++; /* increment number of files sent */
1251 ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
1252 pm_strcpy(jcr->last_fname, ff_pkt->fname);
1255 /* Debug code: check if we must hangup */
1256 if (hangup && (jcr->JobFiles > (uint32_t)hangup)) {
1257 jcr->setJobStatus(JS_Incomplete);
1258 Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
1264 * Send Attributes header to Storage daemon
1265 * <file-index> <stream> <info>
1267 if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
1268 if (!jcr->is_canceled() && !jcr->is_incomplete()) {
1269 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1274 Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
1277 * Send file attributes to Storage daemon
1280 * Filename (full path)
1281 * Encoded attributes
1282 * Link name (if type==FT_LNK or FT_LNKSAVED)
1283 * Encoded extended-attributes (for Win32)
1285 * or send Restore Object to Storage daemon
1289 * Object_len (possibly compressed)
1290 * Object_full_len (not compressed)
1291 * Object_compression
1294 * Binary Object data
1296 * For a directory, link is the same as fname, but with trailing
1297 * slash. For a linked file, link is the link.
1299 if (ff_pkt->type != FT_DELETED) { /* already stripped */
1302 switch (ff_pkt->type) {
1305 Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
1306 stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
1307 ff_pkt->type, ff_pkt->fname, 0, attribs, 0,
1308 ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
1313 /* Here link is the canonical filename (i.e. with trailing slash) */
1314 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1315 ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0,
1316 attribsEx, 0, ff_pkt->delta_seq, 0);
1318 case FT_RESTORE_FIRST:
1319 comp_len = ff_pkt->object_len;
1320 ff_pkt->object_compression = 0;
1321 if (ff_pkt->object_len > 1000) {
1322 /* Big object, compress it */
1324 comp_len = ff_pkt->object_len + 1000;
1325 POOLMEM *comp_obj = get_memory(comp_len);
1326 stat = Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
1327 if (comp_len < ff_pkt->object_len) {
1328 ff_pkt->object = comp_obj;
1329 ff_pkt->object_compression = 1; /* zlib level 9 compression */
1331 /* Uncompressed object smaller, use it */
1332 comp_len = ff_pkt->object_len;
1334 Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
1336 sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
1337 jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
1338 comp_len, ff_pkt->object_len, ff_pkt->object_compression,
1339 ff_pkt->fname, 0, ff_pkt->object_name, 0);
1340 sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
1341 memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);
1342 /* Note we send one extra byte so Dir can store zero after object */
1343 sd->msglen += comp_len + 1;
1345 if (ff_pkt->object_compression) {
1346 free_and_null_pool_memory(ff_pkt->object);
1350 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
1351 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0,
1352 ff_pkt->delta_seq, 0);
1355 stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1356 ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0,
1357 attribsEx, 0, ff_pkt->delta_seq, 0);
1360 if (ff_pkt->type != FT_DELETED) {
1361 unstrip_path(ff_pkt);
1364 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1365 if (!stat && !jcr->is_job_canceled()) {
1366 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1369 sd->signal(BNET_EOD); /* indicate end of attributes data */
1374 * Do in place strip of path
1376 static bool do_strip(int count, char *in)
1382 /** Copy to first path separator -- Win32 might have c: ... */
1383 while (*in && !IsPathSeparator(*in)) {
1387 numsep++; /* one separator seen */
1388 for (stripped=0; stripped<count && *in; stripped++) {
1389 while (*in && !IsPathSeparator(*in)) {
1390 in++; /* skip chars */
1393 numsep++; /* count separators seen */
1394 in++; /* skip separator */
1398 while (*in) { /* copy to end */
1399 if (IsPathSeparator(*in)) {
1405 Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n",
1406 stripped, count, numsep, numsep>count);
1407 return stripped==count && numsep>count;
1411 * If requested strip leading components of the path so that we can
1412 * save file as if it came from a subdirectory. This is most useful
1413 * for dealing with snapshots, by removing the snapshot directory, or
1414 * in handling vendor migrations where files have been restored with
1415 * a vendor product into a subdirectory.
1417 void strip_path(FF_PKT *ff_pkt)
1419 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1420 Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1423 if (!ff_pkt->fname_save) {
1424 ff_pkt->fname_save = get_pool_memory(PM_FNAME);
1425 ff_pkt->link_save = get_pool_memory(PM_FNAME);
1427 pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1428 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1429 pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1430 Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1431 strlen(ff_pkt->link));
1436 * Strip path. If it doesn't succeed put it back. If
1437 * it does, and there is a different link string,
1438 * attempt to strip the link. If it fails, back them
1440 * Do not strip symlinks.
1441 * I.e. if either stripping fails don't strip anything.
1443 if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1444 unstrip_path(ff_pkt);
1447 /** Strip links but not symlinks */
1448 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1449 if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1450 unstrip_path(ff_pkt);
1455 Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
1459 void unstrip_path(FF_PKT *ff_pkt)
1461 if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1464 strcpy(ff_pkt->fname, ff_pkt->fname_save);
1465 if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1466 Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1468 strcpy(ff_pkt->link, ff_pkt->link_save);
1469 Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1470 strlen(ff_pkt->link_save));
1475 static void close_vss_backup_session(JCR *jcr)
1477 #if defined(WIN32_VSS)
1478 /* STOP VSS ON WIN32 */
1479 /* tell vss to close the backup session */
1481 if (g_pVSSClient->CloseBackup()) {
1482 /* inform user about writer states */
1483 for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1484 int msg_type = M_INFO;
1485 if (g_pVSSClient->GetWriterState(i) < 1) {
1486 msg_type = M_WARNING;
1489 Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1492 WCHAR *metadata = g_pVSSClient->GetMetadata();
1494 FF_PKT *ff_pkt = jcr->ff;
1495 ff_pkt->fname = (char *)"job";
1496 ff_pkt->type = FT_RESTORE_FIRST;
1498 ff_pkt->object_name = (char *)"job_metadata.xml";
1499 ff_pkt->object = (char *)metadata;
1500 ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR);
1501 ff_pkt->object_index = (int)time(NULL);
1502 save_file(jcr, ff_pkt, true);