]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/backup.c
1cba287010a383d9e217b155dd90d3fe6ffab69d
[bacula/bacula] / bacula / src / filed / backup.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18  */
19 /*
20  *  Bacula File Daemon  backup.c  send file attributes and data
21  *   to the Storage daemon.
22  *
23  *    Kern Sibbald, March MM
24  *
25  */
26
27 #include "bacula.h"
28 #include "filed.h"
29 #include "backup.h"
30
31 #ifdef HAVE_LZO
32 const bool have_lzo = true;
33 #else
34 const bool have_lzo = false;
35 #endif
36
37 #ifdef HAVE_LIBZ
38 const bool have_libz = true;
39 #else
40 const bool have_libz = false;
41 #endif
42
43 /* Forward referenced functions */
44 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level);
45 static int send_data(bctx_t &bctx, int stream);
46 static void close_vss_backup_session(JCR *jcr);
47 #ifdef HAVE_DARWIN_OS
48 static bool send_resource_fork(bctx_t &bctx);
49 #endif
50 static bool setup_compression(bctx_t &bctx);
51 static bool do_lzo_compression(bctx_t &bctx);
52 static bool do_libz_compression(bctx_t &bctx);
53
54 /**
55  * Find all the requested files and send them
56  * to the Storage daemon.
57  *
58  * Note, we normally carry on a one-way
59  * conversation from this point on with the SD, simply blasting
60  * data to him.  To properly know what is going on, we
61  * also run a "heartbeat" monitor which reads the socket and
62  * reacts accordingly (at the moment it has nothing to do
63  * except echo the heartbeat to the Director).
64  *
65  */
66 bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
67 {
68    BSOCK *sd;
69    bool ok = true;
70    // TODO landonf: Allow user to specify encryption algorithm
71
72    sd = jcr->store_bsock;
73
74    jcr->setJobStatus(JS_Running);
75
76    Dmsg1(300, "bfiled: opened data connection %d to stored\n", sd->m_fd);
77
78    LockRes();
79    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
80    UnlockRes();
81    uint32_t buf_size;
82    if (client) {
83       buf_size = client->max_network_buffer_size;
84    } else {
85       buf_size = 0;                   /* use default */
86    }
87    if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) {
88       jcr->setJobStatus(JS_ErrorTerminated);
89       Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
90       return false;
91    }
92
93    jcr->buf_size = sd->msglen;
94    /**
95     * Adjust for compression so that output buffer is
96     *  12 bytes + 0.1% larger than input buffer plus 18 bytes.
97     *  This gives a bit extra plus room for the sparse addr if any.
98     *  Note, we adjust the read size to be smaller so that the
99     *  same output buffer can be used without growing it.
100     *
101     *  For LZO1X compression the recommended value is :
102     *                  output_block_size = input_block_size + (input_block_size / 16) + 64 + 3 + sizeof(comp_stream_header)
103     *
104     * The zlib compression workset is initialized here to minimize
105     *  the "per file" load. The jcr member is only set, if the init
106     *  was successful.
107     *
108     *  For the same reason, lzo compression is initialized here.
109     */
110    if (have_lzo) {
111       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);
112       jcr->compress_buf = get_memory(jcr->compress_buf_size);
113    } else {
114       jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
115       jcr->compress_buf = get_memory(jcr->compress_buf_size);
116    }
117
118 #ifdef HAVE_LIBZ
119    z_stream *pZlibStream = (z_stream*)malloc(sizeof(z_stream));
120    if (pZlibStream) {
121       pZlibStream->zalloc = Z_NULL;
122       pZlibStream->zfree = Z_NULL;
123       pZlibStream->opaque = Z_NULL;
124       pZlibStream->state = Z_NULL;
125
126       if (deflateInit(pZlibStream, Z_DEFAULT_COMPRESSION) == Z_OK) {
127          jcr->pZLIB_compress_workset = pZlibStream;
128       } else {
129          free (pZlibStream);
130       }
131    }
132 #endif
133
134 #ifdef HAVE_LZO
135    lzo_voidp pLzoMem = (lzo_voidp) malloc(LZO1X_1_MEM_COMPRESS);
136    if (pLzoMem) {
137       if (lzo_init() == LZO_E_OK) {
138          jcr->LZO_compress_workset = pLzoMem;
139       } else {
140          free (pLzoMem);
141       }
142    }
143 #endif
144
145    if (!crypto_session_start(jcr)) {
146       return false;
147    }
148
149    set_find_options(jcr->ff, jcr->incremental, jcr->mtime);
150    set_find_snapshot_function(jcr->ff, snapshot_convert_path);
151
152    /** in accurate mode, we overload the find_one check function */
153    if (jcr->accurate) {
154       set_find_changed_function((FF_PKT *)jcr->ff, accurate_check_file);
155    }
156    start_heartbeat_monitor(jcr);
157
158 #ifdef HAVE_ACL
159    jcr->bacl = (BACL*)new_bacl();
160 #endif
161 #ifdef HAVE_XATTR
162    jcr->bxattr = (BXATTR*)new_bxattr();
163 #endif
164
165    /* Subroutine save_file() is called for each file */
166    if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
167       ok = false;                     /* error */
168       jcr->setJobStatus(JS_ErrorTerminated);
169    }
170 #ifdef HAVE_ACL
171    if (jcr->bacl && jcr->bacl->get_acl_nr_errors() > 0) {
172       Jmsg(jcr, M_WARNING, 0, _("Had %ld acl errors while doing backup\n"),
173          jcr->bacl->get_acl_nr_errors());
174    }
175 #endif
176 #ifdef HAVE_XATTR
177    if (jcr->bxattr && jcr->bxattr->get_xattr_nr_errors() > 0) {
178       Jmsg(jcr, M_WARNING, 0, _("Had %ld xattr errors while doing backup\n"),
179          jcr->bxattr->get_xattr_nr_errors());
180    }
181 #endif
182
183    /* Delete or keep snapshots */
184    close_snapshot_backup_session(jcr);
185    close_vss_backup_session(jcr);
186
187    accurate_finish(jcr);              /* send deleted or base file list to SD */
188
189    stop_heartbeat_monitor(jcr);
190
191    sd->signal(BNET_EOD);            /* end of sending data */
192
193 #ifdef HAVE_ACL
194    if (jcr->bacl) {
195       delete(jcr->bacl);
196       jcr->bacl = NULL;
197    }
198 #endif
199 #ifdef HAVE_XATTR
200    if (jcr->bxattr) {
201       delete(jcr->bxattr);
202       jcr->bxattr = NULL;
203    }
204 #endif
205    if (jcr->big_buf) {
206       bfree_and_null(jcr->big_buf);
207    }
208    if (jcr->compress_buf) {
209       free_and_null_pool_memory(jcr->compress_buf);
210    }
211    if (jcr->pZLIB_compress_workset) {
212       /* Free the zlib stream */
213 #ifdef HAVE_LIBZ
214       deflateEnd((z_stream *)jcr->pZLIB_compress_workset);
215 #endif
216       bfree_and_null(jcr->pZLIB_compress_workset);
217    }
218    if (jcr->LZO_compress_workset) {
219       bfree_and_null(jcr->LZO_compress_workset);
220    }
221
222    crypto_session_end(jcr);
223
224
225    Dmsg1(100, "end blast_data ok=%d\n", ok);
226    return ok;
227 }
228
229
230 /**
231  * Called here by find() for each file included.
232  *   This is a callback. The original is find_files() above.
233  *
234  *  Send the file and its data to the Storage daemon.
235  *
236  *  Returns: 1 if OK
237  *           0 if error
238  *          -1 to ignore file/directory (not used here)
239  */
240 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
241 {
242    bool do_read = false;
243    bool plugin_started = false;
244    bool do_plugin_set = false;
245    int stat;
246    int rtnstat = 0;
247    bool has_file_data = false;
248    struct save_pkt sp;          /* used by option plugin */
249    BSOCK *sd = jcr->store_bsock;
250    bctx_t bctx;                  /* backup context */
251
252    memset(&bctx, 0, sizeof(bctx));
253    bctx.sd = sd;
254    bctx.ff_pkt = ff_pkt;
255    bctx.jcr = jcr;
256
257
258    time_t now = time(NULL);
259    if (jcr->last_stat_time == 0) {
260       jcr->last_stat_time = now;
261       jcr->stat_interval = 30;  /* Default 30 seconds */
262    } else if (now >= jcr->last_stat_time + jcr->stat_interval) {
263       jcr->dir_bsock->fsend("Progress JobId=%ld files=%ld bytes=%lld bps=%ld\n",
264          jcr->JobId, jcr->JobFiles, jcr->JobBytes, jcr->LastRate);
265       jcr->last_stat_time = now;
266    }
267
268    if (jcr->is_canceled() || jcr->is_incomplete()) {
269       Dmsg0(100, "Job canceled by user or marked incomplete.\n");
270       return 0;
271    }
272
273    jcr->num_files_examined++;         /* bump total file count */
274
275    switch (ff_pkt->type) {
276    case FT_LNKSAVED:                  /* Hard linked, file already saved */
277       Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
278       break;
279    case FT_REGE:
280       Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
281       has_file_data = true;
282       break;
283    case FT_REG:
284       Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
285       has_file_data = true;
286       break;
287    case FT_LNK:
288       Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
289       break;
290    case FT_RESTORE_FIRST:
291       Dmsg1(100, "FT_RESTORE_FIRST saving: %s\n", ff_pkt->fname);
292       break;
293    case FT_PLUGIN_CONFIG:
294       Dmsg1(100, "FT_PLUGIN_CONFIG saving: %s\n", ff_pkt->fname);
295       break;
296    case FT_DIRBEGIN:
297       jcr->num_files_examined--;      /* correct file count */
298       return 1;                       /* not used */
299    case FT_NORECURSE:
300       Jmsg(jcr, M_INFO, 1, _("     Recursion turned off. Will not descend from %s into %s\n"),
301            ff_pkt->top_fname, ff_pkt->fname);
302       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
303       break;
304    case FT_NOFSCHG:
305       /* Suppress message for /dev filesystems */
306       if (!is_in_fileset(ff_pkt)) {
307          Jmsg(jcr, M_INFO, 1, _("     %s is a different filesystem. Will not descend from %s into it.\n"),
308               ff_pkt->fname, ff_pkt->top_fname);
309       }
310       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
311       break;
312    case FT_INVALIDFS:
313       Jmsg(jcr, M_INFO, 1, _("     Disallowed filesystem. Will not descend from %s into %s\n"),
314            ff_pkt->top_fname, ff_pkt->fname);
315       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
316       break;
317    case FT_INVALIDDT:
318       Jmsg(jcr, M_INFO, 1, _("     Disallowed drive type. Will not descend into %s\n"),
319            ff_pkt->fname);
320       break;
321    case FT_REPARSE:
322    case FT_JUNCTION:
323    case FT_DIREND:
324       Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
325       break;
326    case FT_SPEC:
327       Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
328       if (S_ISSOCK(ff_pkt->statp.st_mode)) {
329         Jmsg(jcr, M_SKIPPED, 1, _("     Socket file skipped: %s\n"), ff_pkt->fname);
330         return 1;
331       }
332       break;
333    case FT_RAW:
334       Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
335       has_file_data = true;
336       break;
337    case FT_FIFO:
338       Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
339       break;
340    case FT_NOACCESS: {
341       berrno be;
342       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
343          be.bstrerror(ff_pkt->ff_errno));
344       jcr->JobErrors++;
345       return 1;
346    }
347    case FT_NOFOLLOW: {
348       berrno be;
349       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not follow link \"%s\": ERR=%s\n"),
350            ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
351       jcr->JobErrors++;
352       return 1;
353    }
354    case FT_NOSTAT: {
355       berrno be;
356       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
357          be.bstrerror(ff_pkt->ff_errno));
358       jcr->JobErrors++;
359       return 1;
360    }
361    case FT_DIRNOCHG:
362    case FT_NOCHG:
363       Jmsg(jcr, M_SKIPPED, 1, _("     Unchanged file skipped: %s\n"), ff_pkt->fname);
364       return 1;
365    case FT_ISARCH:
366       Jmsg(jcr, M_NOTSAVED, 0, _("     Archive file not saved: %s\n"), ff_pkt->fname);
367       return 1;
368    case FT_NOOPEN: {
369       berrno be;
370       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not open directory \"%s\": ERR=%s\n"),
371            ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
372       jcr->JobErrors++;
373       return 1;
374    }
375    case FT_DELETED:
376       Dmsg1(130, "FT_DELETED: %s\n", ff_pkt->fname);
377       break;
378    default:
379       Jmsg(jcr, M_NOTSAVED, 0,  _("     Unknown file type %d; not saved: %s\n"),
380            ff_pkt->type, ff_pkt->fname);
381       jcr->JobErrors++;
382       return 1;
383    }
384
385    Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
386
387    /** Digests and encryption are only useful if there's file data */
388    if (has_file_data && !crypto_setup_digests(bctx)) {
389       goto good_rtn;
390    }
391
392    /** Initialize the file descriptor we use for data and other streams. */
393    binit(&ff_pkt->bfd);
394    if (ff_pkt->flags & FO_PORTABLE) {
395       set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
396    }
397
398    if (ff_pkt->cmd_plugin) {
399       do_plugin_set = true;
400
401    /* option and cmd plugin are not compatible together */
402    } else if (ff_pkt->opt_plugin) {
403
404       /* ask the option plugin what to do with this file */
405       switch (plugin_option_handle_file(jcr, ff_pkt, &sp)) {
406       case bRC_OK:
407          Dmsg2(10, "Option plugin %s will be used to backup %s\n",
408                ff_pkt->plugin, ff_pkt->fname);
409          do_plugin_set = true;
410          break;
411       case bRC_Skip:
412          Dmsg2(10, "Option plugin %s decided to skip %s\n",
413                ff_pkt->plugin, ff_pkt->fname);
414          goto good_rtn;
415       default:
416          Dmsg2(10, "Option plugin %s decided to let bacula handle %s\n",
417                ff_pkt->plugin, ff_pkt->fname);
418          break;
419       }
420    }
421
422    if (do_plugin_set) {
423       /* Tell bfile that it needs to call plugin */
424       if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
425          goto bail_out;
426       }
427       send_plugin_name(jcr, sd, true);      /* signal start of plugin data */
428       plugin_started = true;
429    }
430
431    /** Send attributes -- must be done after binit() */
432    if (!encode_and_send_attributes(bctx)) {
433       goto bail_out;
434    }
435    /** Meta data only for restore object */
436    if (IS_FT_OBJECT(ff_pkt->type)) {
437       goto good_rtn;
438    }
439    /** Meta data only for deleted files */
440    if (ff_pkt->type == FT_DELETED) {
441       goto good_rtn;
442    }
443    /** Set up the encryption context and send the session data to the SD */
444    if (has_file_data && jcr->crypto.pki_encrypt) {
445       if (!crypto_session_send(jcr, sd)) {
446          goto bail_out;
447       }
448    }
449
450    /**
451     * Open any file with data that we intend to save, then save it.
452     *
453     * Note, if is_win32_backup, we must open the Directory so that
454     * the BackupRead will save its permissions and ownership streams.
455     */
456    if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
457 #ifdef HAVE_WIN32
458       do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
459 #else
460       do_read = ff_pkt->statp.st_size > 0;
461 #endif
462    } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
463               ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION ||
464          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
465       do_read = true;
466    }
467
468    if (ff_pkt->cmd_plugin && !ff_pkt->no_read) {
469       do_read = true;
470    }
471
472    Dmsg2(150, "type=%d do_read=%d\n", ff_pkt->type, do_read);
473    if (do_read) {
474       btimer_t *tid;
475
476       if (ff_pkt->type == FT_FIFO) {
477          tid = start_thread_timer(jcr, pthread_self(), 60);
478       } else {
479          tid = NULL;
480       }
481       int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
482       ff_pkt->bfd.reparse_point = (ff_pkt->type == FT_REPARSE ||
483                                    ff_pkt->type == FT_JUNCTION);
484       set_fattrs(&ff_pkt->bfd, &ff_pkt->statp);
485       if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
486          ff_pkt->ff_errno = errno;
487          berrno be;
488          Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
489               be.bstrerror());
490          jcr->JobErrors++;
491          if (tid) {
492             stop_thread_timer(tid);
493             tid = NULL;
494          }
495          goto good_rtn;
496       }
497       if (tid) {
498          stop_thread_timer(tid);
499          tid = NULL;
500       }
501
502       stat = send_data(bctx, bctx.data_stream);
503
504       if (ff_pkt->flags & FO_CHKCHANGES) {
505          has_file_changed(jcr, ff_pkt);
506       }
507
508       bclose(&ff_pkt->bfd);
509
510       if (!stat) {
511          goto bail_out;
512       }
513    }
514
515 #ifdef HAVE_DARWIN_OS
516    if (!send_resource_fork(bctx)) {
517       goto bail_out;
518    }
519 #endif
520
521    /*
522     * Save ACLs and Extended Attributes when requested and available
523     * for anything not being a symlink.
524     */
525 #ifdef HAVE_ACL
526    if (jcr->bacl && jcr->bacl->backup_acl(jcr, ff_pkt) == bRC_BACL_error) {
527       goto bail_out;
528    }
529 #endif
530 #ifdef HAVE_XATTR
531    if (jcr->bxattr && jcr->bxattr->backup_xattr(jcr, ff_pkt) == bRC_BXATTR_error) {
532       goto bail_out;
533    }
534 #endif
535
536    if (!crypto_terminate_digests(bctx)) {
537       goto bail_out;
538    }
539
540 good_rtn:
541    rtnstat = 1;
542
543 bail_out:
544    if (jcr->is_incomplete() || jcr->is_canceled()) {
545       Dmsg0(100, "Job canceled by user or marked incomplete.\n");
546       rtnstat = 0;
547    }
548    if (plugin_started) {
549       send_plugin_name(jcr, sd, false); /* signal end of plugin data */
550    }
551    if (ff_pkt->opt_plugin) {
552       jcr->plugin_sp = NULL;    /* sp is local to this function */
553       jcr->plugin_ctx = NULL;
554       jcr->plugin = NULL;
555       jcr->opt_plugin = false;
556    }
557    crypto_free(bctx);
558    return rtnstat;
559 }
560
561 /**
562  * Send data read from an already open file descriptor.
563  *
564  * We return 1 on success and 0 on errors.
565  *
566  * ***FIXME***
567  * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
568  *  reading.
569  * Currently this is not a problem as the only other stream, resource forks,
570  * are not handled as sparse files.
571  */
572 static int send_data(bctx_t &bctx, int stream)
573 {
574    JCR *jcr = bctx.jcr;
575    BSOCK *sd = jcr->store_bsock;
576
577 #ifdef FD_NO_SEND_TEST
578    return 1;
579 #endif
580
581    bctx.rsize = jcr->buf_size;
582    bctx.fileAddr = 0;
583    bctx.cipher_ctx = NULL;
584    bctx.msgsave = sd->msg;
585    bctx.rbuf = sd->msg;                    /* read buffer */
586    bctx.wbuf = sd->msg;                    /* write buffer */
587    bctx.cipher_input = (uint8_t *)bctx.rbuf;    /* encrypt uncompressed data */
588
589    Dmsg1(300, "Saving data, type=%d\n", bctx.ff_pkt->type);
590
591    if (!setup_compression(bctx)) {
592       goto err;
593    }
594
595    if (bctx.ff_pkt->flags & FO_ENCRYPT && !crypto_allocate_ctx(bctx)) {
596       return false;
597    }
598
599    /**
600     * Send Data header to Storage daemon
601     *    <file-index> <stream> <expected stream length>
602     */
603    if (!sd->fsend("%ld %d %lld", jcr->JobFiles, stream,
604         (int64_t)bctx.ff_pkt->statp.st_size)) {
605       if (!jcr->is_job_canceled()) {
606          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
607                sd->bstrerror());
608       }
609       goto err;
610    }
611    Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
612
613    /**
614     * Make space at beginning of buffer for fileAddr because this
615     *   same buffer will be used for writing if compression is off.
616     */
617    if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
618       bctx.rbuf += OFFSET_FADDR_SIZE;
619       bctx.rsize -= OFFSET_FADDR_SIZE;
620 #if defined(HAVE_FREEBSD_OS) || defined(__FreeBSD_kernel__)
621       /**
622        * To read FreeBSD partitions, the read size must be
623        *  a multiple of 512.
624        */
625       bctx.rsize = (bctx.rsize/512) * 512;
626 #endif
627    }
628
629    /** a RAW device read on win32 only works if the buffer is a multiple of 512 */
630 #ifdef HAVE_WIN32
631    if (S_ISBLK(bctx.ff_pkt->statp.st_mode)) {
632       bctx.rsize = (bctx.rsize/512) * 512;
633    }
634    Dmsg1(200, "Fattrs=0X%x\n", bctx.ff_pkt->bfd.fattrs);
635    if (bctx.ff_pkt->bfd.fattrs & FILE_ATTRIBUTE_ENCRYPTED) {
636       if (!p_ReadEncryptedFileRaw) {
637          Jmsg0(bctx.jcr, M_FATAL, 0, _("Windows Encrypted data not supported on this OS.\n"));
638          goto err;
639       }
640       /* This single call reads all EFS data delivers it to a callback */
641       if (p_ReadEncryptedFileRaw((PFE_EXPORT_FUNC)read_efs_data_cb, &bctx,
642             bctx.ff_pkt->bfd.pvContext) != 0) {
643          goto err;
644       }
645       /* All read, so skip to finish sending */
646       goto finish_sending;
647    }
648    /* Fall through to standard bread() loop */
649 #endif
650
651    /*
652     * Normal read the file data in a loop and send it to SD
653     */
654    while ((sd->msglen=(uint32_t)bread(&bctx.ff_pkt->bfd, bctx.rbuf, bctx.rsize)) > 0) {
655       if (!process_and_send_data(bctx)) {
656          goto err;
657       }
658    } /* end while read file data */
659    goto finish_sending;
660
661 finish_sending:
662    if (sd->msglen < 0) {                 /* error */
663       berrno be;
664       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
665          bctx.ff_pkt->fname, be.bstrerror(bctx.ff_pkt->bfd.berrno));
666       if (jcr->JobErrors++ > 1000) {       /* insanity check */
667          Jmsg(jcr, M_FATAL, 0, _("Too many errors. JobErrors=%d.\n"), jcr->JobErrors);
668       }
669    } else if (bctx.ff_pkt->flags & FO_ENCRYPT) {
670       /**
671        * For encryption, we must call finalize to push out any
672        *  buffered data.
673        */
674       if (!crypto_cipher_finalize(bctx.cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf,
675            &bctx.encrypted_len)) {
676          /* Padding failed. Shouldn't happen. */
677          Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
678          goto err;
679       }
680
681       /** Note, on SSL pre-0.9.7, there is always some output */
682       if (bctx.encrypted_len > 0) {
683          sd->msglen = bctx.encrypted_len;     /* set encrypted length */
684          sd->msg = jcr->crypto.crypto_buf;    /* set correct write buffer */
685          if (!sd->send()) {
686             if (!jcr->is_job_canceled()) {
687                Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
688                      sd->bstrerror());
689             }
690             goto err;
691          }
692          Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
693          jcr->JobBytes += sd->msglen;     /* count bytes saved possibly compressed/encrypted */
694          sd->msg = bctx.msgsave;          /* restore bnet buffer */
695       }
696    }
697
698
699    if (!sd->signal(BNET_EOD)) {        /* indicate end of file data */
700       if (!jcr->is_job_canceled()) {
701          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
702                sd->bstrerror());
703       }
704       goto err;
705    }
706
707    /** Free the cipher context */
708    if (bctx.cipher_ctx) {
709       crypto_cipher_free(bctx.cipher_ctx);
710    }
711    return 1;
712
713 err:
714    /** Free the cipher context */
715    if (bctx.cipher_ctx) {
716       crypto_cipher_free(bctx.cipher_ctx);
717    }
718
719    sd->msg = bctx.msgsave; /* restore bnet buffer */
720    sd->msglen = 0;
721    return 0;
722 }
723
724
725 /*
726  * Apply processing (sparse, compression, encryption, and
727  *   send to the SD.
728  */
729 bool process_and_send_data(bctx_t &bctx)
730 {
731    BSOCK *sd = bctx.sd;
732    JCR *jcr = bctx.jcr;
733
734    /** Check for sparse blocks */
735    if (bctx.ff_pkt->flags & FO_SPARSE) {
736       ser_declare;
737       bool allZeros = false;
738       if ((sd->msglen == bctx.rsize &&
739            bctx.fileAddr+sd->msglen < (uint64_t)bctx.ff_pkt->statp.st_size) ||
740           ((bctx.ff_pkt->type == FT_RAW || bctx.ff_pkt->type == FT_FIFO) &&
741             (uint64_t)bctx.ff_pkt->statp.st_size == 0)) {
742          allZeros = is_buf_zero(bctx.rbuf, bctx.rsize);
743       }
744       if (!allZeros) {
745          /** Put file address as first data in buffer */
746          ser_begin(bctx.wbuf, OFFSET_FADDR_SIZE);
747          ser_uint64(bctx.fileAddr);     /* store fileAddr in begin of buffer */
748       }
749       bctx.fileAddr += sd->msglen;      /* update file address */
750       /** Skip block of all zeros */
751       if (allZeros) {
752          return true;                 /* skip block of zeros */
753       }
754    } else if (bctx.ff_pkt->flags & FO_OFFSETS) {
755       ser_declare;
756       ser_begin(bctx.wbuf, OFFSET_FADDR_SIZE);
757       ser_uint64(bctx.ff_pkt->bfd.offset);     /* store offset in begin of buffer */
758    }
759
760    jcr->ReadBytes += sd->msglen;         /* count bytes read */
761
762    /** Uncompressed cipher input length */
763    bctx.cipher_input_len = sd->msglen;
764
765    /** Update checksum if requested */
766    if (bctx.digest) {
767       crypto_digest_update(bctx.digest, (uint8_t *)bctx.rbuf, sd->msglen);
768    }
769
770    /** Update signing digest if requested */
771    if (bctx.signing_digest) {
772       crypto_digest_update(bctx.signing_digest, (uint8_t *)bctx.rbuf, sd->msglen);
773    }
774
775    if (have_libz && !do_libz_compression(bctx)) {
776       goto err;
777    }
778
779    if (have_lzo && !do_lzo_compression(bctx)) {
780       goto err;
781    }
782
783    /**
784     * Note, here we prepend the current record length to the beginning
785     *  of the encrypted data. This is because both sparse and compression
786     *  restore handling want records returned to them with exactly the
787     *  same number of bytes that were processed in the backup handling.
788     *  That is, both are block filters rather than a stream.  When doing
789     *  compression, the compression routines may buffer data, so that for
790     *  any one record compressed, when it is decompressed the same size
791     *  will not be obtained. Of course, the buffered data eventually comes
792     *  out in subsequent crypto_cipher_update() calls or at least
793     *  when crypto_cipher_finalize() is called.  Unfortunately, this
794     *  "feature" of encryption enormously complicates the restore code.
795     */
796    if (bctx.ff_pkt->flags & FO_ENCRYPT) {
797       uint32_t initial_len = 0;
798       ser_declare;
799
800       if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
801          bctx.cipher_input_len += OFFSET_FADDR_SIZE;
802       }
803
804       /** Encrypt the length of the input block */
805       uint8_t packet_len[sizeof(uint32_t)];
806
807       ser_begin(packet_len, sizeof(uint32_t));
808       ser_uint32(bctx.cipher_input_len);    /* store data len in begin of buffer */
809       Dmsg1(20, "Encrypt len=%d\n", bctx.cipher_input_len);
810
811       if (!crypto_cipher_update(bctx.cipher_ctx, packet_len, sizeof(packet_len),
812           (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
813          /** Encryption failed. Shouldn't happen. */
814          Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
815          goto err;
816       }
817
818       /** Encrypt the input block */
819       if (crypto_cipher_update(bctx.cipher_ctx, bctx.cipher_input, bctx.cipher_input_len,
820           (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &bctx.encrypted_len)) {
821          if ((initial_len + bctx.encrypted_len) == 0) {
822             /** No full block of data available, read more data */
823             return true;
824          }
825          Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", bctx.encrypted_len,
826                sd->msglen);
827          sd->msglen = initial_len + bctx.encrypted_len; /* set encrypted length */
828       } else {
829          /** Encryption failed. Shouldn't happen. */
830          Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
831          goto err;
832       }
833    }
834
835    /* Send the buffer to the Storage daemon */
836    if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
837       sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
838    }
839    sd->msg = bctx.wbuf;              /* set correct write buffer */
840    if (!sd->send()) {
841       if (!jcr->is_job_canceled()) {
842          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
843                sd->bstrerror());
844       }
845       goto err;
846    }
847    Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
848    /*          #endif */
849    jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed/encrypted */
850    sd->msg = bctx.msgsave;                /* restore read buffer */
851    return true;
852
853 err:
854    return false;
855 }
856
857 bool encode_and_send_attributes(bctx_t &bctx)
858 {
859    BSOCK *sd = bctx.jcr->store_bsock;
860    JCR *jcr = bctx.jcr;
861    FF_PKT *ff_pkt = bctx.ff_pkt;
862    char attribs[MAXSTRING];
863    char attribsExBuf[MAXSTRING];
864    char *attribsEx = NULL;
865    int attr_stream;
866    int comp_len;
867    bool stat;
868    int hangup = get_hangup();
869    int blowup = get_blowup();
870 #ifdef FD_NO_SEND_TEST
871    return true;
872 #endif
873
874    Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
875    /** Find what data stream we will use, then encode the attributes */
876    if ((bctx.data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
877       /* This should not happen */
878       Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
879       return false;
880    }
881    encode_stat(attribs, &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, bctx.data_stream);
882
883    /** Now possibly extend the attributes */
884    if (IS_FT_OBJECT(ff_pkt->type)) {
885       attr_stream = STREAM_RESTORE_OBJECT;
886    } else {
887       attribsEx = attribsExBuf;
888       attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
889    }
890
891    Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
892
893    jcr->lock();
894    jcr->JobFiles++;                    /* increment number of files sent */
895    ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
896    pm_strcpy(jcr->last_fname, ff_pkt->fname);
897    jcr->unlock();
898
899    /* Display the information about the current file if requested */
900    if (is_message_type_set(jcr, M_SAVED)) {
901       ATTR attr;
902       memcpy(&attr.statp, &ff_pkt->statp, sizeof(struct stat));
903       attr.type = ff_pkt->type;
904       attr.ofname = (POOLMEM *)ff_pkt->fname;
905       attr.olname = (POOLMEM *)ff_pkt->link;
906       print_ls_output(jcr, &attr, M_SAVED);
907    }
908
909    /* Debug code: check if we must hangup */
910    if (hangup > 0 && (jcr->JobFiles > (uint32_t)hangup)) {
911       jcr->setJobStatus(JS_Incomplete);
912       Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
913       set_hangup(0);
914       return false;
915    }
916
917    if (blowup > 0 && (jcr->JobFiles > (uint32_t)blowup)) {
918       Jmsg1(jcr, M_ABORT, 0, "Debug blowup requested after %d files.\n", blowup);
919       return false;
920    }
921
922    /**
923     * Send Attributes header to Storage daemon
924     *    <file-index> <stream> <info>
925     */
926    if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
927       if (!jcr->is_canceled() && !jcr->is_incomplete()) {
928          Jmsg2(jcr, M_FATAL, 0, _("Network send error to SD. Data=%s ERR=%s\n"),
929                sd->msg, sd->bstrerror());
930       }
931       return false;
932    }
933    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
934
935    /**
936     * Send file attributes to Storage daemon
937     *   File_index
938     *   File type
939     *   Filename (full path)
940     *   Encoded attributes
941     *   Link name (if type==FT_LNK or FT_LNKSAVED)
942     *   Encoded extended-attributes (for Win32)
943     *
944     * or send Restore Object to Storage daemon
945     *   File_index
946     *   File_type
947     *   Object_index
948     *   Object_len  (possibly compressed)
949     *   Object_full_len (not compressed)
950     *   Object_compression
951     *   Plugin_name
952     *   Object_name
953     *   Binary Object data
954     *
955     * For a directory, link is the same as fname, but with trailing
956     * slash. For a linked file, link is the link.
957     */
958    if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) { /* already stripped */
959       strip_path(ff_pkt);
960    }
961    switch (ff_pkt->type) {
962    case FT_LNK:
963    case FT_LNKSAVED:
964       Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
965       stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
966                        ff_pkt->type, ff_pkt->fname, 0, attribs, 0,
967                        ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
968       break;
969    case FT_DIREND:
970    case FT_REPARSE:
971    case FT_JUNCTION:
972       /* Here link is the canonical filename (i.e. with trailing slash) */
973       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
974                        ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0,
975                        attribsEx, 0, ff_pkt->delta_seq, 0);
976       break;
977    case FT_PLUGIN_CONFIG:
978    case FT_RESTORE_FIRST:
979       comp_len = ff_pkt->object_len;
980       ff_pkt->object_compression = 0;
981       if (ff_pkt->object_len > 1000) {
982          /* Big object, compress it */
983          comp_len = ff_pkt->object_len + 1000;
984          POOLMEM *comp_obj = get_memory(comp_len);
985          /* *** FIXME *** check Zdeflate error */
986          Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
987          if (comp_len < ff_pkt->object_len) {
988             ff_pkt->object = comp_obj;
989             ff_pkt->object_compression = 1;    /* zlib level 9 compression */
990          } else {
991             /* Uncompressed object smaller, use it */
992             comp_len = ff_pkt->object_len;
993          }
994          Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
995       }
996       sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
997                         jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
998                         comp_len, ff_pkt->object_len, ff_pkt->object_compression,
999                         ff_pkt->fname, 0, ff_pkt->object_name, 0);
1000       sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
1001       memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);
1002       /* Note we send one extra byte so Dir can store zero after object */
1003       sd->msglen += comp_len + 1;
1004       stat = sd->send();
1005       if (ff_pkt->object_compression) {
1006          free_and_null_pool_memory(ff_pkt->object);
1007       }
1008       break;
1009    case FT_REG:
1010       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
1011                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0,
1012                ff_pkt->delta_seq, 0);
1013       break;
1014    default:
1015       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
1016                        ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0,
1017                        attribsEx, 0, ff_pkt->delta_seq, 0);
1018       break;
1019    }
1020
1021    if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) {
1022       unstrip_path(ff_pkt);
1023    }
1024
1025    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1026    if (!stat && !jcr->is_job_canceled()) {
1027       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1028             sd->bstrerror());
1029    }
1030    sd->signal(BNET_EOD);            /* indicate end of attributes data */
1031    return stat;
1032 }
1033
1034 /*
1035  * Setup bctx for doing compression
1036  */
1037 static bool setup_compression(bctx_t &bctx)
1038 {
1039    JCR *jcr = bctx.jcr;
1040
1041 #if defined(HAVE_LIBZ) || defined(HAVE_LZO)
1042    bctx.compress_len = 0;
1043    bctx.max_compress_len = 0;
1044    bctx.cbuf = NULL;
1045  #ifdef HAVE_LIBZ
1046    int zstat;
1047
1048    if ((bctx.ff_pkt->flags & FO_COMPRESS) && bctx.ff_pkt->Compress_algo == COMPRESS_GZIP) {
1049       if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
1050          bctx.cbuf = (unsigned char *)jcr->compress_buf + OFFSET_FADDR_SIZE;
1051          bctx.max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
1052       } else {
1053          bctx.cbuf = (unsigned char *)jcr->compress_buf;
1054          bctx.max_compress_len = jcr->compress_buf_size; /* set max length */
1055       }
1056       bctx.wbuf = jcr->compress_buf;    /* compressed output here */
1057       bctx.cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
1058
1059       /**
1060        * Only change zlib parameters if there is no pending operation.
1061        * This should never happen as deflatereset is called after each
1062        * deflate.
1063        */
1064
1065       if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
1066          /** set gzip compression level - must be done per file */
1067          if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset,
1068               bctx.ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
1069             Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
1070             jcr->setJobStatus(JS_ErrorTerminated);
1071             return false;
1072          }
1073       }
1074    }
1075  #endif
1076  #ifdef HAVE_LZO
1077    memset(&bctx.ch, 0, sizeof(comp_stream_header));
1078    bctx.cbuf2 = NULL;
1079
1080    if ((bctx.ff_pkt->flags & FO_COMPRESS) && bctx.ff_pkt->Compress_algo == COMPRESS_LZO1X) {
1081       if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
1082          bctx.cbuf = (unsigned char *)jcr->compress_buf + OFFSET_FADDR_SIZE;
1083          bctx.cbuf2 = (unsigned char *)jcr->compress_buf + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
1084          bctx.max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
1085       } else {
1086          bctx.cbuf = (unsigned char *)jcr->compress_buf;
1087          bctx.cbuf2 = (unsigned char *)jcr->compress_buf + sizeof(comp_stream_header);
1088          bctx.max_compress_len = jcr->compress_buf_size; /* set max length */
1089       }
1090       bctx.ch.magic = COMPRESS_LZO1X;
1091       bctx.ch.version = COMP_HEAD_VERSION;
1092       bctx.wbuf = jcr->compress_buf;    /* compressed output here */
1093       bctx.cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
1094    }
1095  #endif
1096 #endif
1097    return true;
1098 }
1099
1100 /*
1101  * Send MacOS resource fork to SD
1102  */
1103 #ifdef HAVE_DARWIN_OS
1104 static bool send_resource_fork(bctx_t &bctx)
1105 {
1106    FF_PKT *ff_pkt = bctx.ff_pkt;
1107    JCR *jcr = bctx.jcr;
1108    BSOCK *sd = bctx.sd;
1109    int stat;
1110
1111    /** Regular files can have resource forks and Finder Info */
1112    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
1113        ff_pkt->flags & FO_HFSPLUS)) {
1114       if (ff_pkt->hfsinfo.rsrclength > 0) {
1115          int flags;
1116          int rsrc_stream;
1117          if (bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
1118             ff_pkt->ff_errno = errno;
1119             berrno be;
1120             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for \"%s\": ERR=%s.\n"),
1121                  ff_pkt->fname, be.bstrerror());
1122             jcr->JobErrors++;
1123             if (is_bopen(&ff_pkt->bfd)) {
1124                bclose(&ff_pkt->bfd);
1125             }
1126             return true;
1127          }
1128          flags = ff_pkt->flags;
1129          ff_pkt->flags &= ~(FO_COMPRESS|FO_SPARSE|FO_OFFSETS);
1130          if (flags & FO_ENCRYPT) {
1131             rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
1132          } else {
1133             rsrc_stream = STREAM_MACOS_FORK_DATA;
1134          }
1135          stat = send_data(bctx, rsrc_stream);
1136          ff_pkt->flags = flags;
1137          bclose(&ff_pkt->bfd);
1138          if (!stat) {
1139             return false;
1140          }
1141       }
1142
1143       Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
1144       sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
1145       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
1146       pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
1147       sd->msglen = 32;
1148       if (bctx.digest) {
1149          crypto_digest_update(bctx.digest, (uint8_t *)sd->msg, sd->msglen);
1150       }
1151       if (bctx.signing_digest) {
1152          crypto_digest_update(bctx.signing_digest, (uint8_t *)sd->msg, sd->msglen);
1153       }
1154       sd->send();
1155       sd->signal(BNET_EOD);
1156    }
1157    return true;
1158 }
1159 #endif
1160
1161 static bool do_libz_compression(bctx_t &bctx)
1162 {
1163 #ifdef HAVE_LIBZ
1164    JCR *jcr = bctx.jcr;
1165    BSOCK *sd = bctx.sd;
1166    int zstat;
1167
1168    /** Do compression if turned on */
1169    if (bctx.ff_pkt->flags & FO_COMPRESS && bctx.ff_pkt->Compress_algo == COMPRESS_GZIP && jcr->pZLIB_compress_workset) {
1170       Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", bctx.cbuf, bctx.rbuf, sd->msglen);
1171
1172       ((z_stream*)jcr->pZLIB_compress_workset)->next_in   = (unsigned char *)bctx.rbuf;
1173              ((z_stream*)jcr->pZLIB_compress_workset)->avail_in  = sd->msglen;
1174       ((z_stream*)jcr->pZLIB_compress_workset)->next_out  = bctx.cbuf;
1175              ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = bctx.max_compress_len;
1176
1177       if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
1178          Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
1179          jcr->setJobStatus(JS_ErrorTerminated);
1180          return false;
1181       }
1182       bctx.compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
1183       /** reset zlib stream to be able to begin from scratch again */
1184       if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
1185          Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
1186          jcr->setJobStatus(JS_ErrorTerminated);
1187          return false;
1188       }
1189
1190       Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", bctx.compress_len,
1191             sd->msglen);
1192
1193       sd->msglen = bctx.compress_len;      /* set compressed length */
1194       bctx.cipher_input_len = bctx.compress_len;
1195    }
1196 #endif
1197    return true;
1198 }
1199
1200 static bool do_lzo_compression(bctx_t &bctx)
1201 {
1202 #ifdef HAVE_LZO
1203    JCR *jcr = bctx.jcr;
1204    BSOCK *sd = bctx.sd;
1205    int lzores;
1206
1207    /** Do compression if turned on */
1208    if (bctx.ff_pkt->flags & FO_COMPRESS && bctx.ff_pkt->Compress_algo == COMPRESS_LZO1X && jcr->LZO_compress_workset) {
1209       lzo_uint len;          /* TODO: See with the latest patch how to handle lzo_uint with 64bit */
1210
1211       ser_declare;
1212       ser_begin(bctx.cbuf, sizeof(comp_stream_header));
1213
1214       Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", bctx.cbuf, bctx.rbuf, sd->msglen);
1215
1216       lzores = lzo1x_1_compress((const unsigned char*)bctx.rbuf, sd->msglen, bctx.cbuf2,
1217                                 &len, jcr->LZO_compress_workset);
1218       bctx.compress_len = len;
1219       if (lzores == LZO_E_OK && bctx.compress_len <= bctx.max_compress_len) {
1220          /* complete header */
1221          ser_uint32(COMPRESS_LZO1X);
1222          ser_uint32(bctx.compress_len);
1223          ser_uint16(bctx.ch.level);
1224          ser_uint16(bctx.ch.version);
1225       } else {
1226          /** this should NEVER happen */
1227          Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores);
1228          jcr->setJobStatus(JS_ErrorTerminated);
1229          return false;
1230       }
1231
1232       Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", bctx.compress_len,
1233             sd->msglen);
1234
1235       bctx.compress_len += sizeof(comp_stream_header); /* add size of header */
1236       sd->msglen = bctx.compress_len;      /* set compressed length */
1237       bctx.cipher_input_len = bctx.compress_len;
1238    }
1239 #endif
1240    return true;
1241 }
1242
1243 /*
1244  * Do in place strip of path
1245  */
1246 static bool do_snap_strip(FF_PKT *ff)
1247 {
1248    /* if the string starts with the snapshot path name, we can replace
1249     * by the volume name. The volume_path is smaller than the snapshot_path
1250     * snapshot_path = volume_path + /.snapshots/job-xxxx
1251     */
1252    ASSERT(strlen(ff->snapshot_path) > strlen(ff->volume_path));
1253    int sp_first = strlen(ff->snapshot_path); /* point after snapshot_path in fname */
1254    if (strncmp(ff->fname, ff->snapshot_path, sp_first) == 0) {
1255       int last = pm_strcpy(ff->snap_fname, ff->volume_path);
1256       last = MAX(last - 1, 0);
1257
1258       if (ff->snap_fname[last] == '/') {
1259          if (ff->fname[sp_first] == '/') { /* compare with the first character of the string (sp_first not sp_first-1) */
1260             ff->snap_fname[last] = 0;
1261          }
1262       } else {
1263          if (ff->fname[sp_first] != '/') {
1264             pm_strcat(ff->snap_fname, "/");
1265          }
1266       }
1267
1268       pm_strcat(ff->snap_fname, ff->fname + sp_first);
1269       ASSERT(strlen(ff->fname) > strlen(ff->snap_fname));
1270       strcpy(ff->fname, ff->snap_fname);
1271       Dmsg2(DT_SNAPSHOT|20, "%s -> %s\n", ff->fname_save, ff->fname);
1272    }
1273    if (strncmp(ff->link, ff->snapshot_path, sp_first) == 0) {
1274       int last = pm_strcpy(ff->snap_fname, ff->volume_path);
1275       last = MAX(last - 1, 0);
1276
1277       if (ff->snap_fname[last] == '/') {
1278          if (ff->link[sp_first] == '/') { /* compare with the first character of the string (sp_first not sp_first-1) */
1279             ff->snap_fname[last] = 0;
1280          }
1281       } else {
1282          if (ff->link[sp_first] != '/') {
1283             pm_strcat(ff->snap_fname, "/");
1284          }
1285       }
1286
1287       pm_strcat(ff->snap_fname, ff->link + sp_first);
1288       ASSERT(strlen(ff->link) > strlen(ff->snap_fname));
1289       strcpy(ff->link, ff->snap_fname);
1290       Dmsg2(DT_SNAPSHOT|20, "%s -> %s\n", ff->link_save, ff->link);
1291    }
1292
1293    return true;
1294 }
1295
1296 /*
1297  * Do in place strip of path
1298  */
1299 static bool do_strip(int count, char *in)
1300 {
1301    char *out = in;
1302    int stripped;
1303    int numsep = 0;
1304
1305    /** Copy to first path separator -- Win32 might have c: ... */
1306    while (*in && !IsPathSeparator(*in)) {
1307       out++; in++;
1308    }
1309    if (*in) {                    /* Not at the end of the string */
1310       out++; in++;
1311       numsep++;                  /* one separator seen */
1312    }
1313    for (stripped=0; stripped<count && *in; stripped++) {
1314       while (*in && !IsPathSeparator(*in)) {
1315          in++;                   /* skip chars */
1316       }
1317       if (*in) {
1318          numsep++;               /* count separators seen */
1319          in++;                   /* skip separator */
1320       }
1321    }
1322    /* Copy to end */
1323    while (*in) {                /* copy to end */
1324       if (IsPathSeparator(*in)) {
1325          numsep++;
1326       }
1327       *out++ = *in++;
1328    }
1329    *out = 0;
1330    Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n",
1331          stripped, count, numsep, numsep>count);
1332    return stripped==count && numsep>count;
1333 }
1334
1335 /**
1336  * If requested strip leading components of the path so that we can
1337  *   save file as if it came from a subdirectory.  This is most useful
1338  *   for dealing with snapshots, by removing the snapshot directory, or
1339  *   in handling vendor migrations where files have been restored with
1340  *   a vendor product into a subdirectory.
1341  *
1342  *   When we are using snapshots, we might need to convert the path
1343  *   back to the original one using the strip_snap_path option.
1344  */
1345 void strip_path(FF_PKT *ff_pkt)
1346 {
1347    if (!ff_pkt->strip_snap_path        &&
1348        (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0))
1349    {
1350       Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1351       return;
1352    }
1353    /* shared part between strip and snapshot */
1354    if (!ff_pkt->fname_save) {
1355      ff_pkt->fname_save = get_pool_memory(PM_FNAME);
1356      ff_pkt->link_save = get_pool_memory(PM_FNAME);
1357      *ff_pkt->link_save = 0;
1358    }
1359    pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1360    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1361       pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1362       Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1363          strlen(ff_pkt->link));
1364       Dsm_check(200);
1365    }
1366
1367    if (ff_pkt->strip_snap_path) {
1368       if (!do_snap_strip(ff_pkt)) {
1369          Dmsg1(0, "Something wrong with do_snap_strip(%s)\n", ff_pkt->fname);
1370          unstrip_path(ff_pkt);
1371          goto rtn;
1372       }
1373    }
1374
1375    /* See if we want also to strip the path */
1376    if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1377       goto rtn;
1378    }
1379
1380    /**
1381     * Strip path.  If it doesn't succeed put it back.  If
1382     *  it does, and there is a different link string,
1383     *  attempt to strip the link. If it fails, back them
1384     *  both back.
1385     * Do not strip symlinks.
1386     * I.e. if either stripping fails don't strip anything.
1387     */
1388    if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1389       unstrip_path(ff_pkt);
1390       goto rtn;
1391    }
1392    /** Strip links but not symlinks */
1393    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1394       if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1395          unstrip_path(ff_pkt);
1396       }
1397    }
1398
1399 rtn:
1400    Dmsg3(10, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
1401        ff_pkt->link);
1402 }
1403
1404 void unstrip_path(FF_PKT *ff_pkt)
1405 {
1406    if (!ff_pkt->strip_snap_path &&
1407        (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0))
1408    {
1409       return;
1410    }
1411
1412    strcpy(ff_pkt->fname, ff_pkt->fname_save);
1413    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1414       Dmsg2(10, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1415           ff_pkt->link_save);
1416       strcpy(ff_pkt->link, ff_pkt->link_save);
1417       Dmsg2(10, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1418           strlen(ff_pkt->link_save));
1419       Dsm_check(200);
1420    }
1421 }
1422
1423 static void close_vss_backup_session(JCR *jcr)
1424 {
1425 #if defined(WIN32_VSS)
1426    /* STOP VSS ON WIN32 */
1427    /* tell vss to close the backup session */
1428    if (jcr->Snapshot) {
1429       if (g_pVSSClient->CloseBackup()) {
1430          /* inform user about writer states */
1431          for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1432             int msg_type = M_INFO;
1433             if (g_pVSSClient->GetWriterState(i) < 1) {
1434                msg_type = M_WARNING;
1435                jcr->JobErrors++;
1436             }
1437             Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1438          }
1439       }
1440       /* Generate Job global writer metadata */
1441       WCHAR *metadata = g_pVSSClient->GetMetadata();
1442       if (metadata) {
1443          FF_PKT *ff_pkt = jcr->ff;
1444          ff_pkt->fname = (char *)"*all*"; /* for all plugins */
1445          ff_pkt->type = FT_RESTORE_FIRST;
1446          ff_pkt->LinkFI = 0;
1447          ff_pkt->object_name = (char *)"job_metadata.xml";
1448          ff_pkt->object = (char *)metadata;
1449          ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR);
1450          ff_pkt->object_index = (int)time(NULL);
1451          save_file(jcr, ff_pkt, true);
1452      }
1453    }
1454 #endif
1455 }