]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/backup.c
Attempt once again to fix OpenBSD acl/xattr problems
[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 Job=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    /* Debug code: check if we must hangup */
883    if (hangup > 0 && (jcr->JobFiles > (uint32_t)hangup)) {
884       jcr->setJobStatus(JS_Incomplete);
885       Jmsg1(jcr, M_FATAL, 0, "Debug hangup requested after %d files.\n", hangup);
886       set_hangup(0);
887       return false;
888    }
889
890    if (blowup > 0 && (jcr->JobFiles > (uint32_t)blowup)) {
891       Jmsg1(jcr, M_ABORT, 0, "Debug blowup requested after %d files.\n", blowup);
892       return false;
893    }
894
895    /**
896     * Send Attributes header to Storage daemon
897     *    <file-index> <stream> <info>
898     */
899    if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
900       if (!jcr->is_canceled() && !jcr->is_incomplete()) {
901          Jmsg2(jcr, M_FATAL, 0, _("Network send error to SD. Data=%s ERR=%s\n"),
902                sd->msg, sd->bstrerror());
903       }
904       return false;
905    }
906    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
907
908    /**
909     * Send file attributes to Storage daemon
910     *   File_index
911     *   File type
912     *   Filename (full path)
913     *   Encoded attributes
914     *   Link name (if type==FT_LNK or FT_LNKSAVED)
915     *   Encoded extended-attributes (for Win32)
916     *
917     * or send Restore Object to Storage daemon
918     *   File_index
919     *   File_type
920     *   Object_index
921     *   Object_len  (possibly compressed)
922     *   Object_full_len (not compressed)
923     *   Object_compression
924     *   Plugin_name
925     *   Object_name
926     *   Binary Object data
927     *
928     * For a directory, link is the same as fname, but with trailing
929     * slash. For a linked file, link is the link.
930     */
931    if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) { /* already stripped */
932       strip_path(ff_pkt);
933    }
934    switch (ff_pkt->type) {
935    case FT_LNK:
936    case FT_LNKSAVED:
937       Dmsg3(300, "Link %d %s to %s\n", jcr->JobFiles, ff_pkt->fname, ff_pkt->link);
938       stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c%u%c", jcr->JobFiles,
939                        ff_pkt->type, ff_pkt->fname, 0, attribs, 0,
940                        ff_pkt->link, 0, attribsEx, 0, ff_pkt->delta_seq, 0);
941       break;
942    case FT_DIREND:
943    case FT_REPARSE:
944    case FT_JUNCTION:
945       /* Here link is the canonical filename (i.e. with trailing slash) */
946       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
947                        ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0,
948                        attribsEx, 0, ff_pkt->delta_seq, 0);
949       break;
950    case FT_PLUGIN_CONFIG:
951    case FT_RESTORE_FIRST:
952       comp_len = ff_pkt->object_len;
953       ff_pkt->object_compression = 0;
954       if (ff_pkt->object_len > 1000) {
955          /* Big object, compress it */
956          comp_len = ff_pkt->object_len + 1000;
957          POOLMEM *comp_obj = get_memory(comp_len);
958          /* *** FIXME *** check Zdeflate error */
959          Zdeflate(ff_pkt->object, ff_pkt->object_len, comp_obj, comp_len);
960          if (comp_len < ff_pkt->object_len) {
961             ff_pkt->object = comp_obj;
962             ff_pkt->object_compression = 1;    /* zlib level 9 compression */
963          } else {
964             /* Uncompressed object smaller, use it */
965             comp_len = ff_pkt->object_len;
966          }
967          Dmsg2(100, "Object compressed from %d to %d bytes\n", ff_pkt->object_len, comp_len);
968       }
969       sd->msglen = Mmsg(sd->msg, "%d %d %d %d %d %d %s%c%s%c",
970                         jcr->JobFiles, ff_pkt->type, ff_pkt->object_index,
971                         comp_len, ff_pkt->object_len, ff_pkt->object_compression,
972                         ff_pkt->fname, 0, ff_pkt->object_name, 0);
973       sd->msg = check_pool_memory_size(sd->msg, sd->msglen + comp_len + 2);
974       memcpy(sd->msg + sd->msglen, ff_pkt->object, comp_len);
975       /* Note we send one extra byte so Dir can store zero after object */
976       sd->msglen += comp_len + 1;
977       stat = sd->send();
978       if (ff_pkt->object_compression) {
979          free_and_null_pool_memory(ff_pkt->object);
980       }
981       break;
982    case FT_REG:
983       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%d%c", jcr->JobFiles,
984                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0,
985                ff_pkt->delta_seq, 0);
986       break;
987    default:
988       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c%u%c", jcr->JobFiles,
989                        ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0,
990                        attribsEx, 0, ff_pkt->delta_seq, 0);
991       break;
992    }
993
994    if (!IS_FT_OBJECT(ff_pkt->type) && ff_pkt->type != FT_DELETED) {
995       unstrip_path(ff_pkt);
996    }
997
998    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
999    if (!stat && !jcr->is_job_canceled()) {
1000       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1001             sd->bstrerror());
1002    }
1003    sd->signal(BNET_EOD);            /* indicate end of attributes data */
1004    return stat;
1005 }
1006
1007 /*
1008  * Setup bctx for doing compression
1009  */
1010 static bool setup_compression(bctx_t &bctx)
1011 {
1012    JCR *jcr = bctx.jcr;
1013
1014 #if defined(HAVE_LIBZ) || defined(HAVE_LZO)
1015    bctx.compress_len = 0;
1016    bctx.max_compress_len = 0;
1017    bctx.cbuf = NULL;
1018  #ifdef HAVE_LIBZ
1019    int zstat;
1020
1021    if ((bctx.ff_pkt->flags & FO_COMPRESS) && bctx.ff_pkt->Compress_algo == COMPRESS_GZIP) {
1022       if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
1023          bctx.cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
1024          bctx.max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
1025       } else {
1026          bctx.cbuf = (Bytef *)jcr->compress_buf;
1027          bctx.max_compress_len = jcr->compress_buf_size; /* set max length */
1028       }
1029       bctx.wbuf = jcr->compress_buf;    /* compressed output here */
1030       bctx.cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
1031
1032       /**
1033        * Only change zlib parameters if there is no pending operation.
1034        * This should never happen as deflatereset is called after each
1035        * deflate.
1036        */
1037
1038       if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
1039          /** set gzip compression level - must be done per file */
1040          if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset,
1041               bctx.ff_pkt->Compress_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
1042             Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
1043             jcr->setJobStatus(JS_ErrorTerminated);
1044             return false;
1045          }
1046       }
1047    }
1048  #endif
1049  #ifdef HAVE_LZO
1050    memset(&bctx.ch, 0, sizeof(comp_stream_header));
1051    bctx.cbuf2 = NULL;
1052
1053    if ((bctx.ff_pkt->flags & FO_COMPRESS) && bctx.ff_pkt->Compress_algo == COMPRESS_LZO1X) {
1054       if ((bctx.ff_pkt->flags & FO_SPARSE) || (bctx.ff_pkt->flags & FO_OFFSETS)) {
1055          bctx.cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
1056          bctx.cbuf2 = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE + sizeof(comp_stream_header);
1057          bctx.max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
1058       } else {
1059          bctx.cbuf = (Bytef *)jcr->compress_buf;
1060          bctx.cbuf2 = (Bytef *)jcr->compress_buf + sizeof(comp_stream_header);
1061          bctx.max_compress_len = jcr->compress_buf_size; /* set max length */
1062       }
1063       bctx.ch.magic = COMPRESS_LZO1X;
1064       bctx.ch.version = COMP_HEAD_VERSION;
1065       bctx.wbuf = jcr->compress_buf;    /* compressed output here */
1066       bctx.cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
1067    }
1068  #endif
1069 #else
1070    bctx.max_compress_len = 0;
1071 #endif
1072    return true;
1073 }
1074
1075 /*
1076  * Send MacOS resource fork to SD
1077  */
1078 #ifdef HAVE_DARWIN_OS
1079 static bool send_resource_fork(bctx_t &bctx)
1080 {
1081    FF_PKT *ff_pkt = bctx.ff_pkt;
1082    JCR *jcr = bctx.jcr;
1083    BSOCK *sd = bctx.sd;
1084    int stat;
1085
1086    /** Regular files can have resource forks and Finder Info */
1087    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
1088        ff_pkt->flags & FO_HFSPLUS)) {
1089       if (ff_pkt->hfsinfo.rsrclength > 0) {
1090          int flags;
1091          int rsrc_stream;
1092          if (bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
1093             ff_pkt->ff_errno = errno;
1094             berrno be;
1095             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for \"%s\": ERR=%s.\n"),
1096                  ff_pkt->fname, be.bstrerror());
1097             jcr->JobErrors++;
1098             if (is_bopen(&ff_pkt->bfd)) {
1099                bclose(&ff_pkt->bfd);
1100             }
1101             return true;
1102          }
1103          flags = ff_pkt->flags;
1104          ff_pkt->flags &= ~(FO_COMPRESS|FO_SPARSE|FO_OFFSETS);
1105          if (flags & FO_ENCRYPT) {
1106             rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
1107          } else {
1108             rsrc_stream = STREAM_MACOS_FORK_DATA;
1109          }
1110          stat = send_data(bctx, rsrc_stream);
1111          ff_pkt->flags = flags;
1112          bclose(&ff_pkt->bfd);
1113          if (!stat) {
1114             return false;
1115          }
1116       }
1117
1118       Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
1119       sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
1120       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
1121       pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
1122       sd->msglen = 32;
1123       if (bctx.digest) {
1124          crypto_digest_update(bctx.digest, (uint8_t *)sd->msg, sd->msglen);
1125       }
1126       if (bctx.signing_digest) {
1127          crypto_digest_update(bctx.signing_digest, (uint8_t *)sd->msg, sd->msglen);
1128       }
1129       sd->send();
1130       sd->signal(BNET_EOD);
1131    }
1132    return true;
1133 }
1134 #endif
1135
1136 static bool do_libz_compression(bctx_t &bctx)
1137 {
1138 #ifdef HAVE_LIBZ
1139    JCR *jcr = bctx.jcr;
1140    BSOCK *sd = bctx.sd;
1141    int zstat;
1142
1143    /** Do compression if turned on */
1144    if (bctx.ff_pkt->flags & FO_COMPRESS && bctx.ff_pkt->Compress_algo == COMPRESS_GZIP && jcr->pZLIB_compress_workset) {
1145       Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", bctx.cbuf, bctx.rbuf, sd->msglen);
1146
1147       ((z_stream*)jcr->pZLIB_compress_workset)->next_in   = (Bytef *)bctx.rbuf;
1148              ((z_stream*)jcr->pZLIB_compress_workset)->avail_in  = sd->msglen;
1149       ((z_stream*)jcr->pZLIB_compress_workset)->next_out  = bctx.cbuf;
1150              ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = bctx.max_compress_len;
1151
1152       if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
1153          Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
1154          jcr->setJobStatus(JS_ErrorTerminated);
1155          return false;
1156       }
1157       bctx.compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
1158       /** reset zlib stream to be able to begin from scratch again */
1159       if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
1160          Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
1161          jcr->setJobStatus(JS_ErrorTerminated);
1162          return false;
1163       }
1164
1165       Dmsg2(400, "GZIP compressed len=%d uncompressed len=%d\n", bctx.compress_len,
1166             sd->msglen);
1167
1168       sd->msglen = bctx.compress_len;      /* set compressed length */
1169       bctx.cipher_input_len = bctx.compress_len;
1170    }
1171 #endif
1172    return true;
1173 }
1174
1175 static bool do_lzo_compression(bctx_t &bctx)
1176 {
1177 #ifdef HAVE_LZO
1178    JCR *jcr = bctx.jcr;
1179    BSOCK *sd = bctx.sd;
1180    int lzores;
1181
1182    /** Do compression if turned on */
1183    if (bctx.ff_pkt->flags & FO_COMPRESS && bctx.ff_pkt->Compress_algo == COMPRESS_LZO1X && jcr->LZO_compress_workset) {
1184       lzo_uint len;          /* TODO: See with the latest patch how to handle lzo_uint with 64bit */
1185
1186       ser_declare;
1187       ser_begin(bctx.cbuf, sizeof(comp_stream_header));
1188
1189       Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", bctx.cbuf, bctx.rbuf, sd->msglen);
1190
1191       lzores = lzo1x_1_compress((const unsigned char*)bctx.rbuf, sd->msglen, bctx.cbuf2,
1192                                 &len, jcr->LZO_compress_workset);
1193       bctx.compress_len = len;
1194       if (lzores == LZO_E_OK && bctx.compress_len <= bctx.max_compress_len) {
1195          /* complete header */
1196          ser_uint32(COMPRESS_LZO1X);
1197          ser_uint32(bctx.compress_len);
1198          ser_uint16(bctx.ch.level);
1199          ser_uint16(bctx.ch.version);
1200       } else {
1201          /** this should NEVER happen */
1202          Jmsg(jcr, M_FATAL, 0, _("Compression LZO error: %d\n"), lzores);
1203          jcr->setJobStatus(JS_ErrorTerminated);
1204          return false;
1205       }
1206
1207       Dmsg2(400, "LZO compressed len=%d uncompressed len=%d\n", bctx.compress_len,
1208             sd->msglen);
1209
1210       bctx.compress_len += sizeof(comp_stream_header); /* add size of header */
1211       sd->msglen = bctx.compress_len;      /* set compressed length */
1212       bctx.cipher_input_len = bctx.compress_len;
1213    }
1214 #endif
1215    return true;
1216 }
1217
1218 /*
1219  * Do in place strip of path
1220  */
1221 static bool do_snap_strip(FF_PKT *ff)
1222 {
1223    /* if the string starts with the snapshot path name, we can replace
1224     * by the volume name. The volume_path is smaller than the snapshot_path
1225     * snapshot_path = volume_path + /.snapshots/job-xxxx
1226     */
1227    ASSERT(strlen(ff->snapshot_path) > strlen(ff->volume_path));
1228    int sp_first = strlen(ff->snapshot_path); /* point after snapshot_path in fname */
1229    if (strncmp(ff->fname, ff->snapshot_path, sp_first) == 0) {
1230       int last = pm_strcpy(ff->snap_fname, ff->volume_path);
1231       last = MAX(last - 1, 0);
1232
1233       if (ff->snap_fname[last] == '/') {
1234          if (ff->fname[sp_first] == '/') { /* compare with the first character of the string (sp_first not sp_first-1) */
1235             ff->snap_fname[last] = 0;
1236          }
1237       } else {
1238          if (ff->fname[sp_first] != '/') {
1239             pm_strcat(ff->snap_fname, "/");
1240          }
1241       }
1242
1243       pm_strcat(ff->snap_fname, ff->fname + sp_first);
1244       ASSERT(strlen(ff->fname) > strlen(ff->snap_fname));
1245       strcpy(ff->fname, ff->snap_fname);
1246       Dmsg2(DT_SNAPSHOT|20, "%s -> %s\n", ff->fname_save, ff->fname);
1247    }
1248    if (strncmp(ff->link, ff->snapshot_path, sp_first) == 0) {
1249       int last = pm_strcpy(ff->snap_fname, ff->volume_path);
1250       last = MAX(last - 1, 0);
1251
1252       if (ff->snap_fname[last] == '/') {
1253          if (ff->link[sp_first] == '/') { /* compare with the first character of the string (sp_first not sp_first-1) */
1254             ff->snap_fname[last] = 0;
1255          }
1256       } else {
1257          if (ff->link[sp_first] != '/') {
1258             pm_strcat(ff->snap_fname, "/");
1259          }
1260       }
1261
1262       pm_strcat(ff->snap_fname, ff->link + sp_first);
1263       ASSERT(strlen(ff->link) > strlen(ff->snap_fname));
1264       strcpy(ff->link, ff->snap_fname);
1265       Dmsg2(DT_SNAPSHOT|20, "%s -> %s\n", ff->link_save, ff->link);
1266    }
1267
1268    return true;
1269 }
1270
1271 /*
1272  * Do in place strip of path
1273  */
1274 static bool do_strip(int count, char *in)
1275 {
1276    char *out = in;
1277    int stripped;
1278    int numsep = 0;
1279
1280    /** Copy to first path separator -- Win32 might have c: ... */
1281    while (*in && !IsPathSeparator(*in)) {
1282       out++; in++;
1283    }
1284    if (*in) {                    /* Not at the end of the string */
1285       out++; in++;
1286       numsep++;                  /* one separator seen */
1287    }
1288    for (stripped=0; stripped<count && *in; stripped++) {
1289       while (*in && !IsPathSeparator(*in)) {
1290          in++;                   /* skip chars */
1291       }
1292       if (*in) {
1293          numsep++;               /* count separators seen */
1294          in++;                   /* skip separator */
1295       }
1296    }
1297    /* Copy to end */
1298    while (*in) {                /* copy to end */
1299       if (IsPathSeparator(*in)) {
1300          numsep++;
1301       }
1302       *out++ = *in++;
1303    }
1304    *out = 0;
1305    Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n",
1306          stripped, count, numsep, numsep>count);
1307    return stripped==count && numsep>count;
1308 }
1309
1310 /**
1311  * If requested strip leading components of the path so that we can
1312  *   save file as if it came from a subdirectory.  This is most useful
1313  *   for dealing with snapshots, by removing the snapshot directory, or
1314  *   in handling vendor migrations where files have been restored with
1315  *   a vendor product into a subdirectory.
1316  *
1317  *   When we are using snapshots, we might need to convert the path
1318  *   back to the original one using the strip_snap_path option.
1319  */
1320 void strip_path(FF_PKT *ff_pkt)
1321 {
1322    if (!ff_pkt->strip_snap_path        &&
1323        (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0))
1324    {
1325       Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1326       return;
1327    }
1328    /* shared part between strip and snapshot */
1329    if (!ff_pkt->fname_save) {
1330      ff_pkt->fname_save = get_pool_memory(PM_FNAME);
1331      ff_pkt->link_save = get_pool_memory(PM_FNAME);
1332      *ff_pkt->link_save = 0;
1333    }
1334    pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1335    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1336       pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1337       Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1338          strlen(ff_pkt->link));
1339       Dsm_check(200);
1340    }
1341
1342    if (ff_pkt->strip_snap_path) {
1343       if (!do_snap_strip(ff_pkt)) {
1344          Dmsg1(0, "Something wrong with do_snap_strip(%s)\n", ff_pkt->fname);
1345          unstrip_path(ff_pkt);
1346          goto rtn;
1347       }
1348    }
1349
1350    /* See if we want also to strip the path */
1351    if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1352       goto rtn;
1353    }
1354
1355    /**
1356     * Strip path.  If it doesn't succeed put it back.  If
1357     *  it does, and there is a different link string,
1358     *  attempt to strip the link. If it fails, back them
1359     *  both back.
1360     * Do not strip symlinks.
1361     * I.e. if either stripping fails don't strip anything.
1362     */
1363    if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1364       unstrip_path(ff_pkt);
1365       goto rtn;
1366    }
1367    /** Strip links but not symlinks */
1368    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1369       if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1370          unstrip_path(ff_pkt);
1371       }
1372    }
1373
1374 rtn:
1375    Dmsg3(10, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
1376        ff_pkt->link);
1377 }
1378
1379 void unstrip_path(FF_PKT *ff_pkt)
1380 {
1381    if (!ff_pkt->strip_snap_path &&
1382        (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0))
1383    {
1384       return;
1385    }
1386
1387    strcpy(ff_pkt->fname, ff_pkt->fname_save);
1388    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1389       Dmsg2(10, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1390           ff_pkt->link_save);
1391       strcpy(ff_pkt->link, ff_pkt->link_save);
1392       Dmsg2(10, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1393           strlen(ff_pkt->link_save));
1394       Dsm_check(200);
1395    }
1396 }
1397
1398 static void close_vss_backup_session(JCR *jcr)
1399 {
1400 #if defined(WIN32_VSS)
1401    /* STOP VSS ON WIN32 */
1402    /* tell vss to close the backup session */
1403    if (jcr->Snapshot) {
1404       if (g_pVSSClient->CloseBackup()) {
1405          /* inform user about writer states */
1406          for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
1407             int msg_type = M_INFO;
1408             if (g_pVSSClient->GetWriterState(i) < 1) {
1409                msg_type = M_WARNING;
1410                jcr->JobErrors++;
1411             }
1412             Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
1413          }
1414       }
1415       /* Generate Job global writer metadata */
1416       WCHAR *metadata = g_pVSSClient->GetMetadata();
1417       if (metadata) {
1418          FF_PKT *ff_pkt = jcr->ff;
1419          ff_pkt->fname = (char *)"*all*"; /* for all plugins */
1420          ff_pkt->type = FT_RESTORE_FIRST;
1421          ff_pkt->LinkFI = 0;
1422          ff_pkt->object_name = (char *)"job_metadata.xml";
1423          ff_pkt->object = (char *)metadata;
1424          ff_pkt->object_len = (wcslen(metadata) + 1) * sizeof(WCHAR);
1425          ff_pkt->object_index = (int)time(NULL);
1426          save_file(jcr, ff_pkt, true);
1427      }
1428    }
1429 #endif
1430 }