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