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