 +
 +   bsnprintf(buf, sizeof(buf),
 +      "SELECT Path.Path,Filename.Name "
-+        "FROM CurrentBackup "
++        "FROM CurrentFile "
 +             "JOIN File USING (FileId) "
 +             "JOIN Path USING (PathId) "
 +             "JOIN Filename USING (FilenameId) "
-+      "WHERE CurrentBackup.BackupId=%s "
-+        "AND File.MarkId!=%d ",
++      "WHERE CurrentFile.BackupId=%s "
++        "AND CurrentFile.MarkId!=%s ",
 +	     edit_uint64(backupid, ed1), edit_uint64(jcr->JobId, ed2));
 +   /* missing_handler is called for each file found */
++   Dmsg1(1, "display deleted files cmd=%s\n", buf);
 +   db_sql_query(jcr->db, buf, missing_handler, (void *)jcr);
 +
++   bsnprintf(buf, sizeof(buf),
++	     "SELECT Name FROM ToBackup%s",
++	     edit_uint64(jcr->JobId, ed2));
++   /* missing_handler is called for each file found */
++   Dmsg1(1, "display files to backup cmd=%s\n", buf);
++   db_sql_query(jcr->db, buf, missing_handler, (void *)jcr);
++
 +   free_pool_memory(fname);
 +
 +   return true;
++
++bail_out2:
++   db_accurate_drop_backup_table(jcr, jcr->db, jcr->JobId);
++   return false;
 +}
 +
 +/*
   * Do a backup of the specified FileSet
   *
   *  Returns:  false on failure
-@@ -231,6 +534,13 @@
+@@ -231,6 +564,13 @@
        goto bail_out;
     }
  

+       * Got attributes stream, decode it
+       */
+      if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX) {
+         int32_t LinkFIf, LinkFIc;
+         Dmsg2(400, "file_index=%d attr=%s\n", file_index, attr);
+         jcr->JobFiles++;
+         jcr->FileIndex = file_index;    /* remember attribute file_index */
+         decode_stat(attr, &statf, &LinkFIf);  /* decode file stat packet */
+         do_Digest = CRYPTO_DIGEST_NONE;
+         pm_strcpy(jcr->fname, fname);  /* move filename into JCR */
+
+         Dmsg3(040, "dird<filed: stream=%d %s %s\n", stream, jcr->fname, attr);
+
+         /*
+          * Find equivalent record in the database
+          */
+         fdbr.FileId = 0;
+	 /* If file_index==0, file is not saved by fd, check them */
+         if (!db_accurate_get_file_attributes_record(jcr, jcr->db, jcr->fname, backupid, &fdbr)) {
+            Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
+            Dmsg1(1, _("File not in catalog: %s\n"), jcr->fname);
+            continue;
+         } else {
+	    Dmsg1(1, _("File in catalog: %s\n"), jcr->fname);
+            /*
+             * mark file record as visited by stuffing the
+             * current JobId, which is unique, into the MarkId field.
+             */
+            db_mark_file_record(jcr, jcr->db, fdbr.FileId, jcr->JobId);
+         }
+
+         Dmsg3(400, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname,
+            file_index, Opts_Digest);
+         decode_stat(fdbr.LStat, &statc, &LinkFIc); /* decode catalog stat */
+
+	 // TODO: for each JS_Differences, send it to FD for backup
+         /*
+          * Loop over options supplied by user and verify the
+          * fields he requests.
+          */
+	 stat = JS_Terminated;	/* TODO: track changes */
+         for (p=Opts_Digest; *p; p++) {
+            char ed1[30], ed2[30];
+            switch (*p) {
+            case 'i':                /* compare INODEs */
+               if (statc.st_ino != statf.st_ino) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_ino   differ. Cat: %s File: %s\n"),
+                     edit_uint64((uint64_t)statc.st_ino, ed1),
+                     edit_uint64((uint64_t)statf.st_ino, ed2));
+                  stat = JS_Differences;
+               }
+               break;
+            case 'p':                /* permissions bits */
+               if (statc.st_mode != statf.st_mode) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_mode  differ. Cat: %x File: %x\n"),
+                     (uint32_t)statc.st_mode, (uint32_t)statf.st_mode);
+                  stat = JS_Differences;
+               }
+               break;
+            case 'n':                /* number of links */
+               if (statc.st_nlink != statf.st_nlink) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_nlink differ. Cat: %d File: %d\n"),
+                     (uint32_t)statc.st_nlink, (uint32_t)statf.st_nlink);
+                  stat = JS_Differences;
+               }
+               break;
+            case 'u':                /* user id */
+               if (statc.st_uid != statf.st_uid) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_uid   differ. Cat: %u File: %u\n"),
+                     (uint32_t)statc.st_uid, (uint32_t)statf.st_uid);
+                  stat = JS_Differences;
+               }
+               break;
+            case 'g':                /* group id */
+               if (statc.st_gid != statf.st_gid) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_gid   differ. Cat: %u File: %u\n"),
+                     (uint32_t)statc.st_gid, (uint32_t)statf.st_gid);
+                  stat = JS_Differences;
+               }
+               break;
+            case 's':                /* size */
+               if (statc.st_size != statf.st_size) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_size  differ. Cat: %s File: %s\n"),
+                     edit_uint64((uint64_t)statc.st_size, ed1),
+                     edit_uint64((uint64_t)statf.st_size, ed2));
+                  stat = JS_Differences;
+               }
+               break;
+            case 'a':                /* access time */
+               if (statc.st_atime != statf.st_atime) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_atime differs\n"));
+                  stat = JS_Differences;
+               }
+               break;
+            case 'm':
+               if (statc.st_mtime != statf.st_mtime) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_mtime differs\n"));
+                  stat = JS_Differences;
+               }
+               break;
+            case 'c':                /* ctime */
+               if (statc.st_ctime != statf.st_ctime) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_ctime differs\n"));
+                  stat = JS_Differences;
+               }
+               break;
+            case 'd':                /* file size decrease */
+               if (statc.st_size > statf.st_size) {
+                  Jmsg(jcr, M_INFO, 0, _("      st_size  decrease. Cat: %s File: %s\n"),
+                     edit_uint64((uint64_t)statc.st_size, ed1),
+                     edit_uint64((uint64_t)statf.st_size, ed2));
+                  stat = JS_Differences;
+               }
+               break;
+            case '5':                /* compare MD5 */
+               Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname);
+               do_Digest = CRYPTO_DIGEST_MD5;
+               break;
+            case '1':                 /* compare SHA1 */
+               do_Digest = CRYPTO_DIGEST_SHA1;
+               break;
+            case ':':
+            case 'V':
+            default:
+               break;
+            }
+         }
+	 if (stat == JS_Differences) {
+	    Jmsg(jcr, M_INFO, 0, _("      fname=%s\n"), jcr->fname);
+	 }
+
+      /*
+       * Got Digest Signature from Storage daemon

+      char Opts_Digest[MAXSTRING];        /* Verify Opts or MD5/SHA1 digest */
+
+      if (job_canceled(jcr)) {
+         goto bail_out2;
+      }
+      fname = check_pool_memory_size(fname, fd->msglen);
+      jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
