The computer of Narelle’s friend Fatima died a few days ago. She got pretty upset because she had all her family pictures on it, and, like most, didn’t have any backups.

Here is the tale of how we saved her life (there must be some white rabbit in shiny armour involved or something).

After starting the computer under [[System Rescue http://www.sysresccd.org/Index.fr.php]], I used dd_rescue to copy the entire disk over the network onto my computer. System Rescue doesn’t start [[lockd]], so mounting NFS volumes is faster using the nolock option.
I then found a little program called [[Findfile http://linux.softpedia.com/get/System/Recovery/findfile-1433.shtml]] which goes through a raw disk dump to find series of bytes that look like a JPEG file. This returned a few photos, mostly of CD covers, which were not really useful.

Looking more into it, I realised that what is usually known as JPEG is not very precise. Photo processing software usually produces files that follow a file format called JFIF, but cameras produce files in a slightly different format called EXIF, which has a different signature. So I patched Findfile to also find EXIF files (along with a couple other changes as Findfile didn’t work for me out-of-the-tarball):

diff -ur findfile-0.2.orig/error.c findfile-0.2/error.c
--- findfile-0.2.orig/error.c 2004-03-18 18:44:35.000000000 +0100
+++ findfile-0.2/error.c 2007-06-03 12:45:17.000000000 +0200
@@ -14,7 +14,7 @@
 va_start(ap, format);
 (void)vfprintf(stderr, format, ap);
 va_end(ap);
- fprintf(stderr, "errno=%d (if applicable)\sn", errno);
+ fprintf(stderr, "errno=%d %s (if applicable)\sn", errno, strerror(errno));
 
 exit(EXIT_FAILURE);
 }
diff -ur findfile-0.2.orig/findjpeg.c findfile-0.2/findjpeg.c
--- findfile-0.2.orig/findjpeg.c 2004-03-18 18:44:35.000000000 +0100
+++ findfile-0.2/findjpeg.c 2007-06-03 23:39:11.000000000 +0200
@@ -24,15 +24,31 @@
 if (usector[0] == 0xff &&
 usector[1] == 0xd8 &&
 usector[2] == 0xff &&
- sector[5] == 'J' &&
- sector[6] == 'F' &&
- sector[7] == 'I' &&
- sector[8] == 'F' &&
- sector[9] == 0x00)
+ sector[6] == 'J' &&
+ sector[7] == 'F' &&
+ sector[8] == 'I' &&
+ sector[9] == 'F' &&
+ sector[10] == 0x00)
 {
 return 0;
 }
 
+ /* Also check for a EXIF header -- it's similar, and it's
+ * what digital camera pass off as jpeg */
+ if (usector[0] == 0xff &&
+ usector[1] == 0xd8 &&
+ usector[2] == 0xff &&
+ usector[3] == 0xe1 &&
+ sector[6] == 'E' &&
+ sector[7] == 'x' &&
+ sector[8] == 'i' &&
+ sector[9] == 'f' &&
+ sector[10] == 0x00)
+ {
+ return 0;
+ }
+
+
 return -1;
 }
 
@@ -41,13 +57,10 @@
 unsigned char *usector = (unsigned char *)sector;
 int loop;
 
- for(loop=0; loop<length; loop++)
+ for(loop=0; loop<length; loop+=2)
 {
- if (usector[loop] == 0xff)
- {
- if (usector[++loop] == 0xd9)
- return loop;
- }
+ if ((usector[loop] == 0xff) && (usector[loop+1] == 0xd9))
+ return loop + 2;
 }
 
 return -1;
diff -ur findfile-0.2.orig/utils.c findfile-0.2/utils.c
--- findfile-0.2.orig/utils.c 2004-03-18 18:44:35.000000000 +0100
+++ findfile-0.2/utils.c 2007-06-03 13:19:23.000000000 +0200
@@ -18,7 +18,7 @@
 
 (*index)++;
 
- fd = open64(fname, O_WRONLY);
+ fd = open(fname, O_WRONLY | O_CREAT, 0644);
 if (fd == -1)
 error_exit("Cannot create file %s\sn", fname);
 

And voilà: we were rewarded with 463 camera pictures. Fatima’s life is now safe!