]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/backup.c
More Win32 compiler tweaks
[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)) {
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              ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
558                (uint64_t)ff_pkt->statp.st_size == 0)) {
559             sparseBlock = is_buf_zero(rbuf, rsize);
560          }
561
562          ser_begin(wbuf, SPARSE_FADDR_SIZE);
563          ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
564       }
565
566       jcr->ReadBytes += sd->msglen;         /* count bytes read */
567       fileAddr += sd->msglen;
568
569       /* Update checksum if requested */
570       if (digest) {
571          crypto_digest_update(digest, rbuf, sd->msglen);
572       }
573
574       /* Update signing digest if requested */
575       if (signing_digest) {
576          crypto_digest_update(signing_digest, rbuf, sd->msglen);
577       }
578
579 #ifdef HAVE_LIBZ
580       /* Do compression if turned on */
581       if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
582          int zstat;
583          compress_len = max_compress_len;
584          Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
585             rbuf, sd->msglen);
586          /* NOTE! This call modifies compress_len !!! */
587          if ((zstat=compress2((Bytef *)cbuf, &compress_len,
588                (const Bytef *)rbuf, (uLong)sd->msglen,
589                ff_pkt->GZIP_level)) != Z_OK) {
590             Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
591             sd->msg = msgsave;
592             sd->msglen = 0;
593             set_jcr_job_status(jcr, JS_ErrorTerminated);
594             return 0;
595          }
596          Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
597             compress_len, sd->msglen);
598
599          sd->msglen = compress_len;      /* set compressed length */
600       }
601 #endif
602
603       /* Send the buffer to the Storage daemon */
604       if (!sparseBlock) {
605          if (ff_pkt->flags & FO_SPARSE) {
606             sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
607          }
608          sd->msg = wbuf;              /* set correct write buffer */
609          if (!bnet_send(sd)) {
610             Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
611                   bnet_strerror(sd));
612             sd->msg = msgsave;     /* restore bnet buffer */
613             sd->msglen = 0;
614             return 0;
615          }
616       }
617       Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
618       /*          #endif */
619       jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed */
620       sd->msg = msgsave;                /* restore read buffer */
621
622    } /* end while read file data */
623
624
625    if (sd->msglen < 0) {
626       berrno be;
627       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
628          ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
629       if (jcr->Errors++ > 1000) {       /* insanity check */
630          Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
631       }
632
633    }
634
635    if (!bnet_sig(sd, BNET_EOD)) {        /* indicate end of file data */
636       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
637             bnet_strerror(sd));
638       return 0;
639    }
640
641    return 1;
642 }
643
644 /*
645  * Read and send an ACL for the last encountered file.
646  */
647 static bool read_and_send_acl(JCR *jcr, int acltype, int stream)
648 {
649 #ifdef HAVE_ACL
650    BSOCK *sd = jcr->store_bsock;
651    POOLMEM *msgsave;
652    int len;
653 #ifdef FD_NO_SEND_TEST
654    return true;
655 #endif
656
657    len = bacl_get(jcr, acltype);
658    if (len < 0) {
659       Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
660       return true; 
661    }
662    if (len == 0) {
663       return true;                    /* no ACL */
664    }
665
666    /* Send header */
667    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
668       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
669             bnet_strerror(sd));
670       return false;
671    }
672
673    /* Send the buffer to the storage deamon */
674    Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
675    msgsave = sd->msg;
676    sd->msg = jcr->acl_text;
677    sd->msglen = len + 1;
678    if (!bnet_send(sd)) {
679       sd->msg = msgsave;
680       sd->msglen = 0;
681       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
682             bnet_strerror(sd));
683       return false;
684    }
685
686    jcr->JobBytes += sd->msglen;
687    sd->msg = msgsave;
688    if (!bnet_sig(sd, BNET_EOD)) {
689       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
690             bnet_strerror(sd));
691       return false;
692    }
693
694    Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
695 #endif
696    return true;
697 }
698
699 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) 
700 {
701    BSOCK *sd = jcr->store_bsock;
702    char attribs[MAXSTRING];
703    char attribsEx[MAXSTRING];
704    int attr_stream;
705    int stat;
706 #ifdef FD_NO_SEND_TEST
707    return true;
708 #endif
709
710    /* Find what data stream we will use, then encode the attributes */
711    data_stream = select_data_stream(ff_pkt);
712    encode_stat(attribs, ff_pkt, data_stream);
713
714    /* Now possibly extend the attributes */
715    attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
716
717    Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
718
719    P(jcr->mutex);
720    jcr->JobFiles++;                    /* increment number of files sent */
721    ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
722    pm_strcpy(jcr->last_fname, ff_pkt->fname);
723    V(jcr->mutex);
724
725    /*
726     * Send Attributes header to Storage daemon
727     *    <file-index> <stream> <info>
728     */
729    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
730       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
731             bnet_strerror(sd));
732       return false;
733    }
734    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
735
736    /*
737     * Send file attributes to Storage daemon
738     *   File_index
739     *   File type
740     *   Filename (full path)
741     *   Encoded attributes
742     *   Link name (if type==FT_LNK or FT_LNKSAVED)
743     *   Encoded extended-attributes (for Win32)
744     *
745     * For a directory, link is the same as fname, but with trailing
746     * slash. For a linked file, link is the link.
747     */
748    if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
749       Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
750       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
751                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
752                attribsEx, 0);
753    } else if (ff_pkt->type == FT_DIREND) {
754       /* Here link is the canonical filename (i.e. with trailing slash) */
755       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
756                ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
757    } else {
758       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
759                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
760    }
761
762    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
763    if (!stat) {
764       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
765             bnet_strerror(sd));
766       return false;
767    }
768    bnet_sig(sd, BNET_EOD);            /* indicate end of attributes data */
769    return true;
770 }