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