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