--- extract.c.orig	2008-02-04 09:18:27.000000000 -0200
+++ extract.c	2008-02-04 09:19:21.000000000 -0200
@@ -8,6 +8,11 @@
  * Basic structure of firmware data: <len:2><off:2><data:len>, where
  * the $data of size $len is to be put at position $off in the device.
  *
+ * Changelog:
+ *   Feb 4, 2008 - Lucas C. Villa Real <lucasvr@gobolinux.org>
+ *   - Added routine to find offset when a new, unsupported firmware is
+ *     released.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -35,6 +40,47 @@
 #include <usb.h>
 #define TIMEOUT 300
 
+static long 
+find_offset (char *filename)
+{
+	int fd, len;
+	long i, eof;
+	unsigned char data[4], rdata[1024];
+	if ((fd = open(filename, O_RDONLY)) == -1) {
+		perror ("Opening file");
+		return -1;
+	}
+
+	/* check how many bytes we have in the file */
+	eof = (off_t) lseek(fd, 0, SEEK_END);
+
+	for (i=0; i < eof; ++i) {
+		lseek(fd, i, SEEK_SET);
+		while (1) {
+			if ((len = read (fd, data, 4)) != 4) {
+				fprintf(stderr, "Error reading %s: %s\n", filename, strerror(errno));
+				close(fd);
+				return -1;
+			}
+			len = (data[0] << 8) | data[1];
+			if (len == 0x8001) {
+				close(fd);
+				return i;
+			} else if (len == 0) {
+				continue;
+			} else if (len < 0 || len >= 1024) {
+				/* invalid data_length, search again starting at another offset */
+				break;
+			} else if (read (fd, rdata, len) != len) {
+				perror ("Error reading firmware data");
+				break;
+			}
+		}
+	}
+	close(fd);
+	return -1;
+}
+
 static int
 read_fw (struct usb_dev_handle *dev, char *filename, long off)
 {
@@ -154,6 +200,7 @@ int
 main (int argc, char *argv[])
 {
 	int n, found = 0, res, err = 0;
+	long off = -1;
 	char command[1024];
 	struct usb_bus *bus;
 	struct usb_device *dev;
@@ -165,8 +212,9 @@ main (int argc, char *argv[])
 		{ "a14c159b176d27a6e98dcb5dea5d78b81e15ad41", 9176 /* 0x23D8 */ },
 		{ "c6c94dd77b864f8bd231abf3cb2de4c9d139e1bf", 0x1434 },
 		{ "01e291d529e7c18deea2eba252d18114e096276e", 0x2060 },
+		{ "1c60ef27d57221cf3d76687a4973ec72ff6fa103", 0x20d8 },
 		{ NULL }
-	}, *offset;
+	};
 
 	if (argc != 2) {
 		fprintf(stderr, "Usage: %s <firmware file>\n", argv[0]);
@@ -184,14 +232,19 @@ main (int argc, char *argv[])
 		snprintf (command, sizeof (command) - 1,
 			  "test \"x`sha1sum %s`\" == \"x%s  %s\" &> /dev/null",
 			  argv[1], offsets[n].sha1sum, argv[1]);
-		if (system (command) == 0)
+		if (system (command) == 0) {
+			off = offsets[n].off;
 			break;
+		}
 	}
 	if (offsets[n].sha1sum == NULL) {
-		fprintf (stderr, "Sha1sum check on firmware file failed\n");
-		return -1;
+		off = find_offset(argv[1]);
+		if (off == -1) {
+			fprintf (stderr, "Sha1sum check on firmware file failed\n");
+			return -1;
+		}
+		fprintf (stderr, "Firmware found at offset %#lx after linear search\n", off);
 	}
-	offset = &offsets[n];
 
 	/* init usb */
 	usb_init ();
@@ -208,7 +261,7 @@ main (int argc, char *argv[])
 		if (bus->devices != NULL) {
 			for (dev = bus->devices; dev != NULL;
 			     dev = dev->next) {
-				res += probe_dev (dev, argv[1], offset->off);
+				res += probe_dev (dev, argv[1], off);
 				if (res == -1)
 					err++;
 				else
