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