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