Subject: Re: fat16 undelete?
To: None <netbsd-users@netbsd.org>
From: Wolfgang S. Rupprecht <wolfgang+gnus20050426T193906@dailyplanet.dontspam.wsrcc.com>
List: netbsd-users
Date: 04/26/2005 20:00:29
"Wolfgang S. Rupprecht" writes:
> Is there some open source utility for recovering "deleted" files in
> fat-16 format filesystems?
>
> It seems I was a bit too quick hitting the "delete all" button on my
> digital camera.  Only the first 200 pictures had transfered.  I don't
> know if there was a Coolpix-995 firmware problem or a umass/fat16
> problem that only transfered the first 200 filenames.  The fact that
> it stopped at exactly 200 is a bit suspicious.

The program I found that worked was fatback-1.3 from sourceforge:

    http://sourceforge.net/project/showfiles.php?group_id=46038

It needed a stdarg fix to make it stop segv-ing on an amd64, but other
than that it worked well enough.  (The second patched file was just
something that seemed needlessly obtuse and I was worried it was being
miscompiled.)

Now for the weird part.  The program includes a GPL-ed source file,
but the program has various comments that it is only to be used by law
enforcement organizations.  This is at odds with the GPL-ed code it
links against, as well as the public distribution via sourceforge.  If
the license discrepancy can be ironed out, this would be a great tool
for pkgsrc/sysutils .

-wolfgang

diff -ru fatback-1.3-dist/output.c fatback-1.3/output.c
--- fatback-1.3-dist/output.c	Wed May 30 08:47:04 2001
+++ fatback-1.3/output.c	Mon Apr 25 15:05:11 2005
@@ -63,9 +63,13 @@
      /* print the rest of the arguments in standard printf style */
      va_start(arg_list, format);
      retval = vfprintf(Audit_log, format, arg_list);
-     if ((level < VERBOSE) || (verbose && level == VERBOSE))
-          vfprintf(ostream, format, arg_list);
      va_end(arg_list);
+
+     if ((level < VERBOSE) || (verbose && level == VERBOSE)) {
+	  va_start(arg_list, format);
+          vfprintf(ostream, format, arg_list);	 
+	  va_end(arg_list);
+     }
 
      return retval;
 }
diff -ru fatback-1.3-dist/recovery.c fatback-1.3/recovery.c
--- fatback-1.3-dist/recovery.c	Wed May 30 08:47:04 2001
+++ fatback-1.3/recovery.c	Tue Apr 26 19:49:28 2005
@@ -85,10 +85,18 @@
            fname);
 
      chainlen = chain_length(clusts, cluster);
+#if 0
      reqd_clusts = size / bytes_per_clust;
      reqd_clusts += !!(size % bytes_per_clust);
+#else
+				/* this doesn't assume !! returns 0 or 1 */
+     reqd_clusts = (size + bytes_per_clust - 1) / bytes_per_clust;
+#endif
      if (chainlen < reqd_clusts) {
           display(VERBOSE, log_carve, fname);
+          display(VERBOSE, "Need: %d got: %d Missing: %d bytes\n",
+		  size, chainlen * bytes_per_clust,
+		  size - (chainlen * bytes_per_clust));
           carve_file(clusts, cluster, size, bytes_per_clust, file);
           return 0;
      }