]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/backup.c
5cc722fa22dc77f84e620bed0bd3a2f2ee616de3
[bacula/bacula] / bacula / src / filed / backup.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *  Bacula File Daemon  backup.c  send file attributes and data
30  *   to the Storage daemon.
31  *
32  *    Kern Sibbald, March MM
33  *
34  *   Version $Id$
35  *
36  */
37
38 #include "bacula.h"
39 #include "filed.h"
40
41 #if defined(HAVE_ACL)
42 const bool have_acl = true;
43 #else
44 const bool have_acl = false;
45 #endif
46
47 #if defined(HAVE_XATTR)
48 const bool have_xattr = true;
49 #else
50 const bool have_xattr = false;
51 #endif
52
53 /* Forward referenced functions */
54 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level);
55 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
56 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
57 static bool crypto_session_start(JCR *jcr);
58 static void crypto_session_end(JCR *jcr);
59 static bool crypto_session_send(JCR *jcr, BSOCK *sd);
60
61 /*
62  * Find all the requested files and send them
63  * to the Storage daemon.
64  *
65  * Note, we normally carry on a one-way
66  * conversation from this point on with the SD, simply blasting
67  * data to him.  To properly know what is going on, we
68  * also run a "heartbeat" monitor which reads the socket and
69  * reacts accordingly (at the moment it has nothing to do
70  * except echo the heartbeat to the Director).
71  *
72  */
73 bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
74 {
75    BSOCK *sd;
76    bool ok = true;
77    // TODO landonf: Allow user to specify encryption algorithm
78
79    sd = jcr->store_bsock;
80
81    set_jcr_job_status(jcr, JS_Running);
82
83    Dmsg1(300, "bfiled: opened data connection %d to stored\n", sd->m_fd);
84
85    LockRes();
86    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
87    UnlockRes();
88    uint32_t buf_size;
89    if (client) {
90       buf_size = client->max_network_buffer_size;
91    } else {
92       buf_size = 0;                   /* use default */
93    }
94    if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) {
95       set_jcr_job_status(jcr, JS_ErrorTerminated);
96       Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
97       return false;
98    }
99
100    jcr->buf_size = sd->msglen;
101    /* Adjust for compression so that output buffer is
102     *  12 bytes + 0.1% larger than input buffer plus 18 bytes.
103     *  This gives a bit extra plus room for the sparse addr if any.
104     *  Note, we adjust the read size to be smaller so that the
105     *  same output buffer can be used without growing it.
106     *
107     * The zlib compression workset is initialized here to minimize
108     *  the "per file" load. The jcr member is only set, if the init 
109     *  was successful.
110     */
111    jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
112    jcr->compress_buf = get_memory(jcr->compress_buf_size);
113    
114 #ifdef HAVE_LIBZ
115    z_stream *pZlibStream = (z_stream*)malloc(sizeof(z_stream));  
116    if (pZlibStream) {
117       pZlibStream->zalloc = Z_NULL;      
118       pZlibStream->zfree = Z_NULL;
119       pZlibStream->opaque = Z_NULL;
120       pZlibStream->state = Z_NULL;
121
122       if (deflateInit(pZlibStream, Z_DEFAULT_COMPRESSION) == Z_OK) {
123          jcr->pZLIB_compress_workset = pZlibStream;
124       } else {
125          free (pZlibStream);
126       }
127    }
128 #endif
129
130    if (!crypto_session_start(jcr)) {
131       return false;
132    }
133
134    set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
135
136    /* in accurate mode, we overwrite the find_one check function */
137    if (jcr->accurate) {
138       set_find_changed_function((FF_PKT *)jcr->ff, accurate_check_file);
139    } 
140    
141    start_heartbeat_monitor(jcr);
142
143    if (have_acl) {
144       jcr->acl_data = get_pool_memory(PM_MESSAGE);
145       jcr->total_acl_errors = 0;
146    }
147    if (have_xattr) {
148       jcr->xattr_data = get_pool_memory(PM_MESSAGE);
149       jcr->total_xattr_errors = 0;
150    }
151
152    /* Subroutine save_file() is called for each file */
153    if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
154       ok = false;                     /* error */
155       set_jcr_job_status(jcr, JS_ErrorTerminated);
156    }
157
158    if (jcr->total_acl_errors > 0) {
159       Jmsg(jcr, M_ERROR, 0, _("Encountered %ld acl errors while doing backup\n"),
160            jcr->total_acl_errors);
161    }
162    if (jcr->total_xattr_errors > 0) {
163       Jmsg(jcr, M_ERROR, 0, _("Encountered %ld xattr errors while doing backup\n"),
164            jcr->total_xattr_errors);
165    }
166
167    accurate_send_deleted_list(jcr);              /* send deleted list to SD  */
168
169    stop_heartbeat_monitor(jcr);
170
171    sd->signal(BNET_EOD);            /* end of sending data */
172
173    if (have_acl && jcr->acl_data) {
174       free_pool_memory(jcr->acl_data);
175       jcr->acl_data = NULL;
176    }
177    if (have_xattr && jcr->xattr_data) {
178       free_pool_memory(jcr->xattr_data);
179       jcr->xattr_data = NULL;
180    }
181    if (jcr->big_buf) {
182       free(jcr->big_buf);
183       jcr->big_buf = NULL;
184    }
185    if (jcr->compress_buf) {
186       free_pool_memory(jcr->compress_buf);
187       jcr->compress_buf = NULL;
188    }
189    if (jcr->pZLIB_compress_workset) {
190       /* Free the zlib stream */
191 #ifdef HAVE_LIBZ
192       deflateEnd((z_stream *)jcr->pZLIB_compress_workset);
193 #endif
194       free (jcr->pZLIB_compress_workset);
195       jcr->pZLIB_compress_workset = NULL;
196    }
197    crypto_session_end(jcr);
198
199
200    Dmsg1(100, "end blast_data ok=%d\n", ok);
201    return ok;
202 }
203
204 static bool crypto_session_start(JCR *jcr)
205 {
206    crypto_cipher_t cipher = CRYPTO_CIPHER_AES_128_CBC;
207
208    /*
209     * Create encryption session data and a cached, DER-encoded session data
210     * structure. We use a single session key for each backup, so we'll encode
211     * the session data only once.
212     */
213    if (jcr->crypto.pki_encrypt) {
214       uint32_t size = 0;
215
216       /* Create per-job session encryption context */
217       jcr->crypto.pki_session = crypto_session_new(cipher, jcr->crypto.pki_recipients);
218
219       /* Get the session data size */
220       if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)0, &size)) {
221          Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
222          return false;
223       }
224
225       /* Allocate buffer */
226       jcr->crypto.pki_session_encoded = get_memory(size);
227
228       /* Encode session data */
229       if (!crypto_session_encode(jcr->crypto.pki_session, (uint8_t *)jcr->crypto.pki_session_encoded, &size)) {
230          Jmsg(jcr, M_FATAL, 0, _("An error occurred while encrypting the stream.\n"));
231          return false;
232       }
233
234       /* ... and store the encoded size */
235       jcr->crypto.pki_session_encoded_size = size;
236
237       /* Allocate the encryption/decryption buffer */
238       jcr->crypto.crypto_buf = get_memory(CRYPTO_CIPHER_MAX_BLOCK_SIZE);
239    }
240    return true;
241 }
242
243 static void crypto_session_end(JCR *jcr)
244 {
245    if (jcr->crypto.crypto_buf) {
246       free_pool_memory(jcr->crypto.crypto_buf);
247       jcr->crypto.crypto_buf = NULL;
248    }
249    if (jcr->crypto.pki_session) {
250       crypto_session_free(jcr->crypto.pki_session);
251    }
252    if (jcr->crypto.pki_session_encoded) {
253       free_pool_memory(jcr->crypto.pki_session_encoded);
254       jcr->crypto.pki_session_encoded = NULL;
255    }
256 }
257
258 static bool crypto_session_send(JCR *jcr, BSOCK *sd)
259 {
260    POOLMEM *msgsave;
261
262    /* Send our header */
263    Dmsg2(100, "Send hdr fi=%ld stream=%d\n", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
264    sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_ENCRYPTED_SESSION_DATA);
265
266    msgsave = sd->msg;
267    sd->msg = jcr->crypto.pki_session_encoded;
268    sd->msglen = jcr->crypto.pki_session_encoded_size;
269    jcr->JobBytes += sd->msglen;
270
271    Dmsg1(100, "Send data len=%d\n", sd->msglen);
272    sd->send();
273    sd->msg = msgsave;
274    sd->signal(BNET_EOD);
275    return true;
276 }
277
278
279 /*
280  * Called here by find() for each file included.
281  *   This is a callback. The original is find_files() above.
282  *
283  *  Send the file and its data to the Storage daemon.
284  *
285  *  Returns: 1 if OK
286  *           0 if error
287  *          -1 to ignore file/directory (not used here)
288  */
289 int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
290 {
291    bool do_read = false;
292    int stat, data_stream; 
293    int rtnstat = 0;
294    DIGEST *digest = NULL;
295    DIGEST *signing_digest = NULL;
296    int digest_stream = STREAM_NONE;
297    SIGNATURE *sig = NULL;
298    bool has_file_data = false;
299    // TODO landonf: Allow the user to specify the digest algorithm
300 #ifdef HAVE_SHA2
301    crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
302 #else
303    crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
304 #endif
305    BSOCK *sd = jcr->store_bsock;
306
307    if (job_canceled(jcr)) {
308       return 0;
309    }
310
311    jcr->num_files_examined++;         /* bump total file count */
312
313    switch (ff_pkt->type) {
314    case FT_LNKSAVED:                  /* Hard linked, file already saved */
315       Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
316       break;
317    case FT_REGE:
318       Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
319       has_file_data = true;
320       break;
321    case FT_REG:
322       Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
323       has_file_data = true;
324       break;
325    case FT_LNK:
326       Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
327       break;
328    case FT_DIRBEGIN:
329       jcr->num_files_examined--;      /* correct file count */
330       return 1;                       /* not used */
331    case FT_NORECURSE:
332       Jmsg(jcr, M_INFO, 1, _("     Recursion turned off. Will not descend from %s into %s\n"),
333            ff_pkt->top_fname, ff_pkt->fname);
334       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
335       break;
336    case FT_NOFSCHG:
337       /* Suppress message for /dev filesystems */
338       if (!is_in_fileset(ff_pkt)) {
339          Jmsg(jcr, M_INFO, 1, _("     %s is a different filesystem. Will not descend from %s into %s\n"),
340               ff_pkt->fname, ff_pkt->top_fname, ff_pkt->fname);
341       }
342       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
343       break;
344    case FT_INVALIDFS:
345       Jmsg(jcr, M_INFO, 1, _("     Disallowed filesystem. Will not descend from %s into %s\n"),
346            ff_pkt->top_fname, ff_pkt->fname);
347       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
348       break;
349    case FT_INVALIDDT:
350       Jmsg(jcr, M_INFO, 1, _("     Disallowed drive type. Will not descend into %s\n"),
351            ff_pkt->fname);
352       break;
353    case FT_REPARSE:
354    case FT_DIREND:
355       Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
356       break;
357    case FT_SPEC:
358       Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
359       if (S_ISSOCK(ff_pkt->statp.st_mode)) {
360         Jmsg(jcr, M_SKIPPED, 1, _("     Socket file skipped: %s\n"), ff_pkt->fname);
361         return 1;
362       }
363       break;
364    case FT_RAW:
365       Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
366       has_file_data = true;
367       break;
368    case FT_FIFO:
369       Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
370       break;
371    case FT_NOACCESS: {
372       berrno be;
373       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
374          be.bstrerror(ff_pkt->ff_errno));
375       jcr->JobErrors++;
376       return 1;
377    }
378    case FT_NOFOLLOW: {
379       berrno be;
380       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not follow link \"%s\": ERR=%s\n"), 
381            ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
382       jcr->JobErrors++;
383       return 1;
384    }
385    case FT_NOSTAT: {
386       berrno be;
387       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
388          be.bstrerror(ff_pkt->ff_errno));
389       jcr->JobErrors++;
390       return 1;
391    }
392    case FT_DIRNOCHG:
393    case FT_NOCHG:
394       Jmsg(jcr, M_SKIPPED, 1, _("     Unchanged file skipped: %s\n"), ff_pkt->fname);
395       return 1;
396    case FT_ISARCH:
397       Jmsg(jcr, M_NOTSAVED, 0, _("     Archive file not saved: %s\n"), ff_pkt->fname);
398       return 1;
399    case FT_NOOPEN: {
400       berrno be;
401       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not open directory \"%s\": ERR=%s\n"), 
402            ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
403       jcr->JobErrors++;
404       return 1;
405    }
406    default:
407       Jmsg(jcr, M_NOTSAVED, 0,  _("     Unknown file type %d; not saved: %s\n"), 
408            ff_pkt->type, ff_pkt->fname);
409       jcr->JobErrors++;
410       return 1;
411    }
412
413    Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
414
415    /* Digests and encryption are only useful if there's file data */
416    if (has_file_data) {
417       /*
418        * Setup for digest handling. If this fails, the digest will be set to NULL
419        * and not used. Note, the digest (file hash) can be any one of the four
420        * algorithms below.
421        *
422        * The signing digest is a single algorithm depending on
423        * whether or not we have SHA2.              
424        *   ****FIXME****  the signing algoritm should really be
425        *   determined a different way!!!!!!  What happens if
426        *   sha2 was available during backup but not restore?
427        */
428       if (ff_pkt->flags & FO_MD5) {
429          digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5);
430          digest_stream = STREAM_MD5_DIGEST;
431
432       } else if (ff_pkt->flags & FO_SHA1) {
433          digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1);
434          digest_stream = STREAM_SHA1_DIGEST;
435
436       } else if (ff_pkt->flags & FO_SHA256) {
437          digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256);
438          digest_stream = STREAM_SHA256_DIGEST;
439
440       } else if (ff_pkt->flags & FO_SHA512) {
441          digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512);
442          digest_stream = STREAM_SHA512_DIGEST;
443       }
444
445       /* Did digest initialization fail? */
446       if (digest_stream != STREAM_NONE && digest == NULL) {
447          Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
448             stream_to_ascii(digest_stream));
449       }
450
451       /*
452        * Set up signature digest handling. If this fails, the signature digest will be set to
453        * NULL and not used.
454        */
455       // TODO landonf: We should really only calculate the digest once, for both verification and signing.
456       if (jcr->crypto.pki_sign) {
457          signing_digest = crypto_digest_new(jcr, signing_algorithm);
458
459          /* Full-stop if a failure occurred initializing the signature digest */
460          if (signing_digest == NULL) {
461             Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
462                stream_to_ascii(signing_algorithm));
463             jcr->JobErrors++;
464             goto good_rtn;
465          }
466       }
467
468       /* Enable encryption */
469       if (jcr->crypto.pki_encrypt) {
470          ff_pkt->flags |= FO_ENCRYPT;
471       }
472    }
473
474    /* Initialize the file descriptor we use for data and other streams. */
475    binit(&ff_pkt->bfd);
476    if (ff_pkt->flags & FO_PORTABLE) {
477       set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
478    }
479    if (ff_pkt->cmd_plugin) {
480       if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
481          goto bail_out;
482       }
483       send_plugin_name(jcr, sd, true);      /* signal start of plugin data */
484    }
485
486    /* Send attributes -- must be done after binit() */
487    if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
488       goto bail_out;
489    }
490
491    /* Set up the encryption context and send the session data to the SD */
492    if (has_file_data && jcr->crypto.pki_encrypt) {
493       if (!crypto_session_send(jcr, sd)) {
494          goto bail_out;
495       }
496    }
497
498    /*
499     * Open any file with data that we intend to save, then save it.
500     *
501     * Note, if is_win32_backup, we must open the Directory so that
502     * the BackupRead will save its permissions and ownership streams.
503     */
504    if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
505 #ifdef HAVE_WIN32
506       do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
507 #else
508       do_read = ff_pkt->statp.st_size > 0;  
509 #endif
510    } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
511               ff_pkt->type == FT_REPARSE ||
512          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
513       do_read = true;
514    }
515    if (ff_pkt->cmd_plugin) {
516       do_read = true;
517    }
518
519    Dmsg1(400, "do_read=%d\n", do_read);
520    if (do_read) {
521       btimer_t *tid;
522
523       if (ff_pkt->type == FT_FIFO) {
524          tid = start_thread_timer(jcr, pthread_self(), 60);
525       } else {
526          tid = NULL;
527       }
528       int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
529       ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE;
530       if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
531          ff_pkt->ff_errno = errno;
532          berrno be;
533          Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
534               be.bstrerror());
535          jcr->JobErrors++;
536          if (tid) {
537             stop_thread_timer(tid);
538             tid = NULL;
539          }
540          goto good_rtn;
541       }
542       if (tid) {
543          stop_thread_timer(tid);
544          tid = NULL;
545       }
546
547       stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
548
549       if (ff_pkt->flags & FO_CHKCHANGES) {
550          has_file_changed(jcr, ff_pkt);
551       }
552
553       bclose(&ff_pkt->bfd);
554       
555       if (!stat) {
556          goto bail_out;
557       }
558    }
559
560 #ifdef HAVE_DARWIN_OS
561    /* Regular files can have resource forks and Finder Info */
562    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
563             ff_pkt->flags & FO_HFSPLUS)) {
564       if (ff_pkt->hfsinfo.rsrclength > 0) {
565          int flags;
566          int rsrc_stream;
567          if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
568             ff_pkt->ff_errno = errno;
569             berrno be;
570             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for \"%s\": ERR=%s.\n"), 
571                  ff_pkt->fname, be.bstrerror());
572             jcr->JobErrors++;
573             if (is_bopen(&ff_pkt->bfd)) {
574                bclose(&ff_pkt->bfd);
575             }
576             goto good_rtn;
577          }
578          flags = ff_pkt->flags;
579          ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
580          if (flags & FO_ENCRYPT) {
581             rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
582          } else {
583             rsrc_stream = STREAM_MACOS_FORK_DATA;
584          }
585          stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
586          ff_pkt->flags = flags;
587          bclose(&ff_pkt->bfd);
588          if (!stat) {
589             goto bail_out;
590          }
591       }
592
593       Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
594       sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
595       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
596       pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
597       sd->msglen = 32;
598       if (digest) {
599          crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
600       }
601       if (signing_digest) {
602          crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
603       }
604       sd->send();
605       sd->signal(BNET_EOD);
606    }
607 #endif
608
609    /*
610     * Save ACLs when requested and available for anything not being a symlink and not being a plugin.
611     */
612    if (have_acl) {
613       if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
614          switch (build_acl_streams(jcr, ff_pkt))
615          case bsub_exit_fatal:
616             goto bail_out;
617          case bsub_exit_nok:
618             /*
619              * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
620              * print the error message set by the lower level routine in jcr->errmsg.
621              */
622             if (jcr->total_acl_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
623                Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
624             }
625             jcr->total_acl_errors++;
626             break;
627          case bsub_exit_ok:
628             break;
629          }
630       }
631    }
632
633    /*
634     * Save Extended Attributes when requested and available for all files not being a plugin.
635     */
636    if (have_xattr) {
637       if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
638          switch (build_xattr_streams(jcr, ff_pkt)) {
639          case bsub_exit_fatal:
640             goto bail_out;
641          case bsub_exit_nok:
642             /*
643              * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
644              * print the error message set by the lower level routine in jcr->errmsg.
645              */
646             if (jcr->total_xattr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
647                Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
648             }
649             jcr->total_xattr_errors++;
650             break;
651          case bsub_exit_ok:
652             break;
653       }
654    }
655
656    /* Terminate the signing digest and send it to the Storage daemon */
657    if (signing_digest) {
658       uint32_t size = 0;
659
660       if ((sig = crypto_sign_new(jcr)) == NULL) {
661          Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
662          goto bail_out;
663       }
664
665       if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
666          Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
667          goto bail_out;
668       }
669
670       /* Get signature size */
671       if (!crypto_sign_encode(sig, NULL, &size)) {
672          Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
673          goto bail_out;
674       }
675
676       /* Grow the bsock buffer to fit our message if necessary */
677       if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
678          sd->msg = realloc_pool_memory(sd->msg, size);
679       }
680
681       /* Send our header */
682       sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
683       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
684
685       /* Encode signature data */
686       if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
687          Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
688          goto bail_out;
689       }
690
691       sd->msglen = size;
692       sd->send();
693       sd->signal(BNET_EOD);              /* end of checksum */
694    }
695
696    /* Terminate any digest and send it to Storage daemon */
697    if (digest) {
698       uint32_t size;
699
700       sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
701       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
702
703       size = CRYPTO_DIGEST_MAX_SIZE;
704
705       /* Grow the bsock buffer to fit our message if necessary */
706       if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
707          sd->msg = realloc_pool_memory(sd->msg, size);
708       }
709
710       if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
711          Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
712          goto bail_out;
713       }
714
715       sd->msglen = size;
716       sd->send();
717       sd->signal(BNET_EOD);              /* end of checksum */
718    }
719    if (ff_pkt->cmd_plugin) {
720       send_plugin_name(jcr, sd, false); /* signal end of plugin data */
721    }
722
723 good_rtn:
724    rtnstat = 1;                       /* good return */
725
726 bail_out:
727    if (digest) {
728       crypto_digest_free(digest);
729    }
730    if (signing_digest) {
731       crypto_digest_free(signing_digest);
732    }
733    if (sig) {
734       crypto_sign_free(sig);        
735    }
736    return rtnstat;
737 }
738
739 /*
740  * Send data read from an already open file descriptor.
741  *
742  * We return 1 on sucess and 0 on errors.
743  *
744  * ***FIXME***
745  * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
746  *  reading.
747  * Currently this is not a problem as the only other stream, resource forks,
748  * are not handled as sparse files.
749  */
750 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, 
751                      DIGEST *signing_digest)
752 {
753    BSOCK *sd = jcr->store_bsock;
754    uint64_t fileAddr = 0;             /* file address */
755    char *rbuf, *wbuf;
756    int32_t rsize = jcr->buf_size;      /* read buffer size */
757    POOLMEM *msgsave;
758    CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
759    const uint8_t *cipher_input;
760    uint32_t cipher_input_len;
761    uint32_t cipher_block_size;
762    uint32_t encrypted_len;
763 #ifdef FD_NO_SEND_TEST
764    return 1;
765 #endif
766
767    msgsave = sd->msg;
768    rbuf = sd->msg;                    /* read buffer */
769    wbuf = sd->msg;                    /* write buffer */
770    cipher_input = (uint8_t *)rbuf;    /* encrypt uncompressed data */
771
772    Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
773
774 #ifdef HAVE_LIBZ
775    uLong compress_len = 0;
776    uLong max_compress_len = 0;
777    const Bytef *cbuf = NULL;
778    int zstat;
779
780    if (ff_pkt->flags & FO_GZIP) {
781       if (ff_pkt->flags & FO_SPARSE) {
782          cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
783          max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
784       } else {
785          cbuf = (Bytef *)jcr->compress_buf;
786          max_compress_len = jcr->compress_buf_size; /* set max length */
787       }
788       wbuf = jcr->compress_buf;    /* compressed output here */
789       cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
790
791       /* 
792        * Only change zlib parameters if there is no pending operation.
793        * This should never happen as deflatereset is called after each
794        * deflate.
795        */
796
797       if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
798          /* set gzip compression level - must be done per file */
799          if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset, 
800               ff_pkt->GZIP_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
801             Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
802             set_jcr_job_status(jcr, JS_ErrorTerminated);
803             goto err;
804          }
805       }
806    }
807 #else
808    const uint32_t max_compress_len = 0;
809 #endif
810
811    if (ff_pkt->flags & FO_ENCRYPT) {
812       if (ff_pkt->flags & FO_SPARSE) {
813          Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse data not supported.\n"));
814          goto err;
815       }
816       /* Allocate the cipher context */
817       if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true, 
818            &cipher_block_size)) == NULL) {
819          /* Shouldn't happen! */
820          Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
821          goto err;
822       }
823
824       /*
825        * Grow the crypto buffer, if necessary.
826        * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
827        * We grow crypto_buf to the maximum number of blocks that
828        * could be returned for the given read buffer size.
829        * (Using the larger of either rsize or max_compress_len)
830        */
831       jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf, 
832            (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) + 
833             cipher_block_size - 1) / cipher_block_size * cipher_block_size);
834
835       wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
836    }
837
838    /*
839     * Send Data header to Storage daemon
840     *    <file-index> <stream> <info>
841     */
842    if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
843       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
844             sd->bstrerror());
845       goto err;
846    }
847    Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
848
849    /*
850     * Make space at beginning of buffer for fileAddr because this
851     *   same buffer will be used for writing if compression is off.
852     */
853    if (ff_pkt->flags & FO_SPARSE) {
854       rbuf += SPARSE_FADDR_SIZE;
855       rsize -= SPARSE_FADDR_SIZE;
856 #ifdef HAVE_FREEBSD_OS
857       /*
858        * To read FreeBSD partitions, the read size must be
859        *  a multiple of 512.
860        */
861       rsize = (rsize/512) * 512;
862 #endif
863    }
864
865    /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
866 #ifdef HAVE_WIN32
867    if (S_ISBLK(ff_pkt->statp.st_mode))
868       rsize = (rsize/512) * 512;
869 #endif
870    
871    /*
872     * Read the file data
873     */
874    while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
875
876       /* Check for sparse blocks */
877       if (ff_pkt->flags & FO_SPARSE) {
878          ser_declare;
879          bool allZeros = false;
880          if ((sd->msglen == rsize &&
881               fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
882              ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
883                (uint64_t)ff_pkt->statp.st_size == 0)) {
884             allZeros = is_buf_zero(rbuf, rsize);
885          }
886          if (!allZeros) {
887             /* Put file address as first data in buffer */
888             ser_begin(wbuf, SPARSE_FADDR_SIZE);
889             ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
890          }
891          fileAddr += sd->msglen;      /* update file address */
892          /* Skip block of all zeros */
893          if (allZeros) {
894             continue;                 /* skip block of zeros */
895          }
896       }
897
898       jcr->ReadBytes += sd->msglen;         /* count bytes read */
899
900       /* Uncompressed cipher input length */
901       cipher_input_len = sd->msglen;
902
903       /* Update checksum if requested */
904       if (digest) {
905          crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
906       }
907
908       /* Update signing digest if requested */
909       if (signing_digest) {
910          crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
911       }
912
913 #ifdef HAVE_LIBZ
914       /* Do compression if turned on */
915       if (ff_pkt->flags & FO_GZIP && jcr->pZLIB_compress_workset) {
916          Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
917          
918          ((z_stream*)jcr->pZLIB_compress_workset)->next_in   = (Bytef *)rbuf;
919                 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in  = sd->msglen;
920          ((z_stream*)jcr->pZLIB_compress_workset)->next_out  = (Bytef *)cbuf;
921                 ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;
922
923          if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
924             Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
925             set_jcr_job_status(jcr, JS_ErrorTerminated);
926             goto err;
927          }
928          compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
929          /* reset zlib stream to be able to begin from scratch again */
930          if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
931             Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
932             set_jcr_job_status(jcr, JS_ErrorTerminated);
933             goto err;
934          }
935
936          Dmsg2(400, "compressed len=%d uncompressed len=%d\n", compress_len, 
937                sd->msglen);
938
939          sd->msglen = compress_len;      /* set compressed length */
940          cipher_input_len = compress_len;
941       }
942 #endif
943       /* 
944        * Note, here we prepend the current record length to the beginning
945        *  of the encrypted data. This is because both sparse and compression
946        *  restore handling want records returned to them with exactly the
947        *  same number of bytes that were processed in the backup handling.
948        *  That is, both are block filters rather than a stream.  When doing
949        *  compression, the compression routines may buffer data, so that for
950        *  any one record compressed, when it is decompressed the same size
951        *  will not be obtained. Of course, the buffered data eventually comes
952        *  out in subsequent crypto_cipher_update() calls or at least
953        *  when crypto_cipher_finalize() is called.  Unfortunately, this
954        *  "feature" of encryption enormously complicates the restore code.
955        */
956       if (ff_pkt->flags & FO_ENCRYPT) {
957          uint32_t initial_len = 0;
958          ser_declare;
959
960          if (ff_pkt->flags & FO_SPARSE) {
961             cipher_input_len += SPARSE_FADDR_SIZE;
962          }
963
964          /* Encrypt the length of the input block */
965          uint8_t packet_len[sizeof(uint32_t)];
966
967          ser_begin(packet_len, sizeof(uint32_t));
968          ser_uint32(cipher_input_len);    /* store data len in begin of buffer */
969          Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);
970
971          if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
972              (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
973             /* Encryption failed. Shouldn't happen. */
974             Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
975             goto err;
976          }
977
978          /* Encrypt the input block */
979          if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len, 
980              (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
981             if ((initial_len + encrypted_len) == 0) {
982                /* No full block of data available, read more data */
983                continue;
984             }
985             Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len, 
986                   sd->msglen);
987             sd->msglen = initial_len + encrypted_len; /* set encrypted length */
988          } else {
989             /* Encryption failed. Shouldn't happen. */
990             Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
991             goto err;
992          }
993       }
994
995       /* Send the buffer to the Storage daemon */
996       if (ff_pkt->flags & FO_SPARSE) {
997          sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
998       }
999       sd->msg = wbuf;              /* set correct write buffer */
1000       if (!sd->send()) {
1001          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1002                sd->bstrerror());
1003          goto err;
1004       }
1005       Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1006       /*          #endif */
1007       jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed/encrypted */
1008       sd->msg = msgsave;                /* restore read buffer */
1009
1010    } /* end while read file data */
1011
1012    if (sd->msglen < 0) {                 /* error */
1013       berrno be;
1014       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
1015          ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
1016       if (jcr->JobErrors++ > 1000) {       /* insanity check */
1017          Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
1018       }
1019    } else if (ff_pkt->flags & FO_ENCRYPT) {
1020       /* 
1021        * For encryption, we must call finalize to push out any
1022        *  buffered data.
1023        */
1024       if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf, 
1025            &encrypted_len)) {
1026          /* Padding failed. Shouldn't happen. */
1027          Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
1028          goto err;
1029       }
1030
1031       /* Note, on SSL pre-0.9.7, there is always some output */
1032       if (encrypted_len > 0) {
1033          sd->msglen = encrypted_len;      /* set encrypted length */
1034          sd->msg = jcr->crypto.crypto_buf;       /* set correct write buffer */
1035          if (!sd->send()) {
1036             Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1037                   sd->bstrerror());
1038             goto err;
1039          }
1040          Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1041          jcr->JobBytes += sd->msglen;     /* count bytes saved possibly compressed/encrypted */
1042          sd->msg = msgsave;               /* restore bnet buffer */
1043       }
1044    }
1045
1046    if (!sd->signal(BNET_EOD)) {        /* indicate end of file data */
1047       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1048             sd->bstrerror());
1049       goto err;
1050    }
1051
1052    /* Free the cipher context */
1053    if (cipher_ctx) {
1054       crypto_cipher_free(cipher_ctx);
1055    }
1056    return 1;
1057
1058 err:
1059    /* Free the cipher context */
1060    if (cipher_ctx) {
1061       crypto_cipher_free(cipher_ctx);
1062    }
1063
1064    sd->msg = msgsave; /* restore bnet buffer */
1065    sd->msglen = 0;
1066    return 0;
1067 }
1068
1069 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) 
1070 {
1071    BSOCK *sd = jcr->store_bsock;
1072    char attribs[MAXSTRING];
1073    char attribsEx[MAXSTRING];
1074    int attr_stream;
1075    int stat;
1076 #ifdef FD_NO_SEND_TEST
1077    return true;
1078 #endif
1079
1080    Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
1081    /* Find what data stream we will use, then encode the attributes */
1082    if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
1083       /* This should not happen */
1084       Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
1085       return false;
1086    }
1087    encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI, data_stream);
1088
1089    /* Now possibly extend the attributes */
1090    attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
1091
1092    Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
1093
1094    jcr->lock();
1095    jcr->JobFiles++;                    /* increment number of files sent */
1096    ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
1097    pm_strcpy(jcr->last_fname, ff_pkt->fname);
1098    jcr->unlock();
1099
1100    /*
1101     * Send Attributes header to Storage daemon
1102     *    <file-index> <stream> <info>
1103     */
1104    if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
1105       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1106             sd->bstrerror());
1107       return false;
1108    }
1109    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
1110
1111    /*
1112     * Send file attributes to Storage daemon
1113     *   File_index
1114     *   File type
1115     *   Filename (full path)
1116     *   Encoded attributes
1117     *   Link name (if type==FT_LNK or FT_LNKSAVED)
1118     *   Encoded extended-attributes (for Win32)
1119     *
1120     * For a directory, link is the same as fname, but with trailing
1121     * slash. For a linked file, link is the link.
1122     */
1123    if (ff_pkt->type != FT_DELETED) { /* already stripped */
1124       strip_path(ff_pkt);
1125    }
1126    if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
1127       Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
1128       stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
1129                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
1130                attribsEx, 0);
1131    } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) {
1132       /* Here link is the canonical filename (i.e. with trailing slash) */
1133       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
1134                ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
1135    } else {
1136       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
1137                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
1138    }
1139    if (ff_pkt->type != FT_DELETED) {
1140       unstrip_path(ff_pkt);
1141    }
1142
1143    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1144    if (!stat) {
1145       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1146             sd->bstrerror());
1147       return false;
1148    }
1149    sd->signal(BNET_EOD);            /* indicate end of attributes data */
1150    return true;
1151 }
1152
1153 /* 
1154  * Do in place strip of path
1155  */
1156 static bool do_strip(int count, char *in)
1157 {
1158    char *out = in;
1159    int stripped;
1160    int numsep = 0;
1161
1162    /* Copy to first path separator -- Win32 might have c: ... */
1163    while (*in && !IsPathSeparator(*in)) {    
1164       out++; in++;
1165    }
1166    out++; in++;
1167    numsep++;                     /* one separator seen */
1168    for (stripped=0; stripped<count && *in; stripped++) {
1169       while (*in && !IsPathSeparator(*in)) {
1170          in++;                   /* skip chars */
1171       }
1172       if (*in) {
1173          numsep++;               /* count separators seen */
1174          in++;                   /* skip separator */
1175       }
1176    }
1177    /* Copy to end */
1178    while (*in) {                /* copy to end */
1179       if (IsPathSeparator(*in)) {
1180          numsep++;
1181       }
1182       *out++ = *in++;
1183    }
1184    *out = 0;
1185    Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n", 
1186          stripped, count, numsep, numsep>count);
1187    return stripped==count && numsep>count;
1188 }
1189
1190 /*
1191  * If requested strip leading components of the path so that we can
1192  *   save file as if it came from a subdirectory.  This is most useful
1193  *   for dealing with snapshots, by removing the snapshot directory, or
1194  *   in handling vendor migrations where files have been restored with
1195  *   a vendor product into a subdirectory.
1196  */
1197 void strip_path(FF_PKT *ff_pkt)
1198 {
1199    if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1200       Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1201       return;
1202    }
1203    if (!ff_pkt->fname_save) {
1204      ff_pkt->fname_save = get_pool_memory(PM_FNAME); 
1205      ff_pkt->link_save = get_pool_memory(PM_FNAME);
1206    }
1207    pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1208    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1209       pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1210       Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1211          strlen(ff_pkt->link));
1212       sm_check(__FILE__, __LINE__, true);
1213    }
1214
1215    /* 
1216     * Strip path.  If it doesn't succeed put it back.  If
1217     *  it does, and there is a different link string,
1218     *  attempt to strip the link. If it fails, back them
1219     *  both back.
1220     * Do not strip symlinks.
1221     * I.e. if either stripping fails don't strip anything.
1222     */
1223    if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1224       unstrip_path(ff_pkt);
1225       goto rtn;
1226    } 
1227    /* Strip links but not symlinks */
1228    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1229       if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1230          unstrip_path(ff_pkt);
1231       }
1232    }
1233
1234 rtn:
1235    Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname, 
1236        ff_pkt->link);
1237 }
1238
1239 void unstrip_path(FF_PKT *ff_pkt)
1240 {
1241    if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1242       return;
1243    }
1244    strcpy(ff_pkt->fname, ff_pkt->fname_save);
1245    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1246       Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1247           ff_pkt->link_save);
1248       strcpy(ff_pkt->link, ff_pkt->link_save);
1249       Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1250           strlen(ff_pkt->link_save));
1251       sm_check(__FILE__, __LINE__, true);
1252    }
1253 }