+ return found;
+}
+
+/* Create tokyo dbm hash file
+ * If something goes wrong, we cancel accurate mode.
+ */
+static bool accurate_init(JCR *jcr, int nbfile)
+{
+ jcr->file_list = tcadbnew();
+//
+// tchdbsetcache(jcr->file_list, 300000);
+// tchdbtune(jcr->file_list,
+// nbfile, /* nb bucket 0.5n to 4n */
+// 6, /* size of element 2^x */
+// 16,
+// 0); /* options like compression */
+//
+ jcr->hash_name = get_pool_memory(PM_MESSAGE);
+ POOLMEM *temp = get_pool_memory(PM_MESSAGE);
+
+ if (nbfile > 500000) {
+ make_unique_filename(&jcr->hash_name, jcr->JobId, "accurate");
+ pm_strcat(jcr->hash_name, ".tcb");
+ Mmsg(temp, "%s#bnum=%i#mode=e#opts=l",
+ jcr->hash_name, nbfile*4);
+ Dmsg1(dbglvl, "Doing accurate hash on disk %s\n", jcr->hash_name);
+ } else {
+ Dmsg0(dbglvl, "Doing accurate hash on memory\n");
+ pm_strcpy(jcr->hash_name, "*");
+ pm_strcpy(temp, "*");
+ }
+
+ if(!tcadbopen(jcr->file_list, jcr->hash_name)){
+ Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk\n"));
+ Jmsg(jcr, M_INFO, 1, _("Disabling accurate mode\n"));
+ tcadbdel(jcr->file_list);
+ jcr->file_list = NULL;
+ jcr->accurate = false;
+ }
+ free_pool_memory(temp);
+ return jcr->file_list != NULL;
+}
+
+/* This function is called at the end of backup
+ * We walk over all hash disk element, and we check
+ * for elt.seen.
+ */
+bool accurate_send_deleted_list(JCR *jcr)
+{
+ char *key;
+ CurFile *elt;
+ int size;
+ FF_PKT *ff_pkt;
+ int stream = STREAM_UNIX_ATTRIBUTES;
+
+ if (!jcr->accurate || jcr->JobLevel == L_FULL) {
+ goto bail_out;
+ }
+
+ if (jcr->file_list == NULL) {
+ goto bail_out;
+ }
+
+ ff_pkt = init_find_files();
+ ff_pkt->type = FT_DELETED;
+
+ /* traverse records */
+ tcadbiterinit(jcr->file_list);
+ while((key = tcadbiternext2(jcr->file_list)) != NULL) {
+ elt = (CurFile *) tcadbget(jcr->file_list,
+ key, strlen(key)+1, &size);
+ if (elt)
+ {
+ if (!elt->seen) { /* already seen */
+ ff_pkt->fname = key;
+ ff_pkt->statp.st_mtime = elt->mtime;
+ ff_pkt->statp.st_ctime = elt->ctime;
+ encode_and_send_attributes(jcr, ff_pkt, stream);
+ }
+ realfree(elt);
+ }
+ realfree(key); /* tokyo cabinet have to use real free() */
+ }
+
+ term_find_files(ff_pkt);
+bail_out:
+ /* TODO: clean htable when this function is not reached ? */
+ if (jcr->file_list) {
+ if(!tcadbclose(jcr->file_list)){
+ Jmsg(jcr, M_ERROR, 1, _("Can't close accurate hash disk\n"));
+ }
+
+ /* delete the object */
+ tcadbdel(jcr->file_list);
+ if (!bstrcmp(jcr->hash_name, "*")) {
+ unlink(jcr->hash_name);
+ }
+
+ free_pool_memory(jcr->hash_name);
+ jcr->hash_name = NULL;
+ jcr->file_list = NULL;
+ }
+ return true;
+}
+
+#else /* HTABLE mode */
+
+static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
+{
+ CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
+ temp->seen = 1; /* records are in memory */
+ return true;
+}
+
+static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
+{
+ bool found=false;
+ ret->seen = 0;