]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/backup.c
Merge the Bacula Encryption branch to HEAD.
[bacula/bacula] / bacula / src / filed / backup.c
1 /*
2  *  Bacula File Daemon  backup.c  send file attributes and data
3  *   to the Storage daemon.
4  *
5  *    Kern Sibbald, March MM
6  *
7  *   Version $Id$
8  *
9  */
10 /*
11    Copyright (C) 2000-2005 Kern Sibbald
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License
15    version 2 as amended with additional clauses defined in the
16    file LICENSE in the main source directory.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
21    the file LICENSE for additional details.
22
23  */
24
25 #include "bacula.h"
26 #include "filed.h"
27
28 /* Forward referenced functions */
29 static int save_file(FF_PKT *ff_pkt, void *pkt, bool top_level);
30 static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
31 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
32 static bool read_and_send_acl(JCR *jcr, int acltype, int stream);
33
34 /*
35  * Find all the requested files and send them
36  * to the Storage daemon.
37  *
38  * Note, we normally carry on a one-way
39  * conversation from this point on with the SD, simply blasting
40  * data to him.  To properly know what is going on, we
41  * also run a "heartbeat" monitor which reads the socket and
42  * reacts accordingly (at the moment it has nothing to do
43  * except echo the heartbeat to the Director).
44  *
45  */
46 bool blast_data_to_storage_daemon(JCR *jcr, char *addr)
47 {
48    BSOCK *sd;
49    bool ok = true;
50
51    sd = jcr->store_bsock;
52
53    set_jcr_job_status(jcr, JS_Running);
54
55    Dmsg1(300, "bfiled: opened data connection %d to stored\n", sd->fd);
56
57    LockRes();
58    CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
59    UnlockRes();
60    uint32_t buf_size;
61    if (client) {
62       buf_size = client->max_network_buffer_size;
63    } else {
64       buf_size = 0;                   /* use default */
65    }
66    if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
67       set_jcr_job_status(jcr, JS_ErrorTerminated);
68       Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
69       return false;
70    }
71
72    jcr->buf_size = sd->msglen;
73    /* Adjust for compression so that output buffer is
74     * 12 bytes + 0.1% larger than input buffer plus 18 bytes.
75     * This gives a bit extra plus room for the sparse addr if any.
76     * Note, we adjust the read size to be smaller so that the
77     * same output buffer can be used without growing it.
78     */
79    jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
80    jcr->compress_buf = get_memory(jcr->compress_buf_size);
81
82    Dmsg1(300, "set_find_options ff=%p\n", jcr->ff);
83    set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
84    Dmsg0(300, "start find files\n");
85
86    start_heartbeat_monitor(jcr);
87
88    jcr->acl_text = get_pool_memory(PM_MESSAGE);
89
90    /* Subroutine save_file() is called for each file */
91    if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, (void *)jcr)) {
92       ok = false;                     /* error */
93       set_jcr_job_status(jcr, JS_ErrorTerminated);
94 //    Jmsg(jcr, M_FATAL, 0, _("Find files error.\n"));
95    }
96
97    free_pool_memory(jcr->acl_text);
98
99    stop_heartbeat_monitor(jcr);
100
101    bnet_sig(sd, BNET_EOD);            /* end of sending data */
102
103    if (jcr->big_buf) {
104       free(jcr->big_buf);
105       jcr->big_buf = NULL;
106    }
107    if (jcr->compress_buf) {
108       free_pool_memory(jcr->compress_buf);
109       jcr->compress_buf = NULL;
110    }
111    Dmsg1(100, "end blast_data ok=%d\n", ok);
112    return ok;
113 }
114
115 /*
116  * Called here by find() for each file included.
117  *   This is a callback. The original is find_files() above.
118  *
119  *  Send the file and its data to the Storage daemon.
120  *
121  *  Returns: 1 if OK
122  *           0 if error
123  *          -1 to ignore file/directory (not used here)
124  */
125 static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
126 {
127    int stat, data_stream;
128    DIGEST *digest = NULL;
129    DIGEST *signing_digest = NULL;
130    int digest_stream = STREAM_NONE;
131    // TODO landonf: Allow the user to specify the digest algorithm
132 #ifdef HAVE_SHA2
133    crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA256;
134 #else
135    crypto_digest_t signing_algorithm = CRYPTO_DIGEST_SHA1;
136 #endif
137    BSOCK *sd;
138    JCR *jcr = (JCR *)vjcr;
139
140    if (job_canceled(jcr)) {
141       return 0;
142    }
143
144    sd = jcr->store_bsock;
145    jcr->num_files_examined++;         /* bump total file count */
146
147    switch (ff_pkt->type) {
148    case FT_LNKSAVED:                  /* Hard linked, file already saved */
149       Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
150       break;
151    case FT_REGE:
152       Dmsg1(130, "FT_REGE saving: %s\n", ff_pkt->fname);
153       break;
154    case FT_REG:
155       Dmsg1(130, "FT_REG saving: %s\n", ff_pkt->fname);
156       break;
157    case FT_LNK:
158       Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
159       break;
160    case FT_DIRBEGIN:
161       return 1;                       /* not used */
162    case FT_NORECURSE:
163      Jmsg(jcr, M_INFO, 1, _("     Recursion turned off. Will not descend into %s\n"),
164           ff_pkt->fname);
165       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
166       break;
167    case FT_NOFSCHG:
168       /* Suppress message for /dev filesystems */
169       if (strncmp(ff_pkt->fname, "/dev/", 5) != 0) {
170          Jmsg(jcr, M_INFO, 1, _("     Filesystem change prohibited. Will not descend into %s\n"),
171             ff_pkt->fname);
172       }
173       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
174       break;
175    case FT_INVALIDFS:
176       Jmsg(jcr, M_INFO, 1, _("     Disallowed filesystem. Will not descend into %s\n"),
177            ff_pkt->fname);
178       ff_pkt->type = FT_DIREND;       /* Backup only the directory entry */
179       break;
180    case FT_DIREND:
181       Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
182       break;
183    case FT_SPEC:
184       Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
185       break;
186    case FT_RAW:
187       Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
188       break;
189    case FT_FIFO:
190       Dmsg1(130, "FT_FIFO saving: %s\n", ff_pkt->fname);
191       break;
192    case FT_NOACCESS: {
193       berrno be;
194       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not access %s: ERR=%s\n"), ff_pkt->fname,
195          be.strerror(ff_pkt->ff_errno));
196       jcr->Errors++;
197       return 1;
198    }
199    case FT_NOFOLLOW: {
200       berrno be;
201       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not follow link %s: ERR=%s\n"), ff_pkt->fname,
202          be.strerror(ff_pkt->ff_errno));
203       jcr->Errors++;
204       return 1;
205    }
206    case FT_NOSTAT: {
207       berrno be;
208       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not stat %s: ERR=%s\n"), ff_pkt->fname,
209          be.strerror(ff_pkt->ff_errno));
210       jcr->Errors++;
211       return 1;
212    }
213    case FT_DIRNOCHG:
214    case FT_NOCHG:
215       Jmsg(jcr, M_SKIPPED, 1, _("     Unchanged file skipped: %s\n"), ff_pkt->fname);
216       return 1;
217    case FT_ISARCH:
218       Jmsg(jcr, M_NOTSAVED, 0, _("     Archive file not saved: %s\n"), ff_pkt->fname);
219       return 1;
220    case FT_NOOPEN: {
221       berrno be;
222       Jmsg(jcr, M_NOTSAVED, 0, _("     Could not open directory %s: ERR=%s\n"), ff_pkt->fname,
223          be.strerror(ff_pkt->ff_errno));
224       jcr->Errors++;
225       return 1;
226    }
227    default:
228       Jmsg(jcr, M_NOTSAVED, 0,  _("     Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname);
229       jcr->Errors++;
230       return 1;
231    }
232
233    Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname);
234
235    if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
236       return 0;
237    }
238
239    /*
240     * Setup for digest handling. If this fails, the digest will be set to NULL
241     * and not used.
242     */
243    if (ff_pkt->flags & FO_MD5) {
244       digest = crypto_digest_new(CRYPTO_DIGEST_MD5);
245       digest_stream = STREAM_MD5_DIGEST;
246
247    } else if (ff_pkt->flags & FO_SHA1) {
248       digest = crypto_digest_new(CRYPTO_DIGEST_SHA1);
249       digest_stream = STREAM_SHA1_DIGEST;
250
251    } else if (ff_pkt->flags & FO_SHA256) {
252       digest = crypto_digest_new(CRYPTO_DIGEST_SHA256);
253       digest_stream = STREAM_SHA256_DIGEST;
254
255    } else if (ff_pkt->flags & FO_SHA512) {
256       digest = crypto_digest_new(CRYPTO_DIGEST_SHA512);
257       digest_stream = STREAM_SHA512_DIGEST;
258    }
259
260    /* Did digest initialization fail? */
261    if (digest_stream != STREAM_NONE && digest == NULL) {
262       Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
263          stream_to_ascii(digest_stream));
264    }
265
266    /*
267     * Set up signature digest handling. If this fails, the signature digest will be set to
268     * NULL and not used.
269     */
270    // TODO landonf: We should really only calculate the digest once, for both verification and signing.
271    if (jcr->pki_sign) {
272       signing_digest = crypto_digest_new(signing_algorithm);
273    }
274
275    /* Full-stop if a failure occured initializing the signature digest */
276    if (jcr->pki_sign && signing_digest == NULL) {
277       Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
278          stream_to_ascii(signing_algorithm));
279       jcr->Errors++;
280       return 1;
281    }
282
283    /* Initialise the file descriptor we use for data and other streams. */
284    binit(&ff_pkt->bfd);
285    if (ff_pkt->flags & FO_PORTABLE) {
286       set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
287    }
288    if (ff_pkt->reader) {
289       if (!set_prog(&ff_pkt->bfd, ff_pkt->reader, jcr)) {
290          Jmsg(jcr, M_FATAL, 0, _("Python reader program \"%s\" not found.\n"), 
291             ff_pkt->reader);
292          return 0;
293       }
294    }
295
296    /*
297     * Open any file with data that we intend to save, then save it.
298     *
299     * Note, if is_win32_backup, we must open the Directory so that
300     * the BackupRead will save its permissions and ownership streams.
301     */
302    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
303          ff_pkt->statp.st_size > 0) ||
304          ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
305          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
306       btimer_t *tid;
307       if (ff_pkt->type == FT_FIFO) {
308          tid = start_thread_timer(pthread_self(), 60);
309       } else {
310          tid = NULL;
311       }
312       if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
313          ff_pkt->ff_errno = errno;
314          berrno be;
315          Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname,
316               be.strerror());
317          jcr->Errors++;
318          if (tid) {
319             stop_thread_timer(tid);
320             tid = NULL;
321          }
322          return 1;
323       }
324       if (tid) {
325          stop_thread_timer(tid);
326          tid = NULL;
327       }
328       stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
329       bclose(&ff_pkt->bfd);
330       if (!stat) {
331          return 0;
332       }
333    }
334
335 #ifdef HAVE_DARWIN_OS
336    /* Regular files can have resource forks and Finder Info */
337    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
338             ff_pkt->flags & FO_HFSPLUS)) {
339       if (ff_pkt->hfsinfo.rsrclength > 0) {
340          int flags;
341          if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
342             ff_pkt->ff_errno = errno;
343             berrno be;
344             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname,
345                   be.strerror());
346             jcr->Errors++;
347             if (is_bopen(&ff_pkt->bfd)) {
348                bclose(&ff_pkt->bfd);
349             }
350             return 1;
351          }
352          flags = ff_pkt->flags;
353          ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
354          stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, digest);
355          ff_pkt->flags = flags;
356          bclose(&ff_pkt->bfd);
357          if (!stat) {
358             return 0;
359          }
360       }
361
362       Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
363       bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
364       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
365       memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
366       sd->msglen = 32;
367       if (digest) {
368          crypto_digest_update(digest, sd->msg, sd->msglen);
369       }
370       if (signature_digest) {
371          crypto_digest_update(signature_digest, sd->msg, sd->msglen);
372       }
373       bnet_send(sd);
374       bnet_sig(sd, BNET_EOD);
375    }
376 #endif
377
378    if (ff_pkt->flags & FO_ACL) {
379       /* Read access ACLs for files, dirs and links */
380       if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) {
381          return 0;
382       }
383       /* Directories can have default ACLs too */
384       if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
385          if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) {
386             return 0;
387          }
388       }
389    }
390
391    /* Terminate the signing digest and send it to the Storage daemon */
392    if (signing_digest) {
393       SIGNATURE *sig;
394       size_t size = 0;
395       void *buf;
396
397       if ((sig = crypto_sign_new()) == NULL) {
398          Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for stream signature.\n"));
399          return 0;
400       }
401
402       if (crypto_sign_add_signer(sig, signing_digest, jcr->pki_keypair) == false) {
403          Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
404          return 0;
405       }
406
407       /* Get signature size */
408       if (crypto_sign_encode(sig, NULL, &size) == false) {
409          Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
410          return 0;
411       }
412
413       /* Allocate signature data buffer */
414       buf = malloc(size);
415       if (!buf) {
416          free(buf);
417          return 0;
418       }
419
420       /* Encode signature data */
421       if (crypto_sign_encode(sig, buf, &size) == false) {
422          Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
423          return 0;
424       }
425
426       /* Send our header */
427       bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
428       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
429
430       /* Grow the bsock buffer to fit our message if necessary */
431       if ((size_t) sizeof_pool_memory(sd->msg) < size) {
432          sd->msg = realloc_pool_memory(sd->msg, size);
433       }
434
435       /* Copy our message over and send it */
436       memcpy(sd->msg, buf, size);
437       sd->msglen = size;
438       bnet_send(sd);
439       bnet_sig(sd, BNET_EOD);              /* end of checksum */
440
441       crypto_digest_free(signing_digest);
442       crypto_sign_free(sig);        
443       free(buf);
444    }
445
446    /* Terminate any digest and send it to Storage daemon and the Director */
447    if (digest) {
448       char md[CRYPTO_DIGEST_MAX_SIZE];
449       size_t size;
450
451       size = sizeof(md);
452
453       if (crypto_digest_finalize(digest, &md, &size) == true) {
454          bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, digest_stream);
455          Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
456          memcpy(sd->msg, md, size);
457          sd->msglen = size;
458          bnet_send(sd);
459          bnet_sig(sd, BNET_EOD);              /* end of checksum */
460       }
461
462       crypto_digest_free(digest);
463    }
464
465    return 1;
466 }
467
468 /*
469  * Send data read from an already open file descriptor.
470  *
471  * We return 1 on sucess and 0 on errors.
472  *
473  * ***FIXME***
474  * We use ff_pkt->statp.st_size when FO_SPARSE.
475  * Currently this is not a problem as the only other stream, resource forks,
476  * are not handled as sparse files.
477  */
478 int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signing_digest)
479 {
480    BSOCK *sd = jcr->store_bsock;
481    uint64_t fileAddr = 0;             /* file address */
482    char *rbuf, *wbuf;
483    int rsize = jcr->buf_size;      /* read buffer size */
484    POOLMEM *msgsave;
485 #ifdef FD_NO_SEND_TEST
486    return 1;
487 #endif
488
489    msgsave = sd->msg;
490    rbuf = sd->msg;                    /* read buffer */
491    wbuf = sd->msg;                    /* write buffer */
492
493
494    Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
495
496
497 #ifdef HAVE_LIBZ
498    uLong compress_len, max_compress_len = 0;
499    const Bytef *cbuf = NULL;
500
501    if (ff_pkt->flags & FO_GZIP) {
502       if (ff_pkt->flags & FO_SPARSE) {
503          cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
504          max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
505       } else {
506          cbuf = (Bytef *)jcr->compress_buf;
507          max_compress_len = jcr->compress_buf_size; /* set max length */
508       }
509       wbuf = jcr->compress_buf;    /* compressed output here */
510    }
511 #endif
512
513    /*
514     * Send Data header to Storage daemon
515     *    <file-index> <stream> <info>
516     */
517    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
518       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
519             bnet_strerror(sd));
520       return 0;
521    }
522    Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
523
524    /*
525     * Make space at beginning of buffer for fileAddr because this
526     *   same buffer will be used for writing if compression if off.
527     */
528    if (ff_pkt->flags & FO_SPARSE) {
529       rbuf += SPARSE_FADDR_SIZE;
530       rsize -= SPARSE_FADDR_SIZE;
531 #ifdef HAVE_FREEBSD_OS
532       /*
533        * To read FreeBSD partitions, the read size must be
534        *  a multiple of 512.
535        */
536       rsize = (rsize/512) * 512;
537 #endif
538    }
539
540    /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
541 #ifdef HAVE_WIN32
542    if (S_ISBLK(ff_pkt->statp.st_mode))
543       rsize = (rsize/512) * 512;      
544 #endif
545
546    /*
547     * Read the file data
548     */
549    while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
550       int sparseBlock = 0;
551
552       /* Check for sparse blocks */
553       if (ff_pkt->flags & FO_SPARSE) {
554          ser_declare;
555          if (sd->msglen == rsize &&
556              (fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size)) {
557             sparseBlock = is_buf_zero(rbuf, rsize);
558          }
559
560          ser_begin(wbuf, SPARSE_FADDR_SIZE);
561          ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
562       }
563
564       jcr->ReadBytes += sd->msglen;         /* count bytes read */
565       fileAddr += sd->msglen;
566
567       /* Update checksum if requested */
568       if (digest) {
569          crypto_digest_update(digest, rbuf, sd->msglen);
570       }
571
572       /* Update signing digest if requested */
573       if (signing_digest) {
574          crypto_digest_update(signing_digest, rbuf, sd->msglen);
575       }
576
577 #ifdef HAVE_LIBZ
578       /* Do compression if turned on */
579       if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
580          int zstat;
581          compress_len = max_compress_len;
582          Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
583             rbuf, sd->msglen);
584          /* NOTE! This call modifies compress_len !!! */
585          if ((zstat=compress2((Bytef *)cbuf, &compress_len,
586                (const Bytef *)rbuf, (uLong)sd->msglen,
587                ff_pkt->GZIP_level)) != Z_OK) {
588             Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
589             sd->msg = msgsave;
590             sd->msglen = 0;
591             set_jcr_job_status(jcr, JS_ErrorTerminated);
592             return 0;
593          }
594          Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
595             compress_len, sd->msglen);
596
597          sd->msglen = compress_len;      /* set compressed length */
598       }
599 #endif
600
601       /* Send the buffer to the Storage daemon */
602       if (!sparseBlock) {
603          if (ff_pkt->flags & FO_SPARSE) {
604             sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
605          }
606          sd->msg = wbuf;              /* set correct write buffer */
607          if (!bnet_send(sd)) {
608             Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
609                   bnet_strerror(sd));
610             sd->msg = msgsave;     /* restore bnet buffer */
611             sd->msglen = 0;
612             return 0;
613          }
614       }
615       Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
616       /*          #endif */
617       jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed */
618       sd->msg = msgsave;                /* restore read buffer */
619
620    } /* end while read file data */
621
622
623    if (sd->msglen < 0) {
624       berrno be;
625       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
626          ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
627       if (jcr->Errors++ > 1000) {       /* insanity check */
628          Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
629       }
630
631    }
632
633    if (!bnet_sig(sd, BNET_EOD)) {        /* indicate end of file data */
634       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
635             bnet_strerror(sd));
636       return 0;
637    }
638
639    return 1;
640 }
641
642 /*
643  * Read and send an ACL for the last encountered file.
644  */
645 static bool read_and_send_acl(JCR *jcr, int acltype, int stream)
646 {
647 #ifdef HAVE_ACL
648    BSOCK *sd = jcr->store_bsock;
649    POOLMEM *msgsave;
650    int len;
651 #ifdef FD_NO_SEND_TEST
652    return true;
653 #endif
654
655    len = bacl_get(jcr, acltype);
656    if (len < 0) {
657       Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
658       return true; 
659    }
660    if (len == 0) {
661       return true;                    /* no ACL */
662    }
663
664    /* Send header */
665    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
666       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
667             bnet_strerror(sd));
668       return false;
669    }
670
671    /* Send the buffer to the storage deamon */
672    Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
673    msgsave = sd->msg;
674    sd->msg = jcr->acl_text;
675    sd->msglen = len + 1;
676    if (!bnet_send(sd)) {
677       sd->msg = msgsave;
678       sd->msglen = 0;
679       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
680             bnet_strerror(sd));
681       return false;
682    }
683
684    jcr->JobBytes += sd->msglen;
685    sd->msg = msgsave;
686    if (!bnet_sig(sd, BNET_EOD)) {
687       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
688             bnet_strerror(sd));
689       return false;
690    }
691
692    Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
693 #endif
694    return true;
695 }
696
697 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) 
698 {
699    BSOCK *sd = jcr->store_bsock;
700    char attribs[MAXSTRING];
701    char attribsEx[MAXSTRING];
702    int attr_stream;
703    int stat;
704 #ifdef FD_NO_SEND_TEST
705    return true;
706 #endif
707
708    /* Find what data stream we will use, then encode the attributes */
709    data_stream = select_data_stream(ff_pkt);
710    encode_stat(attribs, ff_pkt, data_stream);
711
712    /* Now possibly extend the attributes */
713    attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
714
715    Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
716
717    P(jcr->mutex);
718    jcr->JobFiles++;                    /* increment number of files sent */
719    ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
720    pm_strcpy(jcr->last_fname, ff_pkt->fname);
721    V(jcr->mutex);
722
723    /*
724     * Send Attributes header to Storage daemon
725     *    <file-index> <stream> <info>
726     */
727    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
728       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
729             bnet_strerror(sd));
730       return false;
731    }
732    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
733
734    /*
735     * Send file attributes to Storage daemon
736     *   File_index
737     *   File type
738     *   Filename (full path)
739     *   Encoded attributes
740     *   Link name (if type==FT_LNK or FT_LNKSAVED)
741     *   Encoded extended-attributes (for Win32)
742     *
743     * For a directory, link is the same as fname, but with trailing
744     * slash. For a linked file, link is the link.
745     */
746    if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
747       Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
748       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
749                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
750                attribsEx, 0);
751    } else if (ff_pkt->type == FT_DIREND) {
752       /* Here link is the canonical filename (i.e. with trailing slash) */
753       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
754                ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
755    } else {
756       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
757                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
758    }
759
760    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
761    if (!stat) {
762       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
763             bnet_strerror(sd));
764       return false;
765    }
766    bnet_sig(sd, BNET_EOD);            /* indicate end of attributes data */
767    return true;
768 }