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