term_msg);
 
    Dmsg0(100, "Leave verify_cleanup()\n");
-
+   if (jcr->fname) {
+      free_memory(jcr->fname);
+      jcr->fname = NULL;
+   }
 }
 
 /*
    int stat = JS_Terminated;
    char buf[MAXSTRING];
    char *fname = (char *)get_pool_memory(PM_MESSAGE);
+   int do_MD5 = FALSE;
 
    memset(&fdbr, 0, sizeof(FILE_DBR));
    fd = jcr->file_bsock;
     * Get Attributes and MD5 Signature from File daemon
     */
    while ((n=bget_msg(fd, 0)) > 0) {
-       long file_index, attr_file_index;
-       int stream;
-       char *attr, *p;
-       char Opts_MD5[MAXSTRING];       /* Verify Opts or MD5 signature */
-       int do_MD5;
-
-       fname = (char *)check_pool_memory_size(fname, fd->msglen);
-       jcr->fname = (char *)check_pool_memory_size(fname, fd->msglen);
-       Dmsg1(50, "Atts+MD5=%s\n", fd->msg);
-       if ((len = sscanf(fd->msg, "%ld %d %100s %s", &file_index, &stream, 
-            Opts_MD5, fname)) != 4) {
-          Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 4 fields got %d\n\
-msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
-         jcr->JobStatus = JS_ErrorTerminated;
-         return 0;
-       }
-       /*
-       * Got attributes stream, decode it
-       */
-       if (stream == STREAM_UNIX_ATTRIBUTES) {
-         attr_file_index = file_index;    /* remember attribute file_index */
-         len = strlen(fd->msg);
-         attr = &fd->msg[len+1];
-         decode_stat(attr, &statf);  /* decode file stat packet */
-         do_MD5 = FALSE;
-         jcr->fn_printed = FALSE;
-         strcpy(jcr->fname, fname);  /* move filename into JCR */
-
-          Dmsg2(11, "dird<filed: stream=%d %s\n", stream, jcr->fname);
-          Dmsg1(20, "dird<filed: attr=%s\n", attr);
-
-         /* 
-          * Find equivalent record in the database 
-          */
-         fdbr.FileId = 0;
-         db_get_file_attributes_record(jcr->db, jcr->fname, &fdbr);
-
-         if (fdbr.FileId == 0) {
-             Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
-             Dmsg1(20, _("File not in catalog: %s\n"), jcr->fname);
-            stat = JS_Differences;
-            continue;
-         } else {
-            /* 
-             * mark file record as visited by stuffing the
-             * current JobId, which is unique, into the FileIndex
-             */
-            db_mark_file_record(jcr->db, fdbr.FileId, jcr->JobId);
-         }
-
-          Dmsg2(20, "Found %s in catalog. Opts=%s\n", jcr->fname, Opts_MD5);
-         decode_stat(fdbr.LStat, &statc); /* decode catalog stat */
-         strip_trailing_junk(jcr->fname);
-         /*
-          * Loop over options supplied by user and verify the
-          * fields he requests.
-          */
-         for (p=Opts_MD5; *p; p++) {
-            switch (*p) {
-             case 'i':                /* compare INODEs */
-               if (statc.st_ino != statf.st_ino) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_ino   differ. Cat: %x File: %x\n"), 
-                     statc.st_ino, statf.st_ino);
-                  stat = JS_Differences;
-               }
-               break;
-             case 'p':                /* permissions bits */
-               if (statc.st_mode != statf.st_mode) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_mode  differ. Cat: %x File: %x\n"), 
-                     statc.st_mode, statf.st_mode);
-                  stat = JS_Differences;
-               }
-               break;
-             case 'n':                /* number of links */
-               if (statc.st_nlink != statf.st_nlink) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_nlink differ. Cat: %d File: %d\n"), 
-                     statc.st_nlink, statf.st_nlink);
-                  stat = JS_Differences;
-               }
-               break;
-             case 'u':                /* user id */
-               if (statc.st_uid != statf.st_uid) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_uid   differ. Cat: %d File: %d\n"), 
-                     statc.st_uid, statf.st_uid);
-                  stat = JS_Differences;
-               }
-               break;
-             case 'g':                /* group id */
-               if (statc.st_gid != statf.st_gid) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_gid   differ. Cat: %d File: %d\n"), 
-                     statc.st_gid, statf.st_gid);
-                  stat = JS_Differences;
-               }
-               break;
-             case 's':                /* size */
-               if (statc.st_size != statf.st_size) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_size  differ. Cat: %d File: %d\n"), 
-                     statc.st_size, statf.st_size);
-                  stat = JS_Differences;
-               }
-               break;
-             case 'a':                /* access time */
-               if (statc.st_atime != statf.st_atime) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_atime differs\n"));
-                  stat = JS_Differences;
-               }
-               break;
-             case 'm':
-               if (statc.st_mtime != statf.st_mtime) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_mtime differs\n"));
-                  stat = JS_Differences;
-               }
-               break;
-             case 'c':                /* ctime */
-               if (statc.st_ctime != statf.st_ctime) {
-                  prt_fname(jcr);
-                   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) {
-                  prt_fname(jcr);
-                   Jmsg(jcr, M_INFO, 0, _("      st_size  decrease. Cat: %d File: %d\n"), 
-                     statc.st_size, statf.st_size);
-                  stat = JS_Differences;
-               }
-               break;
-             case '5':                /* compare MD5 */
-               do_MD5 = TRUE;
-               break;
-             case ':':
-             case 'V':
-            default:
-               break;
-            }
-         }
-       /*
-       * Got MD5 Signature from Storage daemon
-       *  It came across in the Opts_MD5 field.
-       */
-       } else if (stream == STREAM_MD5_SIGNATURE) {
-         if (attr_file_index != file_index) {
-             Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"),
-               file_index, attr_file_index);
-            jcr->JobStatus = JS_ErrorTerminated;
-            return 0;
-         } else if (do_MD5) {
-            db_escape_string(buf, Opts_MD5, strlen(Opts_MD5));
-            if (strcmp(buf, fdbr.MD5) != 0) {
-               prt_fname(jcr);
-               if (debug_level >= 10) {
-                   Jmsg(jcr, M_INFO, 0, _("      MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5);
-               } else {
-                   Jmsg(jcr, M_INFO, 0, _("      MD5 differs.\n"));
-               }
-               stat = JS_Differences;
-            }
-         }
-       }
-       jcr->jr.JobFiles = file_index;
-
+      long file_index, attr_file_index;
+      int stream;
+      char *attr, *p;
+      char Opts_MD5[MAXSTRING];        /* Verify Opts or MD5 signature */
+
+      fname = (char *)check_pool_memory_size(fname, fd->msglen);
+      jcr->fname = (char *)check_pool_memory_size(jcr->fname, fd->msglen);
+      Dmsg1(50, "Atts+MD5=%s\n", fd->msg);
+      if ((len = sscanf(fd->msg, "%ld %d %100s %s", &file_index, &stream, 
+           Opts_MD5, fname)) != 4) {
+         Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 4 fields got %d\n\
+ mslen=%d msg=%s\n"), len, fd->msglen, fd->msg);
+        jcr->JobStatus = JS_ErrorTerminated;
+        return 0;
+      }
+      /*
+       * Got attributes stream, decode it
+       */
+      if (stream == STREAM_UNIX_ATTRIBUTES) {
+        attr_file_index = file_index;    /* remember attribute file_index */
+        len = strlen(fd->msg);
+        attr = &fd->msg[len+1];
+        decode_stat(attr, &statf);  /* decode file stat packet */
+        do_MD5 = FALSE;
+        jcr->fn_printed = FALSE;
+        strip_trailing_junk(fname);
+        strcpy(jcr->fname, fname);  /* move filename into JCR */
+
+         Dmsg2(040, "dird<filed: stream=%d %s\n", stream, jcr->fname);
+         Dmsg1(20, "dird<filed: attr=%s\n", attr);
+
+        /* 
+         * Find equivalent record in the database 
+         */
+        fdbr.FileId = 0;
+        if (!db_get_file_attributes_record(jcr->db, jcr->fname, &fdbr)) {
+            Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
+            Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname);
+           stat = JS_Differences;
+           continue;
+        } else {
+           /* 
+            * mark file record as visited by stuffing the
+            * current JobId, which is unique, into the FileIndex
+            */
+           db_mark_file_record(jcr->db, fdbr.FileId, jcr->JobId);
+        }
+
+         Dmsg3(100, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname, 
+           file_index, Opts_MD5);
+        decode_stat(fdbr.LStat, &statc); /* decode catalog stat */
+        /*
+         * Loop over options supplied by user and verify the
+         * fields he requests.
+         */
+        for (p=Opts_MD5; *p; p++) {
+           switch (*p) {
+            case 'i':                /* compare INODEs */
+              if (statc.st_ino != statf.st_ino) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_ino   differ. Cat: %x File: %x\n"), 
+                    statc.st_ino, statf.st_ino);
+                 stat = JS_Differences;
+              }
+              break;
+            case 'p':                /* permissions bits */
+              if (statc.st_mode != statf.st_mode) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_mode  differ. Cat: %x File: %x\n"), 
+                    statc.st_mode, statf.st_mode);
+                 stat = JS_Differences;
+              }
+              break;
+            case 'n':                /* number of links */
+              if (statc.st_nlink != statf.st_nlink) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_nlink differ. Cat: %d File: %d\n"), 
+                    statc.st_nlink, statf.st_nlink);
+                 stat = JS_Differences;
+              }
+              break;
+            case 'u':                /* user id */
+              if (statc.st_uid != statf.st_uid) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_uid   differ. Cat: %d File: %d\n"), 
+                    statc.st_uid, statf.st_uid);
+                 stat = JS_Differences;
+              }
+              break;
+            case 'g':                /* group id */
+              if (statc.st_gid != statf.st_gid) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_gid   differ. Cat: %d File: %d\n"), 
+                    statc.st_gid, statf.st_gid);
+                 stat = JS_Differences;
+              }
+              break;
+            case 's':                /* size */
+              if (statc.st_size != statf.st_size) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_size  differ. Cat: %d File: %d\n"), 
+                    statc.st_size, statf.st_size);
+                 stat = JS_Differences;
+              }
+              break;
+            case 'a':                /* access time */
+              if (statc.st_atime != statf.st_atime) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_atime differs\n"));
+                 stat = JS_Differences;
+              }
+              break;
+            case 'm':
+              if (statc.st_mtime != statf.st_mtime) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_mtime differs\n"));
+                 stat = JS_Differences;
+              }
+              break;
+            case 'c':                /* ctime */
+              if (statc.st_ctime != statf.st_ctime) {
+                 prt_fname(jcr);
+                  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) {
+                 prt_fname(jcr);
+                  Jmsg(jcr, M_INFO, 0, _("      st_size  decrease. Cat: %d File: %d\n"), 
+                    statc.st_size, statf.st_size);
+                 stat = JS_Differences;
+              }
+              break;
+            case '5':                /* compare MD5 */
+               Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname);
+              do_MD5 = TRUE;
+              break;
+            case ':':
+            case 'V':
+           default:
+              break;
+           }
+        }
+      /*
+       * Got MD5 Signature from Storage daemon
+       *  It came across in the Opts_MD5 field.
+       */
+      } else if (stream == STREAM_MD5_SIGNATURE) {
+         Dmsg2(100, "stream=MD5 inx=%d fname=%s\n", file_index, jcr->fname);
+        /* 
+         * When ever we get an MD5 signature is MUST have been
+         * preceded by an attributes record, which sets attr_file_index
+         */
+        if (attr_file_index != file_index) {
+            Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"),
+              file_index, attr_file_index);
+           jcr->JobStatus = JS_ErrorTerminated;
+           return 0;
+        } 
+        if (do_MD5) {
+           db_escape_string(buf, Opts_MD5, strlen(Opts_MD5));
+           if (strcmp(buf, fdbr.MD5) != 0) {
+              prt_fname(jcr);
+              if (debug_level >= 10) {
+                  Jmsg(jcr, M_INFO, 0, _("      MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5);
+              } else {
+                  Jmsg(jcr, M_INFO, 0, _("      MD5 differs.\n"));
+              }
+              stat = JS_Differences;
+           }
+           do_MD5 = FALSE;
+        }
+      }
+      jcr->jr.JobFiles = file_index;
    } 
    if (n < 0) {
       Jmsg2(jcr, M_FATAL, 0, _("bdird<filed: bad attributes from filed n=%d : %s\n"),
 
    set_find_options(jcr->ff, jcr->incremental, jcr->mtime);
    Dmsg0(10, "Start find files\n");
    /* Subroutine verify_file() is called for each file */
-   if (!find_files(jcr->ff, verify_file, (void *)jcr)) {
-      /****FIXME**** error termination */
-      Dmsg0(0, "========= Error return from find_files\n");
-   }
+   find_files(jcr->ff, verify_file, (void *)jcr);  
    Dmsg0(10, "End find files\n");
 
-   dir->msglen = 0;
-   bnet_send(dir);                   /* signal end attributes to director */
+   bnet_sig(dir, BNET_EOD);          /* signal end of data */
+
    if (jcr->big_buf) {
       free(jcr->big_buf);
       jcr->big_buf = NULL;
 {
    char attribs[MAXSTRING];
    int32_t n;
-   int fid;
+   int fid, stat;
    struct MD5Context md5c;
    unsigned char signature[16];
    BSOCK *sd, *dir;
       return 1;
    }
 
-   if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
-      ff_pkt->ff_errno = errno;
-      Jmsg(jcr, M_ERROR, -1, _("  Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
-      return 1;
+
+   if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && 
+        ff_pkt->statp.st_size > 0) {
+      if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
+        ff_pkt->ff_errno = errno;
+         Jmsg(jcr, M_NOTSAVED, -1, _("Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
+        return 1;
+      }
+   } else {
+      fid = -1;
    }
 
-   Dmsg2(50, "opened %s fid=%d\n", ff_pkt->fname, fid);
-   Dmsg1(10, "bfiled: sending %s to Director\n", ff_pkt->fname);
    encode_stat(attribs, &ff_pkt->statp);
      
    jcr->JobFiles++;                 /* increment number of files sent */
       ff_pkt->VerifyOpts[0] = 'V';
       ff_pkt->VerifyOpts[1] = 0;
    }
+
+
+   /* 
+    * Send file attributes to Director
+    *  File_index
+    *  Stream
+    *  Verify Options
+    *  Filename (full path)
+    *  Encoded attributes
+    *  Link name (if type==FT_LNK)
+    * For a directory, link is the same as fname, but with trailing
+    * slash. For a linked file, link is the link.
+    */
    /* Send file attributes to Director (note different format than for Storage) */
+   Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname);
    if (ff_pkt->type == FT_LNK) {
-      dir->msglen = sprintf(dir->msg,"%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
+      stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
                    STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 
                    0, attribs, 0, ff_pkt->link, 0);
    } else {
-      dir->msglen = sprintf(dir->msg,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
+      stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
                    STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 
                    0, attribs, 0, 0);
    }
    Dmsg2(20, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
-   bnet_send(dir);           /* send to Director */
-
+   if (!stat) {
+      Jmsg(jcr, M_ERROR, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir));
+      if (fid >= 0) {
+        close(fid);
+      }
+      return 0;
+   }
 
-   /* 
-    * If MD5 is requested, read the file and compute the MD5   
-    *
-    */
-   if (ff_pkt->flags & FO_MD5) {
+   /* If file opened, compute MD5 */
+   if (fid >= 0  && ff_pkt->flags & FO_MD5) {
       char MD5buf[50];               /* 24 should do */
 
       MD5Init(&md5c);
 
-      if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && 
-           ff_pkt->statp.st_size > 0) {
-        while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) {
-           MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n);
-           jcr->JobBytes += n;
-        }
-        if (n < 0) {
-            Jmsg(jcr, M_ERROR, -1, _("  Error reading %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
-        }
+      while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) {
+        MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n);
+        jcr->JobBytes += n;
+      }
+      if (n < 0) {
+         Jmsg(jcr, M_WARNING, -1, _("  Error reading file %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
       }
 
       MD5Final(signature, &md5c);
 
       bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */
-      dir->msglen = sprintf(dir->msg, "%d %d %s X", jcr->JobFiles, 
-        STREAM_MD5_SIGNATURE, MD5buf);
+      Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf);
+      bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf,
+        jcr->JobFiles);
       Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg);
-      bnet_send(dir);               /* send MD5 signature to Director */
    }
-   close(fid);
+   if (fid >= 0) {
+      close(fid);
+   }
    return 1;
 }