1 Index: src/dird/fd_cmds.c
2 ===================================================================
3 --- src/dird/fd_cmds.c (révision 6443)
4 +++ src/dird/fd_cmds.c (copie de travail)
6 static char filesetcmd[] = "fileset%s\n"; /* set full fileset */
7 static char jobcmd[] = "JobId=%s Job=%s SDid=%u SDtime=%u Authorization=%s\n";
8 /* Note, mtime_only is not used here -- implemented as file option */
9 -static char levelcmd[] = "level = %s%s mtime_only=%d\n";
10 +static char levelcmd[] = "level = %s%s%s mtime_only=%d\n";
11 static char runscript[] = "Run OnSuccess=%u OnFailure=%u AbortOnError=%u When=%u Command=%s\n";
12 static char runbeforenow[]= "RunBeforeNow\n";
17 stime = str_to_utime(jcr->stime);
18 - fd->fsend(levelcmd, NT_("since_utime "), edit_uint64(stime, ed1), 0);
19 + fd->fsend(levelcmd, "", NT_("since_utime "), edit_uint64(stime, ed1), 0);
20 while (bget_dirmsg(fd) >= 0) { /* allow him to poll us to sync clocks */
21 Jmsg(jcr, M_INFO, 0, "%s\n", fd->msg);
24 bool send_level_command(JCR *jcr)
26 BSOCK *fd = jcr->file_bsock;
27 + const char *accurate=jcr->job->accurate?"accurate_":"";
29 * Send Level command to File daemon
31 switch (jcr->JobLevel) {
33 - fd->fsend(levelcmd, "base", " ", 0);
34 + fd->fsend(levelcmd, "", "base", " ", 0);
36 /* L_NONE is the console, sending something off to the FD */
39 - fd->fsend(levelcmd, "full", " ", 0);
40 + fd->fsend(levelcmd, "", "full", " ", 0);
43 - fd->fsend(levelcmd, "differential", " ", 0);
44 + fd->fsend(levelcmd, accurate, "differential", " ", 0);
48 - fd->fsend(levelcmd, "incremental", " ", 0);
49 + fd->fsend(levelcmd, accurate, "incremental", " ", 0);
53 Index: src/dird/backup.c
54 ===================================================================
55 --- src/dird/backup.c (révision 6443)
56 +++ src/dird/backup.c (copie de travail)
61 +#include "findlib/find.h"
63 /* Commands sent to File daemon */
64 static char backupcmd[] = "backup\n";
69 +static int accurate_list_handler(void *ctx, int num_fields, char **row)
71 + JCR *jcr = (JCR *)ctx;
73 + if (job_canceled(jcr)) {
77 + if (row[0] > 0) { /* discard when file_index == 0 */
78 + jcr->file_bsock->fsend("%s%s%c%s", row[1], row[2], 0, row[3]);
84 + * Differential : get the last full id
85 + * Incremental : get the last full + last diff + last incr(s) ids
87 + * TODO: look and merge from ua_restore.c
89 +bool db_accurate_get_jobids(JCR *jcr, POOLMEM *jobids)
91 + pm_strcpy(jobids, "42");
95 +bool send_accurate_current_files(JCR *jcr)
97 + char buf[MAXSTRING];
98 + char ed1[50], ed2[50];
100 + if (jcr->accurate == false || job_canceled(jcr) || jcr->JobLevel == L_FULL) {
104 + POOLMEM *jobids = get_pool_memory(PM_FNAME);
105 + db_accurate_get_jobids(jcr, jobids);
107 + bsnprintf(buf, sizeof(buf),
108 + "CREATE TEMPORARY TABLE btemp2%s AS ( "
109 + "SELECT max(FileId) as FileId, PathId, FilenameId "
110 + "FROM (SELECT FileId, PathId, FilenameId FROM File WHERE JobId IN (%s)) AS F "
111 + "GROUP BY PathId, FilenameId ) ",
112 + edit_uint64(jcr->JobId, ed1),
114 + db_sql_query(jcr->db, buf, NULL, NULL);
116 + bsnprintf(buf, sizeof(buf), "SELECT count(1) FROM btemp2%s",ed1);
117 + db_sql_query(jcr->db, buf, NULL, NULL); // TODO: compter le nombre de rows
119 + jcr->file_bsock->fsend("accurate files=%s\n", edit_uint64(337969*2, ed2));
121 + bsnprintf(buf, sizeof(buf),
122 + "SELECT File.FileIndex, Path.Path, Filename.Name, File.LStat "
123 + "FROM btemp2%s JOIN Path USING (PathId) JOIN Filename USING (FilenameId) "
124 + "JOIN File USING (FileId) "
125 + "WHERE File.FileIndex > 0",
127 + db_sql_query(jcr->db, buf, accurate_list_handler, (void *)jcr);
129 + bsnprintf(buf, sizeof(buf), "DROP TABLE btemp2%s", ed1);
130 + free_pool_memory(jobids);
133 + CREATE TEMPORARY TABLE btemp2 AS (
134 + SELECT max(FileId) as FileId, PathId, FilenameId
135 + FROM (SELECT FileId, PathId, FilenameId FROM File WHERE JobId IN (39867,40341)) AS F
136 + GROUP BY PathId, FilenameId )
138 + SELECT File.FileIndex, Path.Path, Filename.Name, File.LStat
139 + FROM btemp2 JOIN Path USING (PathId) JOIN Filename USING (FilenameId)
140 + JOIN File USING (FileId)
141 + WHERE File.FileIndex > 0
146 +SELECT DISTINCT ON (PathId, FilenameId) FileIndex, Path, Name, LStat
147 + FROM File JOIN Filename USING (FilenameId) JOIN Path USING (PathId) WHERE JobId IN (40341)
148 + ORDER BY PathId, FilenameId, JobId DESC
151 + jcr->file_bsock->signal(BNET_EOD);
156 * Do a backup of the specified FileSet
158 * Returns: false on failure
160 Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
164 + * If backup is in accurate mode, FD will send the list of
167 + if (!send_accurate_current_files(jcr)) {
171 /* Send backup command */
172 fd->fsend(backupcmd);
173 if (!response(jcr, fd, OKbackup, "backup", DISPLAY_ERROR)) {
175 /* Pickup Job termination data */
176 stat = wait_for_job_termination(jcr);
177 db_write_batch_file_records(jcr); /* used by bulk batch file insert */
179 if (stat == JS_Terminated) {
180 backup_cleanup(jcr, stat);
182 Index: src/dird/inc_conf.c
183 ===================================================================
184 --- src/dird/inc_conf.c (révision 6443)
185 +++ src/dird/inc_conf.c (copie de travail)
187 * Items that are valid in an Options resource
189 static RES_ITEM options_items[] = {
190 + {"accurate", store_opts, {0}, 0, 0, 0},
191 {"compression", store_opts, {0}, 0, 0, 0},
192 {"signature", store_opts, {0}, 0, 0, 0},
193 {"verify", store_opts, {0}, 0, 0, 0},
205 * options given above.
207 static struct s_kw FS_option_kw[] = {
208 + {"accurate", INC_KW_ACCURATE},
209 {"compression", INC_KW_COMPRESSION},
210 {"signature", INC_KW_DIGEST},
211 {"encryption", INC_KW_ENCRYPTION},
213 {"no", INC_KW_ENHANCEDWILD, "0"},
214 {"yes", INC_KW_CHKCHANGES, "c"},
215 {"no", INC_KW_CHKCHANGES, "0"},
216 + {"yes", INC_KW_ACCURATE, "C"},
217 + {"no", INC_KW_ACCURATE, "0"},
221 Index: src/filed/backup.c
222 ===================================================================
223 --- src/filed/backup.c (révision 6443)
224 +++ src/filed/backup.c (copie de travail)
226 static bool crypto_session_start(JCR *jcr);
227 static void crypto_session_end(JCR *jcr);
228 static bool crypto_session_send(JCR *jcr, BSOCK *sd);
229 +static bool encode_and_send_deleted_file(JCR *jcr, char *fname);
231 +#include "lib/htable.c"
232 +typedef struct CurFile {
239 + * This function is called for each file seen in fileset.
241 + * If the file is skipped (saved=false), we will check if this
242 + * file have been backuped before. If not, we decide to backup it.
244 + * If the file have saved=true, we mark it as seen
247 +/* TODO: tweak verify code to use the same function */
248 +bool accurate_check_file(JCR *jcr, FF_PKT *ff_pkt, bool saved)
252 + struct stat statc; /* catalog stat */
253 + char *Opts_Digest = ff_pkt->VerifyOpts;
254 + char *fname = ff_pkt->fname;
259 + if (jcr->accurate == false || jcr->JobLevel == L_FULL) {
263 + if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_DIRNOCHG) {
264 + fname = ff_pkt->link;
267 + elt = (CurFile *) jcr->file_list->lookup(fname);
270 + // TODO: we must backup it !
271 + Dmsg1(1, "accurate %s = yes (not found)\n", fname);
275 + if (saved || *elt->lstat == '\0') {
276 + Dmsg1(1, "accurate %s = no (already seen)\n", fname);
277 + *elt->lstat = '\0';
281 + decode_stat(elt->lstat, &statc, &LinkFIc); /* decode catalog stat */
282 +// *do_Digest = CRYPTO_DIGEST_NONE;
284 + for (p=Opts_Digest; *p; p++) {
285 + char ed1[30], ed2[30];
287 + case 'i': /* compare INODEs */
288 + if (statc.st_ino != ff_pkt->statp.st_ino) {
289 + Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %s File: %s\n"),
290 + edit_uint64((uint64_t)statc.st_ino, ed1),
291 + edit_uint64((uint64_t)ff_pkt->statp.st_ino, ed2));
295 + case 'p': /* permissions bits */
296 + if (statc.st_mode != ff_pkt->statp.st_mode) {
297 + Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"),
298 + (uint32_t)statc.st_mode, (uint32_t)ff_pkt->statp.st_mode);
302 + case 'n': /* number of links */
303 + if (statc.st_nlink != ff_pkt->statp.st_nlink) {
304 + Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"),
305 + (uint32_t)statc.st_nlink, (uint32_t)ff_pkt->statp.st_nlink);
309 + case 'u': /* user id */
310 + if (statc.st_uid != ff_pkt->statp.st_uid) {
311 + Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %u File: %u\n"),
312 + (uint32_t)statc.st_uid, (uint32_t)ff_pkt->statp.st_uid);
316 + case 'g': /* group id */
317 + if (statc.st_gid != ff_pkt->statp.st_gid) {
318 + Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %u File: %u\n"),
319 + (uint32_t)statc.st_gid, (uint32_t)ff_pkt->statp.st_gid);
323 + case 's': /* size */
324 + if (statc.st_size != ff_pkt->statp.st_size) {
325 + Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %s File: %s\n"),
326 + edit_uint64((uint64_t)statc.st_size, ed1),
327 + edit_uint64((uint64_t)ff_pkt->statp.st_size, ed2));
331 + case 'a': /* access time */
332 + if (statc.st_atime != ff_pkt->statp.st_atime) {
333 + Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n"));
338 + if (statc.st_mtime != ff_pkt->statp.st_mtime) {
339 + Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n"));
343 + case 'c': /* ctime */
344 + if (statc.st_ctime != ff_pkt->statp.st_ctime) {
345 + Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n"));
349 + case 'd': /* file size decrease */
350 + if (statc.st_size > ff_pkt->statp.st_size) {
351 + Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %s File: %s\n"),
352 + edit_uint64((uint64_t)statc.st_size, ed1),
353 + edit_uint64((uint64_t)ff_pkt->statp.st_size, ed2));
357 + case '5': /* compare MD5 */
358 + Dmsg1(500, "set Do_MD5 for %s\n", ff_pkt->fname);
359 +// *do_Digest = CRYPTO_DIGEST_MD5;
361 + case '1': /* compare SHA1 */
362 +// *do_Digest = CRYPTO_DIGEST_SHA1;
370 + *elt->lstat = '\0'; /* mark it as seen */
371 + Dmsg2(1, "accurate %s = %i\n", fname, stat);
376 +int accurate_get_current_file_list_cmd(JCR *jcr)
378 + BSOCK *dir = jcr->dir_bsock;
383 + if (jcr->accurate == false || job_canceled(jcr) || jcr->JobLevel == L_FULL) {
387 + if (sscanf(dir->msg, "accurate files=%ld", &nb) != 1) {
388 + dir->fsend(_("2991 Bad accurate command\n"));
392 + jcr->file_list = (htable *)malloc(sizeof(htable));
393 + jcr->file_list->init(elt, &elt->link, nb);
395 + /* get current files */
396 + while (dir->recv() >= 0) {
397 + len = strlen(dir->msg);
398 + if ((len+1) < dir->msglen) {
399 + elt = (CurFile *)malloc(sizeof(CurFile));
400 + elt->fname = (char *) malloc(dir->msglen+1);
401 + memcpy(elt->fname, dir->msg, dir->msglen);
402 + elt->fname[dir->msglen]='\0';
403 + elt->lstat = elt->fname + len + 1;
404 + if ((deb % 1000) == 1) {
405 + Dmsg1(1, "deb=%i\n", deb);
407 + if ((deb % 5000) == 1) {
408 + jcr->file_list->stats();
410 + Dmsg2(100, "hash[%s]=%s\n", elt->fname, elt->lstat);
411 + jcr->file_list->insert(elt->fname, elt);
416 + jcr->file_list->stats();
417 +// dir->fsend("2000 OK accurate\n");
422 +bool accurate_send_deleted_list(JCR *jcr)
424 + if (jcr->accurate == false || jcr->JobLevel == L_FULL) {
429 + foreach_htable (elt, jcr->file_list) {
430 + Dmsg3(100, "elt = 0x%x fname=%s lstat=%s\n", elt, elt->fname, elt->lstat);
431 + if (*elt->lstat != '\0') {
432 + encode_and_send_deleted_file(jcr, elt->fname);
436 + jcr->file_list->destroy(); /* TODO: clean htable when this function is not reached ? */
437 + free(jcr->file_list);
438 + jcr->file_list = NULL;
443 * Find all the requested files and send them
444 * to the Storage daemon.
449 // TODO landonf: Allow user to specify encryption algorithm
451 sd = jcr->store_bsock;
453 set_jcr_job_status(jcr, JS_Running);
455 ok = false; /* error */
456 set_jcr_job_status(jcr, JS_ErrorTerminated);
458 + Dmsg1(1, "jcr->accurate == %i\n", jcr->accurate);
460 + accurate_send_deleted_list(jcr); /* send deleted list to SD */
462 free_pool_memory(jcr->acl_text);
464 stop_heartbeat_monitor(jcr);
469 + /* TODO: in accurate mode, we have to change NOCHG attribute to FT_REG... */
470 +// if (!accurate_check_file(jcr, ff_pkt, false)) {
471 +// Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
474 Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname);
477 + /* TODO: in accurate mode, we have to change NOCHG attribute to FT_REG... */
478 +// if (!accurate_check_file(jcr, ff_pkt, false)) {
479 +// Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
482 Jmsg(jcr, M_NOTSAVED, 0, _(" Archive file not saved: %s\n"), ff_pkt->fname);
485 @@ -1118,6 +1342,9 @@
487 unstrip_path(ff_pkt);
489 + /* list backuped files */
490 + accurate_check_file(jcr, ff_pkt, true);
492 Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
494 Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
495 @@ -1128,6 +1355,58 @@
499 +static bool encode_and_send_deleted_file(JCR *jcr, char *fname)
501 + BSOCK *sd = jcr->store_bsock;
505 +#ifdef FD_NO_SEND_TEST
513 + * Send Attributes header to Storage daemon
514 + * <file-index> <stream> <info>
516 + if (!sd->fsend("%ld %d 0", 0, STREAM_UNIX_ATTRIBUTES)) {
517 + Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
521 + Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
524 + * Send file attributes to Storage daemon
527 + * Filename (full path)
528 + * Encoded attributes
529 + * Link name (if type==FT_LNK or FT_LNKSAVED)
530 + * Encoded extended-attributes (for Win32)
532 + * For a directory, link is the same as fname, but with trailing
533 + * slash. For a linked file, link is the link.
535 + stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c",
537 + FT_NOSTAT /* FileType */,
538 + fname /* FileName */,
539 + 0, attribs, 0, 0, 0, attribsEx, 0);
541 + Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
543 + Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
547 + sd->signal(BNET_EOD); /* indicate end of attributes data */
552 * Do in place strip of path
554 Index: src/filed/job.c
555 ===================================================================
556 --- src/filed/job.c (révision 6443)
557 +++ src/filed/job.c (copie de travail)
559 /* Imported functions */
560 extern int status_cmd(JCR *jcr);
561 extern int qstatus_cmd(JCR *jcr);
562 +extern int accurate_get_current_file_list_cmd(JCR *jcr);
564 /* Forward referenced functions */
565 static int backup_cmd(JCR *jcr);
567 {"RunBeforeJob", runbefore_cmd, 0},
568 {"RunAfterJob", runafter_cmd, 0},
569 {"Run", runscript_cmd, 0},
570 + {"accurate", accurate_get_current_file_list_cmd, 0},
571 {NULL, NULL} /* list terminator */
574 @@ -1087,6 +1089,9 @@
576 fo->flags |= FO_CHKCHANGES;
579 + fo->flags |= FO_ACCURATE;
582 Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
584 @@ -1195,6 +1200,9 @@
586 level = get_memory(dir->msglen+1);
587 Dmsg1(110, "level_cmd: %s", dir->msg);
588 + if (strstr(dir->msg, "accurate")) {
589 + jcr->accurate = true;
591 if (sscanf(dir->msg, "level = %s ", level) != 1) {
594 @@ -1204,14 +1212,14 @@
595 /* Full backup requested? */
596 } else if (strcmp(level, "full") == 0) {
597 jcr->JobLevel = L_FULL;
598 - } else if (strcmp(level, "differential") == 0) {
599 + } else if (strstr(level, "differential")) {
600 jcr->JobLevel = L_DIFFERENTIAL;
603 - } else if (strcmp(level, "incremental") == 0) {
604 + } else if (strstr(level, "incremental")) {
605 jcr->JobLevel = L_INCREMENTAL;
610 * We get his UTC since time, then sync the clocks and correct it
611 * to agree with our clock.
612 Index: src/filed/restore.c
613 ===================================================================
614 --- src/filed/restore.c (révision 6443)
615 +++ src/filed/restore.c (copie de travail)
620 + /* TODO: manage deleted files */
621 + if (file_index == 0) { /* deleted file */
626 * Unpack attributes and do sanity check them
628 Index: src/stored/bextract.c
629 ===================================================================
630 --- src/stored/bextract.c (révision 6443)
631 +++ src/stored/bextract.c (copie de travail)
633 Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
636 + /* handle deleted file
638 + if (rec->FileIndex == 0) {
639 + /* if file is included, remove it ? */
640 + Jmsg(jcr, M_INFO, 0, _("fname=%s is marked as deleted.\n", attr->fname));
644 if (attr->file_index != rec->FileIndex) {
645 Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"),
646 rec->FileIndex, attr->file_index);
647 Index: src/stored/bscan.c
648 ===================================================================
649 --- src/stored/bscan.c (révision 6443)
650 +++ src/stored/bscan.c (copie de travail)
652 case STREAM_UNIX_ATTRIBUTES:
653 case STREAM_UNIX_ATTRIBUTES_EX:
655 + /* handle deleted file
657 + if (rec->FileIndex == 0) {
658 + create_file_attributes_record(db, mjcr, attr->fname, attr->lname,
659 + FT_NOSTAT, "", rec);
664 if (!unpack_attributes_record(bjcr, rec->Stream, rec->data, attr)) {
665 Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n"));
667 Index: src/stored/append.c
668 ===================================================================
669 --- src/stored/append.c (révision 6443)
670 +++ src/stored/append.c (copie de travail)
673 /* Read Stream header from the File daemon.
674 * The stream header consists of the following:
675 - * file_index (sequential Bacula file index, base 1)
676 + * file_index (sequential Bacula file index, base 1, 0 for deleted files)
677 * stream (Bacula number to distinguish parts of data)
678 * info (Info for Storage daemon -- compressed, encryped, ...)
679 * info is not currently used, so is read, but ignored!
680 @@ -185,16 +185,18 @@
682 Dmsg2(890, "<filed: Header FilInx=%d stream=%d\n", file_index, stream);
684 - if (!(file_index > 0 && (file_index == last_file_index ||
685 - file_index == last_file_index + 1))) {
686 - Jmsg0(jcr, M_FATAL, 0, _("File index from FD not positive or sequential\n"));
689 + if (file_index != 0) { /* TODO: handle file_index == 0 */
690 + if (!(file_index > 0 && (file_index == last_file_index ||
691 + file_index == last_file_index + 1))) {
692 + Jmsg0(jcr, M_FATAL, 0, _("File index from FD not positive or sequential\n"));
696 + if (file_index != last_file_index) {
697 + jcr->JobFiles = file_index;
698 + last_file_index = file_index;
701 - if (file_index != last_file_index) {
702 - jcr->JobFiles = file_index;
703 - last_file_index = file_index;
706 /* Read data stream from the File daemon.
707 * The data stream is just raw bytes
708 @@ -212,25 +214,26 @@
709 stream_to_ascii(buf1, rec.Stream,rec.FileIndex),
712 - while (!write_record_to_block(dcr->block, &rec)) {
713 - Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
715 - if (!write_block_to_device(dcr)) {
716 - Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
717 - dev->print_name(), dev->bstrerror());
723 - Dmsg0(400, "Not OK\n");
726 - jcr->JobBytes += rec.data_len; /* increment bytes this job */
727 - Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
728 - FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
729 - stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
730 + while (!write_record_to_block(dcr->block, &rec)) {
731 + Dmsg2(850, "!write_record_to_block data_len=%d rem=%d\n", rec.data_len,
733 + if (!write_block_to_device(dcr)) {
734 + Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
735 + dev->print_name(), dev->bstrerror());
741 + Dmsg0(400, "Not OK\n");
744 + jcr->JobBytes += rec.data_len; /* increment bytes this job */
745 + Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
746 + FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
747 + stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);
750 /* Send attributes and digest to Director for Catalog */
751 if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX ||
752 crypto_digest_stream_type(stream) != CRYPTO_DIGEST_NONE) {
754 ===================================================================
755 --- src/jcr.h (révision 6443)
756 +++ src/jcr.h (copie de travail)
759 /* Forward referenced structures */
766 CRYPTO_CTX crypto; /* Crypto ctx */
767 DIRRES* director; /* Director resource */
768 bool VSS; /* VSS used by FD */
769 + htable *file_list; /* Previous file list (accurate mode) */
770 #endif /* FILE_DAEMON */
773 Index: src/findlib/find.h
774 ===================================================================
775 --- src/findlib/find.h (révision 6443)
776 +++ src/findlib/find.h (copie de travail)
778 #define FO_ENHANCEDWILD (1<<23) /* Enhanced wild card processing */
779 #define FO_CHKCHANGES (1<<24) /* Check if file have been modified during backup */
780 #define FO_STRIPPATH (1<<25) /* Check for stripping path */
781 +#define FO_ACCURATE (1<<26) /* Accurate mode */
783 struct s_included_file {
784 struct s_included_file *next;