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