]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/filed/backup.c
- Merge changes made to 1.38.3 into 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    /*
236     * Setup for digest handling. If this fails, the digest will be set to NULL
237     * and not used.
238     */
239    if (ff_pkt->flags & FO_MD5) {
240       digest = crypto_digest_new(CRYPTO_DIGEST_MD5);
241       digest_stream = STREAM_MD5_DIGEST;
242
243    } else if (ff_pkt->flags & FO_SHA1) {
244       digest = crypto_digest_new(CRYPTO_DIGEST_SHA1);
245       digest_stream = STREAM_SHA1_DIGEST;
246
247    } else if (ff_pkt->flags & FO_SHA256) {
248       digest = crypto_digest_new(CRYPTO_DIGEST_SHA256);
249       digest_stream = STREAM_SHA256_DIGEST;
250
251    } else if (ff_pkt->flags & FO_SHA512) {
252       digest = crypto_digest_new(CRYPTO_DIGEST_SHA512);
253       digest_stream = STREAM_SHA512_DIGEST;
254    }
255
256    /* Did digest initialization fail? */
257    if (digest_stream != STREAM_NONE && digest == NULL) {
258       Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"),
259          stream_to_ascii(digest_stream));
260    }
261
262    /*
263     * Set up signature digest handling. If this fails, the signature digest will be set to
264     * NULL and not used.
265     */
266    // TODO landonf: We should really only calculate the digest once, for both verification and signing.
267    if (jcr->pki_sign) {
268       signing_digest = crypto_digest_new(signing_algorithm);
269    }
270
271    /* Full-stop if a failure occured initializing the signature digest */
272    if (jcr->pki_sign && signing_digest == NULL) {
273       Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
274          stream_to_ascii(signing_algorithm));
275       jcr->Errors++;
276       return 1;
277    }
278
279    /* Initialise the file descriptor we use for data and other streams. */
280    binit(&ff_pkt->bfd);
281    if (ff_pkt->flags & FO_PORTABLE) {
282       set_portable_backup(&ff_pkt->bfd); /* disable Win32 BackupRead() */
283    }
284    if (ff_pkt->reader) {
285       if (!set_prog(&ff_pkt->bfd, ff_pkt->reader, jcr)) {
286          Jmsg(jcr, M_FATAL, 0, _("Python reader program \"%s\" not found.\n"), 
287             ff_pkt->reader);
288          return 0;
289       }
290    }
291
292    /* Send attributes -- must be done after binit() */
293    if (!encode_and_send_attributes(jcr, ff_pkt, data_stream)) {
294       return 0;
295    }
296
297    /*
298     * Open any file with data that we intend to save, then save it.
299     *
300     * Note, if is_win32_backup, we must open the Directory so that
301     * the BackupRead will save its permissions and ownership streams.
302     */
303    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
304          ff_pkt->statp.st_size > 0) ||
305          ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
306          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
307       btimer_t *tid;
308       if (ff_pkt->type == FT_FIFO) {
309          tid = start_thread_timer(pthread_self(), 60);
310       } else {
311          tid = NULL;
312       }
313       if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
314          ff_pkt->ff_errno = errno;
315          berrno be;
316          Jmsg(jcr, M_NOTSAVED, 0, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname,
317               be.strerror());
318          jcr->Errors++;
319          if (tid) {
320             stop_thread_timer(tid);
321             tid = NULL;
322          }
323          return 1;
324       }
325       if (tid) {
326          stop_thread_timer(tid);
327          tid = NULL;
328       }
329       stat = send_data(jcr, data_stream, ff_pkt, digest, signing_digest);
330       bclose(&ff_pkt->bfd);
331       if (!stat) {
332          return 0;
333       }
334    }
335
336 #ifdef HAVE_DARWIN_OS
337    /* Regular files can have resource forks and Finder Info */
338    if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
339             ff_pkt->flags & FO_HFSPLUS)) {
340       if (ff_pkt->hfsinfo.rsrclength > 0) {
341          int flags;
342          if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
343             ff_pkt->ff_errno = errno;
344             berrno be;
345             Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname,
346                   be.strerror());
347             jcr->Errors++;
348             if (is_bopen(&ff_pkt->bfd)) {
349                bclose(&ff_pkt->bfd);
350             }
351             return 1;
352          }
353          flags = ff_pkt->flags;
354          ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
355          stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, digest);
356          ff_pkt->flags = flags;
357          bclose(&ff_pkt->bfd);
358          if (!stat) {
359             return 0;
360          }
361       }
362
363       Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
364       bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
365       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
366       memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
367       sd->msglen = 32;
368       if (digest) {
369          crypto_digest_update(digest, sd->msg, sd->msglen);
370       }
371       if (signature_digest) {
372          crypto_digest_update(signature_digest, sd->msg, sd->msglen);
373       }
374       bnet_send(sd);
375       bnet_sig(sd, BNET_EOD);
376    }
377 #endif
378
379    if (ff_pkt->flags & FO_ACL) {
380       /* Read access ACLs for files, dirs and links */
381       if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) {
382          return 0;
383       }
384       /* Directories can have default ACLs too */
385       if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
386          if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) {
387             return 0;
388          }
389       }
390    }
391
392    /* Terminate the signing digest and send it to the Storage daemon */
393    if (signing_digest) {
394       SIGNATURE *sig;
395       size_t size = 0;
396       void *buf;
397
398       if ((sig = crypto_sign_new()) == NULL) {
399          Jmsg(jcr, M_FATAL, 0, _("Failed to allocate memory for stream signature.\n"));
400          return 0;
401       }
402
403       if (crypto_sign_add_signer(sig, signing_digest, jcr->pki_keypair) == false) {
404          Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
405          return 0;
406       }
407
408       /* Get signature size */
409       if (crypto_sign_encode(sig, NULL, &size) == false) {
410          Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
411          return 0;
412       }
413
414       /* Allocate signature data buffer */
415       buf = malloc(size);
416       if (!buf) {
417          free(buf);
418          return 0;
419       }
420
421       /* Encode signature data */
422       if (crypto_sign_encode(sig, buf, &size) == false) {
423          Jmsg(jcr, M_FATAL, 0, _("An error occured while signing the stream.\n"));
424          return 0;
425       }
426
427       /* Send our header */
428       bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
429       Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
430
431       /* Grow the bsock buffer to fit our message if necessary */
432       if ((size_t) sizeof_pool_memory(sd->msg) < size) {
433          sd->msg = realloc_pool_memory(sd->msg, size);
434       }
435
436       /* Copy our message over and send it */
437       memcpy(sd->msg, buf, size);
438       sd->msglen = size;
439       bnet_send(sd);
440       bnet_sig(sd, BNET_EOD);              /* end of checksum */
441
442       crypto_digest_free(signing_digest);
443       crypto_sign_free(sig);        
444       free(buf);
445    }
446
447    /* Terminate any digest and send it to Storage daemon and the Director */
448    if (digest) {
449       char md[CRYPTO_DIGEST_MAX_SIZE];
450       size_t size;
451
452       size = sizeof(md);
453
454       if (crypto_digest_finalize(digest, &md, &size)) {
455          bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, digest_stream);
456          Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
457          memcpy(sd->msg, md, size);
458          sd->msglen = size;
459          bnet_send(sd);
460          bnet_sig(sd, BNET_EOD);              /* end of checksum */
461       }
462
463       crypto_digest_free(digest);
464    }
465
466    return 1;
467 }
468
469 /*
470  * Send data read from an already open file descriptor.
471  *
472  * We return 1 on sucess and 0 on errors.
473  *
474  * ***FIXME***
475  * We use ff_pkt->statp.st_size when FO_SPARSE.
476  * Currently this is not a problem as the only other stream, resource forks,
477  * are not handled as sparse files.
478  */
479 int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signing_digest)
480 {
481    BSOCK *sd = jcr->store_bsock;
482    uint64_t fileAddr = 0;             /* file address */
483    char *rbuf, *wbuf;
484    int rsize = jcr->buf_size;      /* read buffer size */
485    POOLMEM *msgsave;
486 #ifdef FD_NO_SEND_TEST
487    return 1;
488 #endif
489
490    msgsave = sd->msg;
491    rbuf = sd->msg;                    /* read buffer */
492    wbuf = sd->msg;                    /* write buffer */
493
494
495    Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
496
497
498 #ifdef HAVE_LIBZ
499    uLong compress_len, max_compress_len = 0;
500    const Bytef *cbuf = NULL;
501
502    if (ff_pkt->flags & FO_GZIP) {
503       if (ff_pkt->flags & FO_SPARSE) {
504          cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
505          max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
506       } else {
507          cbuf = (Bytef *)jcr->compress_buf;
508          max_compress_len = jcr->compress_buf_size; /* set max length */
509       }
510       wbuf = jcr->compress_buf;    /* compressed output here */
511    }
512 #endif
513
514    /*
515     * Send Data header to Storage daemon
516     *    <file-index> <stream> <info>
517     */
518    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
519       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
520             bnet_strerror(sd));
521       return 0;
522    }
523    Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
524
525    /*
526     * Make space at beginning of buffer for fileAddr because this
527     *   same buffer will be used for writing if compression if off.
528     */
529    if (ff_pkt->flags & FO_SPARSE) {
530       rbuf += SPARSE_FADDR_SIZE;
531       rsize -= SPARSE_FADDR_SIZE;
532 #ifdef HAVE_FREEBSD_OS
533       /*
534        * To read FreeBSD partitions, the read size must be
535        *  a multiple of 512.
536        */
537       rsize = (rsize/512) * 512;
538 #endif
539    }
540
541    /* a RAW device read on win32 only works if the buffer is a multiple of 512 */
542 #ifdef HAVE_WIN32
543    if (S_ISBLK(ff_pkt->statp.st_mode))
544       rsize = (rsize/512) * 512;      
545 #endif
546
547    /*
548     * Read the file data
549     */
550    while ((sd->msglen=(uint32_t)bread(&ff_pkt->bfd, rbuf, rsize)) > 0) {
551       int sparseBlock = 0;
552
553       /* Check for sparse blocks */
554       if (ff_pkt->flags & FO_SPARSE) {
555          ser_declare;
556          if (sd->msglen == rsize &&
557              fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size ||
558              ((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
559                (uint64_t)ff_pkt->statp.st_size == 0)) {
560             sparseBlock = is_buf_zero(rbuf, rsize);
561          }
562
563          ser_begin(wbuf, SPARSE_FADDR_SIZE);
564          ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
565       }
566
567       jcr->ReadBytes += sd->msglen;         /* count bytes read */
568       fileAddr += sd->msglen;
569
570       /* Update checksum if requested */
571       if (digest) {
572          crypto_digest_update(digest, rbuf, sd->msglen);
573       }
574
575       /* Update signing digest if requested */
576       if (signing_digest) {
577          crypto_digest_update(signing_digest, rbuf, sd->msglen);
578       }
579
580 #ifdef HAVE_LIBZ
581       /* Do compression if turned on */
582       if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
583          int zstat;
584          compress_len = max_compress_len;
585          Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
586             rbuf, sd->msglen);
587          /* NOTE! This call modifies compress_len !!! */
588          if ((zstat=compress2((Bytef *)cbuf, &compress_len,
589                (const Bytef *)rbuf, (uLong)sd->msglen,
590                ff_pkt->GZIP_level)) != Z_OK) {
591             Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
592             sd->msg = msgsave;
593             sd->msglen = 0;
594             set_jcr_job_status(jcr, JS_ErrorTerminated);
595             return 0;
596          }
597          Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
598             compress_len, sd->msglen);
599
600          sd->msglen = compress_len;      /* set compressed length */
601       }
602 #endif
603
604       /* Send the buffer to the Storage daemon */
605       if (!sparseBlock) {
606          if (ff_pkt->flags & FO_SPARSE) {
607             sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
608          }
609          sd->msg = wbuf;              /* set correct write buffer */
610          if (!bnet_send(sd)) {
611             Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
612                   bnet_strerror(sd));
613             sd->msg = msgsave;     /* restore bnet buffer */
614             sd->msglen = 0;
615             return 0;
616          }
617       }
618       Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
619       /*          #endif */
620       jcr->JobBytes += sd->msglen;      /* count bytes saved possibly compressed */
621       sd->msg = msgsave;                /* restore read buffer */
622
623    } /* end while read file data */
624
625
626    if (sd->msglen < 0) {
627       berrno be;
628       Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
629          ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
630       if (jcr->Errors++ > 1000) {       /* insanity check */
631          Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
632       }
633
634    }
635
636    if (!bnet_sig(sd, BNET_EOD)) {        /* indicate end of file data */
637       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
638             bnet_strerror(sd));
639       return 0;
640    }
641
642    return 1;
643 }
644
645 /*
646  * Read and send an ACL for the last encountered file.
647  */
648 static bool read_and_send_acl(JCR *jcr, int acltype, int stream)
649 {
650 #ifdef HAVE_ACL
651    BSOCK *sd = jcr->store_bsock;
652    POOLMEM *msgsave;
653    int len;
654 #ifdef FD_NO_SEND_TEST
655    return true;
656 #endif
657
658    len = bacl_get(jcr, acltype);
659    if (len < 0) {
660       Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
661       return true; 
662    }
663    if (len == 0) {
664       return true;                    /* no ACL */
665    }
666
667    /* Send header */
668    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
669       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
670             bnet_strerror(sd));
671       return false;
672    }
673
674    /* Send the buffer to the storage deamon */
675    Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
676    msgsave = sd->msg;
677    sd->msg = jcr->acl_text;
678    sd->msglen = len + 1;
679    if (!bnet_send(sd)) {
680       sd->msg = msgsave;
681       sd->msglen = 0;
682       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
683             bnet_strerror(sd));
684       return false;
685    }
686
687    jcr->JobBytes += sd->msglen;
688    sd->msg = msgsave;
689    if (!bnet_sig(sd, BNET_EOD)) {
690       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
691             bnet_strerror(sd));
692       return false;
693    }
694
695    Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
696 #endif
697    return true;
698 }
699
700 static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream) 
701 {
702    BSOCK *sd = jcr->store_bsock;
703    char attribs[MAXSTRING];
704    char attribsEx[MAXSTRING];
705    int attr_stream;
706    int stat;
707 #ifdef FD_NO_SEND_TEST
708    return true;
709 #endif
710
711    /* Find what data stream we will use, then encode the attributes */
712    data_stream = select_data_stream(ff_pkt);
713    encode_stat(attribs, ff_pkt, data_stream);
714
715    /* Now possibly extend the attributes */
716    attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
717
718    Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
719
720    P(jcr->mutex);
721    jcr->JobFiles++;                    /* increment number of files sent */
722    ff_pkt->FileIndex = jcr->JobFiles;  /* return FileIndex */
723    pm_strcpy(jcr->last_fname, ff_pkt->fname);
724    V(jcr->mutex);
725
726    /*
727     * Send Attributes header to Storage daemon
728     *    <file-index> <stream> <info>
729     */
730    if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
731       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
732             bnet_strerror(sd));
733       return false;
734    }
735    Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
736
737    /*
738     * Send file attributes to Storage daemon
739     *   File_index
740     *   File type
741     *   Filename (full path)
742     *   Encoded attributes
743     *   Link name (if type==FT_LNK or FT_LNKSAVED)
744     *   Encoded extended-attributes (for Win32)
745     *
746     * For a directory, link is the same as fname, but with trailing
747     * slash. For a linked file, link is the link.
748     */
749    if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
750       Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
751       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
752                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
753                attribsEx, 0);
754    } else if (ff_pkt->type == FT_DIREND) {
755       /* Here link is the canonical filename (i.e. with trailing slash) */
756       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
757                ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
758    } else {
759       stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
760                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
761    }
762
763    Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
764    if (!stat) {
765       Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
766             bnet_strerror(sd));
767       return false;
768    }
769    bnet_sig(sd, BNET_EOD);            /* indicate end of attributes data */
770    return true;
771 }