]> 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
458        * will be set to NULL and not used.
459        */
460       /* TODO landonf: We should really only calculate the digest once, for
461        * both verification and signing.
462        */
463       if (jcr->crypto.pki_sign) {
464          signing_digest = crypto_digest_new(jcr, signing_algorithm);
465
466          /* Full-stop if a failure occurred initializing the signature digest */
467          if (signing_digest == NULL) {
468             Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
469                stream_to_ascii(signing_algorithm));
470             jcr->JobErrors++;
471             goto good_rtn;
472          }
473       }
474
475       /* Enable encryption */
476       if (jcr->crypto.pki_encrypt) {
477          ff_pkt->flags |= FO_ENCRYPT;
478       }
479    }
480
481    /* Initialize the file descriptor we use for data and other streams. */
482    binit(&ff_pkt->bfd);
483    if (ff_pkt->flags & FO_PORTABLE) {
484       set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
485    }
486    if (ff_pkt->cmd_plugin) {
487       if (!set_cmd_plugin(&ff_pkt->bfd, jcr)) {
488          goto bail_out;
489       }
490       send_plugin_name(jcr, sd, true);      /* signal start of plugin data */
491    }
492
493    /* Send attributes -- must be done after binit() */
494    if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
495       goto bail_out;
496    }
497
498    /* Set up the encryption context and send the session data to the SD */
499    if (has_file_data && jcr->crypto.pki_encrypt) {
500       if (!crypto_session_send(jcr, sd)) {
501          goto bail_out;
502       }
503    }
504
505    /*
506     * Open any file with data that we intend to save, then save it.
507     *
508     * Note, if is_win32_backup, we must open the Directory so that
509     * the BackupRead will save its permissions and ownership streams.
510     */
511    if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
512 #ifdef HAVE_WIN32
513       do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
514 #else
515       do_read = ff_pkt->statp.st_size > 0;  
516 #endif
517    } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
518               ff_pkt->type == FT_REPARSE ||
519          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
520       do_read = true;
521    }
522    if (ff_pkt->cmd_plugin) {
523       do_read = true;
524    }
525
526    Dmsg1(400, "do_read=%d\n", do_read);
527    if (do_read) {
528       btimer_t *tid;
529
530       if (ff_pkt->type == FT_FIFO) {
531          tid = start_thread_timer(jcr, pthread_self(), 60);
532       } else {
533          tid = NULL;
534       }
535       int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
536       ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE;
537       if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
538          ff_pkt->ff_errno = errno;
539          berrno be;
540          Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
541               be.bstrerror());
542          jcr->JobErrors++;
543          if (tid) {
544             stop_thread_timer(tid);
545             tid = NULL;
546          }
547          goto good_rtn;
548       }
549       if (tid) {
550          stop_thread_timer(tid);
551          tid = NULL;
552       }
553
554       stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
555
556       if (ff_pkt->flags & FO_CHKCHANGES) {
557          has_file_changed(jcr, ff_pkt);
558       }
559
560       bclose(&ff_pkt->bfd);
561       
562       if (!stat) {
563          goto bail_out;
564       }
565    }
566
567 #ifdef HAVE_DARWIN_OS
568    /* Regular files can have resource forks and Finder Info */
569    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
570             ff_pkt->flags & FO_HFSPLUS)) {
571       if (ff_pkt->hfsinfo.rsrclength > 0) {
572          int flags;
573          int rsrc_stream;
574          if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
575             ff_pkt->ff_errno = errno;
576             berrno be;
577             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for \"%s\": ERR=%s.\n"), 
578                  ff_pkt->fname, be.bstrerror());
579             jcr->JobErrors++;
580             if (is_bopen(&ff_pkt->bfd)) {
581                bclose(&ff_pkt->bfd);
582             }
583             goto good_rtn;
584          }
585          flags = ff_pkt->flags;
586          ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
587          if (flags & FO_ENCRYPT) {
588             rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
589          } else {
590             rsrc_stream = STREAM_MACOS_FORK_DATA;
591          }
592          stat = send_data(jcr, rsrc_stream, ff_pkt, digest, signing_digest);
593          ff_pkt->flags = flags;
594          bclose(&ff_pkt->bfd);
595          if (!stat) {
596             goto bail_out;
597          }
598       }
599
600       Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
601       sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
602       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
603       pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
604       sd->msglen = 32;
605       if (digest) {
606          crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
607       }
608       if (signing_digest) {
609          crypto_digest_update(signing_digest, (uint8_t *)sd->msg, sd->msglen);
610       }
611       sd->send();
612       sd->signal(BNET_EOD);
613    }
614 #endif
615
616    /*
617     * Save ACLs when requested and available for anything not being a symlink and not being a plugin.
618     */
619    if (have_acl) {
620       if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK && !ff_pkt->cmd_plugin) {
621          switch (build_acl_streams(jcr, ff_pkt)) {
622          case bacl_exit_fatal:
623             goto bail_out;
624          case bacl_exit_error:
625             /*
626              * Non-fatal errors, count them and when the number is under ACL_REPORT_ERR_MAX_PER_JOB
627              * print the error message set by the lower level routine in jcr->errmsg.
628              */
629             if (jcr->acl_data->nr_errors < ACL_REPORT_ERR_MAX_PER_JOB) {
630                Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
631             }
632             jcr->acl_data->nr_errors++;
633             break;
634          case bacl_exit_ok:
635             break;
636          }
637       }
638    }
639
640    /*
641     * Save Extended Attributes when requested and available for all files not being a plugin.
642     */
643    if (have_xattr) {
644       if (ff_pkt->flags & FO_XATTR && !ff_pkt->cmd_plugin) {
645          switch (build_xattr_streams(jcr, ff_pkt)) {
646          case bxattr_exit_fatal:
647             goto bail_out;
648          case bxattr_exit_error:
649             /*
650              * Non-fatal errors, count them and when the number is under XATTR_REPORT_ERR_MAX_PER_JOB
651              * print the error message set by the lower level routine in jcr->errmsg.
652              */
653             if (jcr->xattr_data->nr_errors < XATTR_REPORT_ERR_MAX_PER_JOB) {
654                Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
655             }
656             jcr->xattr_data->nr_errors++;
657             break;
658          case bxattr_exit_ok:
659             break;
660          }
661       }
662    }
663
664    /* Terminate the signing digest and send it to the Storage daemon */
665    if (signing_digest) {
666       uint32_t size = 0;
667
668       if ((sig = crypto_sign_new(jcr)) == NULL) {
669          Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for crypto signature.\n"));
670          goto bail_out;
671       }
672
673       if (!crypto_sign_add_signer(sig, signing_digest, jcr->crypto.pki_keypair)) {
674          Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
675          goto bail_out;
676       }
677
678       /* Get signature size */
679       if (!crypto_sign_encode(sig, NULL, &size)) {
680          Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
681          goto bail_out;
682       }
683
684       /* Grow the bsock buffer to fit our message if necessary */
685       if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
686          sd->msg = realloc_pool_memory(sd->msg, size);
687       }
688
689       /* Send our header */
690       sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
691       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
692
693       /* Encode signature data */
694       if (!crypto_sign_encode(sig, (uint8_t *)sd->msg, &size)) {
695          Jmsg(jcr, M_FATAL, 0, _("An error occurred while signing the stream.\n"));
696          goto bail_out;
697       }
698
699       sd->msglen = size;
700       sd->send();
701       sd->signal(BNET_EOD);              /* end of checksum */
702    }
703
704    /* Terminate any digest and send it to Storage daemon */
705    if (digest) {
706       uint32_t size;
707
708       sd->fsend("%ld %d 0", jcr->JobFiles, digest_stream);
709       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
710
711       size = CRYPTO_DIGEST_MAX_SIZE;
712
713       /* Grow the bsock buffer to fit our message if necessary */
714       if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
715          sd->msg = realloc_pool_memory(sd->msg, size);
716       }
717
718       if (!crypto_digest_finalize(digest, (uint8_t *)sd->msg, &size)) {
719          Jmsg(jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
720          goto bail_out;
721       }
722
723       sd->msglen = size;
724       sd->send();
725       sd->signal(BNET_EOD);              /* end of checksum */
726    }
727    if (ff_pkt->cmd_plugin) {
728       send_plugin_name(jcr, sd, false); /* signal end of plugin data */
729    }
730
731 good_rtn:
732    rtnstat = 1;                       /* good return */
733
734 bail_out:
735    if (digest) {
736       crypto_digest_free(digest);
737    }
738    if (signing_digest) {
739       crypto_digest_free(signing_digest);
740    }
741    if (sig) {
742       crypto_sign_free(sig);        
743    }
744    return rtnstat;
745 }
746
747 /*
748  * Send data read from an already open file descriptor.
749  *
750  * We return 1 on sucess and 0 on errors.
751  *
752  * ***FIXME***
753  * We use ff_pkt->statp.st_size when FO_SPARSE to know when to stop
754  *  reading.
755  * Currently this is not a problem as the only other stream, resource forks,
756  * are not handled as sparse files.
757  */
758 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, 
759                      DIGEST *signing_digest)
760 {
761    BSOCK *sd = jcr->store_bsock;
762    uint64_t fileAddr = 0;             /* file address */
763    char *rbuf, *wbuf;
764    int32_t rsize = jcr->buf_size;      /* read buffer size */
765    POOLMEM *msgsave;
766    CIPHER_CONTEXT *cipher_ctx = NULL; /* Quell bogus uninitialized warnings */
767    const uint8_t *cipher_input;
768    uint32_t cipher_input_len;
769    uint32_t cipher_block_size;
770    uint32_t encrypted_len;
771 #ifdef FD_NO_SEND_TEST
772    return 1;
773 #endif
774
775    msgsave = sd->msg;
776    rbuf = sd->msg;                    /* read buffer */
777    wbuf = sd->msg;                    /* write buffer */
778    cipher_input = (uint8_t *)rbuf;    /* encrypt uncompressed data */
779
780    Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
781
782 #ifdef HAVE_LIBZ
783    uLong compress_len = 0;
784    uLong max_compress_len = 0;
785    const Bytef *cbuf = NULL;
786    int zstat;
787
788    if (ff_pkt->flags & FO_GZIP) {
789       if (ff_pkt->flags & FO_SPARSE) {
790          cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
791          max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
792       } else {
793          cbuf = (Bytef *)jcr->compress_buf;
794          max_compress_len = jcr->compress_buf_size; /* set max length */
795       }
796       wbuf = jcr->compress_buf;    /* compressed output here */
797       cipher_input = (uint8_t *)jcr->compress_buf; /* encrypt compressed data */
798
799       /* 
800        * Only change zlib parameters if there is no pending operation.
801        * This should never happen as deflatereset is called after each
802        * deflate.
803        */
804
805       if (((z_stream*)jcr->pZLIB_compress_workset)->total_in == 0) {
806          /* set gzip compression level - must be done per file */
807          if ((zstat=deflateParams((z_stream*)jcr->pZLIB_compress_workset, 
808               ff_pkt->GZIP_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
809             Jmsg(jcr, M_FATAL, 0, _("Compression deflateParams error: %d\n"), zstat);
810             set_jcr_job_status(jcr, JS_ErrorTerminated);
811             goto err;
812          }
813       }
814    }
815 #else
816    const uint32_t max_compress_len = 0;
817 #endif
818
819    if (ff_pkt->flags & FO_ENCRYPT) {
820       if (ff_pkt->flags & FO_SPARSE) {
821          Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse data not supported.\n"));
822          goto err;
823       }
824       /* Allocate the cipher context */
825       if ((cipher_ctx = crypto_cipher_new(jcr->crypto.pki_session, true, 
826            &cipher_block_size)) == NULL) {
827          /* Shouldn't happen! */
828          Jmsg0(jcr, M_FATAL, 0, _("Failed to initialize encryption context.\n"));
829          goto err;
830       }
831
832       /*
833        * Grow the crypto buffer, if necessary.
834        * crypto_cipher_update() will buffer up to (cipher_block_size - 1).
835        * We grow crypto_buf to the maximum number of blocks that
836        * could be returned for the given read buffer size.
837        * (Using the larger of either rsize or max_compress_len)
838        */
839       jcr->crypto.crypto_buf = check_pool_memory_size(jcr->crypto.crypto_buf, 
840            (MAX(rsize + (int)sizeof(uint32_t), (int32_t)max_compress_len) + 
841             cipher_block_size - 1) / cipher_block_size * cipher_block_size);
842
843       wbuf = jcr->crypto.crypto_buf; /* Encrypted, possibly compressed output here. */
844    }
845
846    /*
847     * Send Data header to Storage daemon
848     *    <file-index> <stream> <info>
849     */
850    if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
851       if (!job_canceled(jcr)) {
852          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
853                sd->bstrerror());
854       }
855       goto err;
856    }
857    Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
858
859    /*
860     * Make space at beginning of buffer for fileAddr because this
861     *   same buffer will be used for writing if compression is off.
862     */
863    if (ff_pkt->flags & FO_SPARSE) {
864       rbuf += SPARSE_FADDR_SIZE;
865       rsize -= SPARSE_FADDR_SIZE;
866 #ifdef HAVE_FREEBSD_OS
867       /*
868        * To read FreeBSD partitions, the read size must be
869        *  a multiple of 512.
870        */
871       rsize = (rsize/512) * 512;
872 #endif
873    }
874
875    /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
876 #ifdef HAVE_WIN32
877    if (S_ISBLK(ff_pkt->statp.st_mode))
878       rsize = (rsize/512) * 512;
879 #endif
880    
881    /*
882     * Read the file data
883     */
884    while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
885
886       /* Check for sparse blocks */
887       if (ff_pkt->flags & FO_SPARSE) {
888          ser_declare;
889          bool allZeros = false;
890          if ((sd->msglen == rsize &&
891               fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
892              ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
893                (uint64_t)ff_pkt->statp.st_size == 0)) {
894             allZeros = is_buf_zero(rbuf, rsize);
895          }
896          if (!allZeros) {
897             /* Put file address as first data in buffer */
898             ser_begin(wbuf, SPARSE_FADDR_SIZE);
899             ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
900          }
901          fileAddr += sd->msglen;      /* update file address */
902          /* Skip block of all zeros */
903          if (allZeros) {
904             continue;                 /* skip block of zeros */
905          }
906       }
907
908       jcr->ReadBytes += sd->msglen;         /* count bytes read */
909
910       /* Uncompressed cipher input length */
911       cipher_input_len = sd->msglen;
912
913       /* Update checksum if requested */
914       if (digest) {
915          crypto_digest_update(digest, (uint8_t *)rbuf, sd->msglen);
916       }
917
918       /* Update signing digest if requested */
919       if (signing_digest) {
920          crypto_digest_update(signing_digest, (uint8_t *)rbuf, sd->msglen);
921       }
922
923 #ifdef HAVE_LIBZ
924       /* Do compression if turned on */
925       if (ff_pkt->flags & FO_GZIP && jcr->pZLIB_compress_workset) {
926          Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
927          
928          ((z_stream*)jcr->pZLIB_compress_workset)->next_in   = (Bytef *)rbuf;
929                 ((z_stream*)jcr->pZLIB_compress_workset)->avail_in  = sd->msglen;
930          ((z_stream*)jcr->pZLIB_compress_workset)->next_out  = (Bytef *)cbuf;
931                 ((z_stream*)jcr->pZLIB_compress_workset)->avail_out = max_compress_len;
932
933          if ((zstat=deflate((z_stream*)jcr->pZLIB_compress_workset, Z_FINISH)) != Z_STREAM_END) {
934             Jmsg(jcr, M_FATAL, 0, _("Compression deflate error: %d\n"), zstat);
935             set_jcr_job_status(jcr, JS_ErrorTerminated);
936             goto err;
937          }
938          compress_len = ((z_stream*)jcr->pZLIB_compress_workset)->total_out;
939          /* reset zlib stream to be able to begin from scratch again */
940          if ((zstat=deflateReset((z_stream*)jcr->pZLIB_compress_workset)) != Z_OK) {
941             Jmsg(jcr, M_FATAL, 0, _("Compression deflateReset error: %d\n"), zstat);
942             set_jcr_job_status(jcr, JS_ErrorTerminated);
943             goto err;
944          }
945
946          Dmsg2(400, "compressed len=%d uncompressed len=%d\n", compress_len, 
947                sd->msglen);
948
949          sd->msglen = compress_len;      /* set compressed length */
950          cipher_input_len = compress_len;
951       }
952 #endif
953       /* 
954        * Note, here we prepend the current record length to the beginning
955        *  of the encrypted data. This is because both sparse and compression
956        *  restore handling want records returned to them with exactly the
957        *  same number of bytes that were processed in the backup handling.
958        *  That is, both are block filters rather than a stream.  When doing
959        *  compression, the compression routines may buffer data, so that for
960        *  any one record compressed, when it is decompressed the same size
961        *  will not be obtained. Of course, the buffered data eventually comes
962        *  out in subsequent crypto_cipher_update() calls or at least
963        *  when crypto_cipher_finalize() is called.  Unfortunately, this
964        *  "feature" of encryption enormously complicates the restore code.
965        */
966       if (ff_pkt->flags & FO_ENCRYPT) {
967          uint32_t initial_len = 0;
968          ser_declare;
969
970          if (ff_pkt->flags & FO_SPARSE) {
971             cipher_input_len += SPARSE_FADDR_SIZE;
972          }
973
974          /* Encrypt the length of the input block */
975          uint8_t packet_len[sizeof(uint32_t)];
976
977          ser_begin(packet_len, sizeof(uint32_t));
978          ser_uint32(cipher_input_len);    /* store data len in begin of buffer */
979          Dmsg1(20, "Encrypt len=%d\n", cipher_input_len);
980
981          if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
982              (uint8_t *)jcr->crypto.crypto_buf, &initial_len)) {
983             /* Encryption failed. Shouldn't happen. */
984             Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
985             goto err;
986          }
987
988          /* Encrypt the input block */
989          if (crypto_cipher_update(cipher_ctx, cipher_input, cipher_input_len, 
990              (uint8_t *)&jcr->crypto.crypto_buf[initial_len], &encrypted_len)) {
991             if ((initial_len + encrypted_len) == 0) {
992                /* No full block of data available, read more data */
993                continue;
994             }
995             Dmsg2(400, "encrypted len=%d unencrypted len=%d\n", encrypted_len, 
996                   sd->msglen);
997             sd->msglen = initial_len + encrypted_len; /* set encrypted length */
998          } else {
999             /* Encryption failed. Shouldn't happen. */
1000             Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
1001             goto err;
1002          }
1003       }
1004
1005       /* Send the buffer to the Storage daemon */
1006       if (ff_pkt->flags & FO_SPARSE) {
1007          sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
1008       }
1009       sd->msg = wbuf;              /* set correct write buffer */
1010       if (!sd->send()) {
1011          if (!job_canceled(jcr)) {
1012             Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1013                   sd->bstrerror());
1014          }
1015          goto err;
1016       }
1017       Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1018       /*          #endif */
1019       jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed/encrypted */
1020       sd->msg = msgsave;                /* restore read buffer */
1021
1022    } /* end while read file data */
1023
1024    if (sd->msglen < 0) {                 /* error */
1025       berrno be;
1026       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
1027          ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
1028       if (jcr->JobErrors++ > 1000) {       /* insanity check */
1029          Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
1030       }
1031    } else if (ff_pkt->flags & FO_ENCRYPT) {
1032       /* 
1033        * For encryption, we must call finalize to push out any
1034        *  buffered data.
1035        */
1036       if (!crypto_cipher_finalize(cipher_ctx, (uint8_t *)jcr->crypto.crypto_buf, 
1037            &encrypted_len)) {
1038          /* Padding failed. Shouldn't happen. */
1039          Jmsg(jcr, M_FATAL, 0, _("Encryption padding error\n"));
1040          goto err;
1041       }
1042
1043       /* Note, on SSL pre-0.9.7, there is always some output */
1044       if (encrypted_len > 0) {
1045          sd->msglen = encrypted_len;      /* set encrypted length */
1046          sd->msg = jcr->crypto.crypto_buf;       /* set correct write buffer */
1047          if (!sd->send()) {
1048             if (!job_canceled(jcr)) {
1049                Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1050                      sd->bstrerror());
1051             }
1052             goto err;
1053          }
1054          Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
1055          jcr->JobBytes += sd->msglen;     /* count bytes saved possibly compressed/encrypted */
1056          sd->msg = msgsave;               /* restore bnet buffer */
1057       }
1058    }
1059
1060    if (!sd->signal(BNET_EOD)) {        /* indicate end of file data */
1061       if (!job_canceled(jcr)) {
1062          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1063                sd->bstrerror());
1064       }
1065       goto err;
1066    }
1067
1068    /* Free the cipher context */
1069    if (cipher_ctx) {
1070       crypto_cipher_free(cipher_ctx);
1071    }
1072    return 1;
1073
1074 err:
1075    /* Free the cipher context */
1076    if (cipher_ctx) {
1077       crypto_cipher_free(cipher_ctx);
1078    }
1079
1080    sd->msg = msgsave; /* restore bnet buffer */
1081    sd->msglen = 0;
1082    return 0;
1083 }
1084
1085 bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) 
1086 {
1087    BSOCK *sd = jcr->store_bsock;
1088    char attribs[MAXSTRING];
1089    char attribsEx[MAXSTRING];
1090    int attr_stream;
1091    int stat;
1092 #ifdef FD_NO_SEND_TEST
1093    return true;
1094 #endif
1095
1096    Dmsg1(300, "encode_and_send_attrs fname=%s\n", ff_pkt->fname);
1097    /* Find what data stream we will use, then encode the attributes */
1098    if ((data_stream = select_data_stream(ff_pkt)) == STREAM_NONE) {
1099       /* This should not happen */
1100       Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
1101       return false;
1102    }
1103    encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI, data_stream);
1104
1105    /* Now possibly extend the attributes */
1106    attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
1107
1108    Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
1109
1110    jcr->lock();
1111    jcr->JobFiles++;                    /* increment number of files sent */
1112    ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
1113    pm_strcpy(jcr->last_fname, ff_pkt->fname);
1114    jcr->unlock();
1115
1116    /*
1117     * Send Attributes header to Storage daemon
1118     *    <file-index> <stream> <info>
1119     */
1120    if (!sd->fsend("%ld %d 0", jcr->JobFiles, attr_stream)) {
1121       if (!job_canceled(jcr)) {
1122          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1123                sd->bstrerror());
1124       }
1125       return false;
1126    }
1127    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
1128
1129    /*
1130     * Send file attributes to Storage daemon
1131     *   File_index
1132     *   File type
1133     *   Filename (full path)
1134     *   Encoded attributes
1135     *   Link name (if type==FT_LNK or FT_LNKSAVED)
1136     *   Encoded extended-attributes (for Win32)
1137     *
1138     * For a directory, link is the same as fname, but with trailing
1139     * slash. For a linked file, link is the link.
1140     */
1141    if (ff_pkt->type != FT_DELETED) { /* already stripped */
1142       strip_path(ff_pkt);
1143    }
1144    if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
1145       Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
1146       stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
1147                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
1148                attribsEx, 0);
1149    } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) {
1150       /* Here link is the canonical filename (i.e. with trailing slash) */
1151       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
1152                ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
1153    } else {
1154       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
1155                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
1156    }
1157    if (ff_pkt->type != FT_DELETED) {
1158       unstrip_path(ff_pkt);
1159    }
1160
1161    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
1162    if (!stat) {
1163       if (!job_canceled(jcr)) {
1164          Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
1165                sd->bstrerror());
1166       }
1167       return false;
1168    }
1169    sd->signal(BNET_EOD);            /* indicate end of attributes data */
1170    return true;
1171 }
1172
1173 /* 
1174  * Do in place strip of path
1175  */
1176 static bool do_strip(int count, char *in)
1177 {
1178    char *out = in;
1179    int stripped;
1180    int numsep = 0;
1181
1182    /* Copy to first path separator -- Win32 might have c: ... */
1183    while (*in && !IsPathSeparator(*in)) {    
1184       out++; in++;
1185    }
1186    out++; in++;
1187    numsep++;                     /* one separator seen */
1188    for (stripped=0; stripped<count && *in; stripped++) {
1189       while (*in && !IsPathSeparator(*in)) {
1190          in++;                   /* skip chars */
1191       }
1192       if (*in) {
1193          numsep++;               /* count separators seen */
1194          in++;                   /* skip separator */
1195       }
1196    }
1197    /* Copy to end */
1198    while (*in) {                /* copy to end */
1199       if (IsPathSeparator(*in)) {
1200          numsep++;
1201       }
1202       *out++ = *in++;
1203    }
1204    *out = 0;
1205    Dmsg4(500, "stripped=%d count=%d numsep=%d sep>count=%d\n", 
1206          stripped, count, numsep, numsep>count);
1207    return stripped==count && numsep>count;
1208 }
1209
1210 /*
1211  * If requested strip leading components of the path so that we can
1212  *   save file as if it came from a subdirectory.  This is most useful
1213  *   for dealing with snapshots, by removing the snapshot directory, or
1214  *   in handling vendor migrations where files have been restored with
1215  *   a vendor product into a subdirectory.
1216  */
1217 void strip_path(FF_PKT *ff_pkt)
1218 {
1219    if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1220       Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
1221       return;
1222    }
1223    if (!ff_pkt->fname_save) {
1224      ff_pkt->fname_save = get_pool_memory(PM_FNAME); 
1225      ff_pkt->link_save = get_pool_memory(PM_FNAME);
1226    }
1227    pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
1228    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1229       pm_strcpy(ff_pkt->link_save, ff_pkt->link);
1230       Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
1231          strlen(ff_pkt->link));
1232       sm_check(__FILE__, __LINE__, true);
1233    }
1234
1235    /* 
1236     * Strip path.  If it doesn't succeed put it back.  If
1237     *  it does, and there is a different link string,
1238     *  attempt to strip the link. If it fails, back them
1239     *  both back.
1240     * Do not strip symlinks.
1241     * I.e. if either stripping fails don't strip anything.
1242     */
1243    if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
1244       unstrip_path(ff_pkt);
1245       goto rtn;
1246    } 
1247    /* Strip links but not symlinks */
1248    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1249       if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
1250          unstrip_path(ff_pkt);
1251       }
1252    }
1253
1254 rtn:
1255    Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname, 
1256        ff_pkt->link);
1257 }
1258
1259 void unstrip_path(FF_PKT *ff_pkt)
1260 {
1261    if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
1262       return;
1263    }
1264    strcpy(ff_pkt->fname, ff_pkt->fname_save);
1265    if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
1266       Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
1267           ff_pkt->link_save);
1268       strcpy(ff_pkt->link, ff_pkt->link_save);
1269       Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
1270           strlen(ff_pkt->link_save));
1271       sm_check(__FILE__, __LINE__, true);
1272    }
1273 }