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