<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -37,8 +37,8 @@ install-win:	ipsw-patch/pch xpwn/xpwn
 	cp xpwn/ramdisk.dmg xpwn-build/ramdisk.dmg
 	cp -R ipsw-patch/FirmwareBundles xpwn-build/FirmwareBundles
 	cp -R ipsw-patch/bundles xpwn-build/bundles
-	cp README.markdown xpwn-build/README.txt
-	cp LICENSE xpwn-build/LICENSE.txt
+	sed &quot;`echo s/$$/\\\r`/&quot; README.markdown &gt; xpwn-build/README.txt
+	sed &quot;`echo s/$$/\\\r`/&quot; LICENSE &gt; xpwn-build/LICENSE.txt
 	cd xpwn-build; zip -r ../xpwn-windows.zip * 
 
 clean:
@@ -73,3 +73,4 @@ dist-clean:	clean
 	-rm dmg/zlib-1.2.3/contrib/minizip/*.o
 	-rm ipsw-patch/bzip2-1.0.5/*.exe
 	-rm -rf xpwn-build
+</diff>
      <filename>Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,29 +1,29 @@
-UTILOBJS=hdutil.o
-DMGOBJS=../dmg/base64.o ../dmg/resources.o ../dmg/checksum.o ../dmg/udif.o ../dmg/partition.o ../dmg/io.o ../dmg/filevault.o ../dmg/dmgfile.o ../dmg/zlib-1.2.3/libz.a ../dmg/openssl-0.9.8g/libcrypto.a
-HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o ../hfs/fastunicodecompare.o ../hfs/abstractfile.o ../hfs/hfslib.o
-CFLAGS=-D_FILE_OFFSET_BITS=64 -DHAVE_CRYPT
-LIBRARIES=`if $(CC) win32test.c -o /dev/null 2&gt;/dev/null ; then echo &quot;&quot;; else echo &quot;-lgdi32&quot;; fi`
-
-all: util
-
-util: $(DMGOBJS) $(HFSOBJS) $(UTILOBJS)
-	$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(UTILOBJS) $(LIBRARIES) -o hdutil
-
-%.o:	%.c
-	$(CC) $(CFLAGS) -I../dmg/zlib-1.2.3 -I../dmg/openssl-0.9.8g/include -c $&lt; -o $@
-
-../dmg/zlib-1.2.3/Makefile:
-	cd ../dmg/zlib-1.2.3; ./configure
-
-../dmg/zlib-1.2.3/libz.a:	../dmg/zlib-1.2.3/Makefile
-	cd ../dmg/zlib-1.2.3; make
-
+UTILOBJS=hdutil.o
+DMGOBJS=../dmg/base64.o ../dmg/resources.o ../dmg/checksum.o ../dmg/udif.o ../dmg/partition.o ../dmg/io.o ../dmg/filevault.o ../dmg/dmgfile.o ../dmg/zlib-1.2.3/libz.a ../dmg/openssl-0.9.8g/libcrypto.a
+HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o ../hfs/fastunicodecompare.o ../hfs/abstractfile.o ../hfs/hfslib.o
+CFLAGS=-D_FILE_OFFSET_BITS=64 -DHAVE_CRYPT
+LIBRARIES=`if $(CC) win32test.c -o /dev/null 2&gt;/dev/null ; then echo &quot;&quot;; else echo &quot;-lgdi32&quot;; fi`
+
+all: util
+
+util: $(DMGOBJS) $(HFSOBJS) $(UTILOBJS)
+	$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(UTILOBJS) $(LIBRARIES) -o hdutil
+
+%.o:	%.c
+	$(CC) $(CFLAGS) -I../dmg/zlib-1.2.3 -I../dmg/openssl-0.9.8g/include -c $&lt; -o $@
+
+../dmg/zlib-1.2.3/Makefile:
+	cd ../dmg/zlib-1.2.3; ./configure
+
+../dmg/zlib-1.2.3/libz.a:	../dmg/zlib-1.2.3/Makefile
+	cd ../dmg/zlib-1.2.3; make
+
 ../dmg/openssl-0.9.8g/libcrypto.a:
-	touch ../dmg/openssl-0.9.8g/Makefile
-	cd ../dmg/openssl-0.9.8g/crypto; make
-
-
-clean:
-	-rm *.o
-	-rm hdutil
-	-rm hdutil.exe
+	touch ../dmg/openssl-0.9.8g/Makefile
+	cd ../dmg/openssl-0.9.8g/crypto; make
+
+
+clean:
+	-rm *.o
+	-rm hdutil
+	-rm hdutil.exe</diff>
      <filename>hdutil/Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,308 +1,308 @@
-#include &lt;stdlib.h&gt;
-#include &lt;stdio.h&gt;
-#include &lt;stdint.h&gt;
-#include &lt;time.h&gt;
-#include &lt;string.h&gt;
-#include &lt;unistd.h&gt;
-#include &quot;../hfs/hfsplus.h&quot;
-#include &quot;../dmg/dmgfile.h&quot;
-#include &quot;../dmg/filevault.h&quot;
-#include &lt;sys/types.h&gt;
-#include &lt;sys/stat.h&gt;
-#include &lt;dirent.h&gt;
-
-char endianness;
-
-void cmd_ls(Volume* volume, int argc, const char *argv[]) {
-	HFSPlusCatalogRecord* record;
-	char* name;
-	
-	if(argc &gt; 1)
-		hfs_ls(volume, argv[1]);
-	else
-		hfs_ls(volume, &quot;/&quot;);}
-
-void cmd_cat(Volume* volume, int argc, const char *argv[]) {
-	HFSPlusCatalogRecord* record;
+#include &lt;stdlib.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;stdint.h&gt;
+#include &lt;time.h&gt;
+#include &lt;string.h&gt;
+#include &lt;unistd.h&gt;
+#include &quot;../hfs/hfsplus.h&quot;
+#include &quot;../dmg/dmgfile.h&quot;
+#include &quot;../dmg/filevault.h&quot;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;dirent.h&gt;
+
+char endianness;
+
+void cmd_ls(Volume* volume, int argc, const char *argv[]) {
+	HFSPlusCatalogRecord* record;
+	char* name;
+	
+	if(argc &gt; 1)
+		hfs_ls(volume, argv[1]);
+	else
+		hfs_ls(volume, &quot;/&quot;);}
+
+void cmd_cat(Volume* volume, int argc, const char *argv[]) {
+	HFSPlusCatalogRecord* record;
 	AbstractFile* stdoutFile;
-
-	record = getRecordFromPath(argv[1], volume, NULL, NULL);
+
+	record = getRecordFromPath(argv[1], volume, NULL, NULL);
 
 	stdoutFile = createAbstractFileFromFile(stdout);
-	
-	if(record != NULL) {
-		if(record-&gt;recordType == kHFSPlusFileRecord)
-			writeToFile((HFSPlusCatalogFile*)record, stdoutFile, volume);
-		else
-			printf(&quot;Not a file\n&quot;);
-	} else {
-		printf(&quot;No such file or directory\n&quot;);
-	}
-	
+	
+	if(record != NULL) {
+		if(record-&gt;recordType == kHFSPlusFileRecord)
+			writeToFile((HFSPlusCatalogFile*)record, stdoutFile, volume);
+		else
+			printf(&quot;Not a file\n&quot;);
+	} else {
+		printf(&quot;No such file or directory\n&quot;);
+	}
+	
+	free(record);
+	free(stdoutFile);
+}
+
+void cmd_extract(Volume* volume, int argc, const char *argv[]) {
+	HFSPlusCatalogRecord* record;
+	AbstractFile *outFile;
+	
+	if(argc &lt; 3) {
+		printf(&quot;Not enough arguments&quot;);
+		return;
+	}
+	
+	outFile = createAbstractFileFromFile(fopen(argv[2], &quot;wb&quot;));
+	
+	if(outFile == NULL) {
+		printf(&quot;cannot create file&quot;);
+	}
+	
+	record = getRecordFromPath(argv[1], volume, NULL, NULL);
+	
+	if(record != NULL) {
+		if(record-&gt;recordType == kHFSPlusFileRecord)
+			writeToFile((HFSPlusCatalogFile*)record, outFile, volume);
+		else
+			printf(&quot;Not a file\n&quot;);
+	} else {
+		printf(&quot;No such file or directory\n&quot;);
+	}
+	
+	outFile-&gt;close(outFile);
 	free(record);
-	free(stdoutFile);
-}
-
-void cmd_extract(Volume* volume, int argc, const char *argv[]) {
-	HFSPlusCatalogRecord* record;
-	AbstractFile *outFile;
-	
-	if(argc &lt; 3) {
-		printf(&quot;Not enough arguments&quot;);
-		return;
-	}
-	
-	outFile = createAbstractFileFromFile(fopen(argv[2], &quot;wb&quot;));
-	
-	if(outFile == NULL) {
-		printf(&quot;cannot create file&quot;);
-	}
-	
-	record = getRecordFromPath(argv[1], volume, NULL, NULL);
-	
-	if(record != NULL) {
-		if(record-&gt;recordType == kHFSPlusFileRecord)
-			writeToFile((HFSPlusCatalogFile*)record, outFile, volume);
-		else
-			printf(&quot;Not a file\n&quot;);
-	} else {
-		printf(&quot;No such file or directory\n&quot;);
-	}
-	
-	outFile-&gt;close(outFile);
-	free(record);
-}
-
-void cmd_mv(Volume* volume, int argc, const char *argv[]) {
-	if(argc &gt; 2) {
-		move(argv[1], argv[2], volume);
-	} else {
-		printf(&quot;Not enough arguments&quot;);
-	}
 }
 
-void cmd_symlink(Volume* volume, int argc, const char *argv[]) {
-	if(argc &gt; 2) {
-		makeSymlink(argv[1], argv[2], volume);
-	} else {
-		printf(&quot;Not enough arguments&quot;);
-	}
-}
-
-void cmd_mkdir(Volume* volume, int argc, const char *argv[]) {
-	if(argc &gt; 1) {
-		newFolder(argv[1], volume);
-	} else {
-		printf(&quot;Not enough arguments&quot;);
-	}
-}
-
-void cmd_add(Volume* volume, int argc, const char *argv[]) {
-	AbstractFile *inFile;
-	
-	if(argc &lt; 3) {
-		printf(&quot;Not enough arguments&quot;);
-		return;
-	}
-	
-	inFile = createAbstractFileFromFile(fopen(argv[1], &quot;rb&quot;));
-	
-	if(inFile == NULL) {
-		printf(&quot;file to add not found&quot;);
+void cmd_mv(Volume* volume, int argc, const char *argv[]) {
+	if(argc &gt; 2) {
+		move(argv[1], argv[2], volume);
+	} else {
+		printf(&quot;Not enough arguments&quot;);
+	}
+}
+
+void cmd_symlink(Volume* volume, int argc, const char *argv[]) {
+	if(argc &gt; 2) {
+		makeSymlink(argv[1], argv[2], volume);
+	} else {
+		printf(&quot;Not enough arguments&quot;);
+	}
+}
+
+void cmd_mkdir(Volume* volume, int argc, const char *argv[]) {
+	if(argc &gt; 1) {
+		newFolder(argv[1], volume);
+	} else {
+		printf(&quot;Not enough arguments&quot;);
+	}
+}
+
+void cmd_add(Volume* volume, int argc, const char *argv[]) {
+	AbstractFile *inFile;
+	
+	if(argc &lt; 3) {
+		printf(&quot;Not enough arguments&quot;);
+		return;
+	}
+	
+	inFile = createAbstractFileFromFile(fopen(argv[1], &quot;rb&quot;));
+	
+	if(inFile == NULL) {
+		printf(&quot;file to add not found&quot;);
 	}
 
-	add_hfs(volume, inFile, argv[2]);
-}
-
-void cmd_rm(Volume* volume, int argc, const char *argv[]) {
-	if(argc &gt; 1) {
-		removeFile(argv[1], volume);
-	} else {
-		printf(&quot;Not enough arguments&quot;);
-	}
-}
-
-void cmd_chmod(Volume* volume, int argc, const char *argv[]) {
-	int mode;
-	
-	if(argc &gt; 2) {
-		sscanf(argv[1], &quot;%o&quot;, &amp;mode);
-		chmodFile(argv[2], mode, volume);
-	} else {
-		printf(&quot;Not enough arguments&quot;);
-	}
-}
-
-void cmd_extractall(Volume* volume, int argc, const char *argv[]) {
-	HFSPlusCatalogRecord* record;
-	char cwd[1024];
-	char* name;
-	
-	ASSERT(getcwd(cwd, 1024) != NULL, &quot;cannot get current working directory&quot;);
-	
-	if(argc &gt; 1)
-		record = getRecordFromPath(argv[1], volume, &amp;name, NULL);
-	else
-		record = getRecordFromPath(&quot;/&quot;, volume, &amp;name, NULL);
-	
-	if(argc &gt; 2) {
-		ASSERT(chdir(argv[2]) == 0, &quot;chdir&quot;);
-	}
-
-	if(record != NULL) {
-		if(record-&gt;recordType == kHFSPlusFolderRecord)
-			extractAllInFolder(((HFSPlusCatalogFolder*)record)-&gt;folderID, volume);  
-		else
-			printf(&quot;Not a folder\n&quot;);
-	} else {
-		printf(&quot;No such file or directory\n&quot;);
-	}
-	free(record);
-	
-	ASSERT(chdir(cwd) == 0, &quot;chdir&quot;);
-}
-
-
-void cmd_rmall(Volume* volume, int argc, const char *argv[]) {
-	HFSPlusCatalogRecord* record;
-	char* name;
-	char initPath[1024];
-	int lastCharOfPath;
-	
-	if(argc &gt; 1) {
-		record = getRecordFromPath(argv[1], volume, &amp;name, NULL);
-		strcpy(initPath, argv[1]);
-		lastCharOfPath = strlen(argv[1]) - 1;
-		if(argv[1][lastCharOfPath] != '/') {
-			initPath[lastCharOfPath + 1] = '/';
-			initPath[lastCharOfPath + 2] = '\0';
-		}
-	} else {
-		record = getRecordFromPath(&quot;/&quot;, volume, &amp;name, NULL);
-		initPath[0] = '/';
-		initPath[1] = '\0';	
-	}
-	
-	if(record != NULL) {
-		if(record-&gt;recordType == kHFSPlusFolderRecord) {
-			removeAllInFolder(((HFSPlusCatalogFolder*)record)-&gt;folderID, volume, initPath);
-		} else {
-			printf(&quot;Not a folder\n&quot;);
-		}
-	} else {
-		printf(&quot;No such file or directory\n&quot;);
-	}
-	free(record);
-}
-
-void cmd_addall(Volume* volume, int argc, const char *argv[]) {   
-	if(argc &lt; 2) {
-		printf(&quot;Not enough arguments&quot;);
-		return;
+	add_hfs(volume, inFile, argv[2]);
+}
+
+void cmd_rm(Volume* volume, int argc, const char *argv[]) {
+	if(argc &gt; 1) {
+		removeFile(argv[1], volume);
+	} else {
+		printf(&quot;Not enough arguments&quot;);
 	}
+}
 
-	if(argc &gt; 2) {
-		addall_hfs(volume, argv[1], argv[2]);
-	} else {
-		addall_hfs(volume, argv[1], &quot;/&quot;);
-	}
-}
-
-void cmd_grow(Volume* volume, int argc, const char *argv[]) {
-	uint64_t newSize;
-
-	if(argc &lt; 2) {
-		printf(&quot;Not enough arguments\n&quot;);
-		return;
-	}
-	
-	newSize = 0;
+void cmd_chmod(Volume* volume, int argc, const char *argv[]) {
+	int mode;
+	
+	if(argc &gt; 2) {
+		sscanf(argv[1], &quot;%o&quot;, &amp;mode);
+		chmodFile(argv[2], mode, volume);
+	} else {
+		printf(&quot;Not enough arguments&quot;);
+	}
+}
+
+void cmd_extractall(Volume* volume, int argc, const char *argv[]) {
+	HFSPlusCatalogRecord* record;
+	char cwd[1024];
+	char* name;
+	
+	ASSERT(getcwd(cwd, 1024) != NULL, &quot;cannot get current working directory&quot;);
+	
+	if(argc &gt; 1)
+		record = getRecordFromPath(argv[1], volume, &amp;name, NULL);
+	else
+		record = getRecordFromPath(&quot;/&quot;, volume, &amp;name, NULL);
+	
+	if(argc &gt; 2) {
+		ASSERT(chdir(argv[2]) == 0, &quot;chdir&quot;);
+	}
+
+	if(record != NULL) {
+		if(record-&gt;recordType == kHFSPlusFolderRecord)
+			extractAllInFolder(((HFSPlusCatalogFolder*)record)-&gt;folderID, volume);  
+		else
+			printf(&quot;Not a folder\n&quot;);
+	} else {
+		printf(&quot;No such file or directory\n&quot;);
+	}
+	free(record);
+	
+	ASSERT(chdir(cwd) == 0, &quot;chdir&quot;);
+}
+
+
+void cmd_rmall(Volume* volume, int argc, const char *argv[]) {
+	HFSPlusCatalogRecord* record;
+	char* name;
+	char initPath[1024];
+	int lastCharOfPath;
+	
+	if(argc &gt; 1) {
+		record = getRecordFromPath(argv[1], volume, &amp;name, NULL);
+		strcpy(initPath, argv[1]);
+		lastCharOfPath = strlen(argv[1]) - 1;
+		if(argv[1][lastCharOfPath] != '/') {
+			initPath[lastCharOfPath + 1] = '/';
+			initPath[lastCharOfPath + 2] = '\0';
+		}
+	} else {
+		record = getRecordFromPath(&quot;/&quot;, volume, &amp;name, NULL);
+		initPath[0] = '/';
+		initPath[1] = '\0';	
+	}
+	
+	if(record != NULL) {
+		if(record-&gt;recordType == kHFSPlusFolderRecord) {
+			removeAllInFolder(((HFSPlusCatalogFolder*)record)-&gt;folderID, volume, initPath);
+		} else {
+			printf(&quot;Not a folder\n&quot;);
+		}
+	} else {
+		printf(&quot;No such file or directory\n&quot;);
+	}
+	free(record);
+}
+
+void cmd_addall(Volume* volume, int argc, const char *argv[]) {   
+	if(argc &lt; 2) {
+		printf(&quot;Not enough arguments&quot;);
+		return;
+	}
+
+	if(argc &gt; 2) {
+		addall_hfs(volume, argv[1], argv[2]);
+	} else {
+		addall_hfs(volume, argv[1], &quot;/&quot;);
+	}
+}
+
+void cmd_grow(Volume* volume, int argc, const char *argv[]) {
+	uint64_t newSize;
+
+	if(argc &lt; 2) {
+		printf(&quot;Not enough arguments\n&quot;);
+		return;
+	}
+	
+	newSize = 0;
 	sscanf(argv[1], &quot;%lld&quot;, &amp;newSize);
 
 	grow_hfs(volume, newSize);
 
-	printf(&quot;grew volume: %lld\n&quot;, newSize);
+	printf(&quot;grew volume: %lld\n&quot;, newSize);
 }
 
-void TestByteOrder()
-{
-	short int word = 0x0001;
-	char *byte = (char *) &amp;word;
-	endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
+void TestByteOrder()
+{
+	short int word = 0x0001;
+	char *byte = (char *) &amp;word;
+	endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
 }
-
-int main(int argc, const char *argv[]) {
-	io_func* io;
-	Volume* volume;
-	AbstractFile* image;
-	int argOff;
-	
-	TestByteOrder();
-	
-	if(argc &lt; 3) {
-		printf(&quot;usage: %s &lt;image-file&gt; (-k &lt;key&gt;) &lt;ls|cat|mv|mkdir|add|rm|chmod|extract|extractall|rmall|addall&gt; &lt;arguments&gt;\n&quot;, argv[0]);
-		return 0;
-	}
-
-	argOff = 2;
-	
-	if(strstr(argv[1], &quot;.dmg&quot;)) {
-		image = createAbstractFileFromFile(fopen(argv[1], &quot;rb&quot;));
-		if(argc &gt; 3) {
-			if(strcmp(argv[2], &quot;-k&quot;) == 0) {
-				image = createAbstractFileFromFileVault(image, argv[3]);
-				argOff = 4;
-			}
-		}
-		io = openDmgFilePartition(image, -1);
-	} else {
-		io = openFlatFile(argv[1]);
-	}
-
-	if(io == NULL) {
-		fprintf(stderr, &quot;error: Cannot open image-file.\n&quot;);
-		return 1;
-	}
-	
-	volume = openVolume(io); 
-	if(volume == NULL) {
-		fprintf(stderr, &quot;error: Cannot open volume.\n&quot;);
-		CLOSE(io);
-		return 1;
-	}
-	
-	if(argc &gt; argOff) {
-		if(strcmp(argv[argOff], &quot;ls&quot;) == 0) {
-			cmd_ls(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;cat&quot;) == 0) {
-			cmd_cat(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;mv&quot;) == 0) {
+
+int main(int argc, const char *argv[]) {
+	io_func* io;
+	Volume* volume;
+	AbstractFile* image;
+	int argOff;
+	
+	TestByteOrder();
+	
+	if(argc &lt; 3) {
+		printf(&quot;usage: %s &lt;image-file&gt; (-k &lt;key&gt;) &lt;ls|cat|mv|mkdir|add|rm|chmod|extract|extractall|rmall|addall&gt; &lt;arguments&gt;\n&quot;, argv[0]);
+		return 0;
+	}
+
+	argOff = 2;
+	
+	if(strstr(argv[1], &quot;.dmg&quot;)) {
+		image = createAbstractFileFromFile(fopen(argv[1], &quot;rb&quot;));
+		if(argc &gt; 3) {
+			if(strcmp(argv[2], &quot;-k&quot;) == 0) {
+				image = createAbstractFileFromFileVault(image, argv[3]);
+				argOff = 4;
+			}
+		}
+		io = openDmgFilePartition(image, -1);
+	} else {
+		io = openFlatFile(argv[1]);
+	}
+
+	if(io == NULL) {
+		fprintf(stderr, &quot;error: Cannot open image-file.\n&quot;);
+		return 1;
+	}
+	
+	volume = openVolume(io); 
+	if(volume == NULL) {
+		fprintf(stderr, &quot;error: Cannot open volume.\n&quot;);
+		CLOSE(io);
+		return 1;
+	}
+	
+	if(argc &gt; argOff) {
+		if(strcmp(argv[argOff], &quot;ls&quot;) == 0) {
+			cmd_ls(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;cat&quot;) == 0) {
+			cmd_cat(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;mv&quot;) == 0) {
 			cmd_mv(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[2], &quot;symlink&quot;) == 0) {
-			cmd_symlink(volume, argc - 2, argv + 2);
-		} else if(strcmp(argv[argOff], &quot;mkdir&quot;) == 0) {
-			cmd_mkdir(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;add&quot;) == 0) {
-			cmd_add(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;rm&quot;) == 0) {
-			cmd_rm(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;chmod&quot;) == 0) {
-			cmd_chmod(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;extract&quot;) == 0) {
-			cmd_extract(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;extractall&quot;) == 0) {
-			cmd_extractall(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;rmall&quot;) == 0) {
-			cmd_rmall(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;addall&quot;) == 0) {
-			cmd_addall(volume, argc - argOff, argv + argOff);
-		} else if(strcmp(argv[argOff], &quot;grow&quot;) == 0) {
-			cmd_grow(volume, argc - argOff, argv + argOff);
-		}
-	}
-	
-	closeVolume(volume);
-	CLOSE(io);
-	
-	return 0;
-}
+		} else if(strcmp(argv[2], &quot;symlink&quot;) == 0) {
+			cmd_symlink(volume, argc - 2, argv + 2);
+		} else if(strcmp(argv[argOff], &quot;mkdir&quot;) == 0) {
+			cmd_mkdir(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;add&quot;) == 0) {
+			cmd_add(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;rm&quot;) == 0) {
+			cmd_rm(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;chmod&quot;) == 0) {
+			cmd_chmod(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;extract&quot;) == 0) {
+			cmd_extract(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;extractall&quot;) == 0) {
+			cmd_extractall(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;rmall&quot;) == 0) {
+			cmd_rmall(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;addall&quot;) == 0) {
+			cmd_addall(volume, argc - argOff, argv + argOff);
+		} else if(strcmp(argv[argOff], &quot;grow&quot;) == 0) {
+			cmd_grow(volume, argc - argOff, argv + argOff);
+		}
+	}
+	
+	closeVolume(volume);
+	CLOSE(io);
+	
+	return 0;
+}</diff>
      <filename>hdutil/hdutil.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
-#include &lt;stdlib.h&gt;
-
-#ifdef WIN32
-blahfs-o_f-0-(){ {}A
-#else
-int main(int argc, char* argv[]) {
-  return 0;
-}
-#endif
+#include &lt;stdlib.h&gt;
+
+#ifdef WIN32
+blahfs-o_f-0-(){ {}A
+#else
+int main(int argc, char* argv[]) {
+  return 0;
+}
+#endif</diff>
      <filename>hdutil/win32test.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
-all:
-	cd ../../; make
-
-clean:
-	cd ../../; make clean
+all:
+	cd ../../; make
+
+clean:
+	cd ../../; make clean</diff>
      <filename>ide/eclipse/Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,47 +1,47 @@
-#include &lt;stdint.h&gt;
-#include &lt;openssl/aes.h&gt;
-#include &quot;abstractfile.h&quot;
-
-#ifndef INC_8900_H
-#define INC_8900_H
-
-typedef struct {
-	uint32_t        magic;              /* string &quot;8900&quot; */
-	unsigned char  version[3];            /* string &quot;1.0&quot; */
-	uint8_t         format;                /* plaintext format is 0x4, encrypted format is 0x3 */
-	uint32_t        unknown1;
-	uint32_t        sizeOfData;            /* size of data (ie, filesize - header(0x800) - footer signature(0x80) - footer certificate(0xC0A)) */
-	uint32_t        footerSignatureOffset; /* offset to footer signature */
-	uint32_t        footerCertOffset;      /* offset to footer certificate, from end of header (0x800) */
-	uint32_t        footerCertLen;
-	unsigned char  salt[0x20];            /* a seemingly random salt (an awfully big one though... needs more attention) */
-	uint16_t        unknown2;
-	uint16_t        epoch;                 /* the security epoch of the file */
-	unsigned char  headerSignature[0x10]; /* encrypt(sha1(header[0:0x40])[0:0x10], key_0x837, zero_iv) */
-	unsigned char  padding[0x7B0];
-} __attribute__((__packed__)) Apple8900Header;
-
-#define SIGNATURE_8900 0x38393030
-
-static uint8_t key_0x837[] = {0x18, 0x84, 0x58, 0xA6, 0xD1, 0x50, 0x34, 0xDF, 0xE3, 0x86, 0xF2, 0x3B, 0x61, 0xD4, 0x37, 0x74};
-
-typedef struct Info8900 {
-	AbstractFile*		file;
-	
-	Apple8900Header header;
-	size_t          offset;
-	void*           buffer;
-
-	unsigned char	footerSignature[0x80];
-	unsigned char*	footerCertificate;
-	
-	AES_KEY         encryptKey;
-	AES_KEY         decryptKey;
-	
-	char            dirty;
-} Info8900;
-
-AbstractFile* createAbstractFileFrom8900(AbstractFile* file);
-AbstractFile* duplicate8900File(AbstractFile* file, AbstractFile* backing);
-
-#endif
+#include &lt;stdint.h&gt;
+#include &lt;openssl/aes.h&gt;
+#include &quot;abstractfile.h&quot;
+
+#ifndef INC_8900_H
+#define INC_8900_H
+
+typedef struct {
+	uint32_t        magic;              /* string &quot;8900&quot; */
+	unsigned char  version[3];            /* string &quot;1.0&quot; */
+	uint8_t         format;                /* plaintext format is 0x4, encrypted format is 0x3 */
+	uint32_t        unknown1;
+	uint32_t        sizeOfData;            /* size of data (ie, filesize - header(0x800) - footer signature(0x80) - footer certificate(0xC0A)) */
+	uint32_t        footerSignatureOffset; /* offset to footer signature */
+	uint32_t        footerCertOffset;      /* offset to footer certificate, from end of header (0x800) */
+	uint32_t        footerCertLen;
+	unsigned char  salt[0x20];            /* a seemingly random salt (an awfully big one though... needs more attention) */
+	uint16_t        unknown2;
+	uint16_t        epoch;                 /* the security epoch of the file */
+	unsigned char  headerSignature[0x10]; /* encrypt(sha1(header[0:0x40])[0:0x10], key_0x837, zero_iv) */
+	unsigned char  padding[0x7B0];
+} __attribute__((__packed__)) Apple8900Header;
+
+#define SIGNATURE_8900 0x38393030
+
+static uint8_t key_0x837[] = {0x18, 0x84, 0x58, 0xA6, 0xD1, 0x50, 0x34, 0xDF, 0xE3, 0x86, 0xF2, 0x3B, 0x61, 0xD4, 0x37, 0x74};
+
+typedef struct Info8900 {
+	AbstractFile*		file;
+	
+	Apple8900Header header;
+	size_t          offset;
+	void*           buffer;
+
+	unsigned char	footerSignature[0x80];
+	unsigned char*	footerCertificate;
+	
+	AES_KEY         encryptKey;
+	AES_KEY         decryptKey;
+	
+	char            dirty;
+} Info8900;
+
+AbstractFile* createAbstractFileFrom8900(AbstractFile* file);
+AbstractFile* duplicate8900File(AbstractFile* file, AbstractFile* backing);
+
+#endif</diff>
      <filename>ipsw-patch/8900.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,44 +1,44 @@
-RANLIB ?= ranlib
-PCHOBJS=patch.o 
-XPWNOBJS=plist.o pwnutil.o outputstate.o nor_files.o 8900.o img2.o bspatch.o ibootim.o lzss.o lzssfile.o ../dmg/zlib-1.2.3/contrib/minizip/ioapi.o ../dmg/zlib-1.2.3/contrib/minizip/unzip.o ../dmg/zlib-1.2.3/contrib/minizip/zip.o
-DMGOBJS=../dmg/base64.o ../dmg/resources.o ../dmg/checksum.o ../dmg/udif.o ../dmg/partition.o ../dmg/io.o ../dmg/filevault.o ../dmg/dmgfile.o ../dmg/dmglib.o
-HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o ../hfs/fastunicodecompare.o ../hfs/abstractfile.o ../hfs/hfslib.o
+RANLIB ?= ranlib
+PCHOBJS=patch.o 
+XPWNOBJS=plist.o pwnutil.o outputstate.o nor_files.o 8900.o img2.o bspatch.o ibootim.o lzss.o lzssfile.o ../dmg/zlib-1.2.3/contrib/minizip/ioapi.o ../dmg/zlib-1.2.3/contrib/minizip/unzip.o ../dmg/zlib-1.2.3/contrib/minizip/zip.o
+DMGOBJS=../dmg/base64.o ../dmg/resources.o ../dmg/checksum.o ../dmg/udif.o ../dmg/partition.o ../dmg/io.o ../dmg/filevault.o ../dmg/dmgfile.o ../dmg/dmglib.o
+HFSOBJS=../hfs/volume.o ../hfs/btree.o ../hfs/extents.o ../hfs/rawfile.o ../hfs/catalog.o ../hfs/flatfile.o ../hfs/utility.o ../hfs/fastunicodecompare.o ../hfs/abstractfile.o ../hfs/hfslib.o
 CFLAGS=-D_FILE_OFFSET_BITS=64 -DHAVE_CRYPT -O3
-STATIC_LIBRARIES=../dmg/zlib-1.2.3/libz.a ../dmg/openssl-0.9.8g/libcrypto.a ../dmg/openssl-0.9.8g/libcrypto.a bzip2-1.0.5/libbz2.a libpng-1.2.28/libpng.a
-LIBRARIES=`if $(CC) win32test.c -o /dev/null 2&gt;/dev/null ; then echo &quot;&quot;; else echo &quot;-lgdi32&quot;; fi` -lm
+STATIC_LIBRARIES=../dmg/zlib-1.2.3/libz.a ../dmg/openssl-0.9.8g/libcrypto.a ../dmg/openssl-0.9.8g/libcrypto.a bzip2-1.0.5/libbz2.a libpng-1.2.28/libpng.a
+LIBRARIES=`if $(CC) win32test.c -o /dev/null 2&gt;/dev/null ; then echo &quot;&quot;; else echo &quot;-lgdi32&quot;; fi` -lm
 INCLUDES=-I../hfs -I../dmg -Ilibpng-1.2.28 -I../dmg/zlib-1.2.3 -I../dmg/openssl-0.9.8g/include -Ibzip2-1.0.5
-
-all: pch
-
-pch: $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(PCHOBJS) $(STATIC_LIBRARIES)
-	$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(PCHOBJS) $(STATIC_LIBRARIES) $(LIBRARIES) -o pch
-
-libxpwn.a: libxpwn.o $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(STATIC_LIBRARIES)
+
+all: pch
+
+pch: $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(PCHOBJS) $(STATIC_LIBRARIES)
+	$(CC) $(CFLAGS) $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(PCHOBJS) $(STATIC_LIBRARIES) $(LIBRARIES) -o pch
+
+libxpwn.a: libxpwn.o $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(STATIC_LIBRARIES)
 	$(LD) libxpwn.o $(DMGOBJS) $(HFSOBJS) $(XPWNOBJS) $(STATIC_LIBRARIES) -r -o libxpwnbuild.o
 	ar rc libxpwn.a libxpwnbuild.o
-	ranlib libxpwn.a
-
-%.o:	%.c
-	$(CC) $(CFLAGS) $(INCLUDES) -c $&lt; -o $@
-
-../dmg/zlib-1.2.3/Makefile:
-	cd ../dmg/zlib-1.2.3; ./configure
-
-../dmg/zlib-1.2.3/libz.a:	../dmg/zlib-1.2.3/Makefile
-	cd ../dmg/zlib-1.2.3; make
-
-../dmg/openssl-0.9.8g/libcrypto.a:
-	touch ../dmg/openssl-0.9.8g/Makefile
-	cd ../dmg/openssl-0.9.8g/crypto; make
-
-bzip2-1.0.5/libbz2.a:
-	cd bzip2-1.0.5; make
-
-libpng-1.2.28/libpng.a:
-	cd libpng-1.2.28; make
-
-clean:
-	-rm *.o
-	-rm pch
-	-rm pch.exe
-	-rm libxpwn.a
+	ranlib libxpwn.a
+
+%.o:	%.c
+	$(CC) $(CFLAGS) $(INCLUDES) -c $&lt; -o $@
+
+../dmg/zlib-1.2.3/Makefile:
+	cd ../dmg/zlib-1.2.3; ./configure
+
+../dmg/zlib-1.2.3/libz.a:	../dmg/zlib-1.2.3/Makefile
+	cd ../dmg/zlib-1.2.3; make
+
+../dmg/openssl-0.9.8g/libcrypto.a:
+	touch ../dmg/openssl-0.9.8g/Makefile
+	cd ../dmg/openssl-0.9.8g/crypto; make
+
+bzip2-1.0.5/libbz2.a:
+	cd bzip2-1.0.5; make
+
+libpng-1.2.28/libpng.a:
+	cd libpng-1.2.28; make
+
+clean:
+	-rm *.o
+	-rm pch
+	-rm pch.exe
+	-rm libxpwn.a</diff>
      <filename>ipsw-patch/Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,218 +1,218 @@
-#include &lt;stdlib.h&gt;
+#include &lt;stdlib.h&gt;
 #include &lt;stdio.h&gt;
-#include &lt;string.h&gt;
-#include &lt;bzlib.h&gt;
-#include &quot;abstractfile.h&quot;
-
-static off_t offtin(unsigned char *buf)
-{
-	off_t y;
-
-	y = buf[7] &amp; 0x7F;
-	y &lt;&lt;= 8; y += buf[6];
-	y &lt;&lt;= 8; y += buf[5];
-	y &lt;&lt;= 8; y += buf[4];
-	y &lt;&lt;= 8; y += buf[3];
-	y &lt;&lt;= 8; y += buf[2];
-	y &lt;&lt;= 8; y += buf[1];
-	y &lt;&lt;= 8; y += buf[0];
-	
-	if(buf[7] &amp; 0x80) y = -y;
-	
-	return y;
-}
-
-typedef struct {
-	bz_stream bz2;
-	AbstractFile* file;
-	off_t offset;
-	unsigned char* inBuffer;
-	unsigned char* outBuffer;
-	size_t bufferLen;
-	char ended;
-} BZStream;
-
-size_t bzRead(int *bzerr, BZStream* stream, unsigned char* out, size_t len) {
-	size_t toRead;
-	size_t haveRead;
-	size_t total;
-	
-	total = len;
-	
-	*bzerr = BZ_OK;
-	
-	while(total &gt; 0) {
-		if(!stream-&gt;ended) {
-			memmove(stream-&gt;inBuffer, stream-&gt;bz2.next_in, stream-&gt;bz2.avail_in);
-			stream-&gt;file-&gt;seek(stream-&gt;file, stream-&gt;offset);
-			haveRead = stream-&gt;file-&gt;read(stream-&gt;file, stream-&gt;inBuffer + stream-&gt;bz2.avail_in, stream-&gt;bufferLen - stream-&gt;bz2.avail_in);
-			stream-&gt;offset += haveRead;
-			stream-&gt;bz2.avail_in += haveRead;
-			stream-&gt;bz2.next_in = stream-&gt;inBuffer;
-			
-			*bzerr = BZ2_bzDecompress(&amp;(stream-&gt;bz2));
-			
-			if(*bzerr == BZ_STREAM_END) {
-				stream-&gt;ended = TRUE;
-			} else {
-				if(*bzerr != BZ_OK) {
-					return 0;
-				}
-			}
-		}
-		
-		if(total &gt; (stream-&gt;bufferLen - stream-&gt;bz2.avail_out)) {
-			toRead = stream-&gt;bufferLen - stream-&gt;bz2.avail_out;
-		} else {
-			toRead = total;
-		}
-		
-		memcpy(out, stream-&gt;outBuffer, toRead);
-		memmove(stream-&gt;outBuffer, stream-&gt;outBuffer + toRead, stream-&gt;bufferLen - toRead);
-		stream-&gt;bz2.next_out -= toRead;
-		stream-&gt;bz2.avail_out += toRead;
-		out += toRead;
-		total -= toRead;
-		
-		if(total &gt; 0 &amp;&amp; stream-&gt;ended) {
-			return (len - total);
-		}
-	}
-	
-	return len;
-}
-
-void closeBZStream(BZStream* stream) {
-	free(stream-&gt;inBuffer);
-	free(stream-&gt;outBuffer);
-	BZ2_bzDecompressEnd(&amp;(stream-&gt;bz2));
-	free(stream);
-}
-
-BZStream* openBZStream(AbstractFile* file, off_t offset, size_t bufferLen) {
-	BZStream* stream;
-	stream = (BZStream*) malloc(sizeof(BZStream));
-	stream-&gt;file = file;
-	stream-&gt;offset = offset;
-	stream-&gt;bufferLen = bufferLen;
-	stream-&gt;inBuffer = (unsigned char*) malloc(bufferLen);
-	stream-&gt;outBuffer = (unsigned char*) malloc(bufferLen);
-	memset(&amp;(stream-&gt;bz2), 0, sizeof(bz_stream));
-	BZ2_bzDecompressInit(&amp;(stream-&gt;bz2), 0, FALSE);
-	
-	stream-&gt;bz2.next_in = stream-&gt;inBuffer;
-	stream-&gt;bz2.avail_in = 0;
-	stream-&gt;bz2.next_out = stream-&gt;outBuffer;
-	stream-&gt;bz2.avail_out = bufferLen;
-
-	stream-&gt;ended = FALSE;
-	return stream;
-}
-
-int patch(AbstractFile* in, AbstractFile* out, AbstractFile* patch) {
-	unsigned char header[32], buf[8];
-	off_t oldsize, newsize;
-	off_t bzctrllen, bzdatalen;
-	off_t oldpos, newpos;
-	unsigned char *old, *newBuffer;
-	int i;
-	int cbz2err, dbz2err, ebz2err;
-	off_t ctrl[3];
-	size_t lenread;
-	
-	BZStream* cpfbz2;
-	BZStream* dpfbz2;
-	BZStream* epfbz2;
-	
-	/* Read header */
-	if (patch-&gt;read(patch, header, 32) &lt; 32) {
-		return -1;
-	}
-	
-	/* Check for appropriate magic */
-	if (memcmp(header, &quot;BSDIFF40&quot;, 8) != 0)
-		return -2;
-		
-	/* Read lengths from header */
-	bzctrllen = offtin(header + 8);
-	bzdatalen = offtin(header + 16);
-	newsize = offtin(header + 24);
-
-	if((bzctrllen &lt; 0) || (bzdatalen &lt; 0) || (newsize &lt; 0))
-		return -3;
-		
-	cpfbz2 = openBZStream(patch, 32, 1024);
-	dpfbz2 = openBZStream(patch, 32 + bzctrllen, 1024);
-	epfbz2 = openBZStream(patch, 32 + bzctrllen + bzdatalen, 1024);
-	
-	oldsize = in-&gt;getLength(in);
-	old = malloc(oldsize + 1);
-	in-&gt;seek(in, 0);
-	in-&gt;read(in, old, oldsize);
-	in-&gt;close(in);
-	
-	newBuffer = malloc(newsize + 1);
-	
-	oldpos = 0;
-	newpos = 0;
-	while(newpos &lt; newsize) {
-		/* Read control data */
-		for(i=0;i&lt;=2;i++) {
-			lenread = bzRead(&amp;cbz2err, cpfbz2, buf, 8);
-			if ((lenread &lt; 8) || ((cbz2err != BZ_OK) &amp;&amp;
-			    (cbz2err != BZ_STREAM_END)))
-				return -4;
-			ctrl[i] = offtin(buf);
-		};
-			
-		/* Sanity-check */
-		if((newpos + ctrl[0]) &gt; newsize)
-			return -5;
-
-		/* Read diff string */
-		memset(newBuffer + newpos, 0, ctrl[0]);
-		lenread = bzRead(&amp;dbz2err, dpfbz2, newBuffer + newpos, ctrl[0]);
-		if ((lenread &lt; ctrl[0]) ||
-		    ((dbz2err != BZ_OK) &amp;&amp; (dbz2err != BZ_STREAM_END)))
-			return -6;
-
-		/* Add old data to diff string */
-		for(i = 0; i &lt; ctrl[0]; i++) {
-			if(((oldpos + i)&gt;=0) &amp;&amp; ((oldpos + i)&lt;oldsize)) {
-				newBuffer[newpos + i] += old[oldpos + i];
-			}
-		}
-				
-		/* Adjust pointers */
-		newpos += ctrl[0];
-		oldpos += ctrl[0];
-
-		/* Sanity-check */
-		if((newpos + ctrl[1]) &gt; newsize)
-			return -7;
-
-		/* Read extra string */
-		lenread = bzRead(&amp;ebz2err, epfbz2, newBuffer + newpos, ctrl[1]);
-		if ((lenread &lt; ctrl[1]) ||
-		    ((ebz2err != BZ_OK) &amp;&amp; (ebz2err != BZ_STREAM_END)))
-			return -8;
-			
-		/* Adjust pointers */
-		newpos += ctrl[1];
-		oldpos += ctrl[2];
-	};
-	
-	closeBZStream(cpfbz2);
-	closeBZStream(dpfbz2);
-	closeBZStream(epfbz2);
-	out-&gt;seek(out, 0);
-	
-	if(out-&gt;write(out, newBuffer, newsize) != newsize)
-		return -9;
-	out-&gt;close(out);
-	free(newBuffer);
+#include &lt;string.h&gt;
+#include &lt;bzlib.h&gt;
+#include &quot;abstractfile.h&quot;
+
+static off_t offtin(unsigned char *buf)
+{
+	off_t y;
+
+	y = buf[7] &amp; 0x7F;
+	y &lt;&lt;= 8; y += buf[6];
+	y &lt;&lt;= 8; y += buf[5];
+	y &lt;&lt;= 8; y += buf[4];
+	y &lt;&lt;= 8; y += buf[3];
+	y &lt;&lt;= 8; y += buf[2];
+	y &lt;&lt;= 8; y += buf[1];
+	y &lt;&lt;= 8; y += buf[0];
+	
+	if(buf[7] &amp; 0x80) y = -y;
+	
+	return y;
+}
+
+typedef struct {
+	bz_stream bz2;
+	AbstractFile* file;
+	off_t offset;
+	unsigned char* inBuffer;
+	unsigned char* outBuffer;
+	size_t bufferLen;
+	char ended;
+} BZStream;
+
+size_t bzRead(int *bzerr, BZStream* stream, unsigned char* out, size_t len) {
+	size_t toRead;
+	size_t haveRead;
+	size_t total;
+	
+	total = len;
+	
+	*bzerr = BZ_OK;
+	
+	while(total &gt; 0) {
+		if(!stream-&gt;ended) {
+			memmove(stream-&gt;inBuffer, stream-&gt;bz2.next_in, stream-&gt;bz2.avail_in);
+			stream-&gt;file-&gt;seek(stream-&gt;file, stream-&gt;offset);
+			haveRead = stream-&gt;file-&gt;read(stream-&gt;file, stream-&gt;inBuffer + stream-&gt;bz2.avail_in, stream-&gt;bufferLen - stream-&gt;bz2.avail_in);
+			stream-&gt;offset += haveRead;
+			stream-&gt;bz2.avail_in += haveRead;
+			stream-&gt;bz2.next_in = stream-&gt;inBuffer;
+			
+			*bzerr = BZ2_bzDecompress(&amp;(stream-&gt;bz2));
+			
+			if(*bzerr == BZ_STREAM_END) {
+				stream-&gt;ended = TRUE;
+			} else {
+				if(*bzerr != BZ_OK) {
+					return 0;
+				}
+			}
+		}
+		
+		if(total &gt; (stream-&gt;bufferLen - stream-&gt;bz2.avail_out)) {
+			toRead = stream-&gt;bufferLen - stream-&gt;bz2.avail_out;
+		} else {
+			toRead = total;
+		}
+		
+		memcpy(out, stream-&gt;outBuffer, toRead);
+		memmove(stream-&gt;outBuffer, stream-&gt;outBuffer + toRead, stream-&gt;bufferLen - toRead);
+		stream-&gt;bz2.next_out -= toRead;
+		stream-&gt;bz2.avail_out += toRead;
+		out += toRead;
+		total -= toRead;
+		
+		if(total &gt; 0 &amp;&amp; stream-&gt;ended) {
+			return (len - total);
+		}
+	}
+	
+	return len;
+}
+
+void closeBZStream(BZStream* stream) {
+	free(stream-&gt;inBuffer);
+	free(stream-&gt;outBuffer);
+	BZ2_bzDecompressEnd(&amp;(stream-&gt;bz2));
+	free(stream);
+}
+
+BZStream* openBZStream(AbstractFile* file, off_t offset, size_t bufferLen) {
+	BZStream* stream;
+	stream = (BZStream*) malloc(sizeof(BZStream));
+	stream-&gt;file = file;
+	stream-&gt;offset = offset;
+	stream-&gt;bufferLen = bufferLen;
+	stream-&gt;inBuffer = (unsigned char*) malloc(bufferLen);
+	stream-&gt;outBuffer = (unsigned char*) malloc(bufferLen);
+	memset(&amp;(stream-&gt;bz2), 0, sizeof(bz_stream));
+	BZ2_bzDecompressInit(&amp;(stream-&gt;bz2), 0, FALSE);
+	
+	stream-&gt;bz2.next_in = stream-&gt;inBuffer;
+	stream-&gt;bz2.avail_in = 0;
+	stream-&gt;bz2.next_out = stream-&gt;outBuffer;
+	stream-&gt;bz2.avail_out = bufferLen;
+
+	stream-&gt;ended = FALSE;
+	return stream;
+}
+
+int patch(AbstractFile* in, AbstractFile* out, AbstractFile* patch) {
+	unsigned char header[32], buf[8];
+	off_t oldsize, newsize;
+	off_t bzctrllen, bzdatalen;
+	off_t oldpos, newpos;
+	unsigned char *old, *newBuffer;
+	int i;
+	int cbz2err, dbz2err, ebz2err;
+	off_t ctrl[3];
+	size_t lenread;
+	
+	BZStream* cpfbz2;
+	BZStream* dpfbz2;
+	BZStream* epfbz2;
+	
+	/* Read header */
+	if (patch-&gt;read(patch, header, 32) &lt; 32) {
+		return -1;
+	}
+	
+	/* Check for appropriate magic */
+	if (memcmp(header, &quot;BSDIFF40&quot;, 8) != 0)
+		return -2;
+		
+	/* Read lengths from header */
+	bzctrllen = offtin(header + 8);
+	bzdatalen = offtin(header + 16);
+	newsize = offtin(header + 24);
+
+	if((bzctrllen &lt; 0) || (bzdatalen &lt; 0) || (newsize &lt; 0))
+		return -3;
+		
+	cpfbz2 = openBZStream(patch, 32, 1024);
+	dpfbz2 = openBZStream(patch, 32 + bzctrllen, 1024);
+	epfbz2 = openBZStream(patch, 32 + bzctrllen + bzdatalen, 1024);
+	
+	oldsize = in-&gt;getLength(in);
+	old = malloc(oldsize + 1);
+	in-&gt;seek(in, 0);
+	in-&gt;read(in, old, oldsize);
+	in-&gt;close(in);
+	
+	newBuffer = malloc(newsize + 1);
+	
+	oldpos = 0;
+	newpos = 0;
+	while(newpos &lt; newsize) {
+		/* Read control data */
+		for(i=0;i&lt;=2;i++) {
+			lenread = bzRead(&amp;cbz2err, cpfbz2, buf, 8);
+			if ((lenread &lt; 8) || ((cbz2err != BZ_OK) &amp;&amp;
+			    (cbz2err != BZ_STREAM_END)))
+				return -4;
+			ctrl[i] = offtin(buf);
+		};
+			
+		/* Sanity-check */
+		if((newpos + ctrl[0]) &gt; newsize)
+			return -5;
+
+		/* Read diff string */
+		memset(newBuffer + newpos, 0, ctrl[0]);
+		lenread = bzRead(&amp;dbz2err, dpfbz2, newBuffer + newpos, ctrl[0]);
+		if ((lenread &lt; ctrl[0]) ||
+		    ((dbz2err != BZ_OK) &amp;&amp; (dbz2err != BZ_STREAM_END)))
+			return -6;
+
+		/* Add old data to diff string */
+		for(i = 0; i &lt; ctrl[0]; i++) {
+			if(((oldpos + i)&gt;=0) &amp;&amp; ((oldpos + i)&lt;oldsize)) {
+				newBuffer[newpos + i] += old[oldpos + i];
+			}
+		}
+				
+		/* Adjust pointers */
+		newpos += ctrl[0];
+		oldpos += ctrl[0];
+
+		/* Sanity-check */
+		if((newpos + ctrl[1]) &gt; newsize)
+			return -7;
+
+		/* Read extra string */
+		lenread = bzRead(&amp;ebz2err, epfbz2, newBuffer + newpos, ctrl[1]);
+		if ((lenread &lt; ctrl[1]) ||
+		    ((ebz2err != BZ_OK) &amp;&amp; (ebz2err != BZ_STREAM_END)))
+			return -8;
+			
+		/* Adjust pointers */
+		newpos += ctrl[1];
+		oldpos += ctrl[2];
+	};
+	
+	closeBZStream(cpfbz2);
+	closeBZStream(dpfbz2);
+	closeBZStream(epfbz2);
+	out-&gt;seek(out, 0);
+	
+	if(out-&gt;write(out, newBuffer, newsize) != newsize)
+		return -9;
+	out-&gt;close(out);
+	free(newBuffer);
 	free(old);
 
-	patch-&gt;close(patch);
-	return 0;
-}
+	patch-&gt;close(patch);
+	return 0;
+}</diff>
      <filename>ipsw-patch/bspatch.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,59 +1,59 @@
-
-# This Makefile builds a shared version of the library, 
-# libbz2.so.1.0.4, with soname libbz2.so.1.0,
-# at least on x86-Linux (RedHat 7.2), 
-# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).  
-# Please see the README file for some important info 
-# about building the library like this.
-
-# ------------------------------------------------------------------
-# This file is part of bzip2/libbzip2, a program and library for
-# lossless, block-sorting data compression.
-#
-# bzip2/libbzip2 version 1.0.5 of 10 December 2007
-# Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-#
-# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-# README file.
-#
-# This program is released under the terms of the license contained
-# in the file LICENSE.
-# ------------------------------------------------------------------
-
-
-SHELL=/bin/sh
-CC=gcc
-BIGFILES=-D_FILE_OFFSET_BITS=64
-CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)
-
-OBJS= blocksort.o  \
-      huffman.o    \
-      crctable.o   \
-      randtable.o  \
-      compress.o   \
-      decompress.o \
-      bzlib.o
-
-all: $(OBJS)
-	$(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.4 $(OBJS)
-	$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.4
-	rm -f libbz2.so.1.0
-	ln -s libbz2.so.1.0.4 libbz2.so.1.0
-
-clean: 
-	rm -f $(OBJS) bzip2.o libbz2.so.1.0.4 libbz2.so.1.0 bzip2-shared
-
-blocksort.o: blocksort.c
-	$(CC) $(CFLAGS) -c blocksort.c
-huffman.o: huffman.c
-	$(CC) $(CFLAGS) -c huffman.c
-crctable.o: crctable.c
-	$(CC) $(CFLAGS) -c crctable.c
-randtable.o: randtable.c
-	$(CC) $(CFLAGS) -c randtable.c
-compress.o: compress.c
-	$(CC) $(CFLAGS) -c compress.c
-decompress.o: decompress.c
-	$(CC) $(CFLAGS) -c decompress.c
-bzlib.o: bzlib.c
-	$(CC) $(CFLAGS) -c bzlib.c
+
+# This Makefile builds a shared version of the library, 
+# libbz2.so.1.0.4, with soname libbz2.so.1.0,
+# at least on x86-Linux (RedHat 7.2), 
+# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).  
+# Please see the README file for some important info 
+# about building the library like this.
+
+# ------------------------------------------------------------------
+# This file is part of bzip2/libbzip2, a program and library for
+# lossless, block-sorting data compression.
+#
+# bzip2/libbzip2 version 1.0.5 of 10 December 2007
+# Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+#
+# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+# README file.
+#
+# This program is released under the terms of the license contained
+# in the file LICENSE.
+# ------------------------------------------------------------------
+
+
+SHELL=/bin/sh
+CC=gcc
+BIGFILES=-D_FILE_OFFSET_BITS=64
+CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)
+
+OBJS= blocksort.o  \
+      huffman.o    \
+      crctable.o   \
+      randtable.o  \
+      compress.o   \
+      decompress.o \
+      bzlib.o
+
+all: $(OBJS)
+	$(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.4 $(OBJS)
+	$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.4
+	rm -f libbz2.so.1.0
+	ln -s libbz2.so.1.0.4 libbz2.so.1.0
+
+clean: 
+	rm -f $(OBJS) bzip2.o libbz2.so.1.0.4 libbz2.so.1.0 bzip2-shared
+
+blocksort.o: blocksort.c
+	$(CC) $(CFLAGS) -c blocksort.c
+huffman.o: huffman.c
+	$(CC) $(CFLAGS) -c huffman.c
+crctable.o: crctable.c
+	$(CC) $(CFLAGS) -c crctable.c
+randtable.o: randtable.c
+	$(CC) $(CFLAGS) -c randtable.c
+compress.o: compress.c
+	$(CC) $(CFLAGS) -c compress.c
+decompress.o: decompress.c
+	$(CC) $(CFLAGS) -c decompress.c
+bzlib.o: bzlib.c
+	$(CC) $(CFLAGS) -c bzlib.c</diff>
      <filename>ipsw-patch/bzip2-1.0.5/Makefile-libbz2_so</filename>
    </modified>
    <modified>
      <diff>@@ -1,210 +1,210 @@
-
-This is the README for bzip2/libzip2.
-This version is fully compatible with the previous public releases.
-
-------------------------------------------------------------------
-This file is part of bzip2/libbzip2, a program and library for
-lossless, block-sorting data compression.
-
-bzip2/libbzip2 version 1.0.5 of 10 December 2007
-Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
-
-This program is released under the terms of the license contained
-in the file LICENSE.
-------------------------------------------------------------------
-
-Complete documentation is available in Postscript form (manual.ps),
-PDF (manual.pdf) or html (manual.html).  A plain-text version of the
-manual page is available as bzip2.txt.
-
-
-HOW TO BUILD -- UNIX
-
-Type 'make'.  This builds the library libbz2.a and then the programs
-bzip2 and bzip2recover.  Six self-tests are run.  If the self-tests
-complete ok, carry on to installation:
-
-To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
-/usr/local/include, type
-
-   make install
-
-To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
-
-   make install PREFIX=/xxx/yyy
-
-If you are (justifiably) paranoid and want to see what 'make install'
-is going to do, you can first do
-
-   make -n install                      or
-   make -n install PREFIX=/xxx/yyy      respectively.
-
-The -n instructs make to show the commands it would execute, but not
-actually execute them.
-
-
-HOW TO BUILD -- UNIX, shared library libbz2.so.
-
-Do 'make -f Makefile-libbz2_so'.  This Makefile seems to work for
-Linux-ELF (RedHat 7.2 on an x86 box), with gcc.  I make no claims
-that it works for any other platform, though I suspect it probably
-will work for most platforms employing both ELF and gcc.
-
-bzip2-shared, a client of the shared library, is also built, but not
-self-tested.  So I suggest you also build using the normal Makefile,
-since that conducts a self-test.  A second reason to prefer the
-version statically linked to the library is that, on x86 platforms,
-building shared objects makes a valuable register (%ebx) unavailable
-to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
-
-Important note for people upgrading .so's from 0.9.0/0.9.5 to version
-1.0.X.  All the functions in the library have been renamed, from (eg)
-bzCompress to BZ2_bzCompress, to avoid namespace pollution.
-Unfortunately this means that the libbz2.so created by
-Makefile-libbz2_so will not work with any program which used an older
-version of the library.  I do encourage library clients to make the
-effort to upgrade to use version 1.0, since it is both faster and more
-robust than previous versions.
-
-
-HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
-
-It's difficult for me to support compilation on all these platforms.
-My approach is to collect binaries for these platforms, and put them
-on the master web site (http://www.bzip.org).  Look there.  However
-(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
-unmodified with MS Visual C.  If you have difficulties building, you
-might want to read README.COMPILATION.PROBLEMS.
-
-At least using MS Visual C++ 6, you can build from the unmodified
-sources by issuing, in a command shell: 
-
-   nmake -f makefile.msc
-
-(you may need to first run the MSVC-provided script VCVARS32.BAT
- so as to set up paths to the MSVC tools correctly).
-
-
-VALIDATION
-
-Correct operation, in the sense that a compressed file can always be
-decompressed to reproduce the original, is obviously of paramount
-importance.  To validate bzip2, I used a modified version of Mark
-Nelson's churn program.  Churn is an automated test driver which
-recursively traverses a directory structure, using bzip2 to compress
-and then decompress each file it encounters, and checking that the
-decompressed data is the same as the original.
-
-
-
-Please read and be aware of the following:
-
-WARNING:
-
-   This program and library (attempts to) compress data by 
-   performing several non-trivial transformations on it.  
-   Unless you are 100% familiar with *all* the algorithms 
-   contained herein, and with the consequences of modifying them, 
-   you should NOT meddle with the compression or decompression 
-   machinery.  Incorrect changes can and very likely *will* 
-   lead to disastrous loss of data.
-
-
-DISCLAIMER:
-
-   I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
-   USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
-
-   Every compression of a file implies an assumption that the
-   compressed file can be decompressed to reproduce the original.
-   Great efforts in design, coding and testing have been made to
-   ensure that this program works correctly.  However, the complexity
-   of the algorithms, and, in particular, the presence of various
-   special cases in the code which occur with very low but non-zero
-   probability make it impossible to rule out the possibility of bugs
-   remaining in the program.  DO NOT COMPRESS ANY DATA WITH THIS
-   PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
-   SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
-
-   That is not to say this program is inherently unreliable.  
-   Indeed, I very much hope the opposite is true.  bzip2/libbzip2 
-   has been carefully constructed and extensively tested.
-
-
-PATENTS:
-
-   To the best of my knowledge, bzip2/libbzip2 does not use any 
-   patented algorithms.  However, I do not have the resources 
-   to carry out a patent search.  Therefore I cannot give any 
-   guarantee of the above statement.
-
-
-
-WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
-
-   * Approx 10% faster compression, 30% faster decompression
-   * -t (test mode) is a lot quicker
-   * Can decompress concatenated compressed files
-   * Programming interface, so programs can directly read/write .bz2 files
-   * Less restrictive (BSD-style) licensing
-   * Flag handling more compatible with GNU gzip
-   * Much more documentation, i.e., a proper user manual
-   * Hopefully, improved portability (at least of the library)
-
-WHAT'S NEW IN 0.9.5 ?
-
-   * Compression speed is much less sensitive to the input
-     data than in previous versions.  Specifically, the very
-     slow performance caused by repetitive data is fixed.
-   * Many small improvements in file and flag handling.
-   * A Y2K statement.
-
-WHAT'S NEW IN 1.0.0 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.2 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.3 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.4 ?
-
-   See the CHANGES file.
-
-WHAT'S NEW IN 1.0.5 ?
-
-   See the CHANGES file.
-
-
-I hope you find bzip2 useful.  Feel free to contact me at
-   jseward@bzip.org
-if you have any suggestions or queries.  Many people mailed me with
-comments, suggestions and patches after the releases of bzip-0.15,
-bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
-1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
-feedback.  I thank you for your comments.
-
-bzip2's &quot;home&quot; is http://www.bzip.org/
-
-Julian Seward
-jseward@bzip.org
-Cambridge, UK.
-
-18     July 1996 (version 0.15)
-25   August 1996 (version 0.21)
- 7   August 1997 (bzip2, version 0.1)
-29   August 1997 (bzip2, version 0.1pl2)
-23   August 1998 (bzip2, version 0.9.0)
- 8     June 1999 (bzip2, version 0.9.5)
- 4     Sept 1999 (bzip2, version 0.9.5d)
- 5      May 2000 (bzip2, version 1.0pre8)
-30 December 2001 (bzip2, version 1.0.2pre1)
-15 February 2005 (bzip2, version 1.0.3)
-20 December 2006 (bzip2, version 1.0.4)
-10 December 2007 (bzip2, version 1.0.5)
+
+This is the README for bzip2/libzip2.
+This version is fully compatible with the previous public releases.
+
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+Complete documentation is available in Postscript form (manual.ps),
+PDF (manual.pdf) or html (manual.html).  A plain-text version of the
+manual page is available as bzip2.txt.
+
+
+HOW TO BUILD -- UNIX
+
+Type 'make'.  This builds the library libbz2.a and then the programs
+bzip2 and bzip2recover.  Six self-tests are run.  If the self-tests
+complete ok, carry on to installation:
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
+/usr/local/include, type
+
+   make install
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
+
+   make install PREFIX=/xxx/yyy
+
+If you are (justifiably) paranoid and want to see what 'make install'
+is going to do, you can first do
+
+   make -n install                      or
+   make -n install PREFIX=/xxx/yyy      respectively.
+
+The -n instructs make to show the commands it would execute, but not
+actually execute them.
+
+
+HOW TO BUILD -- UNIX, shared library libbz2.so.
+
+Do 'make -f Makefile-libbz2_so'.  This Makefile seems to work for
+Linux-ELF (RedHat 7.2 on an x86 box), with gcc.  I make no claims
+that it works for any other platform, though I suspect it probably
+will work for most platforms employing both ELF and gcc.
+
+bzip2-shared, a client of the shared library, is also built, but not
+self-tested.  So I suggest you also build using the normal Makefile,
+since that conducts a self-test.  A second reason to prefer the
+version statically linked to the library is that, on x86 platforms,
+building shared objects makes a valuable register (%ebx) unavailable
+to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
+
+Important note for people upgrading .so's from 0.9.0/0.9.5 to version
+1.0.X.  All the functions in the library have been renamed, from (eg)
+bzCompress to BZ2_bzCompress, to avoid namespace pollution.
+Unfortunately this means that the libbz2.so created by
+Makefile-libbz2_so will not work with any program which used an older
+version of the library.  I do encourage library clients to make the
+effort to upgrade to use version 1.0, since it is both faster and more
+robust than previous versions.
+
+
+HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
+
+It's difficult for me to support compilation on all these platforms.
+My approach is to collect binaries for these platforms, and put them
+on the master web site (http://www.bzip.org).  Look there.  However
+(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
+unmodified with MS Visual C.  If you have difficulties building, you
+might want to read README.COMPILATION.PROBLEMS.
+
+At least using MS Visual C++ 6, you can build from the unmodified
+sources by issuing, in a command shell: 
+
+   nmake -f makefile.msc
+
+(you may need to first run the MSVC-provided script VCVARS32.BAT
+ so as to set up paths to the MSVC tools correctly).
+
+
+VALIDATION
+
+Correct operation, in the sense that a compressed file can always be
+decompressed to reproduce the original, is obviously of paramount
+importance.  To validate bzip2, I used a modified version of Mark
+Nelson's churn program.  Churn is an automated test driver which
+recursively traverses a directory structure, using bzip2 to compress
+and then decompress each file it encounters, and checking that the
+decompressed data is the same as the original.
+
+
+
+Please read and be aware of the following:
+
+WARNING:
+
+   This program and library (attempts to) compress data by 
+   performing several non-trivial transformations on it.  
+   Unless you are 100% familiar with *all* the algorithms 
+   contained herein, and with the consequences of modifying them, 
+   you should NOT meddle with the compression or decompression 
+   machinery.  Incorrect changes can and very likely *will* 
+   lead to disastrous loss of data.
+
+
+DISCLAIMER:
+
+   I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
+   USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
+
+   Every compression of a file implies an assumption that the
+   compressed file can be decompressed to reproduce the original.
+   Great efforts in design, coding and testing have been made to
+   ensure that this program works correctly.  However, the complexity
+   of the algorithms, and, in particular, the presence of various
+   special cases in the code which occur with very low but non-zero
+   probability make it impossible to rule out the possibility of bugs
+   remaining in the program.  DO NOT COMPRESS ANY DATA WITH THIS
+   PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
+   SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
+
+   That is not to say this program is inherently unreliable.  
+   Indeed, I very much hope the opposite is true.  bzip2/libbzip2 
+   has been carefully constructed and extensively tested.
+
+
+PATENTS:
+
+   To the best of my knowledge, bzip2/libbzip2 does not use any 
+   patented algorithms.  However, I do not have the resources 
+   to carry out a patent search.  Therefore I cannot give any 
+   guarantee of the above statement.
+
+
+
+WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
+
+   * Approx 10% faster compression, 30% faster decompression
+   * -t (test mode) is a lot quicker
+   * Can decompress concatenated compressed files
+   * Programming interface, so programs can directly read/write .bz2 files
+   * Less restrictive (BSD-style) licensing
+   * Flag handling more compatible with GNU gzip
+   * Much more documentation, i.e., a proper user manual
+   * Hopefully, improved portability (at least of the library)
+
+WHAT'S NEW IN 0.9.5 ?
+
+   * Compression speed is much less sensitive to the input
+     data than in previous versions.  Specifically, the very
+     slow performance caused by repetitive data is fixed.
+   * Many small improvements in file and flag handling.
+   * A Y2K statement.
+
+WHAT'S NEW IN 1.0.0 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.2 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.3 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.4 ?
+
+   See the CHANGES file.
+
+WHAT'S NEW IN 1.0.5 ?
+
+   See the CHANGES file.
+
+
+I hope you find bzip2 useful.  Feel free to contact me at
+   jseward@bzip.org
+if you have any suggestions or queries.  Many people mailed me with
+comments, suggestions and patches after the releases of bzip-0.15,
+bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
+feedback.  I thank you for your comments.
+
+bzip2's &quot;home&quot; is http://www.bzip.org/
+
+Julian Seward
+jseward@bzip.org
+Cambridge, UK.
+
+18     July 1996 (version 0.15)
+25   August 1996 (version 0.21)
+ 7   August 1997 (bzip2, version 0.1)
+29   August 1997 (bzip2, version 0.1pl2)
+23   August 1998 (bzip2, version 0.9.0)
+ 8     June 1999 (bzip2, version 0.9.5)
+ 4     Sept 1999 (bzip2, version 0.9.5d)
+ 5      May 2000 (bzip2, version 1.0pre8)
+30 December 2001 (bzip2, version 1.0.2pre1)
+15 February 2005 (bzip2, version 1.0.3)
+20 December 2006 (bzip2, version 1.0.4)
+10 December 2007 (bzip2, version 1.0.5)</diff>
      <filename>ipsw-patch/bzip2-1.0.5/README</filename>
    </modified>
    <modified>
      <diff>@@ -1,58 +1,58 @@
-------------------------------------------------------------------
-This file is part of bzip2/libbzip2, a program and library for
-lossless, block-sorting data compression.
-
-bzip2/libbzip2 version 1.0.5 of 10 December 2007
-Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-README file.
-
-This program is released under the terms of the license contained
-in the file LICENSE.
-------------------------------------------------------------------
-
-bzip2-1.0.5 should compile without problems on the vast majority of
-platforms.  Using the supplied Makefile, I've built and tested it
-myself for x86-linux and amd64-linux.  With makefile.msc, Visual C++
-6.0 and nmake, you can build a native Win32 version too.  Large file
-support seems to work correctly on at least on amd64-linux.
-
-When I say &quot;large file&quot; I mean a file of size 2,147,483,648 (2^31)
-bytes or above.  Many older OSs can't handle files above this size,
-but many newer ones can.  Large files are pretty huge -- most files
-you'll encounter are not Large Files.
-
-Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
-of platforms without difficulty, and I hope this version will continue
-in that tradition.  However, in order to support large files, I've had
-to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.  This
-can cause problems.
-
-The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
-support is, as far as I know, the Recommended Way to get correct large
-file support.  For more details, see the Large File Support
-Specification, published by the Large File Summit, at
-
-   http://ftp.sas.com/standards/large.file
-
-As a general comment, if you get compilation errors which you think
-are related to large file support, try removing the above define from
-the Makefile, ie, delete the line
-
-   BIGFILES=-D_FILE_OFFSET_BITS=64 
-
-from the Makefile, and do 'make clean ; make'.  This will give you a
-version of bzip2 without large file support, which, for most
-applications, is probably not a problem.  
-
-Alternatively, try some of the platform-specific hints listed below.
-
-You can use the spewG.c program to generate huge files to test bzip2's
-large file support, if you are feeling paranoid.  Be aware though that
-any compilation problems which affect bzip2 will also affect spewG.c,
-alas.
-
-AIX: I have reports that for large file support, you need to specify
--D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64.  I have not tested
-this myself.
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+bzip2-1.0.5 should compile without problems on the vast majority of
+platforms.  Using the supplied Makefile, I've built and tested it
+myself for x86-linux and amd64-linux.  With makefile.msc, Visual C++
+6.0 and nmake, you can build a native Win32 version too.  Large file
+support seems to work correctly on at least on amd64-linux.
+
+When I say &quot;large file&quot; I mean a file of size 2,147,483,648 (2^31)
+bytes or above.  Many older OSs can't handle files above this size,
+but many newer ones can.  Large files are pretty huge -- most files
+you'll encounter are not Large Files.
+
+Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
+of platforms without difficulty, and I hope this version will continue
+in that tradition.  However, in order to support large files, I've had
+to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.  This
+can cause problems.
+
+The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
+support is, as far as I know, the Recommended Way to get correct large
+file support.  For more details, see the Large File Support
+Specification, published by the Large File Summit, at
+
+   http://ftp.sas.com/standards/large.file
+
+As a general comment, if you get compilation errors which you think
+are related to large file support, try removing the above define from
+the Makefile, ie, delete the line
+
+   BIGFILES=-D_FILE_OFFSET_BITS=64 
+
+from the Makefile, and do 'make clean ; make'.  This will give you a
+version of bzip2 without large file support, which, for most
+applications, is probably not a problem.  
+
+Alternatively, try some of the platform-specific hints listed below.
+
+You can use the spewG.c program to generate huge files to test bzip2's
+large file support, if you are feeling paranoid.  Be aware though that
+any compilation problems which affect bzip2 will also affect spewG.c,
+alas.
+
+AIX: I have reports that for large file support, you need to specify
+-D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64.  I have not tested
+this myself.</diff>
      <filename>ipsw-patch/bzip2-1.0.5/README.COMPILATION.PROBLEMS</filename>
    </modified>
    <modified>
      <diff>@@ -1,45 +1,45 @@
-  ----------------------------------------------------------------
-  This file is part of bzip2/libbzip2, a program and library for
-  lossless, block-sorting data compression.
-
-  bzip2/libbzip2 version 1.0.5 of 10 December 2007
-  Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-  README file.
-
-  This program is released under the terms of the license contained
-  in the file LICENSE.
-  ----------------------------------------------------------------
-
-The script xmlproc.sh takes an xml file as input,
-and processes it to create .pdf, .html or .ps output.
-It uses format.pl, a perl script to format &lt;pre&gt; blocks nicely,
- and add CDATA tags so writers do not have to use eg. &amp;lt; 
-
-The file &quot;entities.xml&quot; must be edited to reflect current
-version, year, etc.
-
-
-Usage:
-
-  ./xmlproc.sh -v manual.xml
-  Validates an xml file to ensure no dtd-compliance errors
-
-  ./xmlproc.sh -html manual.xml
-  Output: manual.html
-
-  ./xmlproc.sh -pdf manual.xml
-  Output: manual.pdf
-
-  ./xmlproc.sh -ps manual.xml
-  Output: manual.ps
-
-
-Notum bene: 
-- pdfxmltex barfs if given a filename with an underscore in it
-
-- xmltex won't work yet - there's a bug in passivetex
-    which we are all waiting for Sebastian to fix.
-  So we are going the xml -&gt; pdf -&gt; ps route for the time being,
-    using pdfxmltex.
+  ----------------------------------------------------------------
+  This file is part of bzip2/libbzip2, a program and library for
+  lossless, block-sorting data compression.
+
+  bzip2/libbzip2 version 1.0.5 of 10 December 2007
+  Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+  README file.
+
+  This program is released under the terms of the license contained
+  in the file LICENSE.
+  ----------------------------------------------------------------
+
+The script xmlproc.sh takes an xml file as input,
+and processes it to create .pdf, .html or .ps output.
+It uses format.pl, a perl script to format &lt;pre&gt; blocks nicely,
+ and add CDATA tags so writers do not have to use eg. &amp;lt; 
+
+The file &quot;entities.xml&quot; must be edited to reflect current
+version, year, etc.
+
+
+Usage:
+
+  ./xmlproc.sh -v manual.xml
+  Validates an xml file to ensure no dtd-compliance errors
+
+  ./xmlproc.sh -html manual.xml
+  Output: manual.html
+
+  ./xmlproc.sh -pdf manual.xml
+  Output: manual.pdf
+
+  ./xmlproc.sh -ps manual.xml
+  Output: manual.ps
+
+
+Notum bene: 
+- pdfxmltex barfs if given a filename with an underscore in it
+
+- xmltex won't work yet - there's a bug in passivetex
+    which we are all waiting for Sebastian to fix.
+  So we are going the xml -&gt; pdf -&gt; ps route for the time being,
+    using pdfxmltex.</diff>
      <filename>ipsw-patch/bzip2-1.0.5/README.XML.STUFF</filename>
    </modified>
    <modified>
      <diff>@@ -1,1094 +1,1094 @@
-
-/*-------------------------------------------------------------*/
-/*--- Block sorting machinery                               ---*/
-/*---                                           blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &quot;bzlib_private.h&quot;
-
-/*---------------------------------------------*/
-/*--- Fallback O(N log(N)^2) sorting        ---*/
-/*--- algorithm, for repetitive blocks      ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static 
-__inline__
-void fallbackSimpleSort ( UInt32* fmap, 
-                          UInt32* eclass, 
-                          Int32   lo, 
-                          Int32   hi )
-{
-   Int32 i, j, tmp;
-   UInt32 ec_tmp;
-
-   if (lo == hi) return;
-
-   if (hi - lo &gt; 3) {
-      for ( i = hi-4; i &gt;= lo; i-- ) {
-         tmp = fmap[i];
-         ec_tmp = eclass[tmp];
-         for ( j = i+4; j &lt;= hi &amp;&amp; ec_tmp &gt; eclass[fmap[j]]; j += 4 )
-            fmap[j-4] = fmap[j];
-         fmap[j-4] = tmp;
-      }
-   }
-
-   for ( i = hi-1; i &gt;= lo; i-- ) {
-      tmp = fmap[i];
-      ec_tmp = eclass[tmp];
-      for ( j = i+1; j &lt;= hi &amp;&amp; ec_tmp &gt; eclass[fmap[j]]; j++ )
-         fmap[j-1] = fmap[j];
-      fmap[j-1] = tmp;
-   }
-}
-
-
-/*---------------------------------------------*/
-#define fswap(zz1, zz2) \
-   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define fvswap(zzp1, zzp2, zzn)       \
-{                                     \
-   Int32 yyp1 = (zzp1);               \
-   Int32 yyp2 = (zzp2);               \
-   Int32 yyn  = (zzn);                \
-   while (yyn &gt; 0) {                  \
-      fswap(fmap[yyp1], fmap[yyp2]);  \
-      yyp1++; yyp2++; yyn--;          \
-   }                                  \
-}
-
-
-#define fmin(a,b) ((a) &lt; (b)) ? (a) : (b)
-
-#define fpush(lz,hz) { stackLo[sp] = lz; \
-                       stackHi[sp] = hz; \
-                       sp++; }
-
-#define fpop(lz,hz) { sp--;              \
-                      lz = stackLo[sp];  \
-                      hz = stackHi[sp]; }
-
-#define FALLBACK_QSORT_SMALL_THRESH 10
-#define FALLBACK_QSORT_STACK_SIZE   100
-
-
-static
-void fallbackQSort3 ( UInt32* fmap, 
-                      UInt32* eclass,
-                      Int32   loSt, 
-                      Int32   hiSt )
-{
-   Int32 unLo, unHi, ltLo, gtHi, n, m;
-   Int32 sp, lo, hi;
-   UInt32 med, r, r3;
-   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
-   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
-
-   r = 0;
-
-   sp = 0;
-   fpush ( loSt, hiSt );
-
-   while (sp &gt; 0) {
-
-      AssertH ( sp &lt; FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
-
-      fpop ( lo, hi );
-      if (hi - lo &lt; FALLBACK_QSORT_SMALL_THRESH) {
-         fallbackSimpleSort ( fmap, eclass, lo, hi );
-         continue;
-      }
-
-      /* Random partitioning.  Median of 3 sometimes fails to
-         avoid bad cases.  Median of 9 seems to help but 
-         looks rather expensive.  This too seems to work but
-         is cheaper.  Guidance for the magic constants 
-         7621 and 32768 is taken from Sedgewick's algorithms
-         book, chapter 35.
-      */
-      r = ((r * 7621) + 1) % 32768;
-      r3 = r % 3;
-      if (r3 == 0) med = eclass[fmap[lo]]; else
-      if (r3 == 1) med = eclass[fmap[(lo+hi)&gt;&gt;1]]; else
-                   med = eclass[fmap[hi]];
-
-      unLo = ltLo = lo;
-      unHi = gtHi = hi;
-
-      while (1) {
-         while (1) {
-            if (unLo &gt; unHi) break;
-            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
-            if (n == 0) { 
-               fswap(fmap[unLo], fmap[ltLo]); 
-               ltLo++; unLo++; 
-               continue; 
-            };
-            if (n &gt; 0) break;
-            unLo++;
-         }
-         while (1) {
-            if (unLo &gt; unHi) break;
-            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
-            if (n == 0) { 
-               fswap(fmap[unHi], fmap[gtHi]); 
-               gtHi--; unHi--; 
-               continue; 
-            };
-            if (n &lt; 0) break;
-            unHi--;
-         }
-         if (unLo &gt; unHi) break;
-         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
-      }
-
-      AssertD ( unHi == unLo-1, &quot;fallbackQSort3(2)&quot; );
-
-      if (gtHi &lt; ltLo) continue;
-
-      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
-      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
-
-      n = lo + unLo - ltLo - 1;
-      m = hi - (gtHi - unHi) + 1;
-
-      if (n - lo &gt; hi - m) {
-         fpush ( lo, n );
-         fpush ( m, hi );
-      } else {
-         fpush ( m, hi );
-         fpush ( lo, n );
-      }
-   }
-}
-
-#undef fmin
-#undef fpush
-#undef fpop
-#undef fswap
-#undef fvswap
-#undef FALLBACK_QSORT_SMALL_THRESH
-#undef FALLBACK_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock &gt; 0
-      eclass exists for [0 .. nblock-1]
-      ((UChar*)eclass) [0 .. nblock-1] holds block
-      ptr exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)eclass) [0 .. nblock-1] holds block
-      All other areas of eclass destroyed
-      fmap [0 .. nblock-1] holds sorted order
-      bhtab [ 0 .. 2+(nblock/32) ] destroyed
-*/
-
-#define       SET_BH(zz)  bhtab[(zz) &gt;&gt; 5] |= (1 &lt;&lt; ((zz) &amp; 31))
-#define     CLEAR_BH(zz)  bhtab[(zz) &gt;&gt; 5] &amp;= ~(1 &lt;&lt; ((zz) &amp; 31))
-#define     ISSET_BH(zz)  (bhtab[(zz) &gt;&gt; 5] &amp; (1 &lt;&lt; ((zz) &amp; 31)))
-#define      WORD_BH(zz)  bhtab[(zz) &gt;&gt; 5]
-#define UNALIGNED_BH(zz)  ((zz) &amp; 0x01f)
-
-static
-void fallbackSort ( UInt32* fmap, 
-                    UInt32* eclass, 
-                    UInt32* bhtab,
-                    Int32   nblock,
-                    Int32   verb )
-{
-   Int32 ftab[257];
-   Int32 ftabCopy[256];
-   Int32 H, i, j, k, l, r, cc, cc1;
-   Int32 nNotDone;
-   Int32 nBhtab;
-   UChar* eclass8 = (UChar*)eclass;
-
-   /*--
-      Initial 1-char radix sort to generate
-      initial fmap and initial BH bits.
-   --*/
-   if (verb &gt;= 4)
-      VPrintf0 ( &quot;        bucket sorting ...\n&quot; );
-   for (i = 0; i &lt; 257;    i++) ftab[i] = 0;
-   for (i = 0; i &lt; nblock; i++) ftab[eclass8[i]]++;
-   for (i = 0; i &lt; 256;    i++) ftabCopy[i] = ftab[i];
-   for (i = 1; i &lt; 257;    i++) ftab[i] += ftab[i-1];
-
-   for (i = 0; i &lt; nblock; i++) {
-      j = eclass8[i];
-      k = ftab[j] - 1;
-      ftab[j] = k;
-      fmap[k] = i;
-   }
-
-   nBhtab = 2 + (nblock / 32);
-   for (i = 0; i &lt; nBhtab; i++) bhtab[i] = 0;
-   for (i = 0; i &lt; 256; i++) SET_BH(ftab[i]);
-
-   /*--
-      Inductively refine the buckets.  Kind-of an
-      &quot;exponential radix sort&quot; (!), inspired by the
-      Manber-Myers suffix array construction algorithm.
-   --*/
-
-   /*-- set sentinel bits for block-end detection --*/
-   for (i = 0; i &lt; 32; i++) { 
-      SET_BH(nblock + 2*i);
-      CLEAR_BH(nblock + 2*i + 1);
-   }
-
-   /*-- the log(N) loop --*/
-   H = 1;
-   while (1) {
-
-      if (verb &gt;= 4) 
-         VPrintf1 ( &quot;        depth %6d has &quot;, H );
-
-      j = 0;
-      for (i = 0; i &lt; nblock; i++) {
-         if (ISSET_BH(i)) j = i;
-         k = fmap[i] - H; if (k &lt; 0) k += nblock;
-         eclass[k] = j;
-      }
-
-      nNotDone = 0;
-      r = -1;
-      while (1) {
-
-	 /*-- find the next non-singleton bucket --*/
-         k = r + 1;
-         while (ISSET_BH(k) &amp;&amp; UNALIGNED_BH(k)) k++;
-         if (ISSET_BH(k)) {
-            while (WORD_BH(k) == 0xffffffff) k += 32;
-            while (ISSET_BH(k)) k++;
-         }
-         l = k - 1;
-         if (l &gt;= nblock) break;
-         while (!ISSET_BH(k) &amp;&amp; UNALIGNED_BH(k)) k++;
-         if (!ISSET_BH(k)) {
-            while (WORD_BH(k) == 0x00000000) k += 32;
-            while (!ISSET_BH(k)) k++;
-         }
-         r = k - 1;
-         if (r &gt;= nblock) break;
-
-         /*-- now [l, r] bracket current bucket --*/
-         if (r &gt; l) {
-            nNotDone += (r - l + 1);
-            fallbackQSort3 ( fmap, eclass, l, r );
-
-            /*-- scan bucket and generate header bits-- */
-            cc = -1;
-            for (i = l; i &lt;= r; i++) {
-               cc1 = eclass[fmap[i]];
-               if (cc != cc1) { SET_BH(i); cc = cc1; };
-            }
-         }
-      }
-
-      if (verb &gt;= 4) 
-         VPrintf1 ( &quot;%6d unresolved strings\n&quot;, nNotDone );
-
-      H *= 2;
-      if (H &gt; nblock || nNotDone == 0) break;
-   }
-
-   /*-- 
-      Reconstruct the original block in
-      eclass8 [0 .. nblock-1], since the
-      previous phase destroyed it.
-   --*/
-   if (verb &gt;= 4)
-      VPrintf0 ( &quot;        reconstructing block ...\n&quot; );
-   j = 0;
-   for (i = 0; i &lt; nblock; i++) {
-      while (ftabCopy[j] == 0) j++;
-      ftabCopy[j]--;
-      eclass8[fmap[i]] = (UChar)j;
-   }
-   AssertH ( j &lt; 256, 1005 );
-}
-
-#undef       SET_BH
-#undef     CLEAR_BH
-#undef     ISSET_BH
-#undef      WORD_BH
-#undef UNALIGNED_BH
-
-
-/*---------------------------------------------*/
-/*--- The main, O(N^2 log(N)) sorting       ---*/
-/*--- algorithm.  Faster for &quot;normal&quot;       ---*/
-/*--- non-repetitive blocks.                ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-Bool mainGtU ( UInt32  i1, 
-               UInt32  i2,
-               UChar*  block, 
-               UInt16* quadrant,
-               UInt32  nblock,
-               Int32*  budget )
-{
-   Int32  k;
-   UChar  c1, c2;
-   UInt16 s1, s2;
-
-   AssertD ( i1 != i2, &quot;mainGtU&quot; );
-   /* 1 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 2 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 3 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 4 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 5 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 6 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 7 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 8 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 9 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 10 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 11 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-   /* 12 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 &gt; c2);
-   i1++; i2++;
-
-   k = nblock + 8;
-
-   do {
-      /* 1 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 2 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 3 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 4 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 5 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 6 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 7 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-      /* 8 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 &gt; c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 &gt; s2);
-      i1++; i2++;
-
-      if (i1 &gt;= nblock) i1 -= nblock;
-      if (i2 &gt;= nblock) i2 -= nblock;
-
-      k -= 8;
-      (*budget)--;
-   }
-      while (k &gt;= 0);
-
-   return False;
-}
-
-
-/*---------------------------------------------*/
-/*--
-   Knuth's increments seem to work better
-   than Incerpi-Sedgewick here.  Possibly
-   because the number of elems to sort is
-   usually small, typically &lt;= 20.
---*/
-static
-Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
-                   9841, 29524, 88573, 265720,
-                   797161, 2391484 };
-
-static
-void mainSimpleSort ( UInt32* ptr,
-                      UChar*  block,
-                      UInt16* quadrant,
-                      Int32   nblock,
-                      Int32   lo, 
-                      Int32   hi, 
-                      Int32   d,
-                      Int32*  budget )
-{
-   Int32 i, j, h, bigN, hp;
-   UInt32 v;
-
-   bigN = hi - lo + 1;
-   if (bigN &lt; 2) return;
-
-   hp = 0;
-   while (incs[hp] &lt; bigN) hp++;
-   hp--;
-
-   for (; hp &gt;= 0; hp--) {
-      h = incs[hp];
-
-      i = lo + h;
-      while (True) {
-
-         /*-- copy 1 --*/
-         if (i &gt; hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU ( 
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j &lt;= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         /*-- copy 2 --*/
-         if (i &gt; hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU ( 
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j &lt;= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         /*-- copy 3 --*/
-         if (i &gt; hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU ( 
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j &lt;= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         if (*budget &lt; 0) return;
-      }
-   }
-}
-
-
-/*---------------------------------------------*/
-/*--
-   The following is an implementation of
-   an elegant 3-way quicksort for strings,
-   described in a paper &quot;Fast Algorithms for
-   Sorting and Searching Strings&quot;, by Robert
-   Sedgewick and Jon L. Bentley.
---*/
-
-#define mswap(zz1, zz2) \
-   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define mvswap(zzp1, zzp2, zzn)       \
-{                                     \
-   Int32 yyp1 = (zzp1);               \
-   Int32 yyp2 = (zzp2);               \
-   Int32 yyn  = (zzn);                \
-   while (yyn &gt; 0) {                  \
-      mswap(ptr[yyp1], ptr[yyp2]);    \
-      yyp1++; yyp2++; yyn--;          \
-   }                                  \
-}
-
-static 
-__inline__
-UChar mmed3 ( UChar a, UChar b, UChar c )
-{
-   UChar t;
-   if (a &gt; b) { t = a; a = b; b = t; };
-   if (b &gt; c) { 
-      b = c;
-      if (a &gt; b) b = a;
-   }
-   return b;
-}
-
-#define mmin(a,b) ((a) &lt; (b)) ? (a) : (b)
-
-#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
-                          stackHi[sp] = hz; \
-                          stackD [sp] = dz; \
-                          sp++; }
-
-#define mpop(lz,hz,dz) { sp--;             \
-                         lz = stackLo[sp]; \
-                         hz = stackHi[sp]; \
-                         dz = stackD [sp]; }
-
-
-#define mnextsize(az) (nextHi[az]-nextLo[az])
-
-#define mnextswap(az,bz)                                        \
-   { Int32 tz;                                                  \
-     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
-     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
-     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
-
-
-#define MAIN_QSORT_SMALL_THRESH 20
-#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
-#define MAIN_QSORT_STACK_SIZE 100
-
-static
-void mainQSort3 ( UInt32* ptr,
-                  UChar*  block,
-                  UInt16* quadrant,
-                  Int32   nblock,
-                  Int32   loSt, 
-                  Int32   hiSt, 
-                  Int32   dSt,
-                  Int32*  budget )
-{
-   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
-   Int32 sp, lo, hi, d;
-
-   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
-   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
-   Int32 stackD [MAIN_QSORT_STACK_SIZE];
-
-   Int32 nextLo[3];
-   Int32 nextHi[3];
-   Int32 nextD [3];
-
-   sp = 0;
-   mpush ( loSt, hiSt, dSt );
-
-   while (sp &gt; 0) {
-
-      AssertH ( sp &lt; MAIN_QSORT_STACK_SIZE - 2, 1001 );
-
-      mpop ( lo, hi, d );
-      if (hi - lo &lt; MAIN_QSORT_SMALL_THRESH || 
-          d &gt; MAIN_QSORT_DEPTH_THRESH) {
-         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
-         if (*budget &lt; 0) return;
-         continue;
-      }
-
-      med = (Int32) 
-            mmed3 ( block[ptr[ lo         ]+d],
-                    block[ptr[ hi         ]+d],
-                    block[ptr[ (lo+hi)&gt;&gt;1 ]+d] );
-
-      unLo = ltLo = lo;
-      unHi = gtHi = hi;
-
-      while (True) {
-         while (True) {
-            if (unLo &gt; unHi) break;
-            n = ((Int32)block[ptr[unLo]+d]) - med;
-            if (n == 0) { 
-               mswap(ptr[unLo], ptr[ltLo]); 
-               ltLo++; unLo++; continue; 
-            };
-            if (n &gt;  0) break;
-            unLo++;
-         }
-         while (True) {
-            if (unLo &gt; unHi) break;
-            n = ((Int32)block[ptr[unHi]+d]) - med;
-            if (n == 0) { 
-               mswap(ptr[unHi], ptr[gtHi]); 
-               gtHi--; unHi--; continue; 
-            };
-            if (n &lt;  0) break;
-            unHi--;
-         }
-         if (unLo &gt; unHi) break;
-         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
-      }
-
-      AssertD ( unHi == unLo-1, &quot;mainQSort3(2)&quot; );
-
-      if (gtHi &lt; ltLo) {
-         mpush(lo, hi, d+1 );
-         continue;
-      }
-
-      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
-      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
-
-      n = lo + unLo - ltLo - 1;
-      m = hi - (gtHi - unHi) + 1;
-
-      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
-      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
-      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
-
-      if (mnextsize(0) &lt; mnextsize(1)) mnextswap(0,1);
-      if (mnextsize(1) &lt; mnextsize(2)) mnextswap(1,2);
-      if (mnextsize(0) &lt; mnextsize(1)) mnextswap(0,1);
-
-      AssertD (mnextsize(0) &gt;= mnextsize(1), &quot;mainQSort3(8)&quot; );
-      AssertD (mnextsize(1) &gt;= mnextsize(2), &quot;mainQSort3(9)&quot; );
-
-      mpush (nextLo[0], nextHi[0], nextD[0]);
-      mpush (nextLo[1], nextHi[1], nextD[1]);
-      mpush (nextLo[2], nextHi[2], nextD[2]);
-   }
-}
-
-#undef mswap
-#undef mvswap
-#undef mpush
-#undef mpop
-#undef mmin
-#undef mnextsize
-#undef mnextswap
-#undef MAIN_QSORT_SMALL_THRESH
-#undef MAIN_QSORT_DEPTH_THRESH
-#undef MAIN_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock &gt; N_OVERSHOOT
-      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
-      ((UChar*)block32) [0 .. nblock-1] holds block
-      ptr exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)block32) [0 .. nblock-1] holds block
-      All other areas of block32 destroyed
-      ftab [0 .. 65536 ] destroyed
-      ptr [0 .. nblock-1] holds sorted order
-      if (*budget &lt; 0), sorting was abandoned
-*/
-
-#define BIGFREQ(b) (ftab[((b)+1) &lt;&lt; 8] - ftab[(b) &lt;&lt; 8])
-#define SETMASK (1 &lt;&lt; 21)
-#define CLEARMASK (~(SETMASK))
-
-static
-void mainSort ( UInt32* ptr, 
-                UChar*  block,
-                UInt16* quadrant, 
-                UInt32* ftab,
-                Int32   nblock,
-                Int32   verb,
-                Int32*  budget )
-{
-   Int32  i, j, k, ss, sb;
-   Int32  runningOrder[256];
-   Bool   bigDone[256];
-   Int32  copyStart[256];
-   Int32  copyEnd  [256];
-   UChar  c1;
-   Int32  numQSorted;
-   UInt16 s;
-   if (verb &gt;= 4) VPrintf0 ( &quot;        main sort initialise ...\n&quot; );
-
-   /*-- set up the 2-byte frequency table --*/
-   for (i = 65536; i &gt;= 0; i--) ftab[i] = 0;
-
-   j = block[0] &lt;&lt; 8;
-   i = nblock-1;
-   for (; i &gt;= 3; i -= 4) {
-      quadrant[i] = 0;
-      j = (j &gt;&gt; 8) | ( ((UInt16)block[i]) &lt;&lt; 8);
-      ftab[j]++;
-      quadrant[i-1] = 0;
-      j = (j &gt;&gt; 8) | ( ((UInt16)block[i-1]) &lt;&lt; 8);
-      ftab[j]++;
-      quadrant[i-2] = 0;
-      j = (j &gt;&gt; 8) | ( ((UInt16)block[i-2]) &lt;&lt; 8);
-      ftab[j]++;
-      quadrant[i-3] = 0;
-      j = (j &gt;&gt; 8) | ( ((UInt16)block[i-3]) &lt;&lt; 8);
-      ftab[j]++;
-   }
-   for (; i &gt;= 0; i--) {
-      quadrant[i] = 0;
-      j = (j &gt;&gt; 8) | ( ((UInt16)block[i]) &lt;&lt; 8);
-      ftab[j]++;
-   }
-
-   /*-- (emphasises close relationship of block &amp; quadrant) --*/
-   for (i = 0; i &lt; BZ_N_OVERSHOOT; i++) {
-      block   [nblock+i] = block[i];
-      quadrant[nblock+i] = 0;
-   }
-
-   if (verb &gt;= 4) VPrintf0 ( &quot;        bucket sorting ...\n&quot; );
-
-   /*-- Complete the initial radix sort --*/
-   for (i = 1; i &lt;= 65536; i++) ftab[i] += ftab[i-1];
-
-   s = block[0] &lt;&lt; 8;
-   i = nblock-1;
-   for (; i &gt;= 3; i -= 4) {
-      s = (s &gt;&gt; 8) | (block[i] &lt;&lt; 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i;
-      s = (s &gt;&gt; 8) | (block[i-1] &lt;&lt; 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-1;
-      s = (s &gt;&gt; 8) | (block[i-2] &lt;&lt; 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-2;
-      s = (s &gt;&gt; 8) | (block[i-3] &lt;&lt; 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-3;
-   }
-   for (; i &gt;= 0; i--) {
-      s = (s &gt;&gt; 8) | (block[i] &lt;&lt; 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i;
-   }
-
-   /*--
-      Now ftab contains the first loc of every small bucket.
-      Calculate the running order, from smallest to largest
-      big bucket.
-   --*/
-   for (i = 0; i &lt;= 255; i++) {
-      bigDone     [i] = False;
-      runningOrder[i] = i;
-   }
-
-   {
-      Int32 vv;
-      Int32 h = 1;
-      do h = 3 * h + 1; while (h &lt;= 256);
-      do {
-         h = h / 3;
-         for (i = h; i &lt;= 255; i++) {
-            vv = runningOrder[i];
-            j = i;
-            while ( BIGFREQ(runningOrder[j-h]) &gt; BIGFREQ(vv) ) {
-               runningOrder[j] = runningOrder[j-h];
-               j = j - h;
-               if (j &lt;= (h - 1)) goto zero;
-            }
-            zero:
-            runningOrder[j] = vv;
-         }
-      } while (h != 1);
-   }
-
-   /*--
-      The main sorting loop.
-   --*/
-
-   numQSorted = 0;
-
-   for (i = 0; i &lt;= 255; i++) {
-
-      /*--
-         Process big buckets, starting with the least full.
-         Basically this is a 3-step process in which we call
-         mainQSort3 to sort the small buckets [ss, j], but
-         also make a big effort to avoid the calls if we can.
-      --*/
-      ss = runningOrder[i];
-
-      /*--
-         Step 1:
-         Complete the big bucket [ss] by quicksorting
-         any unsorted small buckets [ss, j], for j != ss.  
-         Hopefully previous pointer-scanning phases have already
-         completed many of the small buckets [ss, j], so
-         we don't have to sort them at all.
-      --*/
-      for (j = 0; j &lt;= 255; j++) {
-         if (j != ss) {
-            sb = (ss &lt;&lt; 8) + j;
-            if ( ! (ftab[sb] &amp; SETMASK) ) {
-               Int32 lo = ftab[sb]   &amp; CLEARMASK;
-               Int32 hi = (ftab[sb+1] &amp; CLEARMASK) - 1;
-               if (hi &gt; lo) {
-                  if (verb &gt;= 4)
-                     VPrintf4 ( &quot;        qsort [0x%x, 0x%x]   &quot;
-                                &quot;done %d   this %d\n&quot;,
-                                ss, j, numQSorted, hi - lo + 1 );
-                  mainQSort3 ( 
-                     ptr, block, quadrant, nblock, 
-                     lo, hi, BZ_N_RADIX, budget 
-                  );   
-                  numQSorted += (hi - lo + 1);
-                  if (*budget &lt; 0) return;
-               }
-            }
-            ftab[sb] |= SETMASK;
-         }
-      }
-
-      AssertH ( !bigDone[ss], 1006 );
-
-      /*--
-         Step 2:
-         Now scan this big bucket [ss] so as to synthesise the
-         sorted order for small buckets [t, ss] for all t,
-         including, magically, the bucket [ss,ss] too.
-         This will avoid doing Real Work in subsequent Step 1's.
-      --*/
-      {
-         for (j = 0; j &lt;= 255; j++) {
-            copyStart[j] =  ftab[(j &lt;&lt; 8) + ss]     &amp; CLEARMASK;
-            copyEnd  [j] = (ftab[(j &lt;&lt; 8) + ss + 1] &amp; CLEARMASK) - 1;
-         }
-         for (j = ftab[ss &lt;&lt; 8] &amp; CLEARMASK; j &lt; copyStart[ss]; j++) {
-            k = ptr[j]-1; if (k &lt; 0) k += nblock;
-            c1 = block[k];
-            if (!bigDone[c1])
-               ptr[ copyStart[c1]++ ] = k;
-         }
-         for (j = (ftab[(ss+1) &lt;&lt; 8] &amp; CLEARMASK) - 1; j &gt; copyEnd[ss]; j--) {
-            k = ptr[j]-1; if (k &lt; 0) k += nblock;
-            c1 = block[k];
-            if (!bigDone[c1]) 
-               ptr[ copyEnd[c1]-- ] = k;
-         }
-      }
-
-      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
-                || 
-                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
-                   Necessity for this case is demonstrated by compressing 
-                   a sequence of approximately 48.5 million of character 
-                   251; 1.0.0/1.0.1 will then die here. */
-                (copyStart[ss] == 0 &amp;&amp; copyEnd[ss] == nblock-1),
-                1007 )
-
-      for (j = 0; j &lt;= 255; j++) ftab[(j &lt;&lt; 8) + ss] |= SETMASK;
-
-      /*--
-         Step 3:
-         The [ss] big bucket is now done.  Record this fact,
-         and update the quadrant descriptors.  Remember to
-         update quadrants in the overshoot area too, if
-         necessary.  The &quot;if (i &lt; 255)&quot; test merely skips
-         this updating for the last bucket processed, since
-         updating for the last bucket is pointless.
-
-         The quadrant array provides a way to incrementally
-         cache sort orderings, as they appear, so as to 
-         make subsequent comparisons in fullGtU() complete
-         faster.  For repetitive blocks this makes a big
-         difference (but not big enough to be able to avoid
-         the fallback sorting mechanism, exponential radix sort).
-
-         The precise meaning is: at all times:
-
-            for 0 &lt;= i &lt; nblock and 0 &lt;= j &lt;= nblock
-
-            if block[i] != block[j], 
-
-               then the relative values of quadrant[i] and 
-                    quadrant[j] are meaningless.
-
-               else {
-                  if quadrant[i] &lt; quadrant[j]
-                     then the string starting at i lexicographically
-                     precedes the string starting at j
-
-                  else if quadrant[i] &gt; quadrant[j]
-                     then the string starting at j lexicographically
-                     precedes the string starting at i
-
-                  else
-                     the relative ordering of the strings starting
-                     at i and j has not yet been determined.
-               }
-      --*/
-      bigDone[ss] = True;
-
-      if (i &lt; 255) {
-         Int32 bbStart  = ftab[ss &lt;&lt; 8] &amp; CLEARMASK;
-         Int32 bbSize   = (ftab[(ss+1) &lt;&lt; 8] &amp; CLEARMASK) - bbStart;
-         Int32 shifts   = 0;
-
-         while ((bbSize &gt;&gt; shifts) &gt; 65534) shifts++;
-
-         for (j = bbSize-1; j &gt;= 0; j--) {
-            Int32 a2update     = ptr[bbStart + j];
-            UInt16 qVal        = (UInt16)(j &gt;&gt; shifts);
-            quadrant[a2update] = qVal;
-            if (a2update &lt; BZ_N_OVERSHOOT)
-               quadrant[a2update + nblock] = qVal;
-         }
-         AssertH ( ((bbSize-1) &gt;&gt; shifts) &lt;= 65535, 1002 );
-      }
-
-   }
-
-   if (verb &gt;= 4)
-      VPrintf3 ( &quot;        %d pointers, %d sorted, %d scanned\n&quot;,
-                 nblock, numQSorted, nblock - numQSorted );
-}
-
-#undef BIGFREQ
-#undef SETMASK
-#undef CLEARMASK
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock &gt; 0
-      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
-      ((UChar*)arr2)  [0 .. nblock-1] holds block
-      arr1 exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)arr2) [0 .. nblock-1] holds block
-      All other areas of block destroyed
-      ftab [ 0 .. 65536 ] destroyed
-      arr1 [0 .. nblock-1] holds sorted order
-*/
-void BZ2_blockSort ( EState* s )
-{
-   UInt32* ptr    = s-&gt;ptr; 
-   UChar*  block  = s-&gt;block;
-   UInt32* ftab   = s-&gt;ftab;
-   Int32   nblock = s-&gt;nblock;
-   Int32   verb   = s-&gt;verbosity;
-   Int32   wfact  = s-&gt;workFactor;
-   UInt16* quadrant;
-   Int32   budget;
-   Int32   budgetInit;
-   Int32   i;
-
-   if (nblock &lt; 10000) {
-      fallbackSort ( s-&gt;arr1, s-&gt;arr2, ftab, nblock, verb );
-   } else {
-      /* Calculate the location for quadrant, remembering to get
-         the alignment right.  Assumes that &amp;(block[0]) is at least
-         2-byte aligned -- this should be ok since block is really
-         the first section of arr2.
-      */
-      i = nblock+BZ_N_OVERSHOOT;
-      if (i &amp; 1) i++;
-      quadrant = (UInt16*)(&amp;(block[i]));
-
-      /* (wfact-1) / 3 puts the default-factor-30
-         transition point at very roughly the same place as 
-         with v0.1 and v0.9.0.  
-         Not that it particularly matters any more, since the
-         resulting compressed stream is now the same regardless
-         of whether or not we use the main sort or fallback sort.
-      */
-      if (wfact &lt; 1  ) wfact = 1;
-      if (wfact &gt; 100) wfact = 100;
-      budgetInit = nblock * ((wfact-1) / 3);
-      budget = budgetInit;
-
-      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &amp;budget );
-      if (verb &gt;= 3) 
-         VPrintf3 ( &quot;      %d work, %d block, ratio %5.2f\n&quot;,
-                    budgetInit - budget,
-                    nblock, 
-                    (float)(budgetInit - budget) /
-                    (float)(nblock==0 ? 1 : nblock) ); 
-      if (budget &lt; 0) {
-         if (verb &gt;= 2) 
-            VPrintf0 ( &quot;    too repetitive; using fallback&quot;
-                       &quot; sorting algorithm\n&quot; );
-         fallbackSort ( s-&gt;arr1, s-&gt;arr2, ftab, nblock, verb );
-      }
-   }
-
-   s-&gt;origPtr = -1;
-   for (i = 0; i &lt; s-&gt;nblock; i++)
-      if (ptr[i] == 0)
-         { s-&gt;origPtr = i; break; };
-
-   AssertH( s-&gt;origPtr != -1, 1003 );
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                       blocksort.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &quot;bzlib_private.h&quot;
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static 
+__inline__
+void fallbackSimpleSort ( UInt32* fmap, 
+                          UInt32* eclass, 
+                          Int32   lo, 
+                          Int32   hi )
+{
+   Int32 i, j, tmp;
+   UInt32 ec_tmp;
+
+   if (lo == hi) return;
+
+   if (hi - lo &gt; 3) {
+      for ( i = hi-4; i &gt;= lo; i-- ) {
+         tmp = fmap[i];
+         ec_tmp = eclass[tmp];
+         for ( j = i+4; j &lt;= hi &amp;&amp; ec_tmp &gt; eclass[fmap[j]]; j += 4 )
+            fmap[j-4] = fmap[j];
+         fmap[j-4] = tmp;
+      }
+   }
+
+   for ( i = hi-1; i &gt;= lo; i-- ) {
+      tmp = fmap[i];
+      ec_tmp = eclass[tmp];
+      for ( j = i+1; j &lt;= hi &amp;&amp; ec_tmp &gt; eclass[fmap[j]]; j++ )
+         fmap[j-1] = fmap[j];
+      fmap[j-1] = tmp;
+   }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn &gt; 0) {                  \
+      fswap(fmap[yyp1], fmap[yyp2]);  \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+
+#define fmin(a,b) ((a) &lt; (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+                       stackHi[sp] = hz; \
+                       sp++; }
+
+#define fpop(lz,hz) { sp--;              \
+                      lz = stackLo[sp];  \
+                      hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap, 
+                      UInt32* eclass,
+                      Int32   loSt, 
+                      Int32   hiSt )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m;
+   Int32 sp, lo, hi;
+   UInt32 med, r, r3;
+   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+   r = 0;
+
+   sp = 0;
+   fpush ( loSt, hiSt );
+
+   while (sp &gt; 0) {
+
+      AssertH ( sp &lt; FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+      fpop ( lo, hi );
+      if (hi - lo &lt; FALLBACK_QSORT_SMALL_THRESH) {
+         fallbackSimpleSort ( fmap, eclass, lo, hi );
+         continue;
+      }
+
+      /* Random partitioning.  Median of 3 sometimes fails to
+         avoid bad cases.  Median of 9 seems to help but 
+         looks rather expensive.  This too seems to work but
+         is cheaper.  Guidance for the magic constants 
+         7621 and 32768 is taken from Sedgewick's algorithms
+         book, chapter 35.
+      */
+      r = ((r * 7621) + 1) % 32768;
+      r3 = r % 3;
+      if (r3 == 0) med = eclass[fmap[lo]]; else
+      if (r3 == 1) med = eclass[fmap[(lo+hi)&gt;&gt;1]]; else
+                   med = eclass[fmap[hi]];
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (1) {
+         while (1) {
+            if (unLo &gt; unHi) break;
+            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unLo], fmap[ltLo]); 
+               ltLo++; unLo++; 
+               continue; 
+            };
+            if (n &gt; 0) break;
+            unLo++;
+         }
+         while (1) {
+            if (unLo &gt; unHi) break;
+            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+            if (n == 0) { 
+               fswap(fmap[unHi], fmap[gtHi]); 
+               gtHi--; unHi--; 
+               continue; 
+            };
+            if (n &lt; 0) break;
+            unHi--;
+         }
+         if (unLo &gt; unHi) break;
+         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, &quot;fallbackQSort3(2)&quot; );
+
+      if (gtHi &lt; ltLo) continue;
+
+      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      if (n - lo &gt; hi - m) {
+         fpush ( lo, n );
+         fpush ( m, hi );
+      } else {
+         fpush ( m, hi );
+         fpush ( lo, n );
+      }
+   }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock &gt; 0
+      eclass exists for [0 .. nblock-1]
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)eclass) [0 .. nblock-1] holds block
+      All other areas of eclass destroyed
+      fmap [0 .. nblock-1] holds sorted order
+      bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) &gt;&gt; 5] |= (1 &lt;&lt; ((zz) &amp; 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) &gt;&gt; 5] &amp;= ~(1 &lt;&lt; ((zz) &amp; 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) &gt;&gt; 5] &amp; (1 &lt;&lt; ((zz) &amp; 31)))
+#define      WORD_BH(zz)  bhtab[(zz) &gt;&gt; 5]
+#define UNALIGNED_BH(zz)  ((zz) &amp; 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap, 
+                    UInt32* eclass, 
+                    UInt32* bhtab,
+                    Int32   nblock,
+                    Int32   verb )
+{
+   Int32 ftab[257];
+   Int32 ftabCopy[256];
+   Int32 H, i, j, k, l, r, cc, cc1;
+   Int32 nNotDone;
+   Int32 nBhtab;
+   UChar* eclass8 = (UChar*)eclass;
+
+   /*--
+      Initial 1-char radix sort to generate
+      initial fmap and initial BH bits.
+   --*/
+   if (verb &gt;= 4)
+      VPrintf0 ( &quot;        bucket sorting ...\n&quot; );
+   for (i = 0; i &lt; 257;    i++) ftab[i] = 0;
+   for (i = 0; i &lt; nblock; i++) ftab[eclass8[i]]++;
+   for (i = 0; i &lt; 256;    i++) ftabCopy[i] = ftab[i];
+   for (i = 1; i &lt; 257;    i++) ftab[i] += ftab[i-1];
+
+   for (i = 0; i &lt; nblock; i++) {
+      j = eclass8[i];
+      k = ftab[j] - 1;
+      ftab[j] = k;
+      fmap[k] = i;
+   }
+
+   nBhtab = 2 + (nblock / 32);
+   for (i = 0; i &lt; nBhtab; i++) bhtab[i] = 0;
+   for (i = 0; i &lt; 256; i++) SET_BH(ftab[i]);
+
+   /*--
+      Inductively refine the buckets.  Kind-of an
+      &quot;exponential radix sort&quot; (!), inspired by the
+      Manber-Myers suffix array construction algorithm.
+   --*/
+
+   /*-- set sentinel bits for block-end detection --*/
+   for (i = 0; i &lt; 32; i++) { 
+      SET_BH(nblock + 2*i);
+      CLEAR_BH(nblock + 2*i + 1);
+   }
+
+   /*-- the log(N) loop --*/
+   H = 1;
+   while (1) {
+
+      if (verb &gt;= 4) 
+         VPrintf1 ( &quot;        depth %6d has &quot;, H );
+
+      j = 0;
+      for (i = 0; i &lt; nblock; i++) {
+         if (ISSET_BH(i)) j = i;
+         k = fmap[i] - H; if (k &lt; 0) k += nblock;
+         eclass[k] = j;
+      }
+
+      nNotDone = 0;
+      r = -1;
+      while (1) {
+
+	 /*-- find the next non-singleton bucket --*/
+         k = r + 1;
+         while (ISSET_BH(k) &amp;&amp; UNALIGNED_BH(k)) k++;
+         if (ISSET_BH(k)) {
+            while (WORD_BH(k) == 0xffffffff) k += 32;
+            while (ISSET_BH(k)) k++;
+         }
+         l = k - 1;
+         if (l &gt;= nblock) break;
+         while (!ISSET_BH(k) &amp;&amp; UNALIGNED_BH(k)) k++;
+         if (!ISSET_BH(k)) {
+            while (WORD_BH(k) == 0x00000000) k += 32;
+            while (!ISSET_BH(k)) k++;
+         }
+         r = k - 1;
+         if (r &gt;= nblock) break;
+
+         /*-- now [l, r] bracket current bucket --*/
+         if (r &gt; l) {
+            nNotDone += (r - l + 1);
+            fallbackQSort3 ( fmap, eclass, l, r );
+
+            /*-- scan bucket and generate header bits-- */
+            cc = -1;
+            for (i = l; i &lt;= r; i++) {
+               cc1 = eclass[fmap[i]];
+               if (cc != cc1) { SET_BH(i); cc = cc1; };
+            }
+         }
+      }
+
+      if (verb &gt;= 4) 
+         VPrintf1 ( &quot;%6d unresolved strings\n&quot;, nNotDone );
+
+      H *= 2;
+      if (H &gt; nblock || nNotDone == 0) break;
+   }
+
+   /*-- 
+      Reconstruct the original block in
+      eclass8 [0 .. nblock-1], since the
+      previous phase destroyed it.
+   --*/
+   if (verb &gt;= 4)
+      VPrintf0 ( &quot;        reconstructing block ...\n&quot; );
+   j = 0;
+   for (i = 0; i &lt; nblock; i++) {
+      while (ftabCopy[j] == 0) j++;
+      ftabCopy[j]--;
+      eclass8[fmap[i]] = (UChar)j;
+   }
+   AssertH ( j &lt; 256, 1005 );
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for &quot;normal&quot;       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32  i1, 
+               UInt32  i2,
+               UChar*  block, 
+               UInt16* quadrant,
+               UInt32  nblock,
+               Int32*  budget )
+{
+   Int32  k;
+   UChar  c1, c2;
+   UInt16 s1, s2;
+
+   AssertD ( i1 != i2, &quot;mainGtU&quot; );
+   /* 1 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 2 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 3 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 4 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 5 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 6 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 7 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 8 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 9 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 10 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 11 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+   /* 12 */
+   c1 = block[i1]; c2 = block[i2];
+   if (c1 != c2) return (c1 &gt; c2);
+   i1++; i2++;
+
+   k = nblock + 8;
+
+   do {
+      /* 1 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 2 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 3 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 4 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 5 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 6 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 7 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+      /* 8 */
+      c1 = block[i1]; c2 = block[i2];
+      if (c1 != c2) return (c1 &gt; c2);
+      s1 = quadrant[i1]; s2 = quadrant[i2];
+      if (s1 != s2) return (s1 &gt; s2);
+      i1++; i2++;
+
+      if (i1 &gt;= nblock) i1 -= nblock;
+      if (i2 &gt;= nblock) i2 -= nblock;
+
+      k -= 8;
+      (*budget)--;
+   }
+      while (k &gt;= 0);
+
+   return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Knuth's increments seem to work better
+   than Incerpi-Sedgewick here.  Possibly
+   because the number of elems to sort is
+   usually small, typically &lt;= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+                   9841, 29524, 88573, 265720,
+                   797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+                      UChar*  block,
+                      UInt16* quadrant,
+                      Int32   nblock,
+                      Int32   lo, 
+                      Int32   hi, 
+                      Int32   d,
+                      Int32*  budget )
+{
+   Int32 i, j, h, bigN, hp;
+   UInt32 v;
+
+   bigN = hi - lo + 1;
+   if (bigN &lt; 2) return;
+
+   hp = 0;
+   while (incs[hp] &lt; bigN) hp++;
+   hp--;
+
+   for (; hp &gt;= 0; hp--) {
+      h = incs[hp];
+
+      i = lo + h;
+      while (True) {
+
+         /*-- copy 1 --*/
+         if (i &gt; hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j &lt;= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 2 --*/
+         if (i &gt; hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j &lt;= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         /*-- copy 3 --*/
+         if (i &gt; hi) break;
+         v = ptr[i];
+         j = i;
+         while ( mainGtU ( 
+                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
+                 ) ) {
+            ptr[j] = ptr[j-h];
+            j = j - h;
+            if (j &lt;= (lo + h - 1)) break;
+         }
+         ptr[j] = v;
+         i++;
+
+         if (*budget &lt; 0) return;
+      }
+   }
+}
+
+
+/*---------------------------------------------*/
+/*--
+   The following is an implementation of
+   an elegant 3-way quicksort for strings,
+   described in a paper &quot;Fast Algorithms for
+   Sorting and Searching Strings&quot;, by Robert
+   Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn)       \
+{                                     \
+   Int32 yyp1 = (zzp1);               \
+   Int32 yyp2 = (zzp2);               \
+   Int32 yyn  = (zzn);                \
+   while (yyn &gt; 0) {                  \
+      mswap(ptr[yyp1], ptr[yyp2]);    \
+      yyp1++; yyp2++; yyn--;          \
+   }                                  \
+}
+
+static 
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+   UChar t;
+   if (a &gt; b) { t = a; a = b; b = t; };
+   if (b &gt; c) { 
+      b = c;
+      if (a &gt; b) b = a;
+   }
+   return b;
+}
+
+#define mmin(a,b) ((a) &lt; (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+                          stackHi[sp] = hz; \
+                          stackD [sp] = dz; \
+                          sp++; }
+
+#define mpop(lz,hz,dz) { sp--;             \
+                         lz = stackLo[sp]; \
+                         hz = stackHi[sp]; \
+                         dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz)                                        \
+   { Int32 tz;                                                  \
+     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+                  UChar*  block,
+                  UInt16* quadrant,
+                  Int32   nblock,
+                  Int32   loSt, 
+                  Int32   hiSt, 
+                  Int32   dSt,
+                  Int32*  budget )
+{
+   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+   Int32 sp, lo, hi, d;
+
+   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+   Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+   Int32 nextLo[3];
+   Int32 nextHi[3];
+   Int32 nextD [3];
+
+   sp = 0;
+   mpush ( loSt, hiSt, dSt );
+
+   while (sp &gt; 0) {
+
+      AssertH ( sp &lt; MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+      mpop ( lo, hi, d );
+      if (hi - lo &lt; MAIN_QSORT_SMALL_THRESH || 
+          d &gt; MAIN_QSORT_DEPTH_THRESH) {
+         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+         if (*budget &lt; 0) return;
+         continue;
+      }
+
+      med = (Int32) 
+            mmed3 ( block[ptr[ lo         ]+d],
+                    block[ptr[ hi         ]+d],
+                    block[ptr[ (lo+hi)&gt;&gt;1 ]+d] );
+
+      unLo = ltLo = lo;
+      unHi = gtHi = hi;
+
+      while (True) {
+         while (True) {
+            if (unLo &gt; unHi) break;
+            n = ((Int32)block[ptr[unLo]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unLo], ptr[ltLo]); 
+               ltLo++; unLo++; continue; 
+            };
+            if (n &gt;  0) break;
+            unLo++;
+         }
+         while (True) {
+            if (unLo &gt; unHi) break;
+            n = ((Int32)block[ptr[unHi]+d]) - med;
+            if (n == 0) { 
+               mswap(ptr[unHi], ptr[gtHi]); 
+               gtHi--; unHi--; continue; 
+            };
+            if (n &lt;  0) break;
+            unHi--;
+         }
+         if (unLo &gt; unHi) break;
+         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+      }
+
+      AssertD ( unHi == unLo-1, &quot;mainQSort3(2)&quot; );
+
+      if (gtHi &lt; ltLo) {
+         mpush(lo, hi, d+1 );
+         continue;
+      }
+
+      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+      n = lo + unLo - ltLo - 1;
+      m = hi - (gtHi - unHi) + 1;
+
+      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+      if (mnextsize(0) &lt; mnextsize(1)) mnextswap(0,1);
+      if (mnextsize(1) &lt; mnextsize(2)) mnextswap(1,2);
+      if (mnextsize(0) &lt; mnextsize(1)) mnextswap(0,1);
+
+      AssertD (mnextsize(0) &gt;= mnextsize(1), &quot;mainQSort3(8)&quot; );
+      AssertD (mnextsize(1) &gt;= mnextsize(2), &quot;mainQSort3(9)&quot; );
+
+      mpush (nextLo[0], nextHi[0], nextD[0]);
+      mpush (nextLo[1], nextHi[1], nextD[1]);
+      mpush (nextLo[2], nextHi[2], nextD[2]);
+   }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock &gt; N_OVERSHOOT
+      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      ptr exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)block32) [0 .. nblock-1] holds block
+      All other areas of block32 destroyed
+      ftab [0 .. 65536 ] destroyed
+      ptr [0 .. nblock-1] holds sorted order
+      if (*budget &lt; 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) &lt;&lt; 8] - ftab[(b) &lt;&lt; 8])
+#define SETMASK (1 &lt;&lt; 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr, 
+                UChar*  block,
+                UInt16* quadrant, 
+                UInt32* ftab,
+                Int32   nblock,
+                Int32   verb,
+                Int32*  budget )
+{
+   Int32  i, j, k, ss, sb;
+   Int32  runningOrder[256];
+   Bool   bigDone[256];
+   Int32  copyStart[256];
+   Int32  copyEnd  [256];
+   UChar  c1;
+   Int32  numQSorted;
+   UInt16 s;
+   if (verb &gt;= 4) VPrintf0 ( &quot;        main sort initialise ...\n&quot; );
+
+   /*-- set up the 2-byte frequency table --*/
+   for (i = 65536; i &gt;= 0; i--) ftab[i] = 0;
+
+   j = block[0] &lt;&lt; 8;
+   i = nblock-1;
+   for (; i &gt;= 3; i -= 4) {
+      quadrant[i] = 0;
+      j = (j &gt;&gt; 8) | ( ((UInt16)block[i]) &lt;&lt; 8);
+      ftab[j]++;
+      quadrant[i-1] = 0;
+      j = (j &gt;&gt; 8) | ( ((UInt16)block[i-1]) &lt;&lt; 8);
+      ftab[j]++;
+      quadrant[i-2] = 0;
+      j = (j &gt;&gt; 8) | ( ((UInt16)block[i-2]) &lt;&lt; 8);
+      ftab[j]++;
+      quadrant[i-3] = 0;
+      j = (j &gt;&gt; 8) | ( ((UInt16)block[i-3]) &lt;&lt; 8);
+      ftab[j]++;
+   }
+   for (; i &gt;= 0; i--) {
+      quadrant[i] = 0;
+      j = (j &gt;&gt; 8) | ( ((UInt16)block[i]) &lt;&lt; 8);
+      ftab[j]++;
+   }
+
+   /*-- (emphasises close relationship of block &amp; quadrant) --*/
+   for (i = 0; i &lt; BZ_N_OVERSHOOT; i++) {
+      block   [nblock+i] = block[i];
+      quadrant[nblock+i] = 0;
+   }
+
+   if (verb &gt;= 4) VPrintf0 ( &quot;        bucket sorting ...\n&quot; );
+
+   /*-- Complete the initial radix sort --*/
+   for (i = 1; i &lt;= 65536; i++) ftab[i] += ftab[i-1];
+
+   s = block[0] &lt;&lt; 8;
+   i = nblock-1;
+   for (; i &gt;= 3; i -= 4) {
+      s = (s &gt;&gt; 8) | (block[i] &lt;&lt; 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+      s = (s &gt;&gt; 8) | (block[i-1] &lt;&lt; 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-1;
+      s = (s &gt;&gt; 8) | (block[i-2] &lt;&lt; 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-2;
+      s = (s &gt;&gt; 8) | (block[i-3] &lt;&lt; 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i-3;
+   }
+   for (; i &gt;= 0; i--) {
+      s = (s &gt;&gt; 8) | (block[i] &lt;&lt; 8);
+      j = ftab[s] -1;
+      ftab[s] = j;
+      ptr[j] = i;
+   }
+
+   /*--
+      Now ftab contains the first loc of every small bucket.
+      Calculate the running order, from smallest to largest
+      big bucket.
+   --*/
+   for (i = 0; i &lt;= 255; i++) {
+      bigDone     [i] = False;
+      runningOrder[i] = i;
+   }
+
+   {
+      Int32 vv;
+      Int32 h = 1;
+      do h = 3 * h + 1; while (h &lt;= 256);
+      do {
+         h = h / 3;
+         for (i = h; i &lt;= 255; i++) {
+            vv = runningOrder[i];
+            j = i;
+            while ( BIGFREQ(runningOrder[j-h]) &gt; BIGFREQ(vv) ) {
+               runningOrder[j] = runningOrder[j-h];
+               j = j - h;
+               if (j &lt;= (h - 1)) goto zero;
+            }
+            zero:
+            runningOrder[j] = vv;
+         }
+      } while (h != 1);
+   }
+
+   /*--
+      The main sorting loop.
+   --*/
+
+   numQSorted = 0;
+
+   for (i = 0; i &lt;= 255; i++) {
+
+      /*--
+         Process big buckets, starting with the least full.
+         Basically this is a 3-step process in which we call
+         mainQSort3 to sort the small buckets [ss, j], but
+         also make a big effort to avoid the calls if we can.
+      --*/
+      ss = runningOrder[i];
+
+      /*--
+         Step 1:
+         Complete the big bucket [ss] by quicksorting
+         any unsorted small buckets [ss, j], for j != ss.  
+         Hopefully previous pointer-scanning phases have already
+         completed many of the small buckets [ss, j], so
+         we don't have to sort them at all.
+      --*/
+      for (j = 0; j &lt;= 255; j++) {
+         if (j != ss) {
+            sb = (ss &lt;&lt; 8) + j;
+            if ( ! (ftab[sb] &amp; SETMASK) ) {
+               Int32 lo = ftab[sb]   &amp; CLEARMASK;
+               Int32 hi = (ftab[sb+1] &amp; CLEARMASK) - 1;
+               if (hi &gt; lo) {
+                  if (verb &gt;= 4)
+                     VPrintf4 ( &quot;        qsort [0x%x, 0x%x]   &quot;
+                                &quot;done %d   this %d\n&quot;,
+                                ss, j, numQSorted, hi - lo + 1 );
+                  mainQSort3 ( 
+                     ptr, block, quadrant, nblock, 
+                     lo, hi, BZ_N_RADIX, budget 
+                  );   
+                  numQSorted += (hi - lo + 1);
+                  if (*budget &lt; 0) return;
+               }
+            }
+            ftab[sb] |= SETMASK;
+         }
+      }
+
+      AssertH ( !bigDone[ss], 1006 );
+
+      /*--
+         Step 2:
+         Now scan this big bucket [ss] so as to synthesise the
+         sorted order for small buckets [t, ss] for all t,
+         including, magically, the bucket [ss,ss] too.
+         This will avoid doing Real Work in subsequent Step 1's.
+      --*/
+      {
+         for (j = 0; j &lt;= 255; j++) {
+            copyStart[j] =  ftab[(j &lt;&lt; 8) + ss]     &amp; CLEARMASK;
+            copyEnd  [j] = (ftab[(j &lt;&lt; 8) + ss + 1] &amp; CLEARMASK) - 1;
+         }
+         for (j = ftab[ss &lt;&lt; 8] &amp; CLEARMASK; j &lt; copyStart[ss]; j++) {
+            k = ptr[j]-1; if (k &lt; 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1])
+               ptr[ copyStart[c1]++ ] = k;
+         }
+         for (j = (ftab[(ss+1) &lt;&lt; 8] &amp; CLEARMASK) - 1; j &gt; copyEnd[ss]; j--) {
+            k = ptr[j]-1; if (k &lt; 0) k += nblock;
+            c1 = block[k];
+            if (!bigDone[c1]) 
+               ptr[ copyEnd[c1]-- ] = k;
+         }
+      }
+
+      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+                || 
+                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+                   Necessity for this case is demonstrated by compressing 
+                   a sequence of approximately 48.5 million of character 
+                   251; 1.0.0/1.0.1 will then die here. */
+                (copyStart[ss] == 0 &amp;&amp; copyEnd[ss] == nblock-1),
+                1007 )
+
+      for (j = 0; j &lt;= 255; j++) ftab[(j &lt;&lt; 8) + ss] |= SETMASK;
+
+      /*--
+         Step 3:
+         The [ss] big bucket is now done.  Record this fact,
+         and update the quadrant descriptors.  Remember to
+         update quadrants in the overshoot area too, if
+         necessary.  The &quot;if (i &lt; 255)&quot; test merely skips
+         this updating for the last bucket processed, since
+         updating for the last bucket is pointless.
+
+         The quadrant array provides a way to incrementally
+         cache sort orderings, as they appear, so as to 
+         make subsequent comparisons in fullGtU() complete
+         faster.  For repetitive blocks this makes a big
+         difference (but not big enough to be able to avoid
+         the fallback sorting mechanism, exponential radix sort).
+
+         The precise meaning is: at all times:
+
+            for 0 &lt;= i &lt; nblock and 0 &lt;= j &lt;= nblock
+
+            if block[i] != block[j], 
+
+               then the relative values of quadrant[i] and 
+                    quadrant[j] are meaningless.
+
+               else {
+                  if quadrant[i] &lt; quadrant[j]
+                     then the string starting at i lexicographically
+                     precedes the string starting at j
+
+                  else if quadrant[i] &gt; quadrant[j]
+                     then the string starting at j lexicographically
+                     precedes the string starting at i
+
+                  else
+                     the relative ordering of the strings starting
+                     at i and j has not yet been determined.
+               }
+      --*/
+      bigDone[ss] = True;
+
+      if (i &lt; 255) {
+         Int32 bbStart  = ftab[ss &lt;&lt; 8] &amp; CLEARMASK;
+         Int32 bbSize   = (ftab[(ss+1) &lt;&lt; 8] &amp; CLEARMASK) - bbStart;
+         Int32 shifts   = 0;
+
+         while ((bbSize &gt;&gt; shifts) &gt; 65534) shifts++;
+
+         for (j = bbSize-1; j &gt;= 0; j--) {
+            Int32 a2update     = ptr[bbStart + j];
+            UInt16 qVal        = (UInt16)(j &gt;&gt; shifts);
+            quadrant[a2update] = qVal;
+            if (a2update &lt; BZ_N_OVERSHOOT)
+               quadrant[a2update + nblock] = qVal;
+         }
+         AssertH ( ((bbSize-1) &gt;&gt; shifts) &lt;= 65535, 1002 );
+      }
+
+   }
+
+   if (verb &gt;= 4)
+      VPrintf3 ( &quot;        %d pointers, %d sorted, %d scanned\n&quot;,
+                 nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+      nblock &gt; 0
+      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+      ((UChar*)arr2)  [0 .. nblock-1] holds block
+      arr1 exists for [0 .. nblock-1]
+
+   Post:
+      ((UChar*)arr2) [0 .. nblock-1] holds block
+      All other areas of block destroyed
+      ftab [ 0 .. 65536 ] destroyed
+      arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+   UInt32* ptr    = s-&gt;ptr; 
+   UChar*  block  = s-&gt;block;
+   UInt32* ftab   = s-&gt;ftab;
+   Int32   nblock = s-&gt;nblock;
+   Int32   verb   = s-&gt;verbosity;
+   Int32   wfact  = s-&gt;workFactor;
+   UInt16* quadrant;
+   Int32   budget;
+   Int32   budgetInit;
+   Int32   i;
+
+   if (nblock &lt; 10000) {
+      fallbackSort ( s-&gt;arr1, s-&gt;arr2, ftab, nblock, verb );
+   } else {
+      /* Calculate the location for quadrant, remembering to get
+         the alignment right.  Assumes that &amp;(block[0]) is at least
+         2-byte aligned -- this should be ok since block is really
+         the first section of arr2.
+      */
+      i = nblock+BZ_N_OVERSHOOT;
+      if (i &amp; 1) i++;
+      quadrant = (UInt16*)(&amp;(block[i]));
+
+      /* (wfact-1) / 3 puts the default-factor-30
+         transition point at very roughly the same place as 
+         with v0.1 and v0.9.0.  
+         Not that it particularly matters any more, since the
+         resulting compressed stream is now the same regardless
+         of whether or not we use the main sort or fallback sort.
+      */
+      if (wfact &lt; 1  ) wfact = 1;
+      if (wfact &gt; 100) wfact = 100;
+      budgetInit = nblock * ((wfact-1) / 3);
+      budget = budgetInit;
+
+      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &amp;budget );
+      if (verb &gt;= 3) 
+         VPrintf3 ( &quot;      %d work, %d block, ratio %5.2f\n&quot;,
+                    budgetInit - budget,
+                    nblock, 
+                    (float)(budgetInit - budget) /
+                    (float)(nblock==0 ? 1 : nblock) ); 
+      if (budget &lt; 0) {
+         if (verb &gt;= 2) 
+            VPrintf0 ( &quot;    too repetitive; using fallback&quot;
+                       &quot; sorting algorithm\n&quot; );
+         fallbackSort ( s-&gt;arr1, s-&gt;arr2, ftab, nblock, verb );
+      }
+   }
+
+   s-&gt;origPtr = -1;
+   for (i = 0; i &lt; s-&gt;nblock; i++)
+      if (ptr[i] == 0)
+         { s-&gt;origPtr = i; break; };
+
+   AssertH( s-&gt;origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/blocksort.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,514 +1,514 @@
-/*-----------------------------------------------------------*/
-/*--- Block recoverer program for bzip2                   ---*/
-/*---                                      bzip2recover.c ---*/
-/*-----------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-/* This program is a complete hack and should be rewritten properly.
-	 It isn't very complicated. */
-
-#include &lt;stdio.h&gt;
-#include &lt;errno.h&gt;
-#include &lt;stdlib.h&gt;
-#include &lt;string.h&gt;
-
-
-/* This program records bit locations in the file to be recovered.
-   That means that if 64-bit ints are not supported, we will not
-   be able to recover .bz2 files over 512MB (2^32 bits) long.
-   On GNU supported platforms, we take advantage of the 64-bit
-   int support to circumvent this problem.  Ditto MSVC.
-
-   This change occurred in version 1.0.2; all prior versions have
-   the 512MB limitation.
-*/
-#ifdef __GNUC__
-   typedef  unsigned long long int  MaybeUInt64;
-#  define MaybeUInt64_FMT &quot;%Lu&quot;
-#else
-#ifdef _MSC_VER
-   typedef  unsigned __int64  MaybeUInt64;
-#  define MaybeUInt64_FMT &quot;%I64u&quot;
-#else
-   typedef  unsigned int   MaybeUInt64;
-#  define MaybeUInt64_FMT &quot;%u&quot;
-#endif
-#endif
-
-typedef  unsigned int   UInt32;
-typedef  int            Int32;
-typedef  unsigned char  UChar;
-typedef  char           Char;
-typedef  unsigned char  Bool;
-#define True    ((Bool)1)
-#define False   ((Bool)0)
-
-
-#define BZ_MAX_FILENAME 2000
-
-Char inFileName[BZ_MAX_FILENAME];
-Char outFileName[BZ_MAX_FILENAME];
-Char progName[BZ_MAX_FILENAME];
-
-MaybeUInt64 bytesOut = 0;
-MaybeUInt64 bytesIn  = 0;
-
-
-/*---------------------------------------------------*/
-/*--- Header bytes                                ---*/
-/*---------------------------------------------------*/
-
-#define BZ_HDR_B 0x42                         /* 'B' */
-#define BZ_HDR_Z 0x5a                         /* 'Z' */
-#define BZ_HDR_h 0x68                         /* 'h' */
-#define BZ_HDR_0 0x30                         /* '0' */
- 
-
-/*---------------------------------------------------*/
-/*--- I/O errors                                  ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-static void readError ( void )
-{
-   fprintf ( stderr,
-             &quot;%s: I/O error reading `%s', possible reason follows.\n&quot;,
-            progName, inFileName );
-   perror ( progName );
-   fprintf ( stderr, &quot;%s: warning: output file(s) may be incomplete.\n&quot;,
-             progName );
-   exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-static void writeError ( void )
-{
-   fprintf ( stderr,
-             &quot;%s: I/O error reading `%s', possible reason follows.\n&quot;,
-            progName, inFileName );
-   perror ( progName );
-   fprintf ( stderr, &quot;%s: warning: output file(s) may be incomplete.\n&quot;,
-             progName );
-   exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-static void mallocFail ( Int32 n )
-{
-   fprintf ( stderr,
-             &quot;%s: malloc failed on request for %d bytes.\n&quot;,
-            progName, n );
-   fprintf ( stderr, &quot;%s: warning: output file(s) may be incomplete.\n&quot;,
-             progName );
-   exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-static void tooManyBlocks ( Int32 max_handled_blocks )
-{
-   fprintf ( stderr,
-             &quot;%s: `%s' appears to contain more than %d blocks\n&quot;,
-            progName, inFileName, max_handled_blocks );
-   fprintf ( stderr,
-             &quot;%s: and cannot be handled.  To fix, increase\n&quot;,
-             progName );
-   fprintf ( stderr, 
-             &quot;%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n&quot;,
-             progName );
-   exit ( 1 );
-}
-
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O                              ---*/
-/*---------------------------------------------------*/
-
-typedef
-   struct {
-      FILE*  handle;
-      Int32  buffer;
-      Int32  buffLive;
-      Char   mode;
-   }
-   BitStream;
-
-
-/*---------------------------------------------*/
-static BitStream* bsOpenReadStream ( FILE* stream )
-{
-   BitStream *bs = malloc ( sizeof(BitStream) );
-   if (bs == NULL) mallocFail ( sizeof(BitStream) );
-   bs-&gt;handle = stream;
-   bs-&gt;buffer = 0;
-   bs-&gt;buffLive = 0;
-   bs-&gt;mode = 'r';
-   return bs;
-}
-
-
-/*---------------------------------------------*/
-static BitStream* bsOpenWriteStream ( FILE* stream )
-{
-   BitStream *bs = malloc ( sizeof(BitStream) );
-   if (bs == NULL) mallocFail ( sizeof(BitStream) );
-   bs-&gt;handle = stream;
-   bs-&gt;buffer = 0;
-   bs-&gt;buffLive = 0;
-   bs-&gt;mode = 'w';
-   return bs;
-}
-
-
-/*---------------------------------------------*/
-static void bsPutBit ( BitStream* bs, Int32 bit )
-{
-   if (bs-&gt;buffLive == 8) {
-      Int32 retVal = putc ( (UChar) bs-&gt;buffer, bs-&gt;handle );
-      if (retVal == EOF) writeError();
-      bytesOut++;
-      bs-&gt;buffLive = 1;
-      bs-&gt;buffer = bit &amp; 0x1;
-   } else {
-      bs-&gt;buffer = ( (bs-&gt;buffer &lt;&lt; 1) | (bit &amp; 0x1) );
-      bs-&gt;buffLive++;
-   };
-}
-
-
-/*---------------------------------------------*/
-/*--
-   Returns 0 or 1, or 2 to indicate EOF.
---*/
-static Int32 bsGetBit ( BitStream* bs )
-{
-   if (bs-&gt;buffLive &gt; 0) {
-      bs-&gt;buffLive --;
-      return ( ((bs-&gt;buffer) &gt;&gt; (bs-&gt;buffLive)) &amp; 0x1 );
-   } else {
-      Int32 retVal = getc ( bs-&gt;handle );
-      if ( retVal == EOF ) {
-         if (errno != 0) readError();
-         return 2;
-      }
-      bs-&gt;buffLive = 7;
-      bs-&gt;buffer = retVal;
-      return ( ((bs-&gt;buffer) &gt;&gt; 7) &amp; 0x1 );
-   }
-}
-
-
-/*---------------------------------------------*/
-static void bsClose ( BitStream* bs )
-{
-   Int32 retVal;
-
-   if ( bs-&gt;mode == 'w' ) {
-      while ( bs-&gt;buffLive &lt; 8 ) {
-         bs-&gt;buffLive++;
-         bs-&gt;buffer &lt;&lt;= 1;
-      };
-      retVal = putc ( (UChar) (bs-&gt;buffer), bs-&gt;handle );
-      if (retVal == EOF) writeError();
-      bytesOut++;
-      retVal = fflush ( bs-&gt;handle );
-      if (retVal == EOF) writeError();
-   }
-   retVal = fclose ( bs-&gt;handle );
-   if (retVal == EOF) {
-      if (bs-&gt;mode == 'w') writeError(); else readError();
-   }
-   free ( bs );
-}
-
-
-/*---------------------------------------------*/
-static void bsPutUChar ( BitStream* bs, UChar c )
-{
-   Int32 i;
-   for (i = 7; i &gt;= 0; i--)
-      bsPutBit ( bs, (((UInt32) c) &gt;&gt; i) &amp; 0x1 );
-}
-
-
-/*---------------------------------------------*/
-static void bsPutUInt32 ( BitStream* bs, UInt32 c )
-{
-   Int32 i;
-
-   for (i = 31; i &gt;= 0; i--)
-      bsPutBit ( bs, (c &gt;&gt; i) &amp; 0x1 );
-}
-
-
-/*---------------------------------------------*/
-static Bool endsInBz2 ( Char* name )
-{
-   Int32 n = strlen ( name );
-   if (n &lt;= 4) return False;
-   return
-      (name[n-4] == '.' &amp;&amp;
-       name[n-3] == 'b' &amp;&amp;
-       name[n-2] == 'z' &amp;&amp;
-       name[n-1] == '2');
-}
-
-
-/*---------------------------------------------------*/
-/*---                                             ---*/
-/*---------------------------------------------------*/
-
-/* This logic isn't really right when it comes to Cygwin. */
-#ifdef _WIN32
-#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
-#else
-#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
-#endif
-
-#define BLOCK_HEADER_HI  0x00003141UL
-#define BLOCK_HEADER_LO  0x59265359UL
-
-#define BLOCK_ENDMARK_HI 0x00001772UL
-#define BLOCK_ENDMARK_LO 0x45385090UL
-
-/* Increase if necessary.  However, a .bz2 file with &gt; 50000 blocks
-   would have an uncompressed size of at least 40GB, so the chances
-   are low you'll need to up this.
-*/
-#define BZ_MAX_HANDLED_BLOCKS 50000
-
-MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];
-
-Int32 main ( Int32 argc, Char** argv )
-{
-   FILE*       inFile;
-   FILE*       outFile;
-   BitStream*  bsIn, *bsWr;
-   Int32       b, wrBlock, currBlock, rbCtr;
-   MaybeUInt64 bitsRead;
-
-   UInt32      buffHi, buffLo, blockCRC;
-   Char*       p;
-
-   strcpy ( progName, argv[0] );
-   inFileName[0] = outFileName[0] = 0;
-
-   fprintf ( stderr, 
-             &quot;bzip2recover 1.0.5: extracts blocks from damaged .bz2 files.\n&quot; );
-
-   if (argc != 2) {
-      fprintf ( stderr, &quot;%s: usage is `%s damaged_file_name'.\n&quot;,
-                        progName, progName );
-      switch (sizeof(MaybeUInt64)) {
-         case 8:
-            fprintf(stderr, 
-                    &quot;\trestrictions on size of recovered file: None\n&quot;);
-            break;
-         case 4:
-            fprintf(stderr, 
-                    &quot;\trestrictions on size of recovered file: 512 MB\n&quot;);
-            fprintf(stderr, 
-                    &quot;\tto circumvent, recompile with MaybeUInt64 as an\n&quot;
-                    &quot;\tunsigned 64-bit int.\n&quot;);
-            break;
-         default:
-            fprintf(stderr, 
-                    &quot;\tsizeof(MaybeUInt64) is not 4 or 8 -- &quot;
-                    &quot;configuration error.\n&quot;);
-            break;
-      }
-      exit(1);
-   }
-
-   if (strlen(argv[1]) &gt;= BZ_MAX_FILENAME-20) {
-      fprintf ( stderr, 
-                &quot;%s: supplied filename is suspiciously (&gt;= %d chars) long.  Bye!\n&quot;,
-                progName, (int)strlen(argv[1]) );
-      exit(1);
-   }
-
-   strcpy ( inFileName, argv[1] );
-
-   inFile = fopen ( inFileName, &quot;rb&quot; );
-   if (inFile == NULL) {
-      fprintf ( stderr, &quot;%s: can't read `%s'\n&quot;, progName, inFileName );
-      exit(1);
-   }
-
-   bsIn = bsOpenReadStream ( inFile );
-   fprintf ( stderr, &quot;%s: searching for block boundaries ...\n&quot;, progName );
-
-   bitsRead = 0;
-   buffHi = buffLo = 0;
-   currBlock = 0;
-   bStart[currBlock] = 0;
-
-   rbCtr = 0;
-
-   while (True) {
-      b = bsGetBit ( bsIn );
-      bitsRead++;
-      if (b == 2) {
-         if (bitsRead &gt;= bStart[currBlock] &amp;&amp;
-            (bitsRead - bStart[currBlock]) &gt;= 40) {
-            bEnd[currBlock] = bitsRead-1;
-            if (currBlock &gt; 0)
-               fprintf ( stderr, &quot;   block %d runs from &quot; MaybeUInt64_FMT 
-                                 &quot; to &quot; MaybeUInt64_FMT &quot; (incomplete)\n&quot;,
-                         currBlock,  bStart[currBlock], bEnd[currBlock] );
-         } else
-            currBlock--;
-         break;
-      }
-      buffHi = (buffHi &lt;&lt; 1) | (buffLo &gt;&gt; 31);
-      buffLo = (buffLo &lt;&lt; 1) | (b &amp; 1);
-      if ( ( (buffHi &amp; 0x0000ffff) == BLOCK_HEADER_HI 
-             &amp;&amp; buffLo == BLOCK_HEADER_LO)
-           || 
-           ( (buffHi &amp; 0x0000ffff) == BLOCK_ENDMARK_HI 
-             &amp;&amp; buffLo == BLOCK_ENDMARK_LO)
-         ) {
-         if (bitsRead &gt; 49) {
-            bEnd[currBlock] = bitsRead-49;
-         } else {
-            bEnd[currBlock] = 0;
-         }
-         if (currBlock &gt; 0 &amp;&amp;
-	     (bEnd[currBlock] - bStart[currBlock]) &gt;= 130) {
-            fprintf ( stderr, &quot;   block %d runs from &quot; MaybeUInt64_FMT 
-                              &quot; to &quot; MaybeUInt64_FMT &quot;\n&quot;,
-                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
-            rbStart[rbCtr] = bStart[currBlock];
-            rbEnd[rbCtr] = bEnd[currBlock];
-            rbCtr++;
-         }
-         if (currBlock &gt;= BZ_MAX_HANDLED_BLOCKS)
-            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
-         currBlock++;
-
-         bStart[currBlock] = bitsRead;
-      }
-   }
-
-   bsClose ( bsIn );
-
-   /*-- identified blocks run from 1 to rbCtr inclusive. --*/
-
-   if (rbCtr &lt; 1) {
-      fprintf ( stderr,
-                &quot;%s: sorry, I couldn't find any block boundaries.\n&quot;,
-                progName );
-      exit(1);
-   };
-
-   fprintf ( stderr, &quot;%s: splitting into blocks\n&quot;, progName );
-
-   inFile = fopen ( inFileName, &quot;rb&quot; );
-   if (inFile == NULL) {
-      fprintf ( stderr, &quot;%s: can't open `%s'\n&quot;, progName, inFileName );
-      exit(1);
-   }
-   bsIn = bsOpenReadStream ( inFile );
-
-   /*-- placate gcc's dataflow analyser --*/
-   blockCRC = 0; bsWr = 0;
-
-   bitsRead = 0;
-   outFile = NULL;
-   wrBlock = 0;
-   while (True) {
-      b = bsGetBit(bsIn);
-      if (b == 2) break;
-      buffHi = (buffHi &lt;&lt; 1) | (buffLo &gt;&gt; 31);
-      buffLo = (buffLo &lt;&lt; 1) | (b &amp; 1);
-      if (bitsRead == 47+rbStart[wrBlock]) 
-         blockCRC = (buffHi &lt;&lt; 16) | (buffLo &gt;&gt; 16);
-
-      if (outFile != NULL &amp;&amp; bitsRead &gt;= rbStart[wrBlock]
-                          &amp;&amp; bitsRead &lt;= rbEnd[wrBlock]) {
-         bsPutBit ( bsWr, b );
-      }
-
-      bitsRead++;
-
-      if (bitsRead == rbEnd[wrBlock]+1) {
-         if (outFile != NULL) {
-            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
-            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
-            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
-            bsPutUInt32 ( bsWr, blockCRC );
-            bsClose ( bsWr );
-         }
-         if (wrBlock &gt;= rbCtr) break;
-         wrBlock++;
-      } else
-      if (bitsRead == rbStart[wrBlock]) {
-         /* Create the output file name, correctly handling leading paths. 
-            (31.10.2001 by Sergey E. Kusikov) */
-         Char* split;
-         Int32 ofs, k;
-         for (k = 0; k &lt; BZ_MAX_FILENAME; k++) 
-            outFileName[k] = 0;
-         strcpy (outFileName, inFileName);
-         split = strrchr (outFileName, BZ_SPLIT_SYM);
-         if (split == NULL) {
-            split = outFileName;
-         } else {
-            ++split;
-	 }
-	 /* Now split points to the start of the basename. */
-         ofs  = split - outFileName;
-         sprintf (split, &quot;rec%5d&quot;, wrBlock+1);
-         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
-         strcat (outFileName, inFileName + ofs);
-
-         if ( !endsInBz2(outFileName)) strcat ( outFileName, &quot;.bz2&quot; );
-
-         fprintf ( stderr, &quot;   writing block %d to `%s' ...\n&quot;,
-                           wrBlock+1, outFileName );
-
-         outFile = fopen ( outFileName, &quot;wb&quot; );
-         if (outFile == NULL) {
-            fprintf ( stderr, &quot;%s: can't write `%s'\n&quot;,
-                      progName, outFileName );
-            exit(1);
-         }
-         bsWr = bsOpenWriteStream ( outFile );
-         bsPutUChar ( bsWr, BZ_HDR_B );    
-         bsPutUChar ( bsWr, BZ_HDR_Z );    
-         bsPutUChar ( bsWr, BZ_HDR_h );    
-         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
-         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
-         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
-         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
-      }
-   }
-
-   fprintf ( stderr, &quot;%s: finished\n&quot;, progName );
-   return 0;
-}
-
-
-
-/*-----------------------------------------------------------*/
-/*--- end                                  bzip2recover.c ---*/
-/*-----------------------------------------------------------*/
+/*-----------------------------------------------------------*/
+/*--- Block recoverer program for bzip2                   ---*/
+/*---                                      bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* This program is a complete hack and should be rewritten properly.
+	 It isn't very complicated. */
+
+#include &lt;stdio.h&gt;
+#include &lt;errno.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+
+
+/* This program records bit locations in the file to be recovered.
+   That means that if 64-bit ints are not supported, we will not
+   be able to recover .bz2 files over 512MB (2^32 bits) long.
+   On GNU supported platforms, we take advantage of the 64-bit
+   int support to circumvent this problem.  Ditto MSVC.
+
+   This change occurred in version 1.0.2; all prior versions have
+   the 512MB limitation.
+*/
+#ifdef __GNUC__
+   typedef  unsigned long long int  MaybeUInt64;
+#  define MaybeUInt64_FMT &quot;%Lu&quot;
+#else
+#ifdef _MSC_VER
+   typedef  unsigned __int64  MaybeUInt64;
+#  define MaybeUInt64_FMT &quot;%I64u&quot;
+#else
+   typedef  unsigned int   MaybeUInt64;
+#  define MaybeUInt64_FMT &quot;%u&quot;
+#endif
+#endif
+
+typedef  unsigned int   UInt32;
+typedef  int            Int32;
+typedef  unsigned char  UChar;
+typedef  char           Char;
+typedef  unsigned char  Bool;
+#define True    ((Bool)1)
+#define False   ((Bool)0)
+
+
+#define BZ_MAX_FILENAME 2000
+
+Char inFileName[BZ_MAX_FILENAME];
+Char outFileName[BZ_MAX_FILENAME];
+Char progName[BZ_MAX_FILENAME];
+
+MaybeUInt64 bytesOut = 0;
+MaybeUInt64 bytesIn  = 0;
+
+
+/*---------------------------------------------------*/
+/*--- Header bytes                                ---*/
+/*---------------------------------------------------*/
+
+#define BZ_HDR_B 0x42                         /* 'B' */
+#define BZ_HDR_Z 0x5a                         /* 'Z' */
+#define BZ_HDR_h 0x68                         /* 'h' */
+#define BZ_HDR_0 0x30                         /* '0' */
+ 
+
+/*---------------------------------------------------*/
+/*--- I/O errors                                  ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static void readError ( void )
+{
+   fprintf ( stderr,
+             &quot;%s: I/O error reading `%s', possible reason follows.\n&quot;,
+            progName, inFileName );
+   perror ( progName );
+   fprintf ( stderr, &quot;%s: warning: output file(s) may be incomplete.\n&quot;,
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void writeError ( void )
+{
+   fprintf ( stderr,
+             &quot;%s: I/O error reading `%s', possible reason follows.\n&quot;,
+            progName, inFileName );
+   perror ( progName );
+   fprintf ( stderr, &quot;%s: warning: output file(s) may be incomplete.\n&quot;,
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void mallocFail ( Int32 n )
+{
+   fprintf ( stderr,
+             &quot;%s: malloc failed on request for %d bytes.\n&quot;,
+            progName, n );
+   fprintf ( stderr, &quot;%s: warning: output file(s) may be incomplete.\n&quot;,
+             progName );
+   exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void tooManyBlocks ( Int32 max_handled_blocks )
+{
+   fprintf ( stderr,
+             &quot;%s: `%s' appears to contain more than %d blocks\n&quot;,
+            progName, inFileName, max_handled_blocks );
+   fprintf ( stderr,
+             &quot;%s: and cannot be handled.  To fix, increase\n&quot;,
+             progName );
+   fprintf ( stderr, 
+             &quot;%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n&quot;,
+             progName );
+   exit ( 1 );
+}
+
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+typedef
+   struct {
+      FILE*  handle;
+      Int32  buffer;
+      Int32  buffLive;
+      Char   mode;
+   }
+   BitStream;
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenReadStream ( FILE* stream )
+{
+   BitStream *bs = malloc ( sizeof(BitStream) );
+   if (bs == NULL) mallocFail ( sizeof(BitStream) );
+   bs-&gt;handle = stream;
+   bs-&gt;buffer = 0;
+   bs-&gt;buffLive = 0;
+   bs-&gt;mode = 'r';
+   return bs;
+}
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenWriteStream ( FILE* stream )
+{
+   BitStream *bs = malloc ( sizeof(BitStream) );
+   if (bs == NULL) mallocFail ( sizeof(BitStream) );
+   bs-&gt;handle = stream;
+   bs-&gt;buffer = 0;
+   bs-&gt;buffLive = 0;
+   bs-&gt;mode = 'w';
+   return bs;
+}
+
+
+/*---------------------------------------------*/
+static void bsPutBit ( BitStream* bs, Int32 bit )
+{
+   if (bs-&gt;buffLive == 8) {
+      Int32 retVal = putc ( (UChar) bs-&gt;buffer, bs-&gt;handle );
+      if (retVal == EOF) writeError();
+      bytesOut++;
+      bs-&gt;buffLive = 1;
+      bs-&gt;buffer = bit &amp; 0x1;
+   } else {
+      bs-&gt;buffer = ( (bs-&gt;buffer &lt;&lt; 1) | (bit &amp; 0x1) );
+      bs-&gt;buffLive++;
+   };
+}
+
+
+/*---------------------------------------------*/
+/*--
+   Returns 0 or 1, or 2 to indicate EOF.
+--*/
+static Int32 bsGetBit ( BitStream* bs )
+{
+   if (bs-&gt;buffLive &gt; 0) {
+      bs-&gt;buffLive --;
+      return ( ((bs-&gt;buffer) &gt;&gt; (bs-&gt;buffLive)) &amp; 0x1 );
+   } else {
+      Int32 retVal = getc ( bs-&gt;handle );
+      if ( retVal == EOF ) {
+         if (errno != 0) readError();
+         return 2;
+      }
+      bs-&gt;buffLive = 7;
+      bs-&gt;buffer = retVal;
+      return ( ((bs-&gt;buffer) &gt;&gt; 7) &amp; 0x1 );
+   }
+}
+
+
+/*---------------------------------------------*/
+static void bsClose ( BitStream* bs )
+{
+   Int32 retVal;
+
+   if ( bs-&gt;mode == 'w' ) {
+      while ( bs-&gt;buffLive &lt; 8 ) {
+         bs-&gt;buffLive++;
+         bs-&gt;buffer &lt;&lt;= 1;
+      };
+      retVal = putc ( (UChar) (bs-&gt;buffer), bs-&gt;handle );
+      if (retVal == EOF) writeError();
+      bytesOut++;
+      retVal = fflush ( bs-&gt;handle );
+      if (retVal == EOF) writeError();
+   }
+   retVal = fclose ( bs-&gt;handle );
+   if (retVal == EOF) {
+      if (bs-&gt;mode == 'w') writeError(); else readError();
+   }
+   free ( bs );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUChar ( BitStream* bs, UChar c )
+{
+   Int32 i;
+   for (i = 7; i &gt;= 0; i--)
+      bsPutBit ( bs, (((UInt32) c) &gt;&gt; i) &amp; 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUInt32 ( BitStream* bs, UInt32 c )
+{
+   Int32 i;
+
+   for (i = 31; i &gt;= 0; i--)
+      bsPutBit ( bs, (c &gt;&gt; i) &amp; 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static Bool endsInBz2 ( Char* name )
+{
+   Int32 n = strlen ( name );
+   if (n &lt;= 4) return False;
+   return
+      (name[n-4] == '.' &amp;&amp;
+       name[n-3] == 'b' &amp;&amp;
+       name[n-2] == 'z' &amp;&amp;
+       name[n-1] == '2');
+}
+
+
+/*---------------------------------------------------*/
+/*---                                             ---*/
+/*---------------------------------------------------*/
+
+/* This logic isn't really right when it comes to Cygwin. */
+#ifdef _WIN32
+#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
+#else
+#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
+#endif
+
+#define BLOCK_HEADER_HI  0x00003141UL
+#define BLOCK_HEADER_LO  0x59265359UL
+
+#define BLOCK_ENDMARK_HI 0x00001772UL
+#define BLOCK_ENDMARK_LO 0x45385090UL
+
+/* Increase if necessary.  However, a .bz2 file with &gt; 50000 blocks
+   would have an uncompressed size of at least 40GB, so the chances
+   are low you'll need to up this.
+*/
+#define BZ_MAX_HANDLED_BLOCKS 50000
+
+MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];
+
+Int32 main ( Int32 argc, Char** argv )
+{
+   FILE*       inFile;
+   FILE*       outFile;
+   BitStream*  bsIn, *bsWr;
+   Int32       b, wrBlock, currBlock, rbCtr;
+   MaybeUInt64 bitsRead;
+
+   UInt32      buffHi, buffLo, blockCRC;
+   Char*       p;
+
+   strcpy ( progName, argv[0] );
+   inFileName[0] = outFileName[0] = 0;
+
+   fprintf ( stderr, 
+             &quot;bzip2recover 1.0.5: extracts blocks from damaged .bz2 files.\n&quot; );
+
+   if (argc != 2) {
+      fprintf ( stderr, &quot;%s: usage is `%s damaged_file_name'.\n&quot;,
+                        progName, progName );
+      switch (sizeof(MaybeUInt64)) {
+         case 8:
+            fprintf(stderr, 
+                    &quot;\trestrictions on size of recovered file: None\n&quot;);
+            break;
+         case 4:
+            fprintf(stderr, 
+                    &quot;\trestrictions on size of recovered file: 512 MB\n&quot;);
+            fprintf(stderr, 
+                    &quot;\tto circumvent, recompile with MaybeUInt64 as an\n&quot;
+                    &quot;\tunsigned 64-bit int.\n&quot;);
+            break;
+         default:
+            fprintf(stderr, 
+                    &quot;\tsizeof(MaybeUInt64) is not 4 or 8 -- &quot;
+                    &quot;configuration error.\n&quot;);
+            break;
+      }
+      exit(1);
+   }
+
+   if (strlen(argv[1]) &gt;= BZ_MAX_FILENAME-20) {
+      fprintf ( stderr, 
+                &quot;%s: supplied filename is suspiciously (&gt;= %d chars) long.  Bye!\n&quot;,
+                progName, (int)strlen(argv[1]) );
+      exit(1);
+   }
+
+   strcpy ( inFileName, argv[1] );
+
+   inFile = fopen ( inFileName, &quot;rb&quot; );
+   if (inFile == NULL) {
+      fprintf ( stderr, &quot;%s: can't read `%s'\n&quot;, progName, inFileName );
+      exit(1);
+   }
+
+   bsIn = bsOpenReadStream ( inFile );
+   fprintf ( stderr, &quot;%s: searching for block boundaries ...\n&quot;, progName );
+
+   bitsRead = 0;
+   buffHi = buffLo = 0;
+   currBlock = 0;
+   bStart[currBlock] = 0;
+
+   rbCtr = 0;
+
+   while (True) {
+      b = bsGetBit ( bsIn );
+      bitsRead++;
+      if (b == 2) {
+         if (bitsRead &gt;= bStart[currBlock] &amp;&amp;
+            (bitsRead - bStart[currBlock]) &gt;= 40) {
+            bEnd[currBlock] = bitsRead-1;
+            if (currBlock &gt; 0)
+               fprintf ( stderr, &quot;   block %d runs from &quot; MaybeUInt64_FMT 
+                                 &quot; to &quot; MaybeUInt64_FMT &quot; (incomplete)\n&quot;,
+                         currBlock,  bStart[currBlock], bEnd[currBlock] );
+         } else
+            currBlock--;
+         break;
+      }
+      buffHi = (buffHi &lt;&lt; 1) | (buffLo &gt;&gt; 31);
+      buffLo = (buffLo &lt;&lt; 1) | (b &amp; 1);
+      if ( ( (buffHi &amp; 0x0000ffff) == BLOCK_HEADER_HI 
+             &amp;&amp; buffLo == BLOCK_HEADER_LO)
+           || 
+           ( (buffHi &amp; 0x0000ffff) == BLOCK_ENDMARK_HI 
+             &amp;&amp; buffLo == BLOCK_ENDMARK_LO)
+         ) {
+         if (bitsRead &gt; 49) {
+            bEnd[currBlock] = bitsRead-49;
+         } else {
+            bEnd[currBlock] = 0;
+         }
+         if (currBlock &gt; 0 &amp;&amp;
+	     (bEnd[currBlock] - bStart[currBlock]) &gt;= 130) {
+            fprintf ( stderr, &quot;   block %d runs from &quot; MaybeUInt64_FMT 
+                              &quot; to &quot; MaybeUInt64_FMT &quot;\n&quot;,
+                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
+            rbStart[rbCtr] = bStart[currBlock];
+            rbEnd[rbCtr] = bEnd[currBlock];
+            rbCtr++;
+         }
+         if (currBlock &gt;= BZ_MAX_HANDLED_BLOCKS)
+            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
+         currBlock++;
+
+         bStart[currBlock] = bitsRead;
+      }
+   }
+
+   bsClose ( bsIn );
+
+   /*-- identified blocks run from 1 to rbCtr inclusive. --*/
+
+   if (rbCtr &lt; 1) {
+      fprintf ( stderr,
+                &quot;%s: sorry, I couldn't find any block boundaries.\n&quot;,
+                progName );
+      exit(1);
+   };
+
+   fprintf ( stderr, &quot;%s: splitting into blocks\n&quot;, progName );
+
+   inFile = fopen ( inFileName, &quot;rb&quot; );
+   if (inFile == NULL) {
+      fprintf ( stderr, &quot;%s: can't open `%s'\n&quot;, progName, inFileName );
+      exit(1);
+   }
+   bsIn = bsOpenReadStream ( inFile );
+
+   /*-- placate gcc's dataflow analyser --*/
+   blockCRC = 0; bsWr = 0;
+
+   bitsRead = 0;
+   outFile = NULL;
+   wrBlock = 0;
+   while (True) {
+      b = bsGetBit(bsIn);
+      if (b == 2) break;
+      buffHi = (buffHi &lt;&lt; 1) | (buffLo &gt;&gt; 31);
+      buffLo = (buffLo &lt;&lt; 1) | (b &amp; 1);
+      if (bitsRead == 47+rbStart[wrBlock]) 
+         blockCRC = (buffHi &lt;&lt; 16) | (buffLo &gt;&gt; 16);
+
+      if (outFile != NULL &amp;&amp; bitsRead &gt;= rbStart[wrBlock]
+                          &amp;&amp; bitsRead &lt;= rbEnd[wrBlock]) {
+         bsPutBit ( bsWr, b );
+      }
+
+      bitsRead++;
+
+      if (bitsRead == rbEnd[wrBlock]+1) {
+         if (outFile != NULL) {
+            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
+            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
+            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
+            bsPutUInt32 ( bsWr, blockCRC );
+            bsClose ( bsWr );
+         }
+         if (wrBlock &gt;= rbCtr) break;
+         wrBlock++;
+      } else
+      if (bitsRead == rbStart[wrBlock]) {
+         /* Create the output file name, correctly handling leading paths. 
+            (31.10.2001 by Sergey E. Kusikov) */
+         Char* split;
+         Int32 ofs, k;
+         for (k = 0; k &lt; BZ_MAX_FILENAME; k++) 
+            outFileName[k] = 0;
+         strcpy (outFileName, inFileName);
+         split = strrchr (outFileName, BZ_SPLIT_SYM);
+         if (split == NULL) {
+            split = outFileName;
+         } else {
+            ++split;
+	 }
+	 /* Now split points to the start of the basename. */
+         ofs  = split - outFileName;
+         sprintf (split, &quot;rec%5d&quot;, wrBlock+1);
+         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
+         strcat (outFileName, inFileName + ofs);
+
+         if ( !endsInBz2(outFileName)) strcat ( outFileName, &quot;.bz2&quot; );
+
+         fprintf ( stderr, &quot;   writing block %d to `%s' ...\n&quot;,
+                           wrBlock+1, outFileName );
+
+         outFile = fopen ( outFileName, &quot;wb&quot; );
+         if (outFile == NULL) {
+            fprintf ( stderr, &quot;%s: can't write `%s'\n&quot;,
+                      progName, outFileName );
+            exit(1);
+         }
+         bsWr = bsOpenWriteStream ( outFile );
+         bsPutUChar ( bsWr, BZ_HDR_B );    
+         bsPutUChar ( bsWr, BZ_HDR_Z );    
+         bsPutUChar ( bsWr, BZ_HDR_h );    
+         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
+         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
+         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
+         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
+      }
+   }
+
+   fprintf ( stderr, &quot;%s: finished\n&quot;, progName );
+   return 0;
+}
+
+
+
+/*-----------------------------------------------------------*/
+/*--- end                                  bzip2recover.c ---*/
+/*-----------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/bzip2recover.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,1572 +1,1572 @@
-
-/*-------------------------------------------------------------*/
-/*--- Library top-level functions.                          ---*/
-/*---                                               bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-/* CHANGES
-   0.9.0    -- original version.
-   0.9.0a/b -- no changes in this file.
-   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
-     fixed bzWrite/bzRead to ignore zero-length requests.
-     fixed bzread to correctly handle read requests after EOF.
-     wrong parameter order in call to bzDecompressInit in
-     bzBuffToBuffDecompress.  Fixed.
-*/
-
-#include &quot;bzlib_private.h&quot;
-
-
-/*---------------------------------------------------*/
-/*--- Compression stuff                           ---*/
-/*---------------------------------------------------*/
-
-
-/*---------------------------------------------------*/
-#ifndef BZ_NO_STDIO
-void BZ2_bz__AssertH__fail ( int errcode )
-{
-   fprintf(stderr, 
-      &quot;\n\nbzip2/libbzip2: internal error number %d.\n&quot;
-      &quot;This is a bug in bzip2/libbzip2, %s.\n&quot;
-      &quot;Please report it to me at: jseward@bzip.org.  If this happened\n&quot;
-      &quot;when you were using some program which uses libbzip2 as a\n&quot;
-      &quot;component, you should also report this bug to the author(s)\n&quot;
-      &quot;of that program.  Please make an effort to report this bug;\n&quot;
-      &quot;timely and accurate bug reports eventually lead to higher\n&quot;
-      &quot;quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n&quot;,
-      errcode,
-      BZ2_bzlibVersion()
-   );
-
-   if (errcode == 1007) {
-   fprintf(stderr,
-      &quot;\n*** A special note about internal error number 1007 ***\n&quot;
-      &quot;\n&quot;
-      &quot;Experience suggests that a common cause of i.e. 1007\n&quot;
-      &quot;is unreliable memory or other hardware.  The 1007 assertion\n&quot;
-      &quot;just happens to cross-check the results of huge numbers of\n&quot;
-      &quot;memory reads/writes, and so acts (unintendedly) as a stress\n&quot;
-      &quot;test of your memory system.\n&quot;
-      &quot;\n&quot;
-      &quot;I suggest the following: try compressing the file again,\n&quot;
-      &quot;possibly monitoring progress in detail with the -vv flag.\n&quot;
-      &quot;\n&quot;
-      &quot;* If the error cannot be reproduced, and/or happens at different\n&quot;
-      &quot;  points in compression, you may have a flaky memory system.\n&quot;
-      &quot;  Try a memory-test program.  I have used Memtest86\n&quot;
-      &quot;  (www.memtest86.com).  At the time of writing it is free (GPLd).\n&quot;
-      &quot;  Memtest86 tests memory much more thorougly than your BIOSs\n&quot;
-      &quot;  power-on test, and may find failures that the BIOS doesn't.\n&quot;
-      &quot;\n&quot;
-      &quot;* If the error can be repeatably reproduced, this is a bug in\n&quot;
-      &quot;  bzip2, and I would very much like to hear about it.  Please\n&quot;
-      &quot;  let me know, and, ideally, save a copy of the file causing the\n&quot;
-      &quot;  problem -- without which I will be unable to investigate it.\n&quot;
-      &quot;\n&quot;
-   );
-   }
-
-   exit(3);
-}
-#endif
-
-
-/*---------------------------------------------------*/
-static
-int bz_config_ok ( void )
-{
-   if (sizeof(int)   != 4) return 0;
-   if (sizeof(short) != 2) return 0;
-   if (sizeof(char)  != 1) return 0;
-   return 1;
-}
-
-
-/*---------------------------------------------------*/
-static
-void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
-{
-   void* v = malloc ( items * size );
-   return v;
-}
-
-static
-void default_bzfree ( void* opaque, void* addr )
-{
-   if (addr != NULL) free ( addr );
-}
-
-
-/*---------------------------------------------------*/
-static
-void prepare_new_block ( EState* s )
-{
-   Int32 i;
-   s-&gt;nblock = 0;
-   s-&gt;numZ = 0;
-   s-&gt;state_out_pos = 0;
-   BZ_INITIALISE_CRC ( s-&gt;blockCRC );
-   for (i = 0; i &lt; 256; i++) s-&gt;inUse[i] = False;
-   s-&gt;blockNo++;
-}
-
-
-/*---------------------------------------------------*/
-static
-void init_RL ( EState* s )
-{
-   s-&gt;state_in_ch  = 256;
-   s-&gt;state_in_len = 0;
-}
-
-
-static
-Bool isempty_RL ( EState* s )
-{
-   if (s-&gt;state_in_ch &lt; 256 &amp;&amp; s-&gt;state_in_len &gt; 0)
-      return False; else
-      return True;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressInit) 
-                    ( bz_stream* strm, 
-                     int        blockSize100k,
-                     int        verbosity,
-                     int        workFactor )
-{
-   Int32   n;
-   EState* s;
-
-   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
-   if (strm == NULL || 
-       blockSize100k &lt; 1 || blockSize100k &gt; 9 ||
-       workFactor &lt; 0 || workFactor &gt; 250)
-     return BZ_PARAM_ERROR;
-
-   if (workFactor == 0) workFactor = 30;
-   if (strm-&gt;bzalloc == NULL) strm-&gt;bzalloc = default_bzalloc;
-   if (strm-&gt;bzfree == NULL) strm-&gt;bzfree = default_bzfree;
-
-   s = BZALLOC( sizeof(EState) );
-   if (s == NULL) return BZ_MEM_ERROR;
-   s-&gt;strm = strm;
-
-   s-&gt;arr1 = NULL;
-   s-&gt;arr2 = NULL;
-   s-&gt;ftab = NULL;
-
-   n       = 100000 * blockSize100k;
-   s-&gt;arr1 = BZALLOC( n                  * sizeof(UInt32) );
-   s-&gt;arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
-   s-&gt;ftab = BZALLOC( 65537              * sizeof(UInt32) );
-
-   if (s-&gt;arr1 == NULL || s-&gt;arr2 == NULL || s-&gt;ftab == NULL) {
-      if (s-&gt;arr1 != NULL) BZFREE(s-&gt;arr1);
-      if (s-&gt;arr2 != NULL) BZFREE(s-&gt;arr2);
-      if (s-&gt;ftab != NULL) BZFREE(s-&gt;ftab);
-      if (s       != NULL) BZFREE(s);
-      return BZ_MEM_ERROR;
-   }
-
-   s-&gt;blockNo           = 0;
-   s-&gt;state             = BZ_S_INPUT;
-   s-&gt;mode              = BZ_M_RUNNING;
-   s-&gt;combinedCRC       = 0;
-   s-&gt;blockSize100k     = blockSize100k;
-   s-&gt;nblockMAX         = 100000 * blockSize100k - 19;
-   s-&gt;verbosity         = verbosity;
-   s-&gt;workFactor        = workFactor;
-
-   s-&gt;block             = (UChar*)s-&gt;arr2;
-   s-&gt;mtfv              = (UInt16*)s-&gt;arr1;
-   s-&gt;zbits             = NULL;
-   s-&gt;ptr               = (UInt32*)s-&gt;arr1;
-
-   strm-&gt;state          = s;
-   strm-&gt;total_in_lo32  = 0;
-   strm-&gt;total_in_hi32  = 0;
-   strm-&gt;total_out_lo32 = 0;
-   strm-&gt;total_out_hi32 = 0;
-   init_RL ( s );
-   prepare_new_block ( s );
-   return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void add_pair_to_block ( EState* s )
-{
-   Int32 i;
-   UChar ch = (UChar)(s-&gt;state_in_ch);
-   for (i = 0; i &lt; s-&gt;state_in_len; i++) {
-      BZ_UPDATE_CRC( s-&gt;blockCRC, ch );
-   }
-   s-&gt;inUse[s-&gt;state_in_ch] = True;
-   switch (s-&gt;state_in_len) {
-      case 1:
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         break;
-      case 2:
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         break;
-      case 3:
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         break;
-      default:
-         s-&gt;inUse[s-&gt;state_in_len-4] = True;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
-         s-&gt;block[s-&gt;nblock] = ((UChar)(s-&gt;state_in_len-4));
-         s-&gt;nblock++;
-         break;
-   }
-}
-
-
-/*---------------------------------------------------*/
-static
-void flush_RL ( EState* s )
-{
-   if (s-&gt;state_in_ch &lt; 256) add_pair_to_block ( s );
-   init_RL ( s );
-}
-
-
-/*---------------------------------------------------*/
-#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
-{                                                 \
-   UInt32 zchh = (UInt32)(zchh0);                 \
-   /*-- fast track the common case --*/           \
-   if (zchh != zs-&gt;state_in_ch &amp;&amp;                 \
-       zs-&gt;state_in_len == 1) {                   \
-      UChar ch = (UChar)(zs-&gt;state_in_ch);        \
-      BZ_UPDATE_CRC( zs-&gt;blockCRC, ch );          \
-      zs-&gt;inUse[zs-&gt;state_in_ch] = True;          \
-      zs-&gt;block[zs-&gt;nblock] = (UChar)ch;          \
-      zs-&gt;nblock++;                               \
-      zs-&gt;state_in_ch = zchh;                     \
-   }                                              \
-   else                                           \
-   /*-- general, uncommon cases --*/              \
-   if (zchh != zs-&gt;state_in_ch ||                 \
-      zs-&gt;state_in_len == 255) {                  \
-      if (zs-&gt;state_in_ch &lt; 256)                  \
-         add_pair_to_block ( zs );                \
-      zs-&gt;state_in_ch = zchh;                     \
-      zs-&gt;state_in_len = 1;                       \
-   } else {                                       \
-      zs-&gt;state_in_len++;                         \
-   }                                              \
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_input_until_stop ( EState* s )
-{
-   Bool progress_in = False;
-
-   if (s-&gt;mode == BZ_M_RUNNING) {
-
-      /*-- fast track the common case --*/
-      while (True) {
-         /*-- block full? --*/
-         if (s-&gt;nblock &gt;= s-&gt;nblockMAX) break;
-         /*-- no input? --*/
-         if (s-&gt;strm-&gt;avail_in == 0) break;
-         progress_in = True;
-         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s-&gt;strm-&gt;next_in))) ); 
-         s-&gt;strm-&gt;next_in++;
-         s-&gt;strm-&gt;avail_in--;
-         s-&gt;strm-&gt;total_in_lo32++;
-         if (s-&gt;strm-&gt;total_in_lo32 == 0) s-&gt;strm-&gt;total_in_hi32++;
-      }
-
-   } else {
-
-      /*-- general, uncommon case --*/
-      while (True) {
-         /*-- block full? --*/
-         if (s-&gt;nblock &gt;= s-&gt;nblockMAX) break;
-         /*-- no input? --*/
-         if (s-&gt;strm-&gt;avail_in == 0) break;
-         /*-- flush/finish end? --*/
-         if (s-&gt;avail_in_expect == 0) break;
-         progress_in = True;
-         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s-&gt;strm-&gt;next_in))) ); 
-         s-&gt;strm-&gt;next_in++;
-         s-&gt;strm-&gt;avail_in--;
-         s-&gt;strm-&gt;total_in_lo32++;
-         if (s-&gt;strm-&gt;total_in_lo32 == 0) s-&gt;strm-&gt;total_in_hi32++;
-         s-&gt;avail_in_expect--;
-      }
-   }
-   return progress_in;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_output_until_stop ( EState* s )
-{
-   Bool progress_out = False;
-
-   while (True) {
-
-      /*-- no output space? --*/
-      if (s-&gt;strm-&gt;avail_out == 0) break;
-
-      /*-- block done? --*/
-      if (s-&gt;state_out_pos &gt;= s-&gt;numZ) break;
-
-      progress_out = True;
-      *(s-&gt;strm-&gt;next_out) = s-&gt;zbits[s-&gt;state_out_pos];
-      s-&gt;state_out_pos++;
-      s-&gt;strm-&gt;avail_out--;
-      s-&gt;strm-&gt;next_out++;
-      s-&gt;strm-&gt;total_out_lo32++;
-      if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
-   }
-
-   return progress_out;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool handle_compress ( bz_stream* strm )
-{
-   Bool progress_in  = False;
-   Bool progress_out = False;
-   EState* s = strm-&gt;state;
-   
-   while (True) {
-
-      if (s-&gt;state == BZ_S_OUTPUT) {
-         progress_out |= copy_output_until_stop ( s );
-         if (s-&gt;state_out_pos &lt; s-&gt;numZ) break;
-         if (s-&gt;mode == BZ_M_FINISHING &amp;&amp; 
-             s-&gt;avail_in_expect == 0 &amp;&amp;
-             isempty_RL(s)) break;
-         prepare_new_block ( s );
-         s-&gt;state = BZ_S_INPUT;
-         if (s-&gt;mode == BZ_M_FLUSHING &amp;&amp; 
-             s-&gt;avail_in_expect == 0 &amp;&amp;
-             isempty_RL(s)) break;
-      }
-
-      if (s-&gt;state == BZ_S_INPUT) {
-         progress_in |= copy_input_until_stop ( s );
-         if (s-&gt;mode != BZ_M_RUNNING &amp;&amp; s-&gt;avail_in_expect == 0) {
-            flush_RL ( s );
-            BZ2_compressBlock ( s, (Bool)(s-&gt;mode == BZ_M_FINISHING) );
-            s-&gt;state = BZ_S_OUTPUT;
-         }
-         else
-         if (s-&gt;nblock &gt;= s-&gt;nblockMAX) {
-            BZ2_compressBlock ( s, False );
-            s-&gt;state = BZ_S_OUTPUT;
-         }
-         else
-         if (s-&gt;strm-&gt;avail_in == 0) {
-            break;
-         }
-      }
-
-   }
-
-   return progress_in || progress_out;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
-{
-   Bool progress;
-   EState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm-&gt;state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
-
-   preswitch:
-   switch (s-&gt;mode) {
-
-      case BZ_M_IDLE:
-         return BZ_SEQUENCE_ERROR;
-
-      case BZ_M_RUNNING:
-         if (action == BZ_RUN) {
-            progress = handle_compress ( strm );
-            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
-         } 
-         else
-	 if (action == BZ_FLUSH) {
-            s-&gt;avail_in_expect = strm-&gt;avail_in;
-            s-&gt;mode = BZ_M_FLUSHING;
-            goto preswitch;
-         }
-         else
-         if (action == BZ_FINISH) {
-            s-&gt;avail_in_expect = strm-&gt;avail_in;
-            s-&gt;mode = BZ_M_FINISHING;
-            goto preswitch;
-         }
-         else 
-            return BZ_PARAM_ERROR;
-
-      case BZ_M_FLUSHING:
-         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
-         if (s-&gt;avail_in_expect != s-&gt;strm-&gt;avail_in) 
-            return BZ_SEQUENCE_ERROR;
-         progress = handle_compress ( strm );
-         if (s-&gt;avail_in_expect &gt; 0 || !isempty_RL(s) ||
-             s-&gt;state_out_pos &lt; s-&gt;numZ) return BZ_FLUSH_OK;
-         s-&gt;mode = BZ_M_RUNNING;
-         return BZ_RUN_OK;
-
-      case BZ_M_FINISHING:
-         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
-         if (s-&gt;avail_in_expect != s-&gt;strm-&gt;avail_in) 
-            return BZ_SEQUENCE_ERROR;
-         progress = handle_compress ( strm );
-         if (!progress) return BZ_SEQUENCE_ERROR;
-         if (s-&gt;avail_in_expect &gt; 0 || !isempty_RL(s) ||
-             s-&gt;state_out_pos &lt; s-&gt;numZ) return BZ_FINISH_OK;
-         s-&gt;mode = BZ_M_IDLE;
-         return BZ_STREAM_END;
-   }
-   return BZ_OK; /*--not reached--*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
-{
-   EState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm-&gt;state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
-
-   if (s-&gt;arr1 != NULL) BZFREE(s-&gt;arr1);
-   if (s-&gt;arr2 != NULL) BZFREE(s-&gt;arr2);
-   if (s-&gt;ftab != NULL) BZFREE(s-&gt;ftab);
-   BZFREE(strm-&gt;state);
-
-   strm-&gt;state = NULL;   
-
-   return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/*--- Decompression stuff                         ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressInit) 
-                     ( bz_stream* strm, 
-                       int        verbosity,
-                       int        small )
-{
-   DState* s;
-
-   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   if (small != 0 &amp;&amp; small != 1) return BZ_PARAM_ERROR;
-   if (verbosity &lt; 0 || verbosity &gt; 4) return BZ_PARAM_ERROR;
-
-   if (strm-&gt;bzalloc == NULL) strm-&gt;bzalloc = default_bzalloc;
-   if (strm-&gt;bzfree == NULL) strm-&gt;bzfree = default_bzfree;
-
-   s = BZALLOC( sizeof(DState) );
-   if (s == NULL) return BZ_MEM_ERROR;
-   s-&gt;strm                  = strm;
-   strm-&gt;state              = s;
-   s-&gt;state                 = BZ_X_MAGIC_1;
-   s-&gt;bsLive                = 0;
-   s-&gt;bsBuff                = 0;
-   s-&gt;calculatedCombinedCRC = 0;
-   strm-&gt;total_in_lo32      = 0;
-   strm-&gt;total_in_hi32      = 0;
-   strm-&gt;total_out_lo32     = 0;
-   strm-&gt;total_out_hi32     = 0;
-   s-&gt;smallDecompress       = (Bool)small;
-   s-&gt;ll4                   = NULL;
-   s-&gt;ll16                  = NULL;
-   s-&gt;tt                    = NULL;
-   s-&gt;currBlockNo           = 0;
-   s-&gt;verbosity             = verbosity;
-
-   return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/* Return  True iff data corruption is discovered.
-   Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_FAST ( DState* s )
-{
-   UChar k1;
-
-   if (s-&gt;blockRandomised) {
-
-      while (True) {
-         /* try to finish existing run */
-         while (True) {
-            if (s-&gt;strm-&gt;avail_out == 0) return False;
-            if (s-&gt;state_out_len == 0) break;
-            *( (UChar*)(s-&gt;strm-&gt;next_out) ) = s-&gt;state_out_ch;
-            BZ_UPDATE_CRC ( s-&gt;calculatedBlockCRC, s-&gt;state_out_ch );
-            s-&gt;state_out_len--;
-            s-&gt;strm-&gt;next_out++;
-            s-&gt;strm-&gt;avail_out--;
-            s-&gt;strm-&gt;total_out_lo32++;
-            if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
-         }
-
-         /* can a new run be started? */
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) return False;
-               
-         /* Only caused by corrupt data stream? */
-         if (s-&gt;nblock_used &gt; s-&gt;save_nblock+1)
-            return True;
-   
-         s-&gt;state_out_len = 1;
-         s-&gt;state_out_ch = s-&gt;k0;
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         s-&gt;state_out_len = 2;
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         s-&gt;state_out_len = 3;
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         s-&gt;state_out_len = ((Int32)k1) + 4;
-         BZ_GET_FAST(s-&gt;k0); BZ_RAND_UPD_MASK; 
-         s-&gt;k0 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-      }
-
-   } else {
-
-      /* restore */
-      UInt32        c_calculatedBlockCRC = s-&gt;calculatedBlockCRC;
-      UChar         c_state_out_ch       = s-&gt;state_out_ch;
-      Int32         c_state_out_len      = s-&gt;state_out_len;
-      Int32         c_nblock_used        = s-&gt;nblock_used;
-      Int32         c_k0                 = s-&gt;k0;
-      UInt32*       c_tt                 = s-&gt;tt;
-      UInt32        c_tPos               = s-&gt;tPos;
-      char*         cs_next_out          = s-&gt;strm-&gt;next_out;
-      unsigned int  cs_avail_out         = s-&gt;strm-&gt;avail_out;
-      Int32         ro_blockSize100k     = s-&gt;blockSize100k;
-      /* end restore */
-
-      UInt32       avail_out_INIT = cs_avail_out;
-      Int32        s_save_nblockPP = s-&gt;save_nblock+1;
-      unsigned int total_out_lo32_old;
-
-      while (True) {
-
-         /* try to finish existing run */
-         if (c_state_out_len &gt; 0) {
-            while (True) {
-               if (cs_avail_out == 0) goto return_notr;
-               if (c_state_out_len == 1) break;
-               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
-               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
-               c_state_out_len--;
-               cs_next_out++;
-               cs_avail_out--;
-            }
-            s_state_out_len_eq_one:
-            {
-               if (cs_avail_out == 0) { 
-                  c_state_out_len = 1; goto return_notr;
-               };
-               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
-               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
-               cs_next_out++;
-               cs_avail_out--;
-            }
-         }   
-         /* Only caused by corrupt data stream? */
-         if (c_nblock_used &gt; s_save_nblockPP)
-            return True;
-
-         /* can a new run be started? */
-         if (c_nblock_used == s_save_nblockPP) {
-            c_state_out_len = 0; goto return_notr;
-         };   
-         c_state_out_ch = c_k0;
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         if (k1 != c_k0) { 
-            c_k0 = k1; goto s_state_out_len_eq_one; 
-         };
-         if (c_nblock_used == s_save_nblockPP) 
-            goto s_state_out_len_eq_one;
-   
-         c_state_out_len = 2;
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         if (c_nblock_used == s_save_nblockPP) continue;
-         if (k1 != c_k0) { c_k0 = k1; continue; };
-   
-         c_state_out_len = 3;
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         if (c_nblock_used == s_save_nblockPP) continue;
-         if (k1 != c_k0) { c_k0 = k1; continue; };
-   
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         c_state_out_len = ((Int32)k1) + 4;
-         BZ_GET_FAST_C(c_k0); c_nblock_used++;
-      }
-
-      return_notr:
-      total_out_lo32_old = s-&gt;strm-&gt;total_out_lo32;
-      s-&gt;strm-&gt;total_out_lo32 += (avail_out_INIT - cs_avail_out);
-      if (s-&gt;strm-&gt;total_out_lo32 &lt; total_out_lo32_old)
-         s-&gt;strm-&gt;total_out_hi32++;
-
-      /* save */
-      s-&gt;calculatedBlockCRC = c_calculatedBlockCRC;
-      s-&gt;state_out_ch       = c_state_out_ch;
-      s-&gt;state_out_len      = c_state_out_len;
-      s-&gt;nblock_used        = c_nblock_used;
-      s-&gt;k0                 = c_k0;
-      s-&gt;tt                 = c_tt;
-      s-&gt;tPos               = c_tPos;
-      s-&gt;strm-&gt;next_out     = cs_next_out;
-      s-&gt;strm-&gt;avail_out    = cs_avail_out;
-      /* end save */
-   }
-   return False;
-}
-
-
-
-/*---------------------------------------------------*/
-__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
-{
-   Int32 nb, na, mid;
-   nb = 0;
-   na = 256;
-   do {
-      mid = (nb + na) &gt;&gt; 1;
-      if (indx &gt;= cftab[mid]) nb = mid; else na = mid;
-   }
-   while (na - nb != 1);
-   return nb;
-}
-
-
-/*---------------------------------------------------*/
-/* Return  True iff data corruption is discovered.
-   Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_SMALL ( DState* s )
-{
-   UChar k1;
-
-   if (s-&gt;blockRandomised) {
-
-      while (True) {
-         /* try to finish existing run */
-         while (True) {
-            if (s-&gt;strm-&gt;avail_out == 0) return False;
-            if (s-&gt;state_out_len == 0) break;
-            *( (UChar*)(s-&gt;strm-&gt;next_out) ) = s-&gt;state_out_ch;
-            BZ_UPDATE_CRC ( s-&gt;calculatedBlockCRC, s-&gt;state_out_ch );
-            s-&gt;state_out_len--;
-            s-&gt;strm-&gt;next_out++;
-            s-&gt;strm-&gt;avail_out--;
-            s-&gt;strm-&gt;total_out_lo32++;
-            if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
-         }
-   
-         /* can a new run be started? */
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) return False;
-
-         /* Only caused by corrupt data stream? */
-         if (s-&gt;nblock_used &gt; s-&gt;save_nblock+1)
-            return True;
-   
-         s-&gt;state_out_len = 1;
-         s-&gt;state_out_ch = s-&gt;k0;
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         s-&gt;state_out_len = 2;
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         s-&gt;state_out_len = 3;
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
-         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-         s-&gt;state_out_len = ((Int32)k1) + 4;
-         BZ_GET_SMALL(s-&gt;k0); BZ_RAND_UPD_MASK; 
-         s-&gt;k0 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
-      }
-
-   } else {
-
-      while (True) {
-         /* try to finish existing run */
-         while (True) {
-            if (s-&gt;strm-&gt;avail_out == 0) return False;
-            if (s-&gt;state_out_len == 0) break;
-            *( (UChar*)(s-&gt;strm-&gt;next_out) ) = s-&gt;state_out_ch;
-            BZ_UPDATE_CRC ( s-&gt;calculatedBlockCRC, s-&gt;state_out_ch );
-            s-&gt;state_out_len--;
-            s-&gt;strm-&gt;next_out++;
-            s-&gt;strm-&gt;avail_out--;
-            s-&gt;strm-&gt;total_out_lo32++;
-            if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
-         }
-   
-         /* can a new run be started? */
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) return False;
-
-         /* Only caused by corrupt data stream? */
-         if (s-&gt;nblock_used &gt; s-&gt;save_nblock+1)
-            return True;
-   
-         s-&gt;state_out_len = 1;
-         s-&gt;state_out_ch = s-&gt;k0;
-         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         s-&gt;state_out_len = 2;
-         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         s-&gt;state_out_len = 3;
-         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
-         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
-   
-         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
-         s-&gt;state_out_len = ((Int32)k1) + 4;
-         BZ_GET_SMALL(s-&gt;k0); s-&gt;nblock_used++;
-      }
-
-   }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
-{
-   Bool    corrupt;
-   DState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm-&gt;state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
-
-   while (True) {
-      if (s-&gt;state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
-      if (s-&gt;state == BZ_X_OUTPUT) {
-         if (s-&gt;smallDecompress)
-            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
-            corrupt = unRLE_obuf_to_output_FAST  ( s );
-         if (corrupt) return BZ_DATA_ERROR;
-         if (s-&gt;nblock_used == s-&gt;save_nblock+1 &amp;&amp; s-&gt;state_out_len == 0) {
-            BZ_FINALISE_CRC ( s-&gt;calculatedBlockCRC );
-            if (s-&gt;verbosity &gt;= 3) 
-               VPrintf2 ( &quot; {0x%08x, 0x%08x}&quot;, s-&gt;storedBlockCRC, 
-                          s-&gt;calculatedBlockCRC );
-            if (s-&gt;verbosity &gt;= 2) VPrintf0 ( &quot;]&quot; );
-            if (s-&gt;calculatedBlockCRC != s-&gt;storedBlockCRC)
-               return BZ_DATA_ERROR;
-            s-&gt;calculatedCombinedCRC 
-               = (s-&gt;calculatedCombinedCRC &lt;&lt; 1) | 
-                    (s-&gt;calculatedCombinedCRC &gt;&gt; 31);
-            s-&gt;calculatedCombinedCRC ^= s-&gt;calculatedBlockCRC;
-            s-&gt;state = BZ_X_BLKHDR_1;
-         } else {
-            return BZ_OK;
-         }
-      }
-      if (s-&gt;state &gt;= BZ_X_MAGIC_1) {
-         Int32 r = BZ2_decompress ( s );
-         if (r == BZ_STREAM_END) {
-            if (s-&gt;verbosity &gt;= 3)
-               VPrintf2 ( &quot;\n    combined CRCs: stored = 0x%08x, computed = 0x%08x&quot;, 
-                          s-&gt;storedCombinedCRC, s-&gt;calculatedCombinedCRC );
-            if (s-&gt;calculatedCombinedCRC != s-&gt;storedCombinedCRC)
-               return BZ_DATA_ERROR;
-            return r;
-         }
-         if (s-&gt;state != BZ_X_OUTPUT) return r;
-      }
-   }
-
-   AssertH ( 0, 6001 );
-
-   return 0;  /*NOTREACHED*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
-{
-   DState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm-&gt;state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
-
-   if (s-&gt;tt   != NULL) BZFREE(s-&gt;tt);
-   if (s-&gt;ll16 != NULL) BZFREE(s-&gt;ll16);
-   if (s-&gt;ll4  != NULL) BZFREE(s-&gt;ll4);
-
-   BZFREE(strm-&gt;state);
-   strm-&gt;state = NULL;
-
-   return BZ_OK;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-/*--- File I/O stuff                              ---*/
-/*---------------------------------------------------*/
-
-#define BZ_SETERR(eee)                    \
-{                                         \
-   if (bzerror != NULL) *bzerror = eee;   \
-   if (bzf != NULL) bzf-&gt;lastErr = eee;   \
-}
-
-typedef 
-   struct {
-      FILE*     handle;
-      Char      buf[BZ_MAX_UNUSED];
-      Int32     bufN;
-      Bool      writing;
-      bz_stream strm;
-      Int32     lastErr;
-      Bool      initialisedOk;
-   }
-   bzFile;
-
-
-/*---------------------------------------------*/
-static Bool myfeof ( FILE* f )
-{
-   Int32 c = fgetc ( f );
-   if (c == EOF) return True;
-   ungetc ( c, f );
-   return False;
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzWriteOpen) 
-                    ( int*  bzerror,      
-                      FILE* f, 
-                      int   blockSize100k, 
-                      int   verbosity,
-                      int   workFactor )
-{
-   Int32   ret;
-   bzFile* bzf = NULL;
-
-   BZ_SETERR(BZ_OK);
-
-   if (f == NULL ||
-       (blockSize100k &lt; 1 || blockSize100k &gt; 9) ||
-       (workFactor &lt; 0 || workFactor &gt; 250) ||
-       (verbosity &lt; 0 || verbosity &gt; 4))
-      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
-   if (ferror(f))
-      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
-   bzf = malloc ( sizeof(bzFile) );
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
-   BZ_SETERR(BZ_OK);
-   bzf-&gt;initialisedOk = False;
-   bzf-&gt;bufN          = 0;
-   bzf-&gt;handle        = f;
-   bzf-&gt;writing       = True;
-   bzf-&gt;strm.bzalloc  = NULL;
-   bzf-&gt;strm.bzfree   = NULL;
-   bzf-&gt;strm.opaque   = NULL;
-
-   if (workFactor == 0) workFactor = 30;
-   ret = BZ2_bzCompressInit ( &amp;(bzf-&gt;strm), blockSize100k, 
-                              verbosity, workFactor );
-   if (ret != BZ_OK)
-      { BZ_SETERR(ret); free(bzf); return NULL; };
-
-   bzf-&gt;strm.avail_in = 0;
-   bzf-&gt;initialisedOk = True;
-   return bzf;   
-}
-
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWrite)
-             ( int*    bzerror, 
-               BZFILE* b, 
-               void*   buf, 
-               int     len )
-{
-   Int32 n, n2, ret;
-   bzFile* bzf = (bzFile*)b;
-
-   BZ_SETERR(BZ_OK);
-   if (bzf == NULL || buf == NULL || len &lt; 0)
-      { BZ_SETERR(BZ_PARAM_ERROR); return; };
-   if (!(bzf-&gt;writing))
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-   if (ferror(bzf-&gt;handle))
-      { BZ_SETERR(BZ_IO_ERROR); return; };
-
-   if (len == 0)
-      { BZ_SETERR(BZ_OK); return; };
-
-   bzf-&gt;strm.avail_in = len;
-   bzf-&gt;strm.next_in  = buf;
-
-   while (True) {
-      bzf-&gt;strm.avail_out = BZ_MAX_UNUSED;
-      bzf-&gt;strm.next_out = bzf-&gt;buf;
-      ret = BZ2_bzCompress ( &amp;(bzf-&gt;strm), BZ_RUN );
-      if (ret != BZ_RUN_OK)
-         { BZ_SETERR(ret); return; };
-
-      if (bzf-&gt;strm.avail_out &lt; BZ_MAX_UNUSED) {
-         n = BZ_MAX_UNUSED - bzf-&gt;strm.avail_out;
-         n2 = fwrite ( (void*)(bzf-&gt;buf), sizeof(UChar), 
-                       n, bzf-&gt;handle );
-         if (n != n2 || ferror(bzf-&gt;handle))
-            { BZ_SETERR(BZ_IO_ERROR); return; };
-      }
-
-      if (bzf-&gt;strm.avail_in == 0)
-         { BZ_SETERR(BZ_OK); return; };
-   }
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWriteClose)
-                  ( int*          bzerror, 
-                    BZFILE*       b, 
-                    int           abandon,
-                    unsigned int* nbytes_in,
-                    unsigned int* nbytes_out )
-{
-   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
-                        nbytes_in, NULL, nbytes_out, NULL );
-}
-
-
-void BZ_API(BZ2_bzWriteClose64)
-                  ( int*          bzerror, 
-                    BZFILE*       b, 
-                    int           abandon,
-                    unsigned int* nbytes_in_lo32,
-                    unsigned int* nbytes_in_hi32,
-                    unsigned int* nbytes_out_lo32,
-                    unsigned int* nbytes_out_hi32 )
-{
-   Int32   n, n2, ret;
-   bzFile* bzf = (bzFile*)b;
-
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_OK); return; };
-   if (!(bzf-&gt;writing))
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-   if (ferror(bzf-&gt;handle))
-      { BZ_SETERR(BZ_IO_ERROR); return; };
-
-   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
-   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
-   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
-   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
-
-   if ((!abandon) &amp;&amp; bzf-&gt;lastErr == BZ_OK) {
-      while (True) {
-         bzf-&gt;strm.avail_out = BZ_MAX_UNUSED;
-         bzf-&gt;strm.next_out = bzf-&gt;buf;
-         ret = BZ2_bzCompress ( &amp;(bzf-&gt;strm), BZ_FINISH );
-         if (ret != BZ_FINISH_OK &amp;&amp; ret != BZ_STREAM_END)
-            { BZ_SETERR(ret); return; };
-
-         if (bzf-&gt;strm.avail_out &lt; BZ_MAX_UNUSED) {
-            n = BZ_MAX_UNUSED - bzf-&gt;strm.avail_out;
-            n2 = fwrite ( (void*)(bzf-&gt;buf), sizeof(UChar), 
-                          n, bzf-&gt;handle );
-            if (n != n2 || ferror(bzf-&gt;handle))
-               { BZ_SETERR(BZ_IO_ERROR); return; };
-         }
-
-         if (ret == BZ_STREAM_END) break;
-      }
-   }
-
-   if ( !abandon &amp;&amp; !ferror ( bzf-&gt;handle ) ) {
-      fflush ( bzf-&gt;handle );
-      if (ferror(bzf-&gt;handle))
-         { BZ_SETERR(BZ_IO_ERROR); return; };
-   }
-
-   if (nbytes_in_lo32 != NULL)
-      *nbytes_in_lo32 = bzf-&gt;strm.total_in_lo32;
-   if (nbytes_in_hi32 != NULL)
-      *nbytes_in_hi32 = bzf-&gt;strm.total_in_hi32;
-   if (nbytes_out_lo32 != NULL)
-      *nbytes_out_lo32 = bzf-&gt;strm.total_out_lo32;
-   if (nbytes_out_hi32 != NULL)
-      *nbytes_out_hi32 = bzf-&gt;strm.total_out_hi32;
-
-   BZ_SETERR(BZ_OK);
-   BZ2_bzCompressEnd ( &amp;(bzf-&gt;strm) );
-   free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzReadOpen) 
-                   ( int*  bzerror, 
-                     FILE* f, 
-                     int   verbosity,
-                     int   small,
-                     void* unused,
-                     int   nUnused )
-{
-   bzFile* bzf = NULL;
-   int     ret;
-
-   BZ_SETERR(BZ_OK);
-
-   if (f == NULL || 
-       (small != 0 &amp;&amp; small != 1) ||
-       (verbosity &lt; 0 || verbosity &gt; 4) ||
-       (unused == NULL &amp;&amp; nUnused != 0) ||
-       (unused != NULL &amp;&amp; (nUnused &lt; 0 || nUnused &gt; BZ_MAX_UNUSED)))
-      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
-   if (ferror(f))
-      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
-   bzf = malloc ( sizeof(bzFile) );
-   if (bzf == NULL) 
-      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
-   BZ_SETERR(BZ_OK);
-
-   bzf-&gt;initialisedOk = False;
-   bzf-&gt;handle        = f;
-   bzf-&gt;bufN          = 0;
-   bzf-&gt;writing       = False;
-   bzf-&gt;strm.bzalloc  = NULL;
-   bzf-&gt;strm.bzfree   = NULL;
-   bzf-&gt;strm.opaque   = NULL;
-   
-   while (nUnused &gt; 0) {
-      bzf-&gt;buf[bzf-&gt;bufN] = *((UChar*)(unused)); bzf-&gt;bufN++;
-      unused = ((void*)( 1 + ((UChar*)(unused))  ));
-      nUnused--;
-   }
-
-   ret = BZ2_bzDecompressInit ( &amp;(bzf-&gt;strm), verbosity, small );
-   if (ret != BZ_OK)
-      { BZ_SETERR(ret); free(bzf); return NULL; };
-
-   bzf-&gt;strm.avail_in = bzf-&gt;bufN;
-   bzf-&gt;strm.next_in  = bzf-&gt;buf;
-
-   bzf-&gt;initialisedOk = True;
-   return bzf;   
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
-{
-   bzFile* bzf = (bzFile*)b;
-
-   BZ_SETERR(BZ_OK);
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_OK); return; };
-
-   if (bzf-&gt;writing)
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-
-   if (bzf-&gt;initialisedOk)
-      (void)BZ2_bzDecompressEnd ( &amp;(bzf-&gt;strm) );
-   free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzRead) 
-           ( int*    bzerror, 
-             BZFILE* b, 
-             void*   buf, 
-             int     len )
-{
-   Int32   n, ret;
-   bzFile* bzf = (bzFile*)b;
-
-   BZ_SETERR(BZ_OK);
-
-   if (bzf == NULL || buf == NULL || len &lt; 0)
-      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
-
-   if (bzf-&gt;writing)
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
-
-   if (len == 0)
-      { BZ_SETERR(BZ_OK); return 0; };
-
-   bzf-&gt;strm.avail_out = len;
-   bzf-&gt;strm.next_out = buf;
-
-   while (True) {
-
-      if (ferror(bzf-&gt;handle)) 
-         { BZ_SETERR(BZ_IO_ERROR); return 0; };
-
-      if (bzf-&gt;strm.avail_in == 0 &amp;&amp; !myfeof(bzf-&gt;handle)) {
-         n = fread ( bzf-&gt;buf, sizeof(UChar), 
-                     BZ_MAX_UNUSED, bzf-&gt;handle );
-         if (ferror(bzf-&gt;handle))
-            { BZ_SETERR(BZ_IO_ERROR); return 0; };
-         bzf-&gt;bufN = n;
-         bzf-&gt;strm.avail_in = bzf-&gt;bufN;
-         bzf-&gt;strm.next_in = bzf-&gt;buf;
-      }
-
-      ret = BZ2_bzDecompress ( &amp;(bzf-&gt;strm) );
-
-      if (ret != BZ_OK &amp;&amp; ret != BZ_STREAM_END)
-         { BZ_SETERR(ret); return 0; };
-
-      if (ret == BZ_OK &amp;&amp; myfeof(bzf-&gt;handle) &amp;&amp; 
-          bzf-&gt;strm.avail_in == 0 &amp;&amp; bzf-&gt;strm.avail_out &gt; 0)
-         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
-
-      if (ret == BZ_STREAM_END)
-         { BZ_SETERR(BZ_STREAM_END);
-           return len - bzf-&gt;strm.avail_out; };
-      if (bzf-&gt;strm.avail_out == 0)
-         { BZ_SETERR(BZ_OK); return len; };
-      
-   }
-
-   return 0; /*not reached*/
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadGetUnused) 
-                     ( int*    bzerror, 
-                       BZFILE* b, 
-                       void**  unused, 
-                       int*    nUnused )
-{
-   bzFile* bzf = (bzFile*)b;
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_PARAM_ERROR); return; };
-   if (bzf-&gt;lastErr != BZ_STREAM_END)
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-   if (unused == NULL || nUnused == NULL)
-      { BZ_SETERR(BZ_PARAM_ERROR); return; };
-
-   BZ_SETERR(BZ_OK);
-   *nUnused = bzf-&gt;strm.avail_in;
-   *unused = bzf-&gt;strm.next_in;
-}
-#endif
-
-
-/*---------------------------------------------------*/
-/*--- Misc convenience stuff                      ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffCompress) 
-                         ( char*         dest, 
-                           unsigned int* destLen,
-                           char*         source, 
-                           unsigned int  sourceLen,
-                           int           blockSize100k, 
-                           int           verbosity, 
-                           int           workFactor )
-{
-   bz_stream strm;
-   int ret;
-
-   if (dest == NULL || destLen == NULL || 
-       source == NULL ||
-       blockSize100k &lt; 1 || blockSize100k &gt; 9 ||
-       verbosity &lt; 0 || verbosity &gt; 4 ||
-       workFactor &lt; 0 || workFactor &gt; 250) 
-      return BZ_PARAM_ERROR;
-
-   if (workFactor == 0) workFactor = 30;
-   strm.bzalloc = NULL;
-   strm.bzfree = NULL;
-   strm.opaque = NULL;
-   ret = BZ2_bzCompressInit ( &amp;strm, blockSize100k, 
-                              verbosity, workFactor );
-   if (ret != BZ_OK) return ret;
-
-   strm.next_in = source;
-   strm.next_out = dest;
-   strm.avail_in = sourceLen;
-   strm.avail_out = *destLen;
-
-   ret = BZ2_bzCompress ( &amp;strm, BZ_FINISH );
-   if (ret == BZ_FINISH_OK) goto output_overflow;
-   if (ret != BZ_STREAM_END) goto errhandler;
-
-   /* normal termination */
-   *destLen -= strm.avail_out;   
-   BZ2_bzCompressEnd ( &amp;strm );
-   return BZ_OK;
-
-   output_overflow:
-   BZ2_bzCompressEnd ( &amp;strm );
-   return BZ_OUTBUFF_FULL;
-
-   errhandler:
-   BZ2_bzCompressEnd ( &amp;strm );
-   return ret;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffDecompress) 
-                           ( char*         dest, 
-                             unsigned int* destLen,
-                             char*         source, 
-                             unsigned int  sourceLen,
-                             int           small,
-                             int           verbosity )
-{
-   bz_stream strm;
-   int ret;
-
-   if (dest == NULL || destLen == NULL || 
-       source == NULL ||
-       (small != 0 &amp;&amp; small != 1) ||
-       verbosity &lt; 0 || verbosity &gt; 4) 
-          return BZ_PARAM_ERROR;
-
-   strm.bzalloc = NULL;
-   strm.bzfree = NULL;
-   strm.opaque = NULL;
-   ret = BZ2_bzDecompressInit ( &amp;strm, verbosity, small );
-   if (ret != BZ_OK) return ret;
-
-   strm.next_in = source;
-   strm.next_out = dest;
-   strm.avail_in = sourceLen;
-   strm.avail_out = *destLen;
-
-   ret = BZ2_bzDecompress ( &amp;strm );
-   if (ret == BZ_OK) goto output_overflow_or_eof;
-   if (ret != BZ_STREAM_END) goto errhandler;
-
-   /* normal termination */
-   *destLen -= strm.avail_out;
-   BZ2_bzDecompressEnd ( &amp;strm );
-   return BZ_OK;
-
-   output_overflow_or_eof:
-   if (strm.avail_out &gt; 0) {
-      BZ2_bzDecompressEnd ( &amp;strm );
-      return BZ_UNEXPECTED_EOF;
-   } else {
-      BZ2_bzDecompressEnd ( &amp;strm );
-      return BZ_OUTBUFF_FULL;
-   };      
-
-   errhandler:
-   BZ2_bzDecompressEnd ( &amp;strm );
-   return ret; 
-}
-
-
-/*---------------------------------------------------*/
-/*--
-   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
-   to support better zlib compatibility.
-   This code is not _officially_ part of libbzip2 (yet);
-   I haven't tested it, documented it, or considered the
-   threading-safeness of it.
-   If this code breaks, please contact both Yoshioka and me.
---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-/*--
-   return version like &quot;0.9.5d, 4-Sept-1999&quot;.
---*/
-const char * BZ_API(BZ2_bzlibVersion)(void)
-{
-   return BZ_VERSION;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-
-#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
-#   include &lt;fcntl.h&gt;
-#   include &lt;io.h&gt;
-#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
-#else
-#   define SET_BINARY_MODE(file)
-#endif
-static
-BZFILE * bzopen_or_bzdopen
-               ( const char *path,   /* no use when bzdopen */
-                 int fd,             /* no use when bzdopen */
-                 const char *mode,
-                 int open_mode)      /* bzopen: 0, bzdopen:1 */
-{
-   int    bzerr;
-   char   unused[BZ_MAX_UNUSED];
-   int    blockSize100k = 9;
-   int    writing       = 0;
-   char   mode2[10]     = &quot;&quot;;
-   FILE   *fp           = NULL;
-   BZFILE *bzfp         = NULL;
-   int    verbosity     = 0;
-   int    workFactor    = 30;
-   int    smallMode     = 0;
-   int    nUnused       = 0; 
-
-   if (mode == NULL) return NULL;
-   while (*mode) {
-      switch (*mode) {
-      case 'r':
-         writing = 0; break;
-      case 'w':
-         writing = 1; break;
-      case 's':
-         smallMode = 1; break;
-      default:
-         if (isdigit((int)(*mode))) {
-            blockSize100k = *mode-BZ_HDR_0;
-         }
-      }
-      mode++;
-   }
-   strcat(mode2, writing ? &quot;w&quot; : &quot;r&quot; );
-   strcat(mode2,&quot;b&quot;);   /* binary mode */
-
-   if (open_mode==0) {
-      if (path==NULL || strcmp(path,&quot;&quot;)==0) {
-        fp = (writing ? stdout : stdin);
-        SET_BINARY_MODE(fp);
-      } else {
-        fp = fopen(path,mode2);
-      }
-   } else {
-#ifdef BZ_STRICT_ANSI
-      fp = NULL;
-#else
-      fp = fdopen(fd,mode2);
-#endif
-   }
-   if (fp == NULL) return NULL;
-
-   if (writing) {
-      /* Guard against total chaos and anarchy -- JRS */
-      if (blockSize100k &lt; 1) blockSize100k = 1;
-      if (blockSize100k &gt; 9) blockSize100k = 9; 
-      bzfp = BZ2_bzWriteOpen(&amp;bzerr,fp,blockSize100k,
-                             verbosity,workFactor);
-   } else {
-      bzfp = BZ2_bzReadOpen(&amp;bzerr,fp,verbosity,smallMode,
-                            unused,nUnused);
-   }
-   if (bzfp == NULL) {
-      if (fp != stdin &amp;&amp; fp != stdout) fclose(fp);
-      return NULL;
-   }
-   return bzfp;
-}
-
-
-/*---------------------------------------------------*/
-/*--
-   open file for read or write.
-      ex) bzopen(&quot;file&quot;,&quot;w9&quot;)
-      case path=&quot;&quot; or NULL =&gt; use stdin or stdout.
---*/
-BZFILE * BZ_API(BZ2_bzopen)
-               ( const char *path,
-                 const char *mode )
-{
-   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
-}
-
-
-/*---------------------------------------------------*/
-BZFILE * BZ_API(BZ2_bzdopen)
-               ( int fd,
-                 const char *mode )
-{
-   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
-{
-   int bzerr, nread;
-   if (((bzFile*)b)-&gt;lastErr == BZ_STREAM_END) return 0;
-   nread = BZ2_bzRead(&amp;bzerr,b,buf,len);
-   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
-      return nread;
-   } else {
-      return -1;
-   }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
-{
-   int bzerr;
-
-   BZ2_bzWrite(&amp;bzerr,b,buf,len);
-   if(bzerr == BZ_OK){
-      return len;
-   }else{
-      return -1;
-   }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzflush) (BZFILE *b)
-{
-   /* do nothing now... */
-   return 0;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzclose) (BZFILE* b)
-{
-   int bzerr;
-   FILE *fp;
-   
-   if (b==NULL) {return;}
-   fp = ((bzFile *)b)-&gt;handle;
-   if(((bzFile*)b)-&gt;writing){
-      BZ2_bzWriteClose(&amp;bzerr,b,0,NULL,NULL);
-      if(bzerr != BZ_OK){
-         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
-      }
-   }else{
-      BZ2_bzReadClose(&amp;bzerr,b);
-   }
-   if(fp!=stdin &amp;&amp; fp!=stdout){
-      fclose(fp);
-   }
-}
-
-
-/*---------------------------------------------------*/
-/*--
-   return last error code 
---*/
-static const char *bzerrorstrings[] = {
-       &quot;OK&quot;
-      ,&quot;SEQUENCE_ERROR&quot;
-      ,&quot;PARAM_ERROR&quot;
-      ,&quot;MEM_ERROR&quot;
-      ,&quot;DATA_ERROR&quot;
-      ,&quot;DATA_ERROR_MAGIC&quot;
-      ,&quot;IO_ERROR&quot;
-      ,&quot;UNEXPECTED_EOF&quot;
-      ,&quot;OUTBUFF_FULL&quot;
-      ,&quot;CONFIG_ERROR&quot;
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-};
-
-
-const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
-{
-   int err = ((bzFile *)b)-&gt;lastErr;
-
-   if(err&gt;0) err = 0;
-   *errnum = err;
-   return bzerrorstrings[err*-1];
-}
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                           bzlib.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+/* CHANGES
+   0.9.0    -- original version.
+   0.9.0a/b -- no changes in this file.
+   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+     fixed bzWrite/bzRead to ignore zero-length requests.
+     fixed bzread to correctly handle read requests after EOF.
+     wrong parameter order in call to bzDecompressInit in
+     bzBuffToBuffDecompress.  Fixed.
+*/
+
+#include &quot;bzlib_private.h&quot;
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+   fprintf(stderr, 
+      &quot;\n\nbzip2/libbzip2: internal error number %d.\n&quot;
+      &quot;This is a bug in bzip2/libbzip2, %s.\n&quot;
+      &quot;Please report it to me at: jseward@bzip.org.  If this happened\n&quot;
+      &quot;when you were using some program which uses libbzip2 as a\n&quot;
+      &quot;component, you should also report this bug to the author(s)\n&quot;
+      &quot;of that program.  Please make an effort to report this bug;\n&quot;
+      &quot;timely and accurate bug reports eventually lead to higher\n&quot;
+      &quot;quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n&quot;,
+      errcode,
+      BZ2_bzlibVersion()
+   );
+
+   if (errcode == 1007) {
+   fprintf(stderr,
+      &quot;\n*** A special note about internal error number 1007 ***\n&quot;
+      &quot;\n&quot;
+      &quot;Experience suggests that a common cause of i.e. 1007\n&quot;
+      &quot;is unreliable memory or other hardware.  The 1007 assertion\n&quot;
+      &quot;just happens to cross-check the results of huge numbers of\n&quot;
+      &quot;memory reads/writes, and so acts (unintendedly) as a stress\n&quot;
+      &quot;test of your memory system.\n&quot;
+      &quot;\n&quot;
+      &quot;I suggest the following: try compressing the file again,\n&quot;
+      &quot;possibly monitoring progress in detail with the -vv flag.\n&quot;
+      &quot;\n&quot;
+      &quot;* If the error cannot be reproduced, and/or happens at different\n&quot;
+      &quot;  points in compression, you may have a flaky memory system.\n&quot;
+      &quot;  Try a memory-test program.  I have used Memtest86\n&quot;
+      &quot;  (www.memtest86.com).  At the time of writing it is free (GPLd).\n&quot;
+      &quot;  Memtest86 tests memory much more thorougly than your BIOSs\n&quot;
+      &quot;  power-on test, and may find failures that the BIOS doesn't.\n&quot;
+      &quot;\n&quot;
+      &quot;* If the error can be repeatably reproduced, this is a bug in\n&quot;
+      &quot;  bzip2, and I would very much like to hear about it.  Please\n&quot;
+      &quot;  let me know, and, ideally, save a copy of the file causing the\n&quot;
+      &quot;  problem -- without which I will be unable to investigate it.\n&quot;
+      &quot;\n&quot;
+   );
+   }
+
+   exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+   if (sizeof(int)   != 4) return 0;
+   if (sizeof(short) != 2) return 0;
+   if (sizeof(char)  != 1) return 0;
+   return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+   void* v = malloc ( items * size );
+   return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+   if (addr != NULL) free ( addr );
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+   Int32 i;
+   s-&gt;nblock = 0;
+   s-&gt;numZ = 0;
+   s-&gt;state_out_pos = 0;
+   BZ_INITIALISE_CRC ( s-&gt;blockCRC );
+   for (i = 0; i &lt; 256; i++) s-&gt;inUse[i] = False;
+   s-&gt;blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+   s-&gt;state_in_ch  = 256;
+   s-&gt;state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+   if (s-&gt;state_in_ch &lt; 256 &amp;&amp; s-&gt;state_in_len &gt; 0)
+      return False; else
+      return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit) 
+                    ( bz_stream* strm, 
+                     int        blockSize100k,
+                     int        verbosity,
+                     int        workFactor )
+{
+   Int32   n;
+   EState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL || 
+       blockSize100k &lt; 1 || blockSize100k &gt; 9 ||
+       workFactor &lt; 0 || workFactor &gt; 250)
+     return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   if (strm-&gt;bzalloc == NULL) strm-&gt;bzalloc = default_bzalloc;
+   if (strm-&gt;bzfree == NULL) strm-&gt;bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(EState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s-&gt;strm = strm;
+
+   s-&gt;arr1 = NULL;
+   s-&gt;arr2 = NULL;
+   s-&gt;ftab = NULL;
+
+   n       = 100000 * blockSize100k;
+   s-&gt;arr1 = BZALLOC( n                  * sizeof(UInt32) );
+   s-&gt;arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+   s-&gt;ftab = BZALLOC( 65537              * sizeof(UInt32) );
+
+   if (s-&gt;arr1 == NULL || s-&gt;arr2 == NULL || s-&gt;ftab == NULL) {
+      if (s-&gt;arr1 != NULL) BZFREE(s-&gt;arr1);
+      if (s-&gt;arr2 != NULL) BZFREE(s-&gt;arr2);
+      if (s-&gt;ftab != NULL) BZFREE(s-&gt;ftab);
+      if (s       != NULL) BZFREE(s);
+      return BZ_MEM_ERROR;
+   }
+
+   s-&gt;blockNo           = 0;
+   s-&gt;state             = BZ_S_INPUT;
+   s-&gt;mode              = BZ_M_RUNNING;
+   s-&gt;combinedCRC       = 0;
+   s-&gt;blockSize100k     = blockSize100k;
+   s-&gt;nblockMAX         = 100000 * blockSize100k - 19;
+   s-&gt;verbosity         = verbosity;
+   s-&gt;workFactor        = workFactor;
+
+   s-&gt;block             = (UChar*)s-&gt;arr2;
+   s-&gt;mtfv              = (UInt16*)s-&gt;arr1;
+   s-&gt;zbits             = NULL;
+   s-&gt;ptr               = (UInt32*)s-&gt;arr1;
+
+   strm-&gt;state          = s;
+   strm-&gt;total_in_lo32  = 0;
+   strm-&gt;total_in_hi32  = 0;
+   strm-&gt;total_out_lo32 = 0;
+   strm-&gt;total_out_hi32 = 0;
+   init_RL ( s );
+   prepare_new_block ( s );
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+   Int32 i;
+   UChar ch = (UChar)(s-&gt;state_in_ch);
+   for (i = 0; i &lt; s-&gt;state_in_len; i++) {
+      BZ_UPDATE_CRC( s-&gt;blockCRC, ch );
+   }
+   s-&gt;inUse[s-&gt;state_in_ch] = True;
+   switch (s-&gt;state_in_len) {
+      case 1:
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         break;
+      case 2:
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         break;
+      case 3:
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         break;
+      default:
+         s-&gt;inUse[s-&gt;state_in_len-4] = True;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = (UChar)ch; s-&gt;nblock++;
+         s-&gt;block[s-&gt;nblock] = ((UChar)(s-&gt;state_in_len-4));
+         s-&gt;nblock++;
+         break;
+   }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+   if (s-&gt;state_in_ch &lt; 256) add_pair_to_block ( s );
+   init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
+{                                                 \
+   UInt32 zchh = (UInt32)(zchh0);                 \
+   /*-- fast track the common case --*/           \
+   if (zchh != zs-&gt;state_in_ch &amp;&amp;                 \
+       zs-&gt;state_in_len == 1) {                   \
+      UChar ch = (UChar)(zs-&gt;state_in_ch);        \
+      BZ_UPDATE_CRC( zs-&gt;blockCRC, ch );          \
+      zs-&gt;inUse[zs-&gt;state_in_ch] = True;          \
+      zs-&gt;block[zs-&gt;nblock] = (UChar)ch;          \
+      zs-&gt;nblock++;                               \
+      zs-&gt;state_in_ch = zchh;                     \
+   }                                              \
+   else                                           \
+   /*-- general, uncommon cases --*/              \
+   if (zchh != zs-&gt;state_in_ch ||                 \
+      zs-&gt;state_in_len == 255) {                  \
+      if (zs-&gt;state_in_ch &lt; 256)                  \
+         add_pair_to_block ( zs );                \
+      zs-&gt;state_in_ch = zchh;                     \
+      zs-&gt;state_in_len = 1;                       \
+   } else {                                       \
+      zs-&gt;state_in_len++;                         \
+   }                                              \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+   Bool progress_in = False;
+
+   if (s-&gt;mode == BZ_M_RUNNING) {
+
+      /*-- fast track the common case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s-&gt;nblock &gt;= s-&gt;nblockMAX) break;
+         /*-- no input? --*/
+         if (s-&gt;strm-&gt;avail_in == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s-&gt;strm-&gt;next_in))) ); 
+         s-&gt;strm-&gt;next_in++;
+         s-&gt;strm-&gt;avail_in--;
+         s-&gt;strm-&gt;total_in_lo32++;
+         if (s-&gt;strm-&gt;total_in_lo32 == 0) s-&gt;strm-&gt;total_in_hi32++;
+      }
+
+   } else {
+
+      /*-- general, uncommon case --*/
+      while (True) {
+         /*-- block full? --*/
+         if (s-&gt;nblock &gt;= s-&gt;nblockMAX) break;
+         /*-- no input? --*/
+         if (s-&gt;strm-&gt;avail_in == 0) break;
+         /*-- flush/finish end? --*/
+         if (s-&gt;avail_in_expect == 0) break;
+         progress_in = True;
+         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s-&gt;strm-&gt;next_in))) ); 
+         s-&gt;strm-&gt;next_in++;
+         s-&gt;strm-&gt;avail_in--;
+         s-&gt;strm-&gt;total_in_lo32++;
+         if (s-&gt;strm-&gt;total_in_lo32 == 0) s-&gt;strm-&gt;total_in_hi32++;
+         s-&gt;avail_in_expect--;
+      }
+   }
+   return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+   Bool progress_out = False;
+
+   while (True) {
+
+      /*-- no output space? --*/
+      if (s-&gt;strm-&gt;avail_out == 0) break;
+
+      /*-- block done? --*/
+      if (s-&gt;state_out_pos &gt;= s-&gt;numZ) break;
+
+      progress_out = True;
+      *(s-&gt;strm-&gt;next_out) = s-&gt;zbits[s-&gt;state_out_pos];
+      s-&gt;state_out_pos++;
+      s-&gt;strm-&gt;avail_out--;
+      s-&gt;strm-&gt;next_out++;
+      s-&gt;strm-&gt;total_out_lo32++;
+      if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
+   }
+
+   return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+   Bool progress_in  = False;
+   Bool progress_out = False;
+   EState* s = strm-&gt;state;
+   
+   while (True) {
+
+      if (s-&gt;state == BZ_S_OUTPUT) {
+         progress_out |= copy_output_until_stop ( s );
+         if (s-&gt;state_out_pos &lt; s-&gt;numZ) break;
+         if (s-&gt;mode == BZ_M_FINISHING &amp;&amp; 
+             s-&gt;avail_in_expect == 0 &amp;&amp;
+             isempty_RL(s)) break;
+         prepare_new_block ( s );
+         s-&gt;state = BZ_S_INPUT;
+         if (s-&gt;mode == BZ_M_FLUSHING &amp;&amp; 
+             s-&gt;avail_in_expect == 0 &amp;&amp;
+             isempty_RL(s)) break;
+      }
+
+      if (s-&gt;state == BZ_S_INPUT) {
+         progress_in |= copy_input_until_stop ( s );
+         if (s-&gt;mode != BZ_M_RUNNING &amp;&amp; s-&gt;avail_in_expect == 0) {
+            flush_RL ( s );
+            BZ2_compressBlock ( s, (Bool)(s-&gt;mode == BZ_M_FINISHING) );
+            s-&gt;state = BZ_S_OUTPUT;
+         }
+         else
+         if (s-&gt;nblock &gt;= s-&gt;nblockMAX) {
+            BZ2_compressBlock ( s, False );
+            s-&gt;state = BZ_S_OUTPUT;
+         }
+         else
+         if (s-&gt;strm-&gt;avail_in == 0) {
+            break;
+         }
+      }
+
+   }
+
+   return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+   Bool progress;
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm-&gt;state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
+
+   preswitch:
+   switch (s-&gt;mode) {
+
+      case BZ_M_IDLE:
+         return BZ_SEQUENCE_ERROR;
+
+      case BZ_M_RUNNING:
+         if (action == BZ_RUN) {
+            progress = handle_compress ( strm );
+            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+         } 
+         else
+	 if (action == BZ_FLUSH) {
+            s-&gt;avail_in_expect = strm-&gt;avail_in;
+            s-&gt;mode = BZ_M_FLUSHING;
+            goto preswitch;
+         }
+         else
+         if (action == BZ_FINISH) {
+            s-&gt;avail_in_expect = strm-&gt;avail_in;
+            s-&gt;mode = BZ_M_FINISHING;
+            goto preswitch;
+         }
+         else 
+            return BZ_PARAM_ERROR;
+
+      case BZ_M_FLUSHING:
+         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+         if (s-&gt;avail_in_expect != s-&gt;strm-&gt;avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (s-&gt;avail_in_expect &gt; 0 || !isempty_RL(s) ||
+             s-&gt;state_out_pos &lt; s-&gt;numZ) return BZ_FLUSH_OK;
+         s-&gt;mode = BZ_M_RUNNING;
+         return BZ_RUN_OK;
+
+      case BZ_M_FINISHING:
+         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+         if (s-&gt;avail_in_expect != s-&gt;strm-&gt;avail_in) 
+            return BZ_SEQUENCE_ERROR;
+         progress = handle_compress ( strm );
+         if (!progress) return BZ_SEQUENCE_ERROR;
+         if (s-&gt;avail_in_expect &gt; 0 || !isempty_RL(s) ||
+             s-&gt;state_out_pos &lt; s-&gt;numZ) return BZ_FINISH_OK;
+         s-&gt;mode = BZ_M_IDLE;
+         return BZ_STREAM_END;
+   }
+   return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
+{
+   EState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm-&gt;state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
+
+   if (s-&gt;arr1 != NULL) BZFREE(s-&gt;arr1);
+   if (s-&gt;arr2 != NULL) BZFREE(s-&gt;arr2);
+   if (s-&gt;ftab != NULL) BZFREE(s-&gt;ftab);
+   BZFREE(strm-&gt;state);
+
+   strm-&gt;state = NULL;   
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit) 
+                     ( bz_stream* strm, 
+                       int        verbosity,
+                       int        small )
+{
+   DState* s;
+
+   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   if (small != 0 &amp;&amp; small != 1) return BZ_PARAM_ERROR;
+   if (verbosity &lt; 0 || verbosity &gt; 4) return BZ_PARAM_ERROR;
+
+   if (strm-&gt;bzalloc == NULL) strm-&gt;bzalloc = default_bzalloc;
+   if (strm-&gt;bzfree == NULL) strm-&gt;bzfree = default_bzfree;
+
+   s = BZALLOC( sizeof(DState) );
+   if (s == NULL) return BZ_MEM_ERROR;
+   s-&gt;strm                  = strm;
+   strm-&gt;state              = s;
+   s-&gt;state                 = BZ_X_MAGIC_1;
+   s-&gt;bsLive                = 0;
+   s-&gt;bsBuff                = 0;
+   s-&gt;calculatedCombinedCRC = 0;
+   strm-&gt;total_in_lo32      = 0;
+   strm-&gt;total_in_hi32      = 0;
+   strm-&gt;total_out_lo32     = 0;
+   strm-&gt;total_out_hi32     = 0;
+   s-&gt;smallDecompress       = (Bool)small;
+   s-&gt;ll4                   = NULL;
+   s-&gt;ll16                  = NULL;
+   s-&gt;tt                    = NULL;
+   s-&gt;currBlockNo           = 0;
+   s-&gt;verbosity             = verbosity;
+
+   return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+   UChar k1;
+
+   if (s-&gt;blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s-&gt;strm-&gt;avail_out == 0) return False;
+            if (s-&gt;state_out_len == 0) break;
+            *( (UChar*)(s-&gt;strm-&gt;next_out) ) = s-&gt;state_out_ch;
+            BZ_UPDATE_CRC ( s-&gt;calculatedBlockCRC, s-&gt;state_out_ch );
+            s-&gt;state_out_len--;
+            s-&gt;strm-&gt;next_out++;
+            s-&gt;strm-&gt;avail_out--;
+            s-&gt;strm-&gt;total_out_lo32++;
+            if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
+         }
+
+         /* can a new run be started? */
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) return False;
+               
+         /* Only caused by corrupt data stream? */
+         if (s-&gt;nblock_used &gt; s-&gt;save_nblock+1)
+            return True;
+   
+         s-&gt;state_out_len = 1;
+         s-&gt;state_out_ch = s-&gt;k0;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         s-&gt;state_out_len = 2;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         s-&gt;state_out_len = 3;
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         s-&gt;state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST(s-&gt;k0); BZ_RAND_UPD_MASK; 
+         s-&gt;k0 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+      }
+
+   } else {
+
+      /* restore */
+      UInt32        c_calculatedBlockCRC = s-&gt;calculatedBlockCRC;
+      UChar         c_state_out_ch       = s-&gt;state_out_ch;
+      Int32         c_state_out_len      = s-&gt;state_out_len;
+      Int32         c_nblock_used        = s-&gt;nblock_used;
+      Int32         c_k0                 = s-&gt;k0;
+      UInt32*       c_tt                 = s-&gt;tt;
+      UInt32        c_tPos               = s-&gt;tPos;
+      char*         cs_next_out          = s-&gt;strm-&gt;next_out;
+      unsigned int  cs_avail_out         = s-&gt;strm-&gt;avail_out;
+      Int32         ro_blockSize100k     = s-&gt;blockSize100k;
+      /* end restore */
+
+      UInt32       avail_out_INIT = cs_avail_out;
+      Int32        s_save_nblockPP = s-&gt;save_nblock+1;
+      unsigned int total_out_lo32_old;
+
+      while (True) {
+
+         /* try to finish existing run */
+         if (c_state_out_len &gt; 0) {
+            while (True) {
+               if (cs_avail_out == 0) goto return_notr;
+               if (c_state_out_len == 1) break;
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               c_state_out_len--;
+               cs_next_out++;
+               cs_avail_out--;
+            }
+            s_state_out_len_eq_one:
+            {
+               if (cs_avail_out == 0) { 
+                  c_state_out_len = 1; goto return_notr;
+               };
+               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+               cs_next_out++;
+               cs_avail_out--;
+            }
+         }   
+         /* Only caused by corrupt data stream? */
+         if (c_nblock_used &gt; s_save_nblockPP)
+            return True;
+
+         /* can a new run be started? */
+         if (c_nblock_used == s_save_nblockPP) {
+            c_state_out_len = 0; goto return_notr;
+         };   
+         c_state_out_ch = c_k0;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (k1 != c_k0) { 
+            c_k0 = k1; goto s_state_out_len_eq_one; 
+         };
+         if (c_nblock_used == s_save_nblockPP) 
+            goto s_state_out_len_eq_one;
+   
+         c_state_out_len = 2;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         c_state_out_len = 3;
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         if (c_nblock_used == s_save_nblockPP) continue;
+         if (k1 != c_k0) { c_k0 = k1; continue; };
+   
+         BZ_GET_FAST_C(k1); c_nblock_used++;
+         c_state_out_len = ((Int32)k1) + 4;
+         BZ_GET_FAST_C(c_k0); c_nblock_used++;
+      }
+
+      return_notr:
+      total_out_lo32_old = s-&gt;strm-&gt;total_out_lo32;
+      s-&gt;strm-&gt;total_out_lo32 += (avail_out_INIT - cs_avail_out);
+      if (s-&gt;strm-&gt;total_out_lo32 &lt; total_out_lo32_old)
+         s-&gt;strm-&gt;total_out_hi32++;
+
+      /* save */
+      s-&gt;calculatedBlockCRC = c_calculatedBlockCRC;
+      s-&gt;state_out_ch       = c_state_out_ch;
+      s-&gt;state_out_len      = c_state_out_len;
+      s-&gt;nblock_used        = c_nblock_used;
+      s-&gt;k0                 = c_k0;
+      s-&gt;tt                 = c_tt;
+      s-&gt;tPos               = c_tPos;
+      s-&gt;strm-&gt;next_out     = cs_next_out;
+      s-&gt;strm-&gt;avail_out    = cs_avail_out;
+      /* end save */
+   }
+   return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+   Int32 nb, na, mid;
+   nb = 0;
+   na = 256;
+   do {
+      mid = (nb + na) &gt;&gt; 1;
+      if (indx &gt;= cftab[mid]) nb = mid; else na = mid;
+   }
+   while (na - nb != 1);
+   return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return  True iff data corruption is discovered.
+   Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+   UChar k1;
+
+   if (s-&gt;blockRandomised) {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s-&gt;strm-&gt;avail_out == 0) return False;
+            if (s-&gt;state_out_len == 0) break;
+            *( (UChar*)(s-&gt;strm-&gt;next_out) ) = s-&gt;state_out_ch;
+            BZ_UPDATE_CRC ( s-&gt;calculatedBlockCRC, s-&gt;state_out_ch );
+            s-&gt;state_out_len--;
+            s-&gt;strm-&gt;next_out++;
+            s-&gt;strm-&gt;avail_out--;
+            s-&gt;strm-&gt;total_out_lo32++;
+            if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s-&gt;nblock_used &gt; s-&gt;save_nblock+1)
+            return True;
+   
+         s-&gt;state_out_len = 1;
+         s-&gt;state_out_ch = s-&gt;k0;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         s-&gt;state_out_len = 2;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         s-&gt;state_out_len = 3;
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
+         k1 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+         s-&gt;state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s-&gt;k0); BZ_RAND_UPD_MASK; 
+         s-&gt;k0 ^= BZ_RAND_MASK; s-&gt;nblock_used++;
+      }
+
+   } else {
+
+      while (True) {
+         /* try to finish existing run */
+         while (True) {
+            if (s-&gt;strm-&gt;avail_out == 0) return False;
+            if (s-&gt;state_out_len == 0) break;
+            *( (UChar*)(s-&gt;strm-&gt;next_out) ) = s-&gt;state_out_ch;
+            BZ_UPDATE_CRC ( s-&gt;calculatedBlockCRC, s-&gt;state_out_ch );
+            s-&gt;state_out_len--;
+            s-&gt;strm-&gt;next_out++;
+            s-&gt;strm-&gt;avail_out--;
+            s-&gt;strm-&gt;total_out_lo32++;
+            if (s-&gt;strm-&gt;total_out_lo32 == 0) s-&gt;strm-&gt;total_out_hi32++;
+         }
+   
+         /* can a new run be started? */
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) return False;
+
+         /* Only caused by corrupt data stream? */
+         if (s-&gt;nblock_used &gt; s-&gt;save_nblock+1)
+            return True;
+   
+         s-&gt;state_out_len = 1;
+         s-&gt;state_out_ch = s-&gt;k0;
+         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         s-&gt;state_out_len = 2;
+         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         s-&gt;state_out_len = 3;
+         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1) continue;
+         if (k1 != s-&gt;k0) { s-&gt;k0 = k1; continue; };
+   
+         BZ_GET_SMALL(k1); s-&gt;nblock_used++;
+         s-&gt;state_out_len = ((Int32)k1) + 4;
+         BZ_GET_SMALL(s-&gt;k0); s-&gt;nblock_used++;
+      }
+
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+   Bool    corrupt;
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm-&gt;state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
+
+   while (True) {
+      if (s-&gt;state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+      if (s-&gt;state == BZ_X_OUTPUT) {
+         if (s-&gt;smallDecompress)
+            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+            corrupt = unRLE_obuf_to_output_FAST  ( s );
+         if (corrupt) return BZ_DATA_ERROR;
+         if (s-&gt;nblock_used == s-&gt;save_nblock+1 &amp;&amp; s-&gt;state_out_len == 0) {
+            BZ_FINALISE_CRC ( s-&gt;calculatedBlockCRC );
+            if (s-&gt;verbosity &gt;= 3) 
+               VPrintf2 ( &quot; {0x%08x, 0x%08x}&quot;, s-&gt;storedBlockCRC, 
+                          s-&gt;calculatedBlockCRC );
+            if (s-&gt;verbosity &gt;= 2) VPrintf0 ( &quot;]&quot; );
+            if (s-&gt;calculatedBlockCRC != s-&gt;storedBlockCRC)
+               return BZ_DATA_ERROR;
+            s-&gt;calculatedCombinedCRC 
+               = (s-&gt;calculatedCombinedCRC &lt;&lt; 1) | 
+                    (s-&gt;calculatedCombinedCRC &gt;&gt; 31);
+            s-&gt;calculatedCombinedCRC ^= s-&gt;calculatedBlockCRC;
+            s-&gt;state = BZ_X_BLKHDR_1;
+         } else {
+            return BZ_OK;
+         }
+      }
+      if (s-&gt;state &gt;= BZ_X_MAGIC_1) {
+         Int32 r = BZ2_decompress ( s );
+         if (r == BZ_STREAM_END) {
+            if (s-&gt;verbosity &gt;= 3)
+               VPrintf2 ( &quot;\n    combined CRCs: stored = 0x%08x, computed = 0x%08x&quot;, 
+                          s-&gt;storedCombinedCRC, s-&gt;calculatedCombinedCRC );
+            if (s-&gt;calculatedCombinedCRC != s-&gt;storedCombinedCRC)
+               return BZ_DATA_ERROR;
+            return r;
+         }
+         if (s-&gt;state != BZ_X_OUTPUT) return r;
+      }
+   }
+
+   AssertH ( 0, 6001 );
+
+   return 0;  /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
+{
+   DState* s;
+   if (strm == NULL) return BZ_PARAM_ERROR;
+   s = strm-&gt;state;
+   if (s == NULL) return BZ_PARAM_ERROR;
+   if (s-&gt;strm != strm) return BZ_PARAM_ERROR;
+
+   if (s-&gt;tt   != NULL) BZFREE(s-&gt;tt);
+   if (s-&gt;ll16 != NULL) BZFREE(s-&gt;ll16);
+   if (s-&gt;ll4  != NULL) BZFREE(s-&gt;ll4);
+
+   BZFREE(strm-&gt;state);
+   strm-&gt;state = NULL;
+
+   return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff                              ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee)                    \
+{                                         \
+   if (bzerror != NULL) *bzerror = eee;   \
+   if (bzf != NULL) bzf-&gt;lastErr = eee;   \
+}
+
+typedef 
+   struct {
+      FILE*     handle;
+      Char      buf[BZ_MAX_UNUSED];
+      Int32     bufN;
+      Bool      writing;
+      bz_stream strm;
+      Int32     lastErr;
+      Bool      initialisedOk;
+   }
+   bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+   Int32 c = fgetc ( f );
+   if (c == EOF) return True;
+   ungetc ( c, f );
+   return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen) 
+                    ( int*  bzerror,      
+                      FILE* f, 
+                      int   blockSize100k, 
+                      int   verbosity,
+                      int   workFactor )
+{
+   Int32   ret;
+   bzFile* bzf = NULL;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL ||
+       (blockSize100k &lt; 1 || blockSize100k &gt; 9) ||
+       (workFactor &lt; 0 || workFactor &gt; 250) ||
+       (verbosity &lt; 0 || verbosity &gt; 4))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+   bzf-&gt;initialisedOk = False;
+   bzf-&gt;bufN          = 0;
+   bzf-&gt;handle        = f;
+   bzf-&gt;writing       = True;
+   bzf-&gt;strm.bzalloc  = NULL;
+   bzf-&gt;strm.bzfree   = NULL;
+   bzf-&gt;strm.opaque   = NULL;
+
+   if (workFactor == 0) workFactor = 30;
+   ret = BZ2_bzCompressInit ( &amp;(bzf-&gt;strm), blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf-&gt;strm.avail_in = 0;
+   bzf-&gt;initialisedOk = True;
+   return bzf;   
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+             ( int*    bzerror, 
+               BZFILE* b, 
+               void*   buf, 
+               int     len )
+{
+   Int32 n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL || buf == NULL || len &lt; 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (!(bzf-&gt;writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf-&gt;handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return; };
+
+   bzf-&gt;strm.avail_in = len;
+   bzf-&gt;strm.next_in  = buf;
+
+   while (True) {
+      bzf-&gt;strm.avail_out = BZ_MAX_UNUSED;
+      bzf-&gt;strm.next_out = bzf-&gt;buf;
+      ret = BZ2_bzCompress ( &amp;(bzf-&gt;strm), BZ_RUN );
+      if (ret != BZ_RUN_OK)
+         { BZ_SETERR(ret); return; };
+
+      if (bzf-&gt;strm.avail_out &lt; BZ_MAX_UNUSED) {
+         n = BZ_MAX_UNUSED - bzf-&gt;strm.avail_out;
+         n2 = fwrite ( (void*)(bzf-&gt;buf), sizeof(UChar), 
+                       n, bzf-&gt;handle );
+         if (n != n2 || ferror(bzf-&gt;handle))
+            { BZ_SETERR(BZ_IO_ERROR); return; };
+      }
+
+      if (bzf-&gt;strm.avail_in == 0)
+         { BZ_SETERR(BZ_OK); return; };
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in,
+                    unsigned int* nbytes_out )
+{
+   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
+                        nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+                  ( int*          bzerror, 
+                    BZFILE*       b, 
+                    int           abandon,
+                    unsigned int* nbytes_in_lo32,
+                    unsigned int* nbytes_in_hi32,
+                    unsigned int* nbytes_out_lo32,
+                    unsigned int* nbytes_out_hi32 )
+{
+   Int32   n, n2, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+   if (!(bzf-&gt;writing))
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (ferror(bzf-&gt;handle))
+      { BZ_SETERR(BZ_IO_ERROR); return; };
+
+   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+   if ((!abandon) &amp;&amp; bzf-&gt;lastErr == BZ_OK) {
+      while (True) {
+         bzf-&gt;strm.avail_out = BZ_MAX_UNUSED;
+         bzf-&gt;strm.next_out = bzf-&gt;buf;
+         ret = BZ2_bzCompress ( &amp;(bzf-&gt;strm), BZ_FINISH );
+         if (ret != BZ_FINISH_OK &amp;&amp; ret != BZ_STREAM_END)
+            { BZ_SETERR(ret); return; };
+
+         if (bzf-&gt;strm.avail_out &lt; BZ_MAX_UNUSED) {
+            n = BZ_MAX_UNUSED - bzf-&gt;strm.avail_out;
+            n2 = fwrite ( (void*)(bzf-&gt;buf), sizeof(UChar), 
+                          n, bzf-&gt;handle );
+            if (n != n2 || ferror(bzf-&gt;handle))
+               { BZ_SETERR(BZ_IO_ERROR); return; };
+         }
+
+         if (ret == BZ_STREAM_END) break;
+      }
+   }
+
+   if ( !abandon &amp;&amp; !ferror ( bzf-&gt;handle ) ) {
+      fflush ( bzf-&gt;handle );
+      if (ferror(bzf-&gt;handle))
+         { BZ_SETERR(BZ_IO_ERROR); return; };
+   }
+
+   if (nbytes_in_lo32 != NULL)
+      *nbytes_in_lo32 = bzf-&gt;strm.total_in_lo32;
+   if (nbytes_in_hi32 != NULL)
+      *nbytes_in_hi32 = bzf-&gt;strm.total_in_hi32;
+   if (nbytes_out_lo32 != NULL)
+      *nbytes_out_lo32 = bzf-&gt;strm.total_out_lo32;
+   if (nbytes_out_hi32 != NULL)
+      *nbytes_out_hi32 = bzf-&gt;strm.total_out_hi32;
+
+   BZ_SETERR(BZ_OK);
+   BZ2_bzCompressEnd ( &amp;(bzf-&gt;strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen) 
+                   ( int*  bzerror, 
+                     FILE* f, 
+                     int   verbosity,
+                     int   small,
+                     void* unused,
+                     int   nUnused )
+{
+   bzFile* bzf = NULL;
+   int     ret;
+
+   BZ_SETERR(BZ_OK);
+
+   if (f == NULL || 
+       (small != 0 &amp;&amp; small != 1) ||
+       (verbosity &lt; 0 || verbosity &gt; 4) ||
+       (unused == NULL &amp;&amp; nUnused != 0) ||
+       (unused != NULL &amp;&amp; (nUnused &lt; 0 || nUnused &gt; BZ_MAX_UNUSED)))
+      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+   if (ferror(f))
+      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+   bzf = malloc ( sizeof(bzFile) );
+   if (bzf == NULL) 
+      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+   BZ_SETERR(BZ_OK);
+
+   bzf-&gt;initialisedOk = False;
+   bzf-&gt;handle        = f;
+   bzf-&gt;bufN          = 0;
+   bzf-&gt;writing       = False;
+   bzf-&gt;strm.bzalloc  = NULL;
+   bzf-&gt;strm.bzfree   = NULL;
+   bzf-&gt;strm.opaque   = NULL;
+   
+   while (nUnused &gt; 0) {
+      bzf-&gt;buf[bzf-&gt;bufN] = *((UChar*)(unused)); bzf-&gt;bufN++;
+      unused = ((void*)( 1 + ((UChar*)(unused))  ));
+      nUnused--;
+   }
+
+   ret = BZ2_bzDecompressInit ( &amp;(bzf-&gt;strm), verbosity, small );
+   if (ret != BZ_OK)
+      { BZ_SETERR(ret); free(bzf); return NULL; };
+
+   bzf-&gt;strm.avail_in = bzf-&gt;bufN;
+   bzf-&gt;strm.next_in  = bzf-&gt;buf;
+
+   bzf-&gt;initialisedOk = True;
+   return bzf;   
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_OK); return; };
+
+   if (bzf-&gt;writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+   if (bzf-&gt;initialisedOk)
+      (void)BZ2_bzDecompressEnd ( &amp;(bzf-&gt;strm) );
+   free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead) 
+           ( int*    bzerror, 
+             BZFILE* b, 
+             void*   buf, 
+             int     len )
+{
+   Int32   n, ret;
+   bzFile* bzf = (bzFile*)b;
+
+   BZ_SETERR(BZ_OK);
+
+   if (bzf == NULL || buf == NULL || len &lt; 0)
+      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+   if (bzf-&gt;writing)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+   if (len == 0)
+      { BZ_SETERR(BZ_OK); return 0; };
+
+   bzf-&gt;strm.avail_out = len;
+   bzf-&gt;strm.next_out = buf;
+
+   while (True) {
+
+      if (ferror(bzf-&gt;handle)) 
+         { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+      if (bzf-&gt;strm.avail_in == 0 &amp;&amp; !myfeof(bzf-&gt;handle)) {
+         n = fread ( bzf-&gt;buf, sizeof(UChar), 
+                     BZ_MAX_UNUSED, bzf-&gt;handle );
+         if (ferror(bzf-&gt;handle))
+            { BZ_SETERR(BZ_IO_ERROR); return 0; };
+         bzf-&gt;bufN = n;
+         bzf-&gt;strm.avail_in = bzf-&gt;bufN;
+         bzf-&gt;strm.next_in = bzf-&gt;buf;
+      }
+
+      ret = BZ2_bzDecompress ( &amp;(bzf-&gt;strm) );
+
+      if (ret != BZ_OK &amp;&amp; ret != BZ_STREAM_END)
+         { BZ_SETERR(ret); return 0; };
+
+      if (ret == BZ_OK &amp;&amp; myfeof(bzf-&gt;handle) &amp;&amp; 
+          bzf-&gt;strm.avail_in == 0 &amp;&amp; bzf-&gt;strm.avail_out &gt; 0)
+         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+      if (ret == BZ_STREAM_END)
+         { BZ_SETERR(BZ_STREAM_END);
+           return len - bzf-&gt;strm.avail_out; };
+      if (bzf-&gt;strm.avail_out == 0)
+         { BZ_SETERR(BZ_OK); return len; };
+      
+   }
+
+   return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused) 
+                     ( int*    bzerror, 
+                       BZFILE* b, 
+                       void**  unused, 
+                       int*    nUnused )
+{
+   bzFile* bzf = (bzFile*)b;
+   if (bzf == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+   if (bzf-&gt;lastErr != BZ_STREAM_END)
+      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+   if (unused == NULL || nUnused == NULL)
+      { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+   BZ_SETERR(BZ_OK);
+   *nUnused = bzf-&gt;strm.avail_in;
+   *unused = bzf-&gt;strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress) 
+                         ( char*         dest, 
+                           unsigned int* destLen,
+                           char*         source, 
+                           unsigned int  sourceLen,
+                           int           blockSize100k, 
+                           int           verbosity, 
+                           int           workFactor )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       blockSize100k &lt; 1 || blockSize100k &gt; 9 ||
+       verbosity &lt; 0 || verbosity &gt; 4 ||
+       workFactor &lt; 0 || workFactor &gt; 250) 
+      return BZ_PARAM_ERROR;
+
+   if (workFactor == 0) workFactor = 30;
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzCompressInit ( &amp;strm, blockSize100k, 
+                              verbosity, workFactor );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzCompress ( &amp;strm, BZ_FINISH );
+   if (ret == BZ_FINISH_OK) goto output_overflow;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;   
+   BZ2_bzCompressEnd ( &amp;strm );
+   return BZ_OK;
+
+   output_overflow:
+   BZ2_bzCompressEnd ( &amp;strm );
+   return BZ_OUTBUFF_FULL;
+
+   errhandler:
+   BZ2_bzCompressEnd ( &amp;strm );
+   return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress) 
+                           ( char*         dest, 
+                             unsigned int* destLen,
+                             char*         source, 
+                             unsigned int  sourceLen,
+                             int           small,
+                             int           verbosity )
+{
+   bz_stream strm;
+   int ret;
+
+   if (dest == NULL || destLen == NULL || 
+       source == NULL ||
+       (small != 0 &amp;&amp; small != 1) ||
+       verbosity &lt; 0 || verbosity &gt; 4) 
+          return BZ_PARAM_ERROR;
+
+   strm.bzalloc = NULL;
+   strm.bzfree = NULL;
+   strm.opaque = NULL;
+   ret = BZ2_bzDecompressInit ( &amp;strm, verbosity, small );
+   if (ret != BZ_OK) return ret;
+
+   strm.next_in = source;
+   strm.next_out = dest;
+   strm.avail_in = sourceLen;
+   strm.avail_out = *destLen;
+
+   ret = BZ2_bzDecompress ( &amp;strm );
+   if (ret == BZ_OK) goto output_overflow_or_eof;
+   if (ret != BZ_STREAM_END) goto errhandler;
+
+   /* normal termination */
+   *destLen -= strm.avail_out;
+   BZ2_bzDecompressEnd ( &amp;strm );
+   return BZ_OK;
+
+   output_overflow_or_eof:
+   if (strm.avail_out &gt; 0) {
+      BZ2_bzDecompressEnd ( &amp;strm );
+      return BZ_UNEXPECTED_EOF;
+   } else {
+      BZ2_bzDecompressEnd ( &amp;strm );
+      return BZ_OUTBUFF_FULL;
+   };      
+
+   errhandler:
+   BZ2_bzDecompressEnd ( &amp;strm );
+   return ret; 
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+   return version like &quot;0.9.5d, 4-Sept-1999&quot;.
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+   return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#   include &lt;fcntl.h&gt;
+#   include &lt;io.h&gt;
+#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+               ( const char *path,   /* no use when bzdopen */
+                 int fd,             /* no use when bzdopen */
+                 const char *mode,
+                 int open_mode)      /* bzopen: 0, bzdopen:1 */
+{
+   int    bzerr;
+   char   unused[BZ_MAX_UNUSED];
+   int    blockSize100k = 9;
+   int    writing       = 0;
+   char   mode2[10]     = &quot;&quot;;
+   FILE   *fp           = NULL;
+   BZFILE *bzfp         = NULL;
+   int    verbosity     = 0;
+   int    workFactor    = 30;
+   int    smallMode     = 0;
+   int    nUnused       = 0; 
+
+   if (mode == NULL) return NULL;
+   while (*mode) {
+      switch (*mode) {
+      case 'r':
+         writing = 0; break;
+      case 'w':
+         writing = 1; break;
+      case 's':
+         smallMode = 1; break;
+      default:
+         if (isdigit((int)(*mode))) {
+            blockSize100k = *mode-BZ_HDR_0;
+         }
+      }
+      mode++;
+   }
+   strcat(mode2, writing ? &quot;w&quot; : &quot;r&quot; );
+   strcat(mode2,&quot;b&quot;);   /* binary mode */
+
+   if (open_mode==0) {
+      if (path==NULL || strcmp(path,&quot;&quot;)==0) {
+        fp = (writing ? stdout : stdin);
+        SET_BINARY_MODE(fp);
+      } else {
+        fp = fopen(path,mode2);
+      }
+   } else {
+#ifdef BZ_STRICT_ANSI
+      fp = NULL;
+#else
+      fp = fdopen(fd,mode2);
+#endif
+   }
+   if (fp == NULL) return NULL;
+
+   if (writing) {
+      /* Guard against total chaos and anarchy -- JRS */
+      if (blockSize100k &lt; 1) blockSize100k = 1;
+      if (blockSize100k &gt; 9) blockSize100k = 9; 
+      bzfp = BZ2_bzWriteOpen(&amp;bzerr,fp,blockSize100k,
+                             verbosity,workFactor);
+   } else {
+      bzfp = BZ2_bzReadOpen(&amp;bzerr,fp,verbosity,smallMode,
+                            unused,nUnused);
+   }
+   if (bzfp == NULL) {
+      if (fp != stdin &amp;&amp; fp != stdout) fclose(fp);
+      return NULL;
+   }
+   return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   open file for read or write.
+      ex) bzopen(&quot;file&quot;,&quot;w9&quot;)
+      case path=&quot;&quot; or NULL =&gt; use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+               ( const char *path,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+               ( int fd,
+                 const char *mode )
+{
+   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+   int bzerr, nread;
+   if (((bzFile*)b)-&gt;lastErr == BZ_STREAM_END) return 0;
+   nread = BZ2_bzRead(&amp;bzerr,b,buf,len);
+   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+      return nread;
+   } else {
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+   int bzerr;
+
+   BZ2_bzWrite(&amp;bzerr,b,buf,len);
+   if(bzerr == BZ_OK){
+      return len;
+   }else{
+      return -1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+   /* do nothing now... */
+   return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+   int bzerr;
+   FILE *fp;
+   
+   if (b==NULL) {return;}
+   fp = ((bzFile *)b)-&gt;handle;
+   if(((bzFile*)b)-&gt;writing){
+      BZ2_bzWriteClose(&amp;bzerr,b,0,NULL,NULL);
+      if(bzerr != BZ_OK){
+         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+      }
+   }else{
+      BZ2_bzReadClose(&amp;bzerr,b);
+   }
+   if(fp!=stdin &amp;&amp; fp!=stdout){
+      fclose(fp);
+   }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+   return last error code 
+--*/
+static const char *bzerrorstrings[] = {
+       &quot;OK&quot;
+      ,&quot;SEQUENCE_ERROR&quot;
+      ,&quot;PARAM_ERROR&quot;
+      ,&quot;MEM_ERROR&quot;
+      ,&quot;DATA_ERROR&quot;
+      ,&quot;DATA_ERROR_MAGIC&quot;
+      ,&quot;IO_ERROR&quot;
+      ,&quot;UNEXPECTED_EOF&quot;
+      ,&quot;OUTBUFF_FULL&quot;
+      ,&quot;CONFIG_ERROR&quot;
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+   int err = ((bzFile *)b)-&gt;lastErr;
+
+   if(err&gt;0) err = 0;
+   *errnum = err;
+   return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/bzlib.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,282 +1,282 @@
-
-/*-------------------------------------------------------------*/
-/*--- Public header file for the library.                   ---*/
-/*---                                               bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#ifndef _BZLIB_H
-#define _BZLIB_H
-
-#ifdef __cplusplus
-extern &quot;C&quot; {
-#endif
-
-#define BZ_RUN               0
-#define BZ_FLUSH             1
-#define BZ_FINISH            2
-
-#define BZ_OK                0
-#define BZ_RUN_OK            1
-#define BZ_FLUSH_OK          2
-#define BZ_FINISH_OK         3
-#define BZ_STREAM_END        4
-#define BZ_SEQUENCE_ERROR    (-1)
-#define BZ_PARAM_ERROR       (-2)
-#define BZ_MEM_ERROR         (-3)
-#define BZ_DATA_ERROR        (-4)
-#define BZ_DATA_ERROR_MAGIC  (-5)
-#define BZ_IO_ERROR          (-6)
-#define BZ_UNEXPECTED_EOF    (-7)
-#define BZ_OUTBUFF_FULL      (-8)
-#define BZ_CONFIG_ERROR      (-9)
-
-typedef 
-   struct {
-      char *next_in;
-      unsigned int avail_in;
-      unsigned int total_in_lo32;
-      unsigned int total_in_hi32;
-
-      char *next_out;
-      unsigned int avail_out;
-      unsigned int total_out_lo32;
-      unsigned int total_out_hi32;
-
-      void *state;
-
-      void *(*bzalloc)(void *,int,int);
-      void (*bzfree)(void *,void *);
-      void *opaque;
-   } 
-   bz_stream;
-
-
-#ifndef BZ_IMPORT
-#define BZ_EXPORT
-#endif
-
-#ifndef BZ_NO_STDIO
-/* Need a definitition for FILE */
-#include &lt;stdio.h&gt;
-#endif
-
-#ifdef _WIN32
-#   include &lt;windows.h&gt;
-#   ifdef small
-      /* windows.h define small to char */
-#      undef small
-#   endif
-#   ifdef BZ_EXPORT
-#   define BZ_API(func) WINAPI func
-#   define BZ_EXTERN extern
-#   else
-   /* import windows dll dynamically */
-#   define BZ_API(func) (WINAPI * func)
-#   define BZ_EXTERN
-#   endif
-#else
-#   define BZ_API(func) func
-#   define BZ_EXTERN extern
-#endif
-
-
-/*-- Core (low-level) library functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
-      bz_stream* strm, 
-      int        blockSize100k, 
-      int        verbosity, 
-      int        workFactor 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
-      bz_stream* strm, 
-      int action 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
-      bz_stream* strm 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
-      bz_stream *strm, 
-      int       verbosity, 
-      int       small
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
-      bz_stream* strm 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
-      bz_stream *strm 
-   );
-
-
-
-/*-- High(er) level library functions --*/
-
-#ifndef BZ_NO_STDIO
-#define BZ_MAX_UNUSED 5000
-
-typedef void BZFILE;
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
-      int*  bzerror,   
-      FILE* f, 
-      int   verbosity, 
-      int   small,
-      void* unused,    
-      int   nUnused 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
-      int*    bzerror, 
-      BZFILE* b 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
-      int*    bzerror, 
-      BZFILE* b, 
-      void**  unused,  
-      int*    nUnused 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
-      int*    bzerror, 
-      BZFILE* b, 
-      void*   buf, 
-      int     len 
-   );
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
-      int*  bzerror,      
-      FILE* f, 
-      int   blockSize100k, 
-      int   verbosity, 
-      int   workFactor 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
-      int*    bzerror, 
-      BZFILE* b, 
-      void*   buf, 
-      int     len 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
-      int*          bzerror, 
-      BZFILE*       b, 
-      int           abandon, 
-      unsigned int* nbytes_in, 
-      unsigned int* nbytes_out 
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
-      int*          bzerror, 
-      BZFILE*       b, 
-      int           abandon, 
-      unsigned int* nbytes_in_lo32, 
-      unsigned int* nbytes_in_hi32, 
-      unsigned int* nbytes_out_lo32, 
-      unsigned int* nbytes_out_hi32
-   );
-#endif
-
-
-/*-- Utility functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
-      char*         dest, 
-      unsigned int* destLen,
-      char*         source, 
-      unsigned int  sourceLen,
-      int           blockSize100k, 
-      int           verbosity, 
-      int           workFactor 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
-      char*         dest, 
-      unsigned int* destLen,
-      char*         source, 
-      unsigned int  sourceLen,
-      int           small, 
-      int           verbosity 
-   );
-
-
-/*--
-   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
-   to support better zlib compatibility.
-   This code is not _officially_ part of libbzip2 (yet);
-   I haven't tested it, documented it, or considered the
-   threading-safeness of it.
-   If this code breaks, please contact both Yoshioka and me.
---*/
-
-BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
-      void
-   );
-
-#ifndef BZ_NO_STDIO
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
-      const char *path,
-      const char *mode
-   );
-
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
-      int        fd,
-      const char *mode
-   );
-         
-BZ_EXTERN int BZ_API(BZ2_bzread) (
-      BZFILE* b, 
-      void* buf, 
-      int len 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzwrite) (
-      BZFILE* b, 
-      void*   buf, 
-      int     len 
-   );
-
-BZ_EXTERN int BZ_API(BZ2_bzflush) (
-      BZFILE* b
-   );
-
-BZ_EXTERN void BZ_API(BZ2_bzclose) (
-      BZFILE* b
-   );
-
-BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
-      BZFILE *b, 
-      int    *errnum
-   );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*-------------------------------------------------------------*/
-/*--- end                                           bzlib.h ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern &quot;C&quot; {
+#endif
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef 
+   struct {
+      char *next_in;
+      unsigned int avail_in;
+      unsigned int total_in_lo32;
+      unsigned int total_in_hi32;
+
+      char *next_out;
+      unsigned int avail_out;
+      unsigned int total_out_lo32;
+      unsigned int total_out_hi32;
+
+      void *state;
+
+      void *(*bzalloc)(void *,int,int);
+      void (*bzfree)(void *,void *);
+      void *opaque;
+   } 
+   bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include &lt;stdio.h&gt;
+#endif
+
+#ifdef _WIN32
+#   include &lt;windows.h&gt;
+#   ifdef small
+      /* windows.h define small to char */
+#      undef small
+#   endif
+#   ifdef BZ_EXPORT
+#   define BZ_API(func) WINAPI func
+#   define BZ_EXTERN extern
+#   else
+   /* import windows dll dynamically */
+#   define BZ_API(func) (WINAPI * func)
+#   define BZ_EXTERN
+#   endif
+#else
+#   define BZ_API(func) func
+#   define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
+      bz_stream* strm, 
+      int        blockSize100k, 
+      int        verbosity, 
+      int        workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
+      bz_stream* strm, 
+      int action 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
+      bz_stream *strm, 
+      int       verbosity, 
+      int       small
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
+      bz_stream* strm 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
+      bz_stream *strm 
+   );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
+      int*  bzerror,   
+      FILE* f, 
+      int   verbosity, 
+      int   small,
+      void* unused,    
+      int   nUnused 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
+      int*    bzerror, 
+      BZFILE* b 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void**  unused,  
+      int*    nUnused 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
+      int*  bzerror,      
+      FILE* f, 
+      int   blockSize100k, 
+      int   verbosity, 
+      int   workFactor 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
+      int*    bzerror, 
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in, 
+      unsigned int* nbytes_out 
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
+      int*          bzerror, 
+      BZFILE*       b, 
+      int           abandon, 
+      unsigned int* nbytes_in_lo32, 
+      unsigned int* nbytes_in_hi32, 
+      unsigned int* nbytes_out_lo32, 
+      unsigned int* nbytes_out_hi32
+   );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           blockSize100k, 
+      int           verbosity, 
+      int           workFactor 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
+      char*         dest, 
+      unsigned int* destLen,
+      char*         source, 
+      unsigned int  sourceLen,
+      int           small, 
+      int           verbosity 
+   );
+
+
+/*--
+   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+   to support better zlib compatibility.
+   This code is not _officially_ part of libbzip2 (yet);
+   I haven't tested it, documented it, or considered the
+   threading-safeness of it.
+   If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+      void
+   );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+      const char *path,
+      const char *mode
+   );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+      int        fd,
+      const char *mode
+   );
+         
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+      BZFILE* b, 
+      void* buf, 
+      int len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+      BZFILE* b, 
+      void*   buf, 
+      int     len 
+   );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+      BZFILE* b
+   );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+      BZFILE* b
+   );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+      BZFILE *b, 
+      int    *errnum
+   );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/bzlib.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,509 +1,509 @@
-
-/*-------------------------------------------------------------*/
-/*--- Private header file for the library.                  ---*/
-/*---                                       bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#ifndef _BZLIB_PRIVATE_H
-#define _BZLIB_PRIVATE_H
-
-#include &lt;stdlib.h&gt;
-
-#ifndef BZ_NO_STDIO
-#include &lt;stdio.h&gt;
-#include &lt;ctype.h&gt;
-#include &lt;string.h&gt;
-#endif
-
-#include &quot;bzlib.h&quot;
-
-
-
-/*-- General stuff. --*/
-
-#define BZ_VERSION  &quot;1.0.5, 10-Dec-2007&quot;
-
-typedef char            Char;
-typedef unsigned char   Bool;
-typedef unsigned char   UChar;
-typedef int             Int32;
-typedef unsigned int    UInt32;
-typedef short           Int16;
-typedef unsigned short  UInt16;
-
-#define True  ((Bool)1)
-#define False ((Bool)0)
-
-#ifndef __GNUC__
-#define __inline__  /* */
-#endif 
-
-#ifndef BZ_NO_STDIO
-
-extern void BZ2_bz__AssertH__fail ( int errcode );
-#define AssertH(cond,errcode) \
-   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
-
-#if BZ_DEBUG
-#define AssertD(cond,msg) \
-   { if (!(cond)) {       \
-      fprintf ( stderr,   \
-        &quot;\n\nlibbzip2(debug build): internal error\n\t%s\n&quot;, msg );\
-      exit(1); \
-   }}
-#else
-#define AssertD(cond,msg) /* */
-#endif
-
-#define VPrintf0(zf) \
-   fprintf(stderr,zf)
-#define VPrintf1(zf,za1) \
-   fprintf(stderr,zf,za1)
-#define VPrintf2(zf,za1,za2) \
-   fprintf(stderr,zf,za1,za2)
-#define VPrintf3(zf,za1,za2,za3) \
-   fprintf(stderr,zf,za1,za2,za3)
-#define VPrintf4(zf,za1,za2,za3,za4) \
-   fprintf(stderr,zf,za1,za2,za3,za4)
-#define VPrintf5(zf,za1,za2,za3,za4,za5) \
-   fprintf(stderr,zf,za1,za2,za3,za4,za5)
-
-#else
-
-extern void bz_internal_error ( int errcode );
-#define AssertH(cond,errcode) \
-   { if (!(cond)) bz_internal_error ( errcode ); }
-#define AssertD(cond,msg)                do { } while (0)
-#define VPrintf0(zf)                     do { } while (0)
-#define VPrintf1(zf,za1)                 do { } while (0)
-#define VPrintf2(zf,za1,za2)             do { } while (0)
-#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
-#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
-#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
-
-#endif
-
-
-#define BZALLOC(nnn) (strm-&gt;bzalloc)(strm-&gt;opaque,(nnn),1)
-#define BZFREE(ppp)  (strm-&gt;bzfree)(strm-&gt;opaque,(ppp))
-
-
-/*-- Header bytes. --*/
-
-#define BZ_HDR_B 0x42   /* 'B' */
-#define BZ_HDR_Z 0x5a   /* 'Z' */
-#define BZ_HDR_h 0x68   /* 'h' */
-#define BZ_HDR_0 0x30   /* '0' */
-  
-/*-- Constants for the back end. --*/
-
-#define BZ_MAX_ALPHA_SIZE 258
-#define BZ_MAX_CODE_LEN    23
-
-#define BZ_RUNA 0
-#define BZ_RUNB 1
-
-#define BZ_N_GROUPS 6
-#define BZ_G_SIZE   50
-#define BZ_N_ITERS  4
-
-#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
-
-
-
-/*-- Stuff for randomising repetitive blocks. --*/
-
-extern Int32 BZ2_rNums[512];
-
-#define BZ_RAND_DECLS                          \
-   Int32 rNToGo;                               \
-   Int32 rTPos                                 \
-
-#define BZ_RAND_INIT_MASK                      \
-   s-&gt;rNToGo = 0;                              \
-   s-&gt;rTPos  = 0                               \
-
-#define BZ_RAND_MASK ((s-&gt;rNToGo == 1) ? 1 : 0)
-
-#define BZ_RAND_UPD_MASK                       \
-   if (s-&gt;rNToGo == 0) {                       \
-      s-&gt;rNToGo = BZ2_rNums[s-&gt;rTPos];         \
-      s-&gt;rTPos++;                              \
-      if (s-&gt;rTPos == 512) s-&gt;rTPos = 0;       \
-   }                                           \
-   s-&gt;rNToGo--;
-
-
-
-/*-- Stuff for doing CRCs. --*/
-
-extern UInt32 BZ2_crc32Table[256];
-
-#define BZ_INITIALISE_CRC(crcVar)              \
-{                                              \
-   crcVar = 0xffffffffL;                       \
-}
-
-#define BZ_FINALISE_CRC(crcVar)                \
-{                                              \
-   crcVar = ~(crcVar);                         \
-}
-
-#define BZ_UPDATE_CRC(crcVar,cha)              \
-{                                              \
-   crcVar = (crcVar &lt;&lt; 8) ^                    \
-            BZ2_crc32Table[(crcVar &gt;&gt; 24) ^    \
-                           ((UChar)cha)];      \
-}
-
-
-
-/*-- States and modes for compression. --*/
-
-#define BZ_M_IDLE      1
-#define BZ_M_RUNNING   2
-#define BZ_M_FLUSHING  3
-#define BZ_M_FINISHING 4
-
-#define BZ_S_OUTPUT    1
-#define BZ_S_INPUT     2
-
-#define BZ_N_RADIX 2
-#define BZ_N_QSORT 12
-#define BZ_N_SHELL 18
-#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
-
-
-
-
-/*-- Structure holding all the compression-side stuff. --*/
-
-typedef
-   struct {
-      /* pointer back to the struct bz_stream */
-      bz_stream* strm;
-
-      /* mode this stream is in, and whether inputting */
-      /* or outputting data */
-      Int32    mode;
-      Int32    state;
-
-      /* remembers avail_in when flush/finish requested */
-      UInt32   avail_in_expect;
-
-      /* for doing the block sorting */
-      UInt32*  arr1;
-      UInt32*  arr2;
-      UInt32*  ftab;
-      Int32    origPtr;
-
-      /* aliases for arr1 and arr2 */
-      UInt32*  ptr;
-      UChar*   block;
-      UInt16*  mtfv;
-      UChar*   zbits;
-
-      /* for deciding when to use the fallback sorting algorithm */
-      Int32    workFactor;
-
-      /* run-length-encoding of the input */
-      UInt32   state_in_ch;
-      Int32    state_in_len;
-      BZ_RAND_DECLS;
-
-      /* input and output limits and current posns */
-      Int32    nblock;
-      Int32    nblockMAX;
-      Int32    numZ;
-      Int32    state_out_pos;
-
-      /* map of bytes used in block */
-      Int32    nInUse;
-      Bool     inUse[256];
-      UChar    unseqToSeq[256];
-
-      /* the buffer for bit stream creation */
-      UInt32   bsBuff;
-      Int32    bsLive;
-
-      /* block and combined CRCs */
-      UInt32   blockCRC;
-      UInt32   combinedCRC;
-
-      /* misc administratium */
-      Int32    verbosity;
-      Int32    blockNo;
-      Int32    blockSize100k;
-
-      /* stuff for coding the MTF values */
-      Int32    nMTF;
-      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
-      UChar    selector   [BZ_MAX_SELECTORS];
-      UChar    selectorMtf[BZ_MAX_SELECTORS];
-
-      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-      /* second dimension: only 3 needed; 4 makes index calculations faster */
-      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
-
-   }
-   EState;
-
-
-
-/*-- externs for compression. --*/
-
-extern void 
-BZ2_blockSort ( EState* );
-
-extern void 
-BZ2_compressBlock ( EState*, Bool );
-
-extern void 
-BZ2_bsInitWrite ( EState* );
-
-extern void 
-BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
-
-extern void 
-BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
-
-
-
-/*-- states for decompression. --*/
-
-#define BZ_X_IDLE        1
-#define BZ_X_OUTPUT      2
-
-#define BZ_X_MAGIC_1     10
-#define BZ_X_MAGIC_2     11
-#define BZ_X_MAGIC_3     12
-#define BZ_X_MAGIC_4     13
-#define BZ_X_BLKHDR_1    14
-#define BZ_X_BLKHDR_2    15
-#define BZ_X_BLKHDR_3    16
-#define BZ_X_BLKHDR_4    17
-#define BZ_X_BLKHDR_5    18
-#define BZ_X_BLKHDR_6    19
-#define BZ_X_BCRC_1      20
-#define BZ_X_BCRC_2      21
-#define BZ_X_BCRC_3      22
-#define BZ_X_BCRC_4      23
-#define BZ_X_RANDBIT     24
-#define BZ_X_ORIGPTR_1   25
-#define BZ_X_ORIGPTR_2   26
-#define BZ_X_ORIGPTR_3   27
-#define BZ_X_MAPPING_1   28
-#define BZ_X_MAPPING_2   29
-#define BZ_X_SELECTOR_1  30
-#define BZ_X_SELECTOR_2  31
-#define BZ_X_SELECTOR_3  32
-#define BZ_X_CODING_1    33
-#define BZ_X_CODING_2    34
-#define BZ_X_CODING_3    35
-#define BZ_X_MTF_1       36
-#define BZ_X_MTF_2       37
-#define BZ_X_MTF_3       38
-#define BZ_X_MTF_4       39
-#define BZ_X_MTF_5       40
-#define BZ_X_MTF_6       41
-#define BZ_X_ENDHDR_2    42
-#define BZ_X_ENDHDR_3    43
-#define BZ_X_ENDHDR_4    44
-#define BZ_X_ENDHDR_5    45
-#define BZ_X_ENDHDR_6    46
-#define BZ_X_CCRC_1      47
-#define BZ_X_CCRC_2      48
-#define BZ_X_CCRC_3      49
-#define BZ_X_CCRC_4      50
-
-
-
-/*-- Constants for the fast MTF decoder. --*/
-
-#define MTFA_SIZE 4096
-#define MTFL_SIZE 16
-
-
-
-/*-- Structure holding all the decompression-side stuff. --*/
-
-typedef
-   struct {
-      /* pointer back to the struct bz_stream */
-      bz_stream* strm;
-
-      /* state indicator for this stream */
-      Int32    state;
-
-      /* for doing the final run-length decoding */
-      UChar    state_out_ch;
-      Int32    state_out_len;
-      Bool     blockRandomised;
-      BZ_RAND_DECLS;
-
-      /* the buffer for bit stream reading */
-      UInt32   bsBuff;
-      Int32    bsLive;
-
-      /* misc administratium */
-      Int32    blockSize100k;
-      Bool     smallDecompress;
-      Int32    currBlockNo;
-      Int32    verbosity;
-
-      /* for undoing the Burrows-Wheeler transform */
-      Int32    origPtr;
-      UInt32   tPos;
-      Int32    k0;
-      Int32    unzftab[256];
-      Int32    nblock_used;
-      Int32    cftab[257];
-      Int32    cftabCopy[257];
-
-      /* for undoing the Burrows-Wheeler transform (FAST) */
-      UInt32   *tt;
-
-      /* for undoing the Burrows-Wheeler transform (SMALL) */
-      UInt16   *ll16;
-      UChar    *ll4;
-
-      /* stored and calculated CRCs */
-      UInt32   storedBlockCRC;
-      UInt32   storedCombinedCRC;
-      UInt32   calculatedBlockCRC;
-      UInt32   calculatedCombinedCRC;
-
-      /* map of bytes used in block */
-      Int32    nInUse;
-      Bool     inUse[256];
-      Bool     inUse16[16];
-      UChar    seqToUnseq[256];
-
-      /* for decoding the MTF values */
-      UChar    mtfa   [MTFA_SIZE];
-      Int32    mtfbase[256 / MTFL_SIZE];
-      UChar    selector   [BZ_MAX_SELECTORS];
-      UChar    selectorMtf[BZ_MAX_SELECTORS];
-      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-
-      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-      Int32    minLens[BZ_N_GROUPS];
-
-      /* save area for scalars in the main decompress code */
-      Int32    save_i;
-      Int32    save_j;
-      Int32    save_t;
-      Int32    save_alphaSize;
-      Int32    save_nGroups;
-      Int32    save_nSelectors;
-      Int32    save_EOB;
-      Int32    save_groupNo;
-      Int32    save_groupPos;
-      Int32    save_nextSym;
-      Int32    save_nblockMAX;
-      Int32    save_nblock;
-      Int32    save_es;
-      Int32    save_N;
-      Int32    save_curr;
-      Int32    save_zt;
-      Int32    save_zn; 
-      Int32    save_zvec;
-      Int32    save_zj;
-      Int32    save_gSel;
-      Int32    save_gMinlen;
-      Int32*   save_gLimit;
-      Int32*   save_gBase;
-      Int32*   save_gPerm;
-
-   }
-   DState;
-
-
-
-/*-- Macros for decompression. --*/
-
-#define BZ_GET_FAST(cccc)                     \
-    /* c_tPos is unsigned, hence test &lt; 0 is pointless. */ \
-    if (s-&gt;tPos &gt;= (UInt32)100000 * (UInt32)s-&gt;blockSize100k) return True; \
-    s-&gt;tPos = s-&gt;tt[s-&gt;tPos];                 \
-    cccc = (UChar)(s-&gt;tPos &amp; 0xff);           \
-    s-&gt;tPos &gt;&gt;= 8;
-
-#define BZ_GET_FAST_C(cccc)                   \
-    /* c_tPos is unsigned, hence test &lt; 0 is pointless. */ \
-    if (c_tPos &gt;= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
-    c_tPos = c_tt[c_tPos];                    \
-    cccc = (UChar)(c_tPos &amp; 0xff);            \
-    c_tPos &gt;&gt;= 8;
-
-#define SET_LL4(i,n)                                          \
-   { if (((i) &amp; 0x1) == 0)                                    \
-        s-&gt;ll4[(i) &gt;&gt; 1] = (s-&gt;ll4[(i) &gt;&gt; 1] &amp; 0xf0) | (n); else    \
-        s-&gt;ll4[(i) &gt;&gt; 1] = (s-&gt;ll4[(i) &gt;&gt; 1] &amp; 0x0f) | ((n) &lt;&lt; 4);  \
-   }
-
-#define GET_LL4(i)                             \
-   ((((UInt32)(s-&gt;ll4[(i) &gt;&gt; 1])) &gt;&gt; (((i) &lt;&lt; 2) &amp; 0x4)) &amp; 0xF)
-
-#define SET_LL(i,n)                          \
-   { s-&gt;ll16[i] = (UInt16)(n &amp; 0x0000ffff);  \
-     SET_LL4(i, n &gt;&gt; 16);                    \
-   }
-
-#define GET_LL(i) \
-   (((UInt32)s-&gt;ll16[i]) | (GET_LL4(i) &lt;&lt; 16))
-
-#define BZ_GET_SMALL(cccc)                            \
-    /* c_tPos is unsigned, hence test &lt; 0 is pointless. */ \
-    if (s-&gt;tPos &gt;= (UInt32)100000 * (UInt32)s-&gt;blockSize100k) return True; \
-    cccc = BZ2_indexIntoF ( s-&gt;tPos, s-&gt;cftab );    \
-    s-&gt;tPos = GET_LL(s-&gt;tPos);
-
-
-/*-- externs for decompression. --*/
-
-extern Int32 
-BZ2_indexIntoF ( Int32, Int32* );
-
-extern Int32 
-BZ2_decompress ( DState* );
-
-extern void 
-BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
-                           Int32,  Int32, Int32 );
-
-
-#endif
-
-
-/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
-
-#ifdef BZ_NO_STDIO
-#ifndef NULL
-#define NULL 0
-#endif
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                   bzlib_private.h ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include &lt;stdlib.h&gt;
+
+#ifndef BZ_NO_STDIO
+#include &lt;stdio.h&gt;
+#include &lt;ctype.h&gt;
+#include &lt;string.h&gt;
+#endif
+
+#include &quot;bzlib.h&quot;
+
+
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION  &quot;1.0.5, 10-Dec-2007&quot;
+
+typedef char            Char;
+typedef unsigned char   Bool;
+typedef unsigned char   UChar;
+typedef int             Int32;
+typedef unsigned int    UInt32;
+typedef short           Int16;
+typedef unsigned short  UInt16;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__  /* */
+#endif 
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+   { if (!(cond)) {       \
+      fprintf ( stderr,   \
+        &quot;\n\nlibbzip2(debug build): internal error\n\t%s\n&quot;, msg );\
+      exit(1); \
+   }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+   fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+   fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+   fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+   fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+   fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+   fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+   { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg)                do { } while (0)
+#define VPrintf0(zf)                     do { } while (0)
+#define VPrintf1(zf,za1)                 do { } while (0)
+#define VPrintf2(zf,za1,za2)             do { } while (0)
+#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm-&gt;bzalloc)(strm-&gt;opaque,(nnn),1)
+#define BZFREE(ppp)  (strm-&gt;bzfree)(strm-&gt;opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+  
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS                          \
+   Int32 rNToGo;                               \
+   Int32 rTPos                                 \
+
+#define BZ_RAND_INIT_MASK                      \
+   s-&gt;rNToGo = 0;                              \
+   s-&gt;rTPos  = 0                               \
+
+#define BZ_RAND_MASK ((s-&gt;rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK                       \
+   if (s-&gt;rNToGo == 0) {                       \
+      s-&gt;rNToGo = BZ2_rNums[s-&gt;rTPos];         \
+      s-&gt;rTPos++;                              \
+      if (s-&gt;rTPos == 512) s-&gt;rTPos = 0;       \
+   }                                           \
+   s-&gt;rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar)              \
+{                                              \
+   crcVar = 0xffffffffL;                       \
+}
+
+#define BZ_FINALISE_CRC(crcVar)                \
+{                                              \
+   crcVar = ~(crcVar);                         \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha)              \
+{                                              \
+   crcVar = (crcVar &lt;&lt; 8) ^                    \
+            BZ2_crc32Table[(crcVar &gt;&gt; 24) ^    \
+                           ((UChar)cha)];      \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* mode this stream is in, and whether inputting */
+      /* or outputting data */
+      Int32    mode;
+      Int32    state;
+
+      /* remembers avail_in when flush/finish requested */
+      UInt32   avail_in_expect;
+
+      /* for doing the block sorting */
+      UInt32*  arr1;
+      UInt32*  arr2;
+      UInt32*  ftab;
+      Int32    origPtr;
+
+      /* aliases for arr1 and arr2 */
+      UInt32*  ptr;
+      UChar*   block;
+      UInt16*  mtfv;
+      UChar*   zbits;
+
+      /* for deciding when to use the fallback sorting algorithm */
+      Int32    workFactor;
+
+      /* run-length-encoding of the input */
+      UInt32   state_in_ch;
+      Int32    state_in_len;
+      BZ_RAND_DECLS;
+
+      /* input and output limits and current posns */
+      Int32    nblock;
+      Int32    nblockMAX;
+      Int32    numZ;
+      Int32    state_out_pos;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      UChar    unseqToSeq[256];
+
+      /* the buffer for bit stream creation */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* block and combined CRCs */
+      UInt32   blockCRC;
+      UInt32   combinedCRC;
+
+      /* misc administratium */
+      Int32    verbosity;
+      Int32    blockNo;
+      Int32    blockSize100k;
+
+      /* stuff for coding the MTF values */
+      Int32    nMTF;
+      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+
+      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      /* second dimension: only 3 needed; 4 makes index calculations faster */
+      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+   }
+   EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void 
+BZ2_blockSort ( EState* );
+
+extern void 
+BZ2_compressBlock ( EState*, Bool );
+
+extern void 
+BZ2_bsInitWrite ( EState* );
+
+extern void 
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void 
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE        1
+#define BZ_X_OUTPUT      2
+
+#define BZ_X_MAGIC_1     10
+#define BZ_X_MAGIC_2     11
+#define BZ_X_MAGIC_3     12
+#define BZ_X_MAGIC_4     13
+#define BZ_X_BLKHDR_1    14
+#define BZ_X_BLKHDR_2    15
+#define BZ_X_BLKHDR_3    16
+#define BZ_X_BLKHDR_4    17
+#define BZ_X_BLKHDR_5    18
+#define BZ_X_BLKHDR_6    19
+#define BZ_X_BCRC_1      20
+#define BZ_X_BCRC_2      21
+#define BZ_X_BCRC_3      22
+#define BZ_X_BCRC_4      23
+#define BZ_X_RANDBIT     24
+#define BZ_X_ORIGPTR_1   25
+#define BZ_X_ORIGPTR_2   26
+#define BZ_X_ORIGPTR_3   27
+#define BZ_X_MAPPING_1   28
+#define BZ_X_MAPPING_2   29
+#define BZ_X_SELECTOR_1  30
+#define BZ_X_SELECTOR_2  31
+#define BZ_X_SELECTOR_3  32
+#define BZ_X_CODING_1    33
+#define BZ_X_CODING_2    34
+#define BZ_X_CODING_3    35
+#define BZ_X_MTF_1       36
+#define BZ_X_MTF_2       37
+#define BZ_X_MTF_3       38
+#define BZ_X_MTF_4       39
+#define BZ_X_MTF_5       40
+#define BZ_X_MTF_6       41
+#define BZ_X_ENDHDR_2    42
+#define BZ_X_ENDHDR_3    43
+#define BZ_X_ENDHDR_4    44
+#define BZ_X_ENDHDR_5    45
+#define BZ_X_ENDHDR_6    46
+#define BZ_X_CCRC_1      47
+#define BZ_X_CCRC_2      48
+#define BZ_X_CCRC_3      49
+#define BZ_X_CCRC_4      50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+   struct {
+      /* pointer back to the struct bz_stream */
+      bz_stream* strm;
+
+      /* state indicator for this stream */
+      Int32    state;
+
+      /* for doing the final run-length decoding */
+      UChar    state_out_ch;
+      Int32    state_out_len;
+      Bool     blockRandomised;
+      BZ_RAND_DECLS;
+
+      /* the buffer for bit stream reading */
+      UInt32   bsBuff;
+      Int32    bsLive;
+
+      /* misc administratium */
+      Int32    blockSize100k;
+      Bool     smallDecompress;
+      Int32    currBlockNo;
+      Int32    verbosity;
+
+      /* for undoing the Burrows-Wheeler transform */
+      Int32    origPtr;
+      UInt32   tPos;
+      Int32    k0;
+      Int32    unzftab[256];
+      Int32    nblock_used;
+      Int32    cftab[257];
+      Int32    cftabCopy[257];
+
+      /* for undoing the Burrows-Wheeler transform (FAST) */
+      UInt32   *tt;
+
+      /* for undoing the Burrows-Wheeler transform (SMALL) */
+      UInt16   *ll16;
+      UChar    *ll4;
+
+      /* stored and calculated CRCs */
+      UInt32   storedBlockCRC;
+      UInt32   storedCombinedCRC;
+      UInt32   calculatedBlockCRC;
+      UInt32   calculatedCombinedCRC;
+
+      /* map of bytes used in block */
+      Int32    nInUse;
+      Bool     inUse[256];
+      Bool     inUse16[16];
+      UChar    seqToUnseq[256];
+
+      /* for decoding the MTF values */
+      UChar    mtfa   [MTFA_SIZE];
+      Int32    mtfbase[256 / MTFL_SIZE];
+      UChar    selector   [BZ_MAX_SELECTORS];
+      UChar    selectorMtf[BZ_MAX_SELECTORS];
+      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+      Int32    minLens[BZ_N_GROUPS];
+
+      /* save area for scalars in the main decompress code */
+      Int32    save_i;
+      Int32    save_j;
+      Int32    save_t;
+      Int32    save_alphaSize;
+      Int32    save_nGroups;
+      Int32    save_nSelectors;
+      Int32    save_EOB;
+      Int32    save_groupNo;
+      Int32    save_groupPos;
+      Int32    save_nextSym;
+      Int32    save_nblockMAX;
+      Int32    save_nblock;
+      Int32    save_es;
+      Int32    save_N;
+      Int32    save_curr;
+      Int32    save_zt;
+      Int32    save_zn; 
+      Int32    save_zvec;
+      Int32    save_zj;
+      Int32    save_gSel;
+      Int32    save_gMinlen;
+      Int32*   save_gLimit;
+      Int32*   save_gBase;
+      Int32*   save_gPerm;
+
+   }
+   DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc)                     \
+    /* c_tPos is unsigned, hence test &lt; 0 is pointless. */ \
+    if (s-&gt;tPos &gt;= (UInt32)100000 * (UInt32)s-&gt;blockSize100k) return True; \
+    s-&gt;tPos = s-&gt;tt[s-&gt;tPos];                 \
+    cccc = (UChar)(s-&gt;tPos &amp; 0xff);           \
+    s-&gt;tPos &gt;&gt;= 8;
+
+#define BZ_GET_FAST_C(cccc)                   \
+    /* c_tPos is unsigned, hence test &lt; 0 is pointless. */ \
+    if (c_tPos &gt;= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+    c_tPos = c_tt[c_tPos];                    \
+    cccc = (UChar)(c_tPos &amp; 0xff);            \
+    c_tPos &gt;&gt;= 8;
+
+#define SET_LL4(i,n)                                          \
+   { if (((i) &amp; 0x1) == 0)                                    \
+        s-&gt;ll4[(i) &gt;&gt; 1] = (s-&gt;ll4[(i) &gt;&gt; 1] &amp; 0xf0) | (n); else    \
+        s-&gt;ll4[(i) &gt;&gt; 1] = (s-&gt;ll4[(i) &gt;&gt; 1] &amp; 0x0f) | ((n) &lt;&lt; 4);  \
+   }
+
+#define GET_LL4(i)                             \
+   ((((UInt32)(s-&gt;ll4[(i) &gt;&gt; 1])) &gt;&gt; (((i) &lt;&lt; 2) &amp; 0x4)) &amp; 0xF)
+
+#define SET_LL(i,n)                          \
+   { s-&gt;ll16[i] = (UInt16)(n &amp; 0x0000ffff);  \
+     SET_LL4(i, n &gt;&gt; 16);                    \
+   }
+
+#define GET_LL(i) \
+   (((UInt32)s-&gt;ll16[i]) | (GET_LL4(i) &lt;&lt; 16))
+
+#define BZ_GET_SMALL(cccc)                            \
+    /* c_tPos is unsigned, hence test &lt; 0 is pointless. */ \
+    if (s-&gt;tPos &gt;= (UInt32)100000 * (UInt32)s-&gt;blockSize100k) return True; \
+    cccc = BZ2_indexIntoF ( s-&gt;tPos, s-&gt;cftab );    \
+    s-&gt;tPos = GET_LL(s-&gt;tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32 
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32 
+BZ2_decompress ( DState* );
+
+extern void 
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+                           Int32,  Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/bzlib_private.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,672 +1,672 @@
-
-/*-------------------------------------------------------------*/
-/*--- Compression machinery (not incl block sorting)        ---*/
-/*---                                            compress.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-/* CHANGES
-    0.9.0    -- original version.
-    0.9.0a/b -- no changes in this file.
-    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
-                so as to do a bit better on small files
-*/
-
-#include &quot;bzlib_private.h&quot;
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O                              ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-void BZ2_bsInitWrite ( EState* s )
-{
-   s-&gt;bsLive = 0;
-   s-&gt;bsBuff = 0;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsFinishWrite ( EState* s )
-{
-   while (s-&gt;bsLive &gt; 0) {
-      s-&gt;zbits[s-&gt;numZ] = (UChar)(s-&gt;bsBuff &gt;&gt; 24);
-      s-&gt;numZ++;
-      s-&gt;bsBuff &lt;&lt;= 8;
-      s-&gt;bsLive -= 8;
-   }
-}
-
-
-/*---------------------------------------------------*/
-#define bsNEEDW(nz)                           \
-{                                             \
-   while (s-&gt;bsLive &gt;= 8) {                   \
-      s-&gt;zbits[s-&gt;numZ]                       \
-         = (UChar)(s-&gt;bsBuff &gt;&gt; 24);          \
-      s-&gt;numZ++;                              \
-      s-&gt;bsBuff &lt;&lt;= 8;                        \
-      s-&gt;bsLive -= 8;                         \
-   }                                          \
-}
-
-
-/*---------------------------------------------------*/
-static
-__inline__
-void bsW ( EState* s, Int32 n, UInt32 v )
-{
-   bsNEEDW ( n );
-   s-&gt;bsBuff |= (v &lt;&lt; (32 - s-&gt;bsLive - n));
-   s-&gt;bsLive += n;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUInt32 ( EState* s, UInt32 u )
-{
-   bsW ( s, 8, (u &gt;&gt; 24) &amp; 0xffL );
-   bsW ( s, 8, (u &gt;&gt; 16) &amp; 0xffL );
-   bsW ( s, 8, (u &gt;&gt;  8) &amp; 0xffL );
-   bsW ( s, 8,  u        &amp; 0xffL );
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUChar ( EState* s, UChar c )
-{
-   bsW( s, 8, (UInt32)c );
-}
-
-
-/*---------------------------------------------------*/
-/*--- The back end proper                         ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-static
-void makeMaps_e ( EState* s )
-{
-   Int32 i;
-   s-&gt;nInUse = 0;
-   for (i = 0; i &lt; 256; i++)
-      if (s-&gt;inUse[i]) {
-         s-&gt;unseqToSeq[i] = s-&gt;nInUse;
-         s-&gt;nInUse++;
-      }
-}
-
-
-/*---------------------------------------------------*/
-static
-void generateMTFValues ( EState* s )
-{
-   UChar   yy[256];
-   Int32   i, j;
-   Int32   zPend;
-   Int32   wr;
-   Int32   EOB;
-
-   /* 
-      After sorting (eg, here),
-         s-&gt;arr1 [ 0 .. s-&gt;nblock-1 ] holds sorted order,
-         and
-         ((UChar*)s-&gt;arr2) [ 0 .. s-&gt;nblock-1 ] 
-         holds the original block data.
-
-      The first thing to do is generate the MTF values,
-      and put them in
-         ((UInt16*)s-&gt;arr1) [ 0 .. s-&gt;nblock-1 ].
-      Because there are strictly fewer or equal MTF values
-      than block values, ptr values in this area are overwritten
-      with MTF values only when they are no longer needed.
-
-      The final compressed bitstream is generated into the
-      area starting at
-         (UChar*) (&amp;((UChar*)s-&gt;arr2)[s-&gt;nblock])
-
-      These storage aliases are set up in bzCompressInit(),
-      except for the last one, which is arranged in 
-      compressBlock().
-   */
-   UInt32* ptr   = s-&gt;ptr;
-   UChar* block  = s-&gt;block;
-   UInt16* mtfv  = s-&gt;mtfv;
-
-   makeMaps_e ( s );
-   EOB = s-&gt;nInUse+1;
-
-   for (i = 0; i &lt;= EOB; i++) s-&gt;mtfFreq[i] = 0;
-
-   wr = 0;
-   zPend = 0;
-   for (i = 0; i &lt; s-&gt;nInUse; i++) yy[i] = (UChar) i;
-
-   for (i = 0; i &lt; s-&gt;nblock; i++) {
-      UChar ll_i;
-      AssertD ( wr &lt;= i, &quot;generateMTFValues(1)&quot; );
-      j = ptr[i]-1; if (j &lt; 0) j += s-&gt;nblock;
-      ll_i = s-&gt;unseqToSeq[block[j]];
-      AssertD ( ll_i &lt; s-&gt;nInUse, &quot;generateMTFValues(2a)&quot; );
-
-      if (yy[0] == ll_i) { 
-         zPend++;
-      } else {
-
-         if (zPend &gt; 0) {
-            zPend--;
-            while (True) {
-               if (zPend &amp; 1) {
-                  mtfv[wr] = BZ_RUNB; wr++; 
-                  s-&gt;mtfFreq[BZ_RUNB]++; 
-               } else {
-                  mtfv[wr] = BZ_RUNA; wr++; 
-                  s-&gt;mtfFreq[BZ_RUNA]++; 
-               }
-               if (zPend &lt; 2) break;
-               zPend = (zPend - 2) / 2;
-            };
-            zPend = 0;
-         }
-         {
-            register UChar  rtmp;
-            register UChar* ryy_j;
-            register UChar  rll_i;
-            rtmp  = yy[1];
-            yy[1] = yy[0];
-            ryy_j = &amp;(yy[1]);
-            rll_i = ll_i;
-            while ( rll_i != rtmp ) {
-               register UChar rtmp2;
-               ryy_j++;
-               rtmp2  = rtmp;
-               rtmp   = *ryy_j;
-               *ryy_j = rtmp2;
-            };
-            yy[0] = rtmp;
-            j = ryy_j - &amp;(yy[0]);
-            mtfv[wr] = j+1; wr++; s-&gt;mtfFreq[j+1]++;
-         }
-
-      }
-   }
-
-   if (zPend &gt; 0) {
-      zPend--;
-      while (True) {
-         if (zPend &amp; 1) {
-            mtfv[wr] = BZ_RUNB; wr++; 
-            s-&gt;mtfFreq[BZ_RUNB]++; 
-         } else {
-            mtfv[wr] = BZ_RUNA; wr++; 
-            s-&gt;mtfFreq[BZ_RUNA]++; 
-         }
-         if (zPend &lt; 2) break;
-         zPend = (zPend - 2) / 2;
-      };
-      zPend = 0;
-   }
-
-   mtfv[wr] = EOB; wr++; s-&gt;mtfFreq[EOB]++;
-
-   s-&gt;nMTF = wr;
-}
-
-
-/*---------------------------------------------------*/
-#define BZ_LESSER_ICOST  0
-#define BZ_GREATER_ICOST 15
-
-static
-void sendMTFValues ( EState* s )
-{
-   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
-   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
-   Int32 nGroups, nBytes;
-
-   /*--
-   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-   is a global since the decoder also needs it.
-
-   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-   are also globals only used in this proc.
-   Made global to keep stack frame size small.
-   --*/
-
-
-   UInt16 cost[BZ_N_GROUPS];
-   Int32  fave[BZ_N_GROUPS];
-
-   UInt16* mtfv = s-&gt;mtfv;
-
-   if (s-&gt;verbosity &gt;= 3)
-      VPrintf3( &quot;      %d in block, %d after MTF &amp; 1-2 coding, &quot;
-                &quot;%d+2 syms in use\n&quot;, 
-                s-&gt;nblock, s-&gt;nMTF, s-&gt;nInUse );
-
-   alphaSize = s-&gt;nInUse+2;
-   for (t = 0; t &lt; BZ_N_GROUPS; t++)
-      for (v = 0; v &lt; alphaSize; v++)
-         s-&gt;len[t][v] = BZ_GREATER_ICOST;
-
-   /*--- Decide how many coding tables to use ---*/
-   AssertH ( s-&gt;nMTF &gt; 0, 3001 );
-   if (s-&gt;nMTF &lt; 200)  nGroups = 2; else
-   if (s-&gt;nMTF &lt; 600)  nGroups = 3; else
-   if (s-&gt;nMTF &lt; 1200) nGroups = 4; else
-   if (s-&gt;nMTF &lt; 2400) nGroups = 5; else
-                       nGroups = 6;
-
-   /*--- Generate an initial set of coding tables ---*/
-   { 
-      Int32 nPart, remF, tFreq, aFreq;
-
-      nPart = nGroups;
-      remF  = s-&gt;nMTF;
-      gs = 0;
-      while (nPart &gt; 0) {
-         tFreq = remF / nPart;
-         ge = gs-1;
-         aFreq = 0;
-         while (aFreq &lt; tFreq &amp;&amp; ge &lt; alphaSize-1) {
-            ge++;
-            aFreq += s-&gt;mtfFreq[ge];
-         }
-
-         if (ge &gt; gs 
-             &amp;&amp; nPart != nGroups &amp;&amp; nPart != 1 
-             &amp;&amp; ((nGroups-nPart) % 2 == 1)) {
-            aFreq -= s-&gt;mtfFreq[ge];
-            ge--;
-         }
-
-         if (s-&gt;verbosity &gt;= 3)
-            VPrintf5( &quot;      initial group %d, [%d .. %d], &quot;
-                      &quot;has %d syms (%4.1f%%)\n&quot;,
-                      nPart, gs, ge, aFreq, 
-                      (100.0 * (float)aFreq) / (float)(s-&gt;nMTF) );
- 
-         for (v = 0; v &lt; alphaSize; v++)
-            if (v &gt;= gs &amp;&amp; v &lt;= ge) 
-               s-&gt;len[nPart-1][v] = BZ_LESSER_ICOST; else
-               s-&gt;len[nPart-1][v] = BZ_GREATER_ICOST;
- 
-         nPart--;
-         gs = ge+1;
-         remF -= aFreq;
-      }
-   }
-
-   /*--- 
-      Iterate up to BZ_N_ITERS times to improve the tables.
-   ---*/
-   for (iter = 0; iter &lt; BZ_N_ITERS; iter++) {
-
-      for (t = 0; t &lt; nGroups; t++) fave[t] = 0;
-
-      for (t = 0; t &lt; nGroups; t++)
-         for (v = 0; v &lt; alphaSize; v++)
-            s-&gt;rfreq[t][v] = 0;
-
-      /*---
-        Set up an auxiliary length table which is used to fast-track
-	the common case (nGroups == 6). 
-      ---*/
-      if (nGroups == 6) {
-         for (v = 0; v &lt; alphaSize; v++) {
-            s-&gt;len_pack[v][0] = (s-&gt;len[1][v] &lt;&lt; 16) | s-&gt;len[0][v];
-            s-&gt;len_pack[v][1] = (s-&gt;len[3][v] &lt;&lt; 16) | s-&gt;len[2][v];
-            s-&gt;len_pack[v][2] = (s-&gt;len[5][v] &lt;&lt; 16) | s-&gt;len[4][v];
-	 }
-      }
-
-      nSelectors = 0;
-      totc = 0;
-      gs = 0;
-      while (True) {
-
-         /*--- Set group start &amp; end marks. --*/
-         if (gs &gt;= s-&gt;nMTF) break;
-         ge = gs + BZ_G_SIZE - 1; 
-         if (ge &gt;= s-&gt;nMTF) ge = s-&gt;nMTF-1;
-
-         /*-- 
-            Calculate the cost of this group as coded
-            by each of the coding tables.
-         --*/
-         for (t = 0; t &lt; nGroups; t++) cost[t] = 0;
-
-         if (nGroups == 6 &amp;&amp; 50 == ge-gs+1) {
-            /*--- fast track the common case ---*/
-            register UInt32 cost01, cost23, cost45;
-            register UInt16 icv;
-            cost01 = cost23 = cost45 = 0;
-
-#           define BZ_ITER(nn)                \
-               icv = mtfv[gs+(nn)];           \
-               cost01 += s-&gt;len_pack[icv][0]; \
-               cost23 += s-&gt;len_pack[icv][1]; \
-               cost45 += s-&gt;len_pack[icv][2]; \
-
-            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
-            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
-            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
-            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
-            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
-            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
-            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
-            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
-            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
-            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
-
-#           undef BZ_ITER
-
-            cost[0] = cost01 &amp; 0xffff; cost[1] = cost01 &gt;&gt; 16;
-            cost[2] = cost23 &amp; 0xffff; cost[3] = cost23 &gt;&gt; 16;
-            cost[4] = cost45 &amp; 0xffff; cost[5] = cost45 &gt;&gt; 16;
-
-         } else {
-	    /*--- slow version which correctly handles all situations ---*/
-            for (i = gs; i &lt;= ge; i++) { 
-               UInt16 icv = mtfv[i];
-               for (t = 0; t &lt; nGroups; t++) cost[t] += s-&gt;len[t][icv];
-            }
-         }
- 
-         /*-- 
-            Find the coding table which is best for this group,
-            and record its identity in the selector table.
-         --*/
-         bc = 999999999; bt = -1;
-         for (t = 0; t &lt; nGroups; t++)
-            if (cost[t] &lt; bc) { bc = cost[t]; bt = t; };
-         totc += bc;
-         fave[bt]++;
-         s-&gt;selector[nSelectors] = bt;
-         nSelectors++;
-
-         /*-- 
-            Increment the symbol frequencies for the selected table.
-          --*/
-         if (nGroups == 6 &amp;&amp; 50 == ge-gs+1) {
-            /*--- fast track the common case ---*/
-
-#           define BZ_ITUR(nn) s-&gt;rfreq[bt][ mtfv[gs+(nn)] ]++
-
-            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
-            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
-            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
-            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
-            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
-            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
-            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
-            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
-            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
-            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
-
-#           undef BZ_ITUR
-
-         } else {
-	    /*--- slow version which correctly handles all situations ---*/
-            for (i = gs; i &lt;= ge; i++)
-               s-&gt;rfreq[bt][ mtfv[i] ]++;
-         }
-
-         gs = ge+1;
-      }
-      if (s-&gt;verbosity &gt;= 3) {
-         VPrintf2 ( &quot;      pass %d: size is %d, grp uses are &quot;, 
-                   iter+1, totc/8 );
-         for (t = 0; t &lt; nGroups; t++)
-            VPrintf1 ( &quot;%d &quot;, fave[t] );
-         VPrintf0 ( &quot;\n&quot; );
-      }
-
-      /*--
-        Recompute the tables based on the accumulated frequencies.
-      --*/
-      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
-         comment in huffman.c for details. */
-      for (t = 0; t &lt; nGroups; t++)
-         BZ2_hbMakeCodeLengths ( &amp;(s-&gt;len[t][0]), &amp;(s-&gt;rfreq[t][0]), 
-                                 alphaSize, 17 /*20*/ );
-   }
-
-
-   AssertH( nGroups &lt; 8, 3002 );
-   AssertH( nSelectors &lt; 32768 &amp;&amp;
-            nSelectors &lt;= (2 + (900000 / BZ_G_SIZE)),
-            3003 );
-
-
-   /*--- Compute MTF values for the selectors. ---*/
-   {
-      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
-      for (i = 0; i &lt; nGroups; i++) pos[i] = i;
-      for (i = 0; i &lt; nSelectors; i++) {
-         ll_i = s-&gt;selector[i];
-         j = 0;
-         tmp = pos[j];
-         while ( ll_i != tmp ) {
-            j++;
-            tmp2 = tmp;
-            tmp = pos[j];
-            pos[j] = tmp2;
-         };
-         pos[0] = tmp;
-         s-&gt;selectorMtf[i] = j;
-      }
-   };
-
-   /*--- Assign actual codes for the tables. --*/
-   for (t = 0; t &lt; nGroups; t++) {
-      minLen = 32;
-      maxLen = 0;
-      for (i = 0; i &lt; alphaSize; i++) {
-         if (s-&gt;len[t][i] &gt; maxLen) maxLen = s-&gt;len[t][i];
-         if (s-&gt;len[t][i] &lt; minLen) minLen = s-&gt;len[t][i];
-      }
-      AssertH ( !(maxLen &gt; 17 /*20*/ ), 3004 );
-      AssertH ( !(minLen &lt; 1),  3005 );
-      BZ2_hbAssignCodes ( &amp;(s-&gt;code[t][0]), &amp;(s-&gt;len[t][0]), 
-                          minLen, maxLen, alphaSize );
-   }
-
-   /*--- Transmit the mapping table. ---*/
-   { 
-      Bool inUse16[16];
-      for (i = 0; i &lt; 16; i++) {
-          inUse16[i] = False;
-          for (j = 0; j &lt; 16; j++)
-             if (s-&gt;inUse[i * 16 + j]) inUse16[i] = True;
-      }
-     
-      nBytes = s-&gt;numZ;
-      for (i = 0; i &lt; 16; i++)
-         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
-
-      for (i = 0; i &lt; 16; i++)
-         if (inUse16[i])
-            for (j = 0; j &lt; 16; j++) {
-               if (s-&gt;inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
-            }
-
-      if (s-&gt;verbosity &gt;= 3) 
-         VPrintf1( &quot;      bytes: mapping %d, &quot;, s-&gt;numZ-nBytes );
-   }
-
-   /*--- Now the selectors. ---*/
-   nBytes = s-&gt;numZ;
-   bsW ( s, 3, nGroups );
-   bsW ( s, 15, nSelectors );
-   for (i = 0; i &lt; nSelectors; i++) { 
-      for (j = 0; j &lt; s-&gt;selectorMtf[i]; j++) bsW(s,1,1);
-      bsW(s,1,0);
-   }
-   if (s-&gt;verbosity &gt;= 3)
-      VPrintf1( &quot;selectors %d, &quot;, s-&gt;numZ-nBytes );
-
-   /*--- Now the coding tables. ---*/
-   nBytes = s-&gt;numZ;
-
-   for (t = 0; t &lt; nGroups; t++) {
-      Int32 curr = s-&gt;len[t][0];
-      bsW ( s, 5, curr );
-      for (i = 0; i &lt; alphaSize; i++) {
-         while (curr &lt; s-&gt;len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
-         while (curr &gt; s-&gt;len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
-         bsW ( s, 1, 0 );
-      }
-   }
-
-   if (s-&gt;verbosity &gt;= 3)
-      VPrintf1 ( &quot;code lengths %d, &quot;, s-&gt;numZ-nBytes );
-
-   /*--- And finally, the block data proper ---*/
-   nBytes = s-&gt;numZ;
-   selCtr = 0;
-   gs = 0;
-   while (True) {
-      if (gs &gt;= s-&gt;nMTF) break;
-      ge = gs + BZ_G_SIZE - 1; 
-      if (ge &gt;= s-&gt;nMTF) ge = s-&gt;nMTF-1;
-      AssertH ( s-&gt;selector[selCtr] &lt; nGroups, 3006 );
-
-      if (nGroups == 6 &amp;&amp; 50 == ge-gs+1) {
-            /*--- fast track the common case ---*/
-            UInt16 mtfv_i;
-            UChar* s_len_sel_selCtr 
-               = &amp;(s-&gt;len[s-&gt;selector[selCtr]][0]);
-            Int32* s_code_sel_selCtr
-               = &amp;(s-&gt;code[s-&gt;selector[selCtr]][0]);
-
-#           define BZ_ITAH(nn)                      \
-               mtfv_i = mtfv[gs+(nn)];              \
-               bsW ( s,                             \
-                     s_len_sel_selCtr[mtfv_i],      \
-                     s_code_sel_selCtr[mtfv_i] )
-
-            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
-            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
-            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
-            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
-            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
-            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
-            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
-            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
-            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
-            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
-
-#           undef BZ_ITAH
-
-      } else {
-	 /*--- slow version which correctly handles all situations ---*/
-         for (i = gs; i &lt;= ge; i++) {
-            bsW ( s, 
-                  s-&gt;len  [s-&gt;selector[selCtr]] [mtfv[i]],
-                  s-&gt;code [s-&gt;selector[selCtr]] [mtfv[i]] );
-         }
-      }
-
-
-      gs = ge+1;
-      selCtr++;
-   }
-   AssertH( selCtr == nSelectors, 3007 );
-
-   if (s-&gt;verbosity &gt;= 3)
-      VPrintf1( &quot;codes %d\n&quot;, s-&gt;numZ-nBytes );
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_compressBlock ( EState* s, Bool is_last_block )
-{
-   if (s-&gt;nblock &gt; 0) {
-
-      BZ_FINALISE_CRC ( s-&gt;blockCRC );
-      s-&gt;combinedCRC = (s-&gt;combinedCRC &lt;&lt; 1) | (s-&gt;combinedCRC &gt;&gt; 31);
-      s-&gt;combinedCRC ^= s-&gt;blockCRC;
-      if (s-&gt;blockNo &gt; 1) s-&gt;numZ = 0;
-
-      if (s-&gt;verbosity &gt;= 2)
-         VPrintf4( &quot;    block %d: crc = 0x%08x, &quot;
-                   &quot;combined CRC = 0x%08x, size = %d\n&quot;,
-                   s-&gt;blockNo, s-&gt;blockCRC, s-&gt;combinedCRC, s-&gt;nblock );
-
-      BZ2_blockSort ( s );
-   }
-
-   s-&gt;zbits = (UChar*) (&amp;((UChar*)s-&gt;arr2)[s-&gt;nblock]);
-
-   /*-- If this is the first block, create the stream header. --*/
-   if (s-&gt;blockNo == 1) {
-      BZ2_bsInitWrite ( s );
-      bsPutUChar ( s, BZ_HDR_B );
-      bsPutUChar ( s, BZ_HDR_Z );
-      bsPutUChar ( s, BZ_HDR_h );
-      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s-&gt;blockSize100k) );
-   }
-
-   if (s-&gt;nblock &gt; 0) {
-
-      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
-      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
-      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
-
-      /*-- Now the block's CRC, so it is in a known place. --*/
-      bsPutUInt32 ( s, s-&gt;blockCRC );
-
-      /*-- 
-         Now a single bit indicating (non-)randomisation. 
-         As of version 0.9.5, we use a better sorting algorithm
-         which makes randomisation unnecessary.  So always set
-         the randomised bit to 'no'.  Of course, the decoder
-         still needs to be able to handle randomised blocks
-         so as to maintain backwards compatibility with
-         older versions of bzip2.
-      --*/
-      bsW(s,1,0);
-
-      bsW ( s, 24, s-&gt;origPtr );
-      generateMTFValues ( s );
-      sendMTFValues ( s );
-   }
-
-
-   /*-- If this is the last block, add the stream trailer. --*/
-   if (is_last_block) {
-
-      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
-      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
-      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
-      bsPutUInt32 ( s, s-&gt;combinedCRC );
-      if (s-&gt;verbosity &gt;= 2)
-         VPrintf1( &quot;    final combined CRC = 0x%08x\n   &quot;, s-&gt;combinedCRC );
-      bsFinishWrite ( s );
-   }
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                        compress.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+/* CHANGES
+    0.9.0    -- original version.
+    0.9.0a/b -- no changes in this file.
+    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
+                so as to do a bit better on small files
+*/
+
+#include &quot;bzlib_private.h&quot;
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+   s-&gt;bsLive = 0;
+   s-&gt;bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+   while (s-&gt;bsLive &gt; 0) {
+      s-&gt;zbits[s-&gt;numZ] = (UChar)(s-&gt;bsBuff &gt;&gt; 24);
+      s-&gt;numZ++;
+      s-&gt;bsBuff &lt;&lt;= 8;
+      s-&gt;bsLive -= 8;
+   }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz)                           \
+{                                             \
+   while (s-&gt;bsLive &gt;= 8) {                   \
+      s-&gt;zbits[s-&gt;numZ]                       \
+         = (UChar)(s-&gt;bsBuff &gt;&gt; 24);          \
+      s-&gt;numZ++;                              \
+      s-&gt;bsBuff &lt;&lt;= 8;                        \
+      s-&gt;bsLive -= 8;                         \
+   }                                          \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+   bsNEEDW ( n );
+   s-&gt;bsBuff |= (v &lt;&lt; (32 - s-&gt;bsLive - n));
+   s-&gt;bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+   bsW ( s, 8, (u &gt;&gt; 24) &amp; 0xffL );
+   bsW ( s, 8, (u &gt;&gt; 16) &amp; 0xffL );
+   bsW ( s, 8, (u &gt;&gt;  8) &amp; 0xffL );
+   bsW ( s, 8,  u        &amp; 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+   bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+   Int32 i;
+   s-&gt;nInUse = 0;
+   for (i = 0; i &lt; 256; i++)
+      if (s-&gt;inUse[i]) {
+         s-&gt;unseqToSeq[i] = s-&gt;nInUse;
+         s-&gt;nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+   UChar   yy[256];
+   Int32   i, j;
+   Int32   zPend;
+   Int32   wr;
+   Int32   EOB;
+
+   /* 
+      After sorting (eg, here),
+         s-&gt;arr1 [ 0 .. s-&gt;nblock-1 ] holds sorted order,
+         and
+         ((UChar*)s-&gt;arr2) [ 0 .. s-&gt;nblock-1 ] 
+         holds the original block data.
+
+      The first thing to do is generate the MTF values,
+      and put them in
+         ((UInt16*)s-&gt;arr1) [ 0 .. s-&gt;nblock-1 ].
+      Because there are strictly fewer or equal MTF values
+      than block values, ptr values in this area are overwritten
+      with MTF values only when they are no longer needed.
+
+      The final compressed bitstream is generated into the
+      area starting at
+         (UChar*) (&amp;((UChar*)s-&gt;arr2)[s-&gt;nblock])
+
+      These storage aliases are set up in bzCompressInit(),
+      except for the last one, which is arranged in 
+      compressBlock().
+   */
+   UInt32* ptr   = s-&gt;ptr;
+   UChar* block  = s-&gt;block;
+   UInt16* mtfv  = s-&gt;mtfv;
+
+   makeMaps_e ( s );
+   EOB = s-&gt;nInUse+1;
+
+   for (i = 0; i &lt;= EOB; i++) s-&gt;mtfFreq[i] = 0;
+
+   wr = 0;
+   zPend = 0;
+   for (i = 0; i &lt; s-&gt;nInUse; i++) yy[i] = (UChar) i;
+
+   for (i = 0; i &lt; s-&gt;nblock; i++) {
+      UChar ll_i;
+      AssertD ( wr &lt;= i, &quot;generateMTFValues(1)&quot; );
+      j = ptr[i]-1; if (j &lt; 0) j += s-&gt;nblock;
+      ll_i = s-&gt;unseqToSeq[block[j]];
+      AssertD ( ll_i &lt; s-&gt;nInUse, &quot;generateMTFValues(2a)&quot; );
+
+      if (yy[0] == ll_i) { 
+         zPend++;
+      } else {
+
+         if (zPend &gt; 0) {
+            zPend--;
+            while (True) {
+               if (zPend &amp; 1) {
+                  mtfv[wr] = BZ_RUNB; wr++; 
+                  s-&gt;mtfFreq[BZ_RUNB]++; 
+               } else {
+                  mtfv[wr] = BZ_RUNA; wr++; 
+                  s-&gt;mtfFreq[BZ_RUNA]++; 
+               }
+               if (zPend &lt; 2) break;
+               zPend = (zPend - 2) / 2;
+            };
+            zPend = 0;
+         }
+         {
+            register UChar  rtmp;
+            register UChar* ryy_j;
+            register UChar  rll_i;
+            rtmp  = yy[1];
+            yy[1] = yy[0];
+            ryy_j = &amp;(yy[1]);
+            rll_i = ll_i;
+            while ( rll_i != rtmp ) {
+               register UChar rtmp2;
+               ryy_j++;
+               rtmp2  = rtmp;
+               rtmp   = *ryy_j;
+               *ryy_j = rtmp2;
+            };
+            yy[0] = rtmp;
+            j = ryy_j - &amp;(yy[0]);
+            mtfv[wr] = j+1; wr++; s-&gt;mtfFreq[j+1]++;
+         }
+
+      }
+   }
+
+   if (zPend &gt; 0) {
+      zPend--;
+      while (True) {
+         if (zPend &amp; 1) {
+            mtfv[wr] = BZ_RUNB; wr++; 
+            s-&gt;mtfFreq[BZ_RUNB]++; 
+         } else {
+            mtfv[wr] = BZ_RUNA; wr++; 
+            s-&gt;mtfFreq[BZ_RUNA]++; 
+         }
+         if (zPend &lt; 2) break;
+         zPend = (zPend - 2) / 2;
+      };
+      zPend = 0;
+   }
+
+   mtfv[wr] = EOB; wr++; s-&gt;mtfFreq[EOB]++;
+
+   s-&gt;nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+   Int32 nGroups, nBytes;
+
+   /*--
+   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   is a global since the decoder also needs it.
+
+   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+   are also globals only used in this proc.
+   Made global to keep stack frame size small.
+   --*/
+
+
+   UInt16 cost[BZ_N_GROUPS];
+   Int32  fave[BZ_N_GROUPS];
+
+   UInt16* mtfv = s-&gt;mtfv;
+
+   if (s-&gt;verbosity &gt;= 3)
+      VPrintf3( &quot;      %d in block, %d after MTF &amp; 1-2 coding, &quot;
+                &quot;%d+2 syms in use\n&quot;, 
+                s-&gt;nblock, s-&gt;nMTF, s-&gt;nInUse );
+
+   alphaSize = s-&gt;nInUse+2;
+   for (t = 0; t &lt; BZ_N_GROUPS; t++)
+      for (v = 0; v &lt; alphaSize; v++)
+         s-&gt;len[t][v] = BZ_GREATER_ICOST;
+
+   /*--- Decide how many coding tables to use ---*/
+   AssertH ( s-&gt;nMTF &gt; 0, 3001 );
+   if (s-&gt;nMTF &lt; 200)  nGroups = 2; else
+   if (s-&gt;nMTF &lt; 600)  nGroups = 3; else
+   if (s-&gt;nMTF &lt; 1200) nGroups = 4; else
+   if (s-&gt;nMTF &lt; 2400) nGroups = 5; else
+                       nGroups = 6;
+
+   /*--- Generate an initial set of coding tables ---*/
+   { 
+      Int32 nPart, remF, tFreq, aFreq;
+
+      nPart = nGroups;
+      remF  = s-&gt;nMTF;
+      gs = 0;
+      while (nPart &gt; 0) {
+         tFreq = remF / nPart;
+         ge = gs-1;
+         aFreq = 0;
+         while (aFreq &lt; tFreq &amp;&amp; ge &lt; alphaSize-1) {
+            ge++;
+            aFreq += s-&gt;mtfFreq[ge];
+         }
+
+         if (ge &gt; gs 
+             &amp;&amp; nPart != nGroups &amp;&amp; nPart != 1 
+             &amp;&amp; ((nGroups-nPart) % 2 == 1)) {
+            aFreq -= s-&gt;mtfFreq[ge];
+            ge--;
+         }
+
+         if (s-&gt;verbosity &gt;= 3)
+            VPrintf5( &quot;      initial group %d, [%d .. %d], &quot;
+                      &quot;has %d syms (%4.1f%%)\n&quot;,
+                      nPart, gs, ge, aFreq, 
+                      (100.0 * (float)aFreq) / (float)(s-&gt;nMTF) );
+ 
+         for (v = 0; v &lt; alphaSize; v++)
+            if (v &gt;= gs &amp;&amp; v &lt;= ge) 
+               s-&gt;len[nPart-1][v] = BZ_LESSER_ICOST; else
+               s-&gt;len[nPart-1][v] = BZ_GREATER_ICOST;
+ 
+         nPart--;
+         gs = ge+1;
+         remF -= aFreq;
+      }
+   }
+
+   /*--- 
+      Iterate up to BZ_N_ITERS times to improve the tables.
+   ---*/
+   for (iter = 0; iter &lt; BZ_N_ITERS; iter++) {
+
+      for (t = 0; t &lt; nGroups; t++) fave[t] = 0;
+
+      for (t = 0; t &lt; nGroups; t++)
+         for (v = 0; v &lt; alphaSize; v++)
+            s-&gt;rfreq[t][v] = 0;
+
+      /*---
+        Set up an auxiliary length table which is used to fast-track
+	the common case (nGroups == 6). 
+      ---*/
+      if (nGroups == 6) {
+         for (v = 0; v &lt; alphaSize; v++) {
+            s-&gt;len_pack[v][0] = (s-&gt;len[1][v] &lt;&lt; 16) | s-&gt;len[0][v];
+            s-&gt;len_pack[v][1] = (s-&gt;len[3][v] &lt;&lt; 16) | s-&gt;len[2][v];
+            s-&gt;len_pack[v][2] = (s-&gt;len[5][v] &lt;&lt; 16) | s-&gt;len[4][v];
+	 }
+      }
+
+      nSelectors = 0;
+      totc = 0;
+      gs = 0;
+      while (True) {
+
+         /*--- Set group start &amp; end marks. --*/
+         if (gs &gt;= s-&gt;nMTF) break;
+         ge = gs + BZ_G_SIZE - 1; 
+         if (ge &gt;= s-&gt;nMTF) ge = s-&gt;nMTF-1;
+
+         /*-- 
+            Calculate the cost of this group as coded
+            by each of the coding tables.
+         --*/
+         for (t = 0; t &lt; nGroups; t++) cost[t] = 0;
+
+         if (nGroups == 6 &amp;&amp; 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            register UInt32 cost01, cost23, cost45;
+            register UInt16 icv;
+            cost01 = cost23 = cost45 = 0;
+
+#           define BZ_ITER(nn)                \
+               icv = mtfv[gs+(nn)];           \
+               cost01 += s-&gt;len_pack[icv][0]; \
+               cost23 += s-&gt;len_pack[icv][1]; \
+               cost45 += s-&gt;len_pack[icv][2]; \
+
+            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+#           undef BZ_ITER
+
+            cost[0] = cost01 &amp; 0xffff; cost[1] = cost01 &gt;&gt; 16;
+            cost[2] = cost23 &amp; 0xffff; cost[3] = cost23 &gt;&gt; 16;
+            cost[4] = cost45 &amp; 0xffff; cost[5] = cost45 &gt;&gt; 16;
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i &lt;= ge; i++) { 
+               UInt16 icv = mtfv[i];
+               for (t = 0; t &lt; nGroups; t++) cost[t] += s-&gt;len[t][icv];
+            }
+         }
+ 
+         /*-- 
+            Find the coding table which is best for this group,
+            and record its identity in the selector table.
+         --*/
+         bc = 999999999; bt = -1;
+         for (t = 0; t &lt; nGroups; t++)
+            if (cost[t] &lt; bc) { bc = cost[t]; bt = t; };
+         totc += bc;
+         fave[bt]++;
+         s-&gt;selector[nSelectors] = bt;
+         nSelectors++;
+
+         /*-- 
+            Increment the symbol frequencies for the selected table.
+          --*/
+         if (nGroups == 6 &amp;&amp; 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+
+#           define BZ_ITUR(nn) s-&gt;rfreq[bt][ mtfv[gs+(nn)] ]++
+
+            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+#           undef BZ_ITUR
+
+         } else {
+	    /*--- slow version which correctly handles all situations ---*/
+            for (i = gs; i &lt;= ge; i++)
+               s-&gt;rfreq[bt][ mtfv[i] ]++;
+         }
+
+         gs = ge+1;
+      }
+      if (s-&gt;verbosity &gt;= 3) {
+         VPrintf2 ( &quot;      pass %d: size is %d, grp uses are &quot;, 
+                   iter+1, totc/8 );
+         for (t = 0; t &lt; nGroups; t++)
+            VPrintf1 ( &quot;%d &quot;, fave[t] );
+         VPrintf0 ( &quot;\n&quot; );
+      }
+
+      /*--
+        Recompute the tables based on the accumulated frequencies.
+      --*/
+      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
+         comment in huffman.c for details. */
+      for (t = 0; t &lt; nGroups; t++)
+         BZ2_hbMakeCodeLengths ( &amp;(s-&gt;len[t][0]), &amp;(s-&gt;rfreq[t][0]), 
+                                 alphaSize, 17 /*20*/ );
+   }
+
+
+   AssertH( nGroups &lt; 8, 3002 );
+   AssertH( nSelectors &lt; 32768 &amp;&amp;
+            nSelectors &lt;= (2 + (900000 / BZ_G_SIZE)),
+            3003 );
+
+
+   /*--- Compute MTF values for the selectors. ---*/
+   {
+      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+      for (i = 0; i &lt; nGroups; i++) pos[i] = i;
+      for (i = 0; i &lt; nSelectors; i++) {
+         ll_i = s-&gt;selector[i];
+         j = 0;
+         tmp = pos[j];
+         while ( ll_i != tmp ) {
+            j++;
+            tmp2 = tmp;
+            tmp = pos[j];
+            pos[j] = tmp2;
+         };
+         pos[0] = tmp;
+         s-&gt;selectorMtf[i] = j;
+      }
+   };
+
+   /*--- Assign actual codes for the tables. --*/
+   for (t = 0; t &lt; nGroups; t++) {
+      minLen = 32;
+      maxLen = 0;
+      for (i = 0; i &lt; alphaSize; i++) {
+         if (s-&gt;len[t][i] &gt; maxLen) maxLen = s-&gt;len[t][i];
+         if (s-&gt;len[t][i] &lt; minLen) minLen = s-&gt;len[t][i];
+      }
+      AssertH ( !(maxLen &gt; 17 /*20*/ ), 3004 );
+      AssertH ( !(minLen &lt; 1),  3005 );
+      BZ2_hbAssignCodes ( &amp;(s-&gt;code[t][0]), &amp;(s-&gt;len[t][0]), 
+                          minLen, maxLen, alphaSize );
+   }
+
+   /*--- Transmit the mapping table. ---*/
+   { 
+      Bool inUse16[16];
+      for (i = 0; i &lt; 16; i++) {
+          inUse16[i] = False;
+          for (j = 0; j &lt; 16; j++)
+             if (s-&gt;inUse[i * 16 + j]) inUse16[i] = True;
+      }
+     
+      nBytes = s-&gt;numZ;
+      for (i = 0; i &lt; 16; i++)
+         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+      for (i = 0; i &lt; 16; i++)
+         if (inUse16[i])
+            for (j = 0; j &lt; 16; j++) {
+               if (s-&gt;inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+            }
+
+      if (s-&gt;verbosity &gt;= 3) 
+         VPrintf1( &quot;      bytes: mapping %d, &quot;, s-&gt;numZ-nBytes );
+   }
+
+   /*--- Now the selectors. ---*/
+   nBytes = s-&gt;numZ;
+   bsW ( s, 3, nGroups );
+   bsW ( s, 15, nSelectors );
+   for (i = 0; i &lt; nSelectors; i++) { 
+      for (j = 0; j &lt; s-&gt;selectorMtf[i]; j++) bsW(s,1,1);
+      bsW(s,1,0);
+   }
+   if (s-&gt;verbosity &gt;= 3)
+      VPrintf1( &quot;selectors %d, &quot;, s-&gt;numZ-nBytes );
+
+   /*--- Now the coding tables. ---*/
+   nBytes = s-&gt;numZ;
+
+   for (t = 0; t &lt; nGroups; t++) {
+      Int32 curr = s-&gt;len[t][0];
+      bsW ( s, 5, curr );
+      for (i = 0; i &lt; alphaSize; i++) {
+         while (curr &lt; s-&gt;len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+         while (curr &gt; s-&gt;len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+         bsW ( s, 1, 0 );
+      }
+   }
+
+   if (s-&gt;verbosity &gt;= 3)
+      VPrintf1 ( &quot;code lengths %d, &quot;, s-&gt;numZ-nBytes );
+
+   /*--- And finally, the block data proper ---*/
+   nBytes = s-&gt;numZ;
+   selCtr = 0;
+   gs = 0;
+   while (True) {
+      if (gs &gt;= s-&gt;nMTF) break;
+      ge = gs + BZ_G_SIZE - 1; 
+      if (ge &gt;= s-&gt;nMTF) ge = s-&gt;nMTF-1;
+      AssertH ( s-&gt;selector[selCtr] &lt; nGroups, 3006 );
+
+      if (nGroups == 6 &amp;&amp; 50 == ge-gs+1) {
+            /*--- fast track the common case ---*/
+            UInt16 mtfv_i;
+            UChar* s_len_sel_selCtr 
+               = &amp;(s-&gt;len[s-&gt;selector[selCtr]][0]);
+            Int32* s_code_sel_selCtr
+               = &amp;(s-&gt;code[s-&gt;selector[selCtr]][0]);
+
+#           define BZ_ITAH(nn)                      \
+               mtfv_i = mtfv[gs+(nn)];              \
+               bsW ( s,                             \
+                     s_len_sel_selCtr[mtfv_i],      \
+                     s_code_sel_selCtr[mtfv_i] )
+
+            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+#           undef BZ_ITAH
+
+      } else {
+	 /*--- slow version which correctly handles all situations ---*/
+         for (i = gs; i &lt;= ge; i++) {
+            bsW ( s, 
+                  s-&gt;len  [s-&gt;selector[selCtr]] [mtfv[i]],
+                  s-&gt;code [s-&gt;selector[selCtr]] [mtfv[i]] );
+         }
+      }
+
+
+      gs = ge+1;
+      selCtr++;
+   }
+   AssertH( selCtr == nSelectors, 3007 );
+
+   if (s-&gt;verbosity &gt;= 3)
+      VPrintf1( &quot;codes %d\n&quot;, s-&gt;numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+   if (s-&gt;nblock &gt; 0) {
+
+      BZ_FINALISE_CRC ( s-&gt;blockCRC );
+      s-&gt;combinedCRC = (s-&gt;combinedCRC &lt;&lt; 1) | (s-&gt;combinedCRC &gt;&gt; 31);
+      s-&gt;combinedCRC ^= s-&gt;blockCRC;
+      if (s-&gt;blockNo &gt; 1) s-&gt;numZ = 0;
+
+      if (s-&gt;verbosity &gt;= 2)
+         VPrintf4( &quot;    block %d: crc = 0x%08x, &quot;
+                   &quot;combined CRC = 0x%08x, size = %d\n&quot;,
+                   s-&gt;blockNo, s-&gt;blockCRC, s-&gt;combinedCRC, s-&gt;nblock );
+
+      BZ2_blockSort ( s );
+   }
+
+   s-&gt;zbits = (UChar*) (&amp;((UChar*)s-&gt;arr2)[s-&gt;nblock]);
+
+   /*-- If this is the first block, create the stream header. --*/
+   if (s-&gt;blockNo == 1) {
+      BZ2_bsInitWrite ( s );
+      bsPutUChar ( s, BZ_HDR_B );
+      bsPutUChar ( s, BZ_HDR_Z );
+      bsPutUChar ( s, BZ_HDR_h );
+      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s-&gt;blockSize100k) );
+   }
+
+   if (s-&gt;nblock &gt; 0) {
+
+      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+      /*-- Now the block's CRC, so it is in a known place. --*/
+      bsPutUInt32 ( s, s-&gt;blockCRC );
+
+      /*-- 
+         Now a single bit indicating (non-)randomisation. 
+         As of version 0.9.5, we use a better sorting algorithm
+         which makes randomisation unnecessary.  So always set
+         the randomised bit to 'no'.  Of course, the decoder
+         still needs to be able to handle randomised blocks
+         so as to maintain backwards compatibility with
+         older versions of bzip2.
+      --*/
+      bsW(s,1,0);
+
+      bsW ( s, 24, s-&gt;origPtr );
+      generateMTFValues ( s );
+      sendMTFValues ( s );
+   }
+
+
+   /*-- If this is the last block, add the stream trailer. --*/
+   if (is_last_block) {
+
+      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+      bsPutUInt32 ( s, s-&gt;combinedCRC );
+      if (s-&gt;verbosity &gt;= 2)
+         VPrintf1( &quot;    final combined CRC = 0x%08x\n   &quot;, s-&gt;combinedCRC );
+      bsFinishWrite ( s );
+   }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/compress.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,104 +1,104 @@
-
-/*-------------------------------------------------------------*/
-/*--- Table for doing CRCs                                  ---*/
-/*---                                            crctable.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &quot;bzlib_private.h&quot;
-
-/*--
-  I think this is an implementation of the AUTODIN-II,
-  Ethernet &amp; FDDI 32-bit CRC standard.  Vaguely derived
-  from code by Rob Warnock, in Section 51 of the
-  comp.compression FAQ.
---*/
-
-UInt32 BZ2_crc32Table[256] = {
-
-   /*-- Ugly, innit? --*/
-
-   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
-   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
-   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
-   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
-   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
-   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
-   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
-   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
-   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
-   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
-   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
-   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
-   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
-   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
-   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
-   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
-   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
-   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
-   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
-   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
-   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
-   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
-   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
-   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
-   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
-   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
-   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
-   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
-   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
-   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
-   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
-   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
-   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
-   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
-   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
-   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
-   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
-   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
-   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
-   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
-   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
-   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
-   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
-   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
-   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
-   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
-   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
-   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
-   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
-   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
-   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
-   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
-   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
-   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
-   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
-   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
-   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
-   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
-   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
-   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
-   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
-   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
-   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
-   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
-};
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                        crctable.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs                                  ---*/
+/*---                                            crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &quot;bzlib_private.h&quot;
+
+/*--
+  I think this is an implementation of the AUTODIN-II,
+  Ethernet &amp; FDDI 32-bit CRC standard.  Vaguely derived
+  from code by Rob Warnock, in Section 51 of the
+  comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+   /*-- Ugly, innit? --*/
+
+   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        crctable.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/crctable.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,626 +1,626 @@
-
-/*-------------------------------------------------------------*/
-/*--- Decompression machinery                               ---*/
-/*---                                          decompress.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &quot;bzlib_private.h&quot;
-
-
-/*---------------------------------------------------*/
-static
-void makeMaps_d ( DState* s )
-{
-   Int32 i;
-   s-&gt;nInUse = 0;
-   for (i = 0; i &lt; 256; i++)
-      if (s-&gt;inUse[i]) {
-         s-&gt;seqToUnseq[s-&gt;nInUse] = i;
-         s-&gt;nInUse++;
-      }
-}
-
-
-/*---------------------------------------------------*/
-#define RETURN(rrr)                               \
-   { retVal = rrr; goto save_state_and_return; };
-
-#define GET_BITS(lll,vvv,nnn)                     \
-   case lll: s-&gt;state = lll;                      \
-   while (True) {                                 \
-      if (s-&gt;bsLive &gt;= nnn) {                     \
-         UInt32 v;                                \
-         v = (s-&gt;bsBuff &gt;&gt;                        \
-             (s-&gt;bsLive-nnn)) &amp; ((1 &lt;&lt; nnn)-1);   \
-         s-&gt;bsLive -= nnn;                        \
-         vvv = v;                                 \
-         break;                                   \
-      }                                           \
-      if (s-&gt;strm-&gt;avail_in == 0) RETURN(BZ_OK);  \
-      s-&gt;bsBuff                                   \
-         = (s-&gt;bsBuff &lt;&lt; 8) |                     \
-           ((UInt32)                              \
-              (*((UChar*)(s-&gt;strm-&gt;next_in))));   \
-      s-&gt;bsLive += 8;                             \
-      s-&gt;strm-&gt;next_in++;                         \
-      s-&gt;strm-&gt;avail_in--;                        \
-      s-&gt;strm-&gt;total_in_lo32++;                   \
-      if (s-&gt;strm-&gt;total_in_lo32 == 0)            \
-         s-&gt;strm-&gt;total_in_hi32++;                \
-   }
-
-#define GET_UCHAR(lll,uuu)                        \
-   GET_BITS(lll,uuu,8)
-
-#define GET_BIT(lll,uuu)                          \
-   GET_BITS(lll,uuu,1)
-
-/*---------------------------------------------------*/
-#define GET_MTF_VAL(label1,label2,lval)           \
-{                                                 \
-   if (groupPos == 0) {                           \
-      groupNo++;                                  \
-      if (groupNo &gt;= nSelectors)                  \
-         RETURN(BZ_DATA_ERROR);                   \
-      groupPos = BZ_G_SIZE;                       \
-      gSel = s-&gt;selector[groupNo];                \
-      gMinlen = s-&gt;minLens[gSel];                 \
-      gLimit = &amp;(s-&gt;limit[gSel][0]);              \
-      gPerm = &amp;(s-&gt;perm[gSel][0]);                \
-      gBase = &amp;(s-&gt;base[gSel][0]);                \
-   }                                              \
-   groupPos--;                                    \
-   zn = gMinlen;                                  \
-   GET_BITS(label1, zvec, zn);                    \
-   while (1) {                                    \
-      if (zn &gt; 20 /* the longest code */)         \
-         RETURN(BZ_DATA_ERROR);                   \
-      if (zvec &lt;= gLimit[zn]) break;              \
-      zn++;                                       \
-      GET_BIT(label2, zj);                        \
-      zvec = (zvec &lt;&lt; 1) | zj;                    \
-   };                                             \
-   if (zvec - gBase[zn] &lt; 0                       \
-       || zvec - gBase[zn] &gt;= BZ_MAX_ALPHA_SIZE)  \
-      RETURN(BZ_DATA_ERROR);                      \
-   lval = gPerm[zvec - gBase[zn]];                \
-}
-
-
-/*---------------------------------------------------*/
-Int32 BZ2_decompress ( DState* s )
-{
-   UChar      uc;
-   Int32      retVal;
-   Int32      minLen, maxLen;
-   bz_stream* strm = s-&gt;strm;
-
-   /* stuff that needs to be saved/restored */
-   Int32  i;
-   Int32  j;
-   Int32  t;
-   Int32  alphaSize;
-   Int32  nGroups;
-   Int32  nSelectors;
-   Int32  EOB;
-   Int32  groupNo;
-   Int32  groupPos;
-   Int32  nextSym;
-   Int32  nblockMAX;
-   Int32  nblock;
-   Int32  es;
-   Int32  N;
-   Int32  curr;
-   Int32  zt;
-   Int32  zn; 
-   Int32  zvec;
-   Int32  zj;
-   Int32  gSel;
-   Int32  gMinlen;
-   Int32* gLimit;
-   Int32* gBase;
-   Int32* gPerm;
-
-   if (s-&gt;state == BZ_X_MAGIC_1) {
-      /*initialise the save area*/
-      s-&gt;save_i           = 0;
-      s-&gt;save_j           = 0;
-      s-&gt;save_t           = 0;
-      s-&gt;save_alphaSize   = 0;
-      s-&gt;save_nGroups     = 0;
-      s-&gt;save_nSelectors  = 0;
-      s-&gt;save_EOB         = 0;
-      s-&gt;save_groupNo     = 0;
-      s-&gt;save_groupPos    = 0;
-      s-&gt;save_nextSym     = 0;
-      s-&gt;save_nblockMAX   = 0;
-      s-&gt;save_nblock      = 0;
-      s-&gt;save_es          = 0;
-      s-&gt;save_N           = 0;
-      s-&gt;save_curr        = 0;
-      s-&gt;save_zt          = 0;
-      s-&gt;save_zn          = 0;
-      s-&gt;save_zvec        = 0;
-      s-&gt;save_zj          = 0;
-      s-&gt;save_gSel        = 0;
-      s-&gt;save_gMinlen     = 0;
-      s-&gt;save_gLimit      = NULL;
-      s-&gt;save_gBase       = NULL;
-      s-&gt;save_gPerm       = NULL;
-   }
-
-   /*restore from the save area*/
-   i           = s-&gt;save_i;
-   j           = s-&gt;save_j;
-   t           = s-&gt;save_t;
-   alphaSize   = s-&gt;save_alphaSize;
-   nGroups     = s-&gt;save_nGroups;
-   nSelectors  = s-&gt;save_nSelectors;
-   EOB         = s-&gt;save_EOB;
-   groupNo     = s-&gt;save_groupNo;
-   groupPos    = s-&gt;save_groupPos;
-   nextSym     = s-&gt;save_nextSym;
-   nblockMAX   = s-&gt;save_nblockMAX;
-   nblock      = s-&gt;save_nblock;
-   es          = s-&gt;save_es;
-   N           = s-&gt;save_N;
-   curr        = s-&gt;save_curr;
-   zt          = s-&gt;save_zt;
-   zn          = s-&gt;save_zn; 
-   zvec        = s-&gt;save_zvec;
-   zj          = s-&gt;save_zj;
-   gSel        = s-&gt;save_gSel;
-   gMinlen     = s-&gt;save_gMinlen;
-   gLimit      = s-&gt;save_gLimit;
-   gBase       = s-&gt;save_gBase;
-   gPerm       = s-&gt;save_gPerm;
-
-   retVal = BZ_OK;
-
-   switch (s-&gt;state) {
-
-      GET_UCHAR(BZ_X_MAGIC_1, uc);
-      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
-
-      GET_UCHAR(BZ_X_MAGIC_2, uc);
-      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
-
-      GET_UCHAR(BZ_X_MAGIC_3, uc)
-      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
-
-      GET_BITS(BZ_X_MAGIC_4, s-&gt;blockSize100k, 8)
-      if (s-&gt;blockSize100k &lt; (BZ_HDR_0 + 1) || 
-          s-&gt;blockSize100k &gt; (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
-      s-&gt;blockSize100k -= BZ_HDR_0;
-
-      if (s-&gt;smallDecompress) {
-         s-&gt;ll16 = BZALLOC( s-&gt;blockSize100k * 100000 * sizeof(UInt16) );
-         s-&gt;ll4  = BZALLOC( 
-                      ((1 + s-&gt;blockSize100k * 100000) &gt;&gt; 1) * sizeof(UChar) 
-                   );
-         if (s-&gt;ll16 == NULL || s-&gt;ll4 == NULL) RETURN(BZ_MEM_ERROR);
-      } else {
-         s-&gt;tt  = BZALLOC( s-&gt;blockSize100k * 100000 * sizeof(Int32) );
-         if (s-&gt;tt == NULL) RETURN(BZ_MEM_ERROR);
-      }
-
-      GET_UCHAR(BZ_X_BLKHDR_1, uc);
-
-      if (uc == 0x17) goto endhdr_2;
-      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_BLKHDR_2, uc);
-      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_BLKHDR_3, uc);
-      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_BLKHDR_4, uc);
-      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_BLKHDR_5, uc);
-      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_BLKHDR_6, uc);
-      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
-
-      s-&gt;currBlockNo++;
-      if (s-&gt;verbosity &gt;= 2)
-         VPrintf1 ( &quot;\n    [%d: huff+mtf &quot;, s-&gt;currBlockNo );
- 
-      s-&gt;storedBlockCRC = 0;
-      GET_UCHAR(BZ_X_BCRC_1, uc);
-      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
-      GET_UCHAR(BZ_X_BCRC_2, uc);
-      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
-      GET_UCHAR(BZ_X_BCRC_3, uc);
-      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
-      GET_UCHAR(BZ_X_BCRC_4, uc);
-      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
-
-      GET_BITS(BZ_X_RANDBIT, s-&gt;blockRandomised, 1);
-
-      s-&gt;origPtr = 0;
-      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
-      s-&gt;origPtr = (s-&gt;origPtr &lt;&lt; 8) | ((Int32)uc);
-      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
-      s-&gt;origPtr = (s-&gt;origPtr &lt;&lt; 8) | ((Int32)uc);
-      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
-      s-&gt;origPtr = (s-&gt;origPtr &lt;&lt; 8) | ((Int32)uc);
-
-      if (s-&gt;origPtr &lt; 0)
-         RETURN(BZ_DATA_ERROR);
-      if (s-&gt;origPtr &gt; 10 + 100000*s-&gt;blockSize100k) 
-         RETURN(BZ_DATA_ERROR);
-
-      /*--- Receive the mapping table ---*/
-      for (i = 0; i &lt; 16; i++) {
-         GET_BIT(BZ_X_MAPPING_1, uc);
-         if (uc == 1) 
-            s-&gt;inUse16[i] = True; else 
-            s-&gt;inUse16[i] = False;
-      }
-
-      for (i = 0; i &lt; 256; i++) s-&gt;inUse[i] = False;
-
-      for (i = 0; i &lt; 16; i++)
-         if (s-&gt;inUse16[i])
-            for (j = 0; j &lt; 16; j++) {
-               GET_BIT(BZ_X_MAPPING_2, uc);
-               if (uc == 1) s-&gt;inUse[i * 16 + j] = True;
-            }
-      makeMaps_d ( s );
-      if (s-&gt;nInUse == 0) RETURN(BZ_DATA_ERROR);
-      alphaSize = s-&gt;nInUse+2;
-
-      /*--- Now the selectors ---*/
-      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
-      if (nGroups &lt; 2 || nGroups &gt; 6) RETURN(BZ_DATA_ERROR);
-      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
-      if (nSelectors &lt; 1) RETURN(BZ_DATA_ERROR);
-      for (i = 0; i &lt; nSelectors; i++) {
-         j = 0;
-         while (True) {
-            GET_BIT(BZ_X_SELECTOR_3, uc);
-            if (uc == 0) break;
-            j++;
-            if (j &gt;= nGroups) RETURN(BZ_DATA_ERROR);
-         }
-         s-&gt;selectorMtf[i] = j;
-      }
-
-      /*--- Undo the MTF values for the selectors. ---*/
-      {
-         UChar pos[BZ_N_GROUPS], tmp, v;
-         for (v = 0; v &lt; nGroups; v++) pos[v] = v;
-   
-         for (i = 0; i &lt; nSelectors; i++) {
-            v = s-&gt;selectorMtf[i];
-            tmp = pos[v];
-            while (v &gt; 0) { pos[v] = pos[v-1]; v--; }
-            pos[0] = tmp;
-            s-&gt;selector[i] = tmp;
-         }
-      }
-
-      /*--- Now the coding tables ---*/
-      for (t = 0; t &lt; nGroups; t++) {
-         GET_BITS(BZ_X_CODING_1, curr, 5);
-         for (i = 0; i &lt; alphaSize; i++) {
-            while (True) {
-               if (curr &lt; 1 || curr &gt; 20) RETURN(BZ_DATA_ERROR);
-               GET_BIT(BZ_X_CODING_2, uc);
-               if (uc == 0) break;
-               GET_BIT(BZ_X_CODING_3, uc);
-               if (uc == 0) curr++; else curr--;
-            }
-            s-&gt;len[t][i] = curr;
-         }
-      }
-
-      /*--- Create the Huffman decoding tables ---*/
-      for (t = 0; t &lt; nGroups; t++) {
-         minLen = 32;
-         maxLen = 0;
-         for (i = 0; i &lt; alphaSize; i++) {
-            if (s-&gt;len[t][i] &gt; maxLen) maxLen = s-&gt;len[t][i];
-            if (s-&gt;len[t][i] &lt; minLen) minLen = s-&gt;len[t][i];
-         }
-         BZ2_hbCreateDecodeTables ( 
-            &amp;(s-&gt;limit[t][0]), 
-            &amp;(s-&gt;base[t][0]), 
-            &amp;(s-&gt;perm[t][0]), 
-            &amp;(s-&gt;len[t][0]),
-            minLen, maxLen, alphaSize
-         );
-         s-&gt;minLens[t] = minLen;
-      }
-
-      /*--- Now the MTF values ---*/
-
-      EOB      = s-&gt;nInUse+1;
-      nblockMAX = 100000 * s-&gt;blockSize100k;
-      groupNo  = -1;
-      groupPos = 0;
-
-      for (i = 0; i &lt;= 255; i++) s-&gt;unzftab[i] = 0;
-
-      /*-- MTF init --*/
-      {
-         Int32 ii, jj, kk;
-         kk = MTFA_SIZE-1;
-         for (ii = 256 / MTFL_SIZE - 1; ii &gt;= 0; ii--) {
-            for (jj = MTFL_SIZE-1; jj &gt;= 0; jj--) {
-               s-&gt;mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
-               kk--;
-            }
-            s-&gt;mtfbase[ii] = kk + 1;
-         }
-      }
-      /*-- end MTF init --*/
-
-      nblock = 0;
-      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
-
-      while (True) {
-
-         if (nextSym == EOB) break;
-
-         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
-
-            es = -1;
-            N = 1;
-            do {
-               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
-               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
-               N = N * 2;
-               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
-            }
-               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
-
-            es++;
-            uc = s-&gt;seqToUnseq[ s-&gt;mtfa[s-&gt;mtfbase[0]] ];
-            s-&gt;unzftab[uc] += es;
-
-            if (s-&gt;smallDecompress)
-               while (es &gt; 0) {
-                  if (nblock &gt;= nblockMAX) RETURN(BZ_DATA_ERROR);
-                  s-&gt;ll16[nblock] = (UInt16)uc;
-                  nblock++;
-                  es--;
-               }
-            else
-               while (es &gt; 0) {
-                  if (nblock &gt;= nblockMAX) RETURN(BZ_DATA_ERROR);
-                  s-&gt;tt[nblock] = (UInt32)uc;
-                  nblock++;
-                  es--;
-               };
-
-            continue;
-
-         } else {
-
-            if (nblock &gt;= nblockMAX) RETURN(BZ_DATA_ERROR);
-
-            /*-- uc = MTF ( nextSym-1 ) --*/
-            {
-               Int32 ii, jj, kk, pp, lno, off;
-               UInt32 nn;
-               nn = (UInt32)(nextSym - 1);
-
-               if (nn &lt; MTFL_SIZE) {
-                  /* avoid general-case expense */
-                  pp = s-&gt;mtfbase[0];
-                  uc = s-&gt;mtfa[pp+nn];
-                  while (nn &gt; 3) {
-                     Int32 z = pp+nn;
-                     s-&gt;mtfa[(z)  ] = s-&gt;mtfa[(z)-1];
-                     s-&gt;mtfa[(z)-1] = s-&gt;mtfa[(z)-2];
-                     s-&gt;mtfa[(z)-2] = s-&gt;mtfa[(z)-3];
-                     s-&gt;mtfa[(z)-3] = s-&gt;mtfa[(z)-4];
-                     nn -= 4;
-                  }
-                  while (nn &gt; 0) { 
-                     s-&gt;mtfa[(pp+nn)] = s-&gt;mtfa[(pp+nn)-1]; nn--; 
-                  };
-                  s-&gt;mtfa[pp] = uc;
-               } else { 
-                  /* general case */
-                  lno = nn / MTFL_SIZE;
-                  off = nn % MTFL_SIZE;
-                  pp = s-&gt;mtfbase[lno] + off;
-                  uc = s-&gt;mtfa[pp];
-                  while (pp &gt; s-&gt;mtfbase[lno]) { 
-                     s-&gt;mtfa[pp] = s-&gt;mtfa[pp-1]; pp--; 
-                  };
-                  s-&gt;mtfbase[lno]++;
-                  while (lno &gt; 0) {
-                     s-&gt;mtfbase[lno]--;
-                     s-&gt;mtfa[s-&gt;mtfbase[lno]] 
-                        = s-&gt;mtfa[s-&gt;mtfbase[lno-1] + MTFL_SIZE - 1];
-                     lno--;
-                  }
-                  s-&gt;mtfbase[0]--;
-                  s-&gt;mtfa[s-&gt;mtfbase[0]] = uc;
-                  if (s-&gt;mtfbase[0] == 0) {
-                     kk = MTFA_SIZE-1;
-                     for (ii = 256 / MTFL_SIZE-1; ii &gt;= 0; ii--) {
-                        for (jj = MTFL_SIZE-1; jj &gt;= 0; jj--) {
-                           s-&gt;mtfa[kk] = s-&gt;mtfa[s-&gt;mtfbase[ii] + jj];
-                           kk--;
-                        }
-                        s-&gt;mtfbase[ii] = kk + 1;
-                     }
-                  }
-               }
-            }
-            /*-- end uc = MTF ( nextSym-1 ) --*/
-
-            s-&gt;unzftab[s-&gt;seqToUnseq[uc]]++;
-            if (s-&gt;smallDecompress)
-               s-&gt;ll16[nblock] = (UInt16)(s-&gt;seqToUnseq[uc]); else
-               s-&gt;tt[nblock]   = (UInt32)(s-&gt;seqToUnseq[uc]);
-            nblock++;
-
-            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
-            continue;
-         }
-      }
-
-      /* Now we know what nblock is, we can do a better sanity
-         check on s-&gt;origPtr.
-      */
-      if (s-&gt;origPtr &lt; 0 || s-&gt;origPtr &gt;= nblock)
-         RETURN(BZ_DATA_ERROR);
-
-      /*-- Set up cftab to facilitate generation of T^(-1) --*/
-      s-&gt;cftab[0] = 0;
-      for (i = 1; i &lt;= 256; i++) s-&gt;cftab[i] = s-&gt;unzftab[i-1];
-      for (i = 1; i &lt;= 256; i++) s-&gt;cftab[i] += s-&gt;cftab[i-1];
-      for (i = 0; i &lt;= 256; i++) {
-         if (s-&gt;cftab[i] &lt; 0 || s-&gt;cftab[i] &gt; nblock) {
-            /* s-&gt;cftab[i] can legitimately be == nblock */
-            RETURN(BZ_DATA_ERROR);
-         }
-      }
-
-      s-&gt;state_out_len = 0;
-      s-&gt;state_out_ch  = 0;
-      BZ_INITIALISE_CRC ( s-&gt;calculatedBlockCRC );
-      s-&gt;state = BZ_X_OUTPUT;
-      if (s-&gt;verbosity &gt;= 2) VPrintf0 ( &quot;rt+rld&quot; );
-
-      if (s-&gt;smallDecompress) {
-
-         /*-- Make a copy of cftab, used in generation of T --*/
-         for (i = 0; i &lt;= 256; i++) s-&gt;cftabCopy[i] = s-&gt;cftab[i];
-
-         /*-- compute the T vector --*/
-         for (i = 0; i &lt; nblock; i++) {
-            uc = (UChar)(s-&gt;ll16[i]);
-            SET_LL(i, s-&gt;cftabCopy[uc]);
-            s-&gt;cftabCopy[uc]++;
-         }
-
-         /*-- Compute T^(-1) by pointer reversal on T --*/
-         i = s-&gt;origPtr;
-         j = GET_LL(i);
-         do {
-            Int32 tmp = GET_LL(j);
-            SET_LL(j, i);
-            i = j;
-            j = tmp;
-         }
-            while (i != s-&gt;origPtr);
-
-         s-&gt;tPos = s-&gt;origPtr;
-         s-&gt;nblock_used = 0;
-         if (s-&gt;blockRandomised) {
-            BZ_RAND_INIT_MASK;
-            BZ_GET_SMALL(s-&gt;k0); s-&gt;nblock_used++;
-            BZ_RAND_UPD_MASK; s-&gt;k0 ^= BZ_RAND_MASK; 
-         } else {
-            BZ_GET_SMALL(s-&gt;k0); s-&gt;nblock_used++;
-         }
-
-      } else {
-
-         /*-- compute the T^(-1) vector --*/
-         for (i = 0; i &lt; nblock; i++) {
-            uc = (UChar)(s-&gt;tt[i] &amp; 0xff);
-            s-&gt;tt[s-&gt;cftab[uc]] |= (i &lt;&lt; 8);
-            s-&gt;cftab[uc]++;
-         }
-
-         s-&gt;tPos = s-&gt;tt[s-&gt;origPtr] &gt;&gt; 8;
-         s-&gt;nblock_used = 0;
-         if (s-&gt;blockRandomised) {
-            BZ_RAND_INIT_MASK;
-            BZ_GET_FAST(s-&gt;k0); s-&gt;nblock_used++;
-            BZ_RAND_UPD_MASK; s-&gt;k0 ^= BZ_RAND_MASK; 
-         } else {
-            BZ_GET_FAST(s-&gt;k0); s-&gt;nblock_used++;
-         }
-
-      }
-
-      RETURN(BZ_OK);
-
-
-
-    endhdr_2:
-
-      GET_UCHAR(BZ_X_ENDHDR_2, uc);
-      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_ENDHDR_3, uc);
-      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_ENDHDR_4, uc);
-      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_ENDHDR_5, uc);
-      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
-      GET_UCHAR(BZ_X_ENDHDR_6, uc);
-      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
-
-      s-&gt;storedCombinedCRC = 0;
-      GET_UCHAR(BZ_X_CCRC_1, uc);
-      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
-      GET_UCHAR(BZ_X_CCRC_2, uc);
-      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
-      GET_UCHAR(BZ_X_CCRC_3, uc);
-      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
-      GET_UCHAR(BZ_X_CCRC_4, uc);
-      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
-
-      s-&gt;state = BZ_X_IDLE;
-      RETURN(BZ_STREAM_END);
-
-      default: AssertH ( False, 4001 );
-   }
-
-   AssertH ( False, 4002 );
-
-   save_state_and_return:
-
-   s-&gt;save_i           = i;
-   s-&gt;save_j           = j;
-   s-&gt;save_t           = t;
-   s-&gt;save_alphaSize   = alphaSize;
-   s-&gt;save_nGroups     = nGroups;
-   s-&gt;save_nSelectors  = nSelectors;
-   s-&gt;save_EOB         = EOB;
-   s-&gt;save_groupNo     = groupNo;
-   s-&gt;save_groupPos    = groupPos;
-   s-&gt;save_nextSym     = nextSym;
-   s-&gt;save_nblockMAX   = nblockMAX;
-   s-&gt;save_nblock      = nblock;
-   s-&gt;save_es          = es;
-   s-&gt;save_N           = N;
-   s-&gt;save_curr        = curr;
-   s-&gt;save_zt          = zt;
-   s-&gt;save_zn          = zn;
-   s-&gt;save_zvec        = zvec;
-   s-&gt;save_zj          = zj;
-   s-&gt;save_gSel        = gSel;
-   s-&gt;save_gMinlen     = gMinlen;
-   s-&gt;save_gLimit      = gLimit;
-   s-&gt;save_gBase       = gBase;
-   s-&gt;save_gPerm       = gPerm;
-
-   return retVal;   
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                      decompress.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery                               ---*/
+/*---                                          decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &quot;bzlib_private.h&quot;
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+   Int32 i;
+   s-&gt;nInUse = 0;
+   for (i = 0; i &lt; 256; i++)
+      if (s-&gt;inUse[i]) {
+         s-&gt;seqToUnseq[s-&gt;nInUse] = i;
+         s-&gt;nInUse++;
+      }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr)                               \
+   { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn)                     \
+   case lll: s-&gt;state = lll;                      \
+   while (True) {                                 \
+      if (s-&gt;bsLive &gt;= nnn) {                     \
+         UInt32 v;                                \
+         v = (s-&gt;bsBuff &gt;&gt;                        \
+             (s-&gt;bsLive-nnn)) &amp; ((1 &lt;&lt; nnn)-1);   \
+         s-&gt;bsLive -= nnn;                        \
+         vvv = v;                                 \
+         break;                                   \
+      }                                           \
+      if (s-&gt;strm-&gt;avail_in == 0) RETURN(BZ_OK);  \
+      s-&gt;bsBuff                                   \
+         = (s-&gt;bsBuff &lt;&lt; 8) |                     \
+           ((UInt32)                              \
+              (*((UChar*)(s-&gt;strm-&gt;next_in))));   \
+      s-&gt;bsLive += 8;                             \
+      s-&gt;strm-&gt;next_in++;                         \
+      s-&gt;strm-&gt;avail_in--;                        \
+      s-&gt;strm-&gt;total_in_lo32++;                   \
+      if (s-&gt;strm-&gt;total_in_lo32 == 0)            \
+         s-&gt;strm-&gt;total_in_hi32++;                \
+   }
+
+#define GET_UCHAR(lll,uuu)                        \
+   GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu)                          \
+   GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval)           \
+{                                                 \
+   if (groupPos == 0) {                           \
+      groupNo++;                                  \
+      if (groupNo &gt;= nSelectors)                  \
+         RETURN(BZ_DATA_ERROR);                   \
+      groupPos = BZ_G_SIZE;                       \
+      gSel = s-&gt;selector[groupNo];                \
+      gMinlen = s-&gt;minLens[gSel];                 \
+      gLimit = &amp;(s-&gt;limit[gSel][0]);              \
+      gPerm = &amp;(s-&gt;perm[gSel][0]);                \
+      gBase = &amp;(s-&gt;base[gSel][0]);                \
+   }                                              \
+   groupPos--;                                    \
+   zn = gMinlen;                                  \
+   GET_BITS(label1, zvec, zn);                    \
+   while (1) {                                    \
+      if (zn &gt; 20 /* the longest code */)         \
+         RETURN(BZ_DATA_ERROR);                   \
+      if (zvec &lt;= gLimit[zn]) break;              \
+      zn++;                                       \
+      GET_BIT(label2, zj);                        \
+      zvec = (zvec &lt;&lt; 1) | zj;                    \
+   };                                             \
+   if (zvec - gBase[zn] &lt; 0                       \
+       || zvec - gBase[zn] &gt;= BZ_MAX_ALPHA_SIZE)  \
+      RETURN(BZ_DATA_ERROR);                      \
+   lval = gPerm[zvec - gBase[zn]];                \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+   UChar      uc;
+   Int32      retVal;
+   Int32      minLen, maxLen;
+   bz_stream* strm = s-&gt;strm;
+
+   /* stuff that needs to be saved/restored */
+   Int32  i;
+   Int32  j;
+   Int32  t;
+   Int32  alphaSize;
+   Int32  nGroups;
+   Int32  nSelectors;
+   Int32  EOB;
+   Int32  groupNo;
+   Int32  groupPos;
+   Int32  nextSym;
+   Int32  nblockMAX;
+   Int32  nblock;
+   Int32  es;
+   Int32  N;
+   Int32  curr;
+   Int32  zt;
+   Int32  zn; 
+   Int32  zvec;
+   Int32  zj;
+   Int32  gSel;
+   Int32  gMinlen;
+   Int32* gLimit;
+   Int32* gBase;
+   Int32* gPerm;
+
+   if (s-&gt;state == BZ_X_MAGIC_1) {
+      /*initialise the save area*/
+      s-&gt;save_i           = 0;
+      s-&gt;save_j           = 0;
+      s-&gt;save_t           = 0;
+      s-&gt;save_alphaSize   = 0;
+      s-&gt;save_nGroups     = 0;
+      s-&gt;save_nSelectors  = 0;
+      s-&gt;save_EOB         = 0;
+      s-&gt;save_groupNo     = 0;
+      s-&gt;save_groupPos    = 0;
+      s-&gt;save_nextSym     = 0;
+      s-&gt;save_nblockMAX   = 0;
+      s-&gt;save_nblock      = 0;
+      s-&gt;save_es          = 0;
+      s-&gt;save_N           = 0;
+      s-&gt;save_curr        = 0;
+      s-&gt;save_zt          = 0;
+      s-&gt;save_zn          = 0;
+      s-&gt;save_zvec        = 0;
+      s-&gt;save_zj          = 0;
+      s-&gt;save_gSel        = 0;
+      s-&gt;save_gMinlen     = 0;
+      s-&gt;save_gLimit      = NULL;
+      s-&gt;save_gBase       = NULL;
+      s-&gt;save_gPerm       = NULL;
+   }
+
+   /*restore from the save area*/
+   i           = s-&gt;save_i;
+   j           = s-&gt;save_j;
+   t           = s-&gt;save_t;
+   alphaSize   = s-&gt;save_alphaSize;
+   nGroups     = s-&gt;save_nGroups;
+   nSelectors  = s-&gt;save_nSelectors;
+   EOB         = s-&gt;save_EOB;
+   groupNo     = s-&gt;save_groupNo;
+   groupPos    = s-&gt;save_groupPos;
+   nextSym     = s-&gt;save_nextSym;
+   nblockMAX   = s-&gt;save_nblockMAX;
+   nblock      = s-&gt;save_nblock;
+   es          = s-&gt;save_es;
+   N           = s-&gt;save_N;
+   curr        = s-&gt;save_curr;
+   zt          = s-&gt;save_zt;
+   zn          = s-&gt;save_zn; 
+   zvec        = s-&gt;save_zvec;
+   zj          = s-&gt;save_zj;
+   gSel        = s-&gt;save_gSel;
+   gMinlen     = s-&gt;save_gMinlen;
+   gLimit      = s-&gt;save_gLimit;
+   gBase       = s-&gt;save_gBase;
+   gPerm       = s-&gt;save_gPerm;
+
+   retVal = BZ_OK;
+
+   switch (s-&gt;state) {
+
+      GET_UCHAR(BZ_X_MAGIC_1, uc);
+      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_2, uc);
+      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_UCHAR(BZ_X_MAGIC_3, uc)
+      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+      GET_BITS(BZ_X_MAGIC_4, s-&gt;blockSize100k, 8)
+      if (s-&gt;blockSize100k &lt; (BZ_HDR_0 + 1) || 
+          s-&gt;blockSize100k &gt; (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+      s-&gt;blockSize100k -= BZ_HDR_0;
+
+      if (s-&gt;smallDecompress) {
+         s-&gt;ll16 = BZALLOC( s-&gt;blockSize100k * 100000 * sizeof(UInt16) );
+         s-&gt;ll4  = BZALLOC( 
+                      ((1 + s-&gt;blockSize100k * 100000) &gt;&gt; 1) * sizeof(UChar) 
+                   );
+         if (s-&gt;ll16 == NULL || s-&gt;ll4 == NULL) RETURN(BZ_MEM_ERROR);
+      } else {
+         s-&gt;tt  = BZALLOC( s-&gt;blockSize100k * 100000 * sizeof(Int32) );
+         if (s-&gt;tt == NULL) RETURN(BZ_MEM_ERROR);
+      }
+
+      GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+      if (uc == 0x17) goto endhdr_2;
+      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_2, uc);
+      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_3, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_4, uc);
+      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_5, uc);
+      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_BLKHDR_6, uc);
+      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+      s-&gt;currBlockNo++;
+      if (s-&gt;verbosity &gt;= 2)
+         VPrintf1 ( &quot;\n    [%d: huff+mtf &quot;, s-&gt;currBlockNo );
+ 
+      s-&gt;storedBlockCRC = 0;
+      GET_UCHAR(BZ_X_BCRC_1, uc);
+      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_2, uc);
+      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_3, uc);
+      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_BCRC_4, uc);
+      s-&gt;storedBlockCRC = (s-&gt;storedBlockCRC &lt;&lt; 8) | ((UInt32)uc);
+
+      GET_BITS(BZ_X_RANDBIT, s-&gt;blockRandomised, 1);
+
+      s-&gt;origPtr = 0;
+      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+      s-&gt;origPtr = (s-&gt;origPtr &lt;&lt; 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+      s-&gt;origPtr = (s-&gt;origPtr &lt;&lt; 8) | ((Int32)uc);
+      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+      s-&gt;origPtr = (s-&gt;origPtr &lt;&lt; 8) | ((Int32)uc);
+
+      if (s-&gt;origPtr &lt; 0)
+         RETURN(BZ_DATA_ERROR);
+      if (s-&gt;origPtr &gt; 10 + 100000*s-&gt;blockSize100k) 
+         RETURN(BZ_DATA_ERROR);
+
+      /*--- Receive the mapping table ---*/
+      for (i = 0; i &lt; 16; i++) {
+         GET_BIT(BZ_X_MAPPING_1, uc);
+         if (uc == 1) 
+            s-&gt;inUse16[i] = True; else 
+            s-&gt;inUse16[i] = False;
+      }
+
+      for (i = 0; i &lt; 256; i++) s-&gt;inUse[i] = False;
+
+      for (i = 0; i &lt; 16; i++)
+         if (s-&gt;inUse16[i])
+            for (j = 0; j &lt; 16; j++) {
+               GET_BIT(BZ_X_MAPPING_2, uc);
+               if (uc == 1) s-&gt;inUse[i * 16 + j] = True;
+            }
+      makeMaps_d ( s );
+      if (s-&gt;nInUse == 0) RETURN(BZ_DATA_ERROR);
+      alphaSize = s-&gt;nInUse+2;
+
+      /*--- Now the selectors ---*/
+      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+      if (nGroups &lt; 2 || nGroups &gt; 6) RETURN(BZ_DATA_ERROR);
+      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+      if (nSelectors &lt; 1) RETURN(BZ_DATA_ERROR);
+      for (i = 0; i &lt; nSelectors; i++) {
+         j = 0;
+         while (True) {
+            GET_BIT(BZ_X_SELECTOR_3, uc);
+            if (uc == 0) break;
+            j++;
+            if (j &gt;= nGroups) RETURN(BZ_DATA_ERROR);
+         }
+         s-&gt;selectorMtf[i] = j;
+      }
+
+      /*--- Undo the MTF values for the selectors. ---*/
+      {
+         UChar pos[BZ_N_GROUPS], tmp, v;
+         for (v = 0; v &lt; nGroups; v++) pos[v] = v;
+   
+         for (i = 0; i &lt; nSelectors; i++) {
+            v = s-&gt;selectorMtf[i];
+            tmp = pos[v];
+            while (v &gt; 0) { pos[v] = pos[v-1]; v--; }
+            pos[0] = tmp;
+            s-&gt;selector[i] = tmp;
+         }
+      }
+
+      /*--- Now the coding tables ---*/
+      for (t = 0; t &lt; nGroups; t++) {
+         GET_BITS(BZ_X_CODING_1, curr, 5);
+         for (i = 0; i &lt; alphaSize; i++) {
+            while (True) {
+               if (curr &lt; 1 || curr &gt; 20) RETURN(BZ_DATA_ERROR);
+               GET_BIT(BZ_X_CODING_2, uc);
+               if (uc == 0) break;
+               GET_BIT(BZ_X_CODING_3, uc);
+               if (uc == 0) curr++; else curr--;
+            }
+            s-&gt;len[t][i] = curr;
+         }
+      }
+
+      /*--- Create the Huffman decoding tables ---*/
+      for (t = 0; t &lt; nGroups; t++) {
+         minLen = 32;
+         maxLen = 0;
+         for (i = 0; i &lt; alphaSize; i++) {
+            if (s-&gt;len[t][i] &gt; maxLen) maxLen = s-&gt;len[t][i];
+            if (s-&gt;len[t][i] &lt; minLen) minLen = s-&gt;len[t][i];
+         }
+         BZ2_hbCreateDecodeTables ( 
+            &amp;(s-&gt;limit[t][0]), 
+            &amp;(s-&gt;base[t][0]), 
+            &amp;(s-&gt;perm[t][0]), 
+            &amp;(s-&gt;len[t][0]),
+            minLen, maxLen, alphaSize
+         );
+         s-&gt;minLens[t] = minLen;
+      }
+
+      /*--- Now the MTF values ---*/
+
+      EOB      = s-&gt;nInUse+1;
+      nblockMAX = 100000 * s-&gt;blockSize100k;
+      groupNo  = -1;
+      groupPos = 0;
+
+      for (i = 0; i &lt;= 255; i++) s-&gt;unzftab[i] = 0;
+
+      /*-- MTF init --*/
+      {
+         Int32 ii, jj, kk;
+         kk = MTFA_SIZE-1;
+         for (ii = 256 / MTFL_SIZE - 1; ii &gt;= 0; ii--) {
+            for (jj = MTFL_SIZE-1; jj &gt;= 0; jj--) {
+               s-&gt;mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+               kk--;
+            }
+            s-&gt;mtfbase[ii] = kk + 1;
+         }
+      }
+      /*-- end MTF init --*/
+
+      nblock = 0;
+      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+      while (True) {
+
+         if (nextSym == EOB) break;
+
+         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+            es = -1;
+            N = 1;
+            do {
+               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+               N = N * 2;
+               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+            }
+               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+            es++;
+            uc = s-&gt;seqToUnseq[ s-&gt;mtfa[s-&gt;mtfbase[0]] ];
+            s-&gt;unzftab[uc] += es;
+
+            if (s-&gt;smallDecompress)
+               while (es &gt; 0) {
+                  if (nblock &gt;= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s-&gt;ll16[nblock] = (UInt16)uc;
+                  nblock++;
+                  es--;
+               }
+            else
+               while (es &gt; 0) {
+                  if (nblock &gt;= nblockMAX) RETURN(BZ_DATA_ERROR);
+                  s-&gt;tt[nblock] = (UInt32)uc;
+                  nblock++;
+                  es--;
+               };
+
+            continue;
+
+         } else {
+
+            if (nblock &gt;= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+            /*-- uc = MTF ( nextSym-1 ) --*/
+            {
+               Int32 ii, jj, kk, pp, lno, off;
+               UInt32 nn;
+               nn = (UInt32)(nextSym - 1);
+
+               if (nn &lt; MTFL_SIZE) {
+                  /* avoid general-case expense */
+                  pp = s-&gt;mtfbase[0];
+                  uc = s-&gt;mtfa[pp+nn];
+                  while (nn &gt; 3) {
+                     Int32 z = pp+nn;
+                     s-&gt;mtfa[(z)  ] = s-&gt;mtfa[(z)-1];
+                     s-&gt;mtfa[(z)-1] = s-&gt;mtfa[(z)-2];
+                     s-&gt;mtfa[(z)-2] = s-&gt;mtfa[(z)-3];
+                     s-&gt;mtfa[(z)-3] = s-&gt;mtfa[(z)-4];
+                     nn -= 4;
+                  }
+                  while (nn &gt; 0) { 
+                     s-&gt;mtfa[(pp+nn)] = s-&gt;mtfa[(pp+nn)-1]; nn--; 
+                  };
+                  s-&gt;mtfa[pp] = uc;
+               } else { 
+                  /* general case */
+                  lno = nn / MTFL_SIZE;
+                  off = nn % MTFL_SIZE;
+                  pp = s-&gt;mtfbase[lno] + off;
+                  uc = s-&gt;mtfa[pp];
+                  while (pp &gt; s-&gt;mtfbase[lno]) { 
+                     s-&gt;mtfa[pp] = s-&gt;mtfa[pp-1]; pp--; 
+                  };
+                  s-&gt;mtfbase[lno]++;
+                  while (lno &gt; 0) {
+                     s-&gt;mtfbase[lno]--;
+                     s-&gt;mtfa[s-&gt;mtfbase[lno]] 
+                        = s-&gt;mtfa[s-&gt;mtfbase[lno-1] + MTFL_SIZE - 1];
+                     lno--;
+                  }
+                  s-&gt;mtfbase[0]--;
+                  s-&gt;mtfa[s-&gt;mtfbase[0]] = uc;
+                  if (s-&gt;mtfbase[0] == 0) {
+                     kk = MTFA_SIZE-1;
+                     for (ii = 256 / MTFL_SIZE-1; ii &gt;= 0; ii--) {
+                        for (jj = MTFL_SIZE-1; jj &gt;= 0; jj--) {
+                           s-&gt;mtfa[kk] = s-&gt;mtfa[s-&gt;mtfbase[ii] + jj];
+                           kk--;
+                        }
+                        s-&gt;mtfbase[ii] = kk + 1;
+                     }
+                  }
+               }
+            }
+            /*-- end uc = MTF ( nextSym-1 ) --*/
+
+            s-&gt;unzftab[s-&gt;seqToUnseq[uc]]++;
+            if (s-&gt;smallDecompress)
+               s-&gt;ll16[nblock] = (UInt16)(s-&gt;seqToUnseq[uc]); else
+               s-&gt;tt[nblock]   = (UInt32)(s-&gt;seqToUnseq[uc]);
+            nblock++;
+
+            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+            continue;
+         }
+      }
+
+      /* Now we know what nblock is, we can do a better sanity
+         check on s-&gt;origPtr.
+      */
+      if (s-&gt;origPtr &lt; 0 || s-&gt;origPtr &gt;= nblock)
+         RETURN(BZ_DATA_ERROR);
+
+      /*-- Set up cftab to facilitate generation of T^(-1) --*/
+      s-&gt;cftab[0] = 0;
+      for (i = 1; i &lt;= 256; i++) s-&gt;cftab[i] = s-&gt;unzftab[i-1];
+      for (i = 1; i &lt;= 256; i++) s-&gt;cftab[i] += s-&gt;cftab[i-1];
+      for (i = 0; i &lt;= 256; i++) {
+         if (s-&gt;cftab[i] &lt; 0 || s-&gt;cftab[i] &gt; nblock) {
+            /* s-&gt;cftab[i] can legitimately be == nblock */
+            RETURN(BZ_DATA_ERROR);
+         }
+      }
+
+      s-&gt;state_out_len = 0;
+      s-&gt;state_out_ch  = 0;
+      BZ_INITIALISE_CRC ( s-&gt;calculatedBlockCRC );
+      s-&gt;state = BZ_X_OUTPUT;
+      if (s-&gt;verbosity &gt;= 2) VPrintf0 ( &quot;rt+rld&quot; );
+
+      if (s-&gt;smallDecompress) {
+
+         /*-- Make a copy of cftab, used in generation of T --*/
+         for (i = 0; i &lt;= 256; i++) s-&gt;cftabCopy[i] = s-&gt;cftab[i];
+
+         /*-- compute the T vector --*/
+         for (i = 0; i &lt; nblock; i++) {
+            uc = (UChar)(s-&gt;ll16[i]);
+            SET_LL(i, s-&gt;cftabCopy[uc]);
+            s-&gt;cftabCopy[uc]++;
+         }
+
+         /*-- Compute T^(-1) by pointer reversal on T --*/
+         i = s-&gt;origPtr;
+         j = GET_LL(i);
+         do {
+            Int32 tmp = GET_LL(j);
+            SET_LL(j, i);
+            i = j;
+            j = tmp;
+         }
+            while (i != s-&gt;origPtr);
+
+         s-&gt;tPos = s-&gt;origPtr;
+         s-&gt;nblock_used = 0;
+         if (s-&gt;blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_SMALL(s-&gt;k0); s-&gt;nblock_used++;
+            BZ_RAND_UPD_MASK; s-&gt;k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_SMALL(s-&gt;k0); s-&gt;nblock_used++;
+         }
+
+      } else {
+
+         /*-- compute the T^(-1) vector --*/
+         for (i = 0; i &lt; nblock; i++) {
+            uc = (UChar)(s-&gt;tt[i] &amp; 0xff);
+            s-&gt;tt[s-&gt;cftab[uc]] |= (i &lt;&lt; 8);
+            s-&gt;cftab[uc]++;
+         }
+
+         s-&gt;tPos = s-&gt;tt[s-&gt;origPtr] &gt;&gt; 8;
+         s-&gt;nblock_used = 0;
+         if (s-&gt;blockRandomised) {
+            BZ_RAND_INIT_MASK;
+            BZ_GET_FAST(s-&gt;k0); s-&gt;nblock_used++;
+            BZ_RAND_UPD_MASK; s-&gt;k0 ^= BZ_RAND_MASK; 
+         } else {
+            BZ_GET_FAST(s-&gt;k0); s-&gt;nblock_used++;
+         }
+
+      }
+
+      RETURN(BZ_OK);
+
+
+
+    endhdr_2:
+
+      GET_UCHAR(BZ_X_ENDHDR_2, uc);
+      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_3, uc);
+      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_4, uc);
+      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_5, uc);
+      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+      GET_UCHAR(BZ_X_ENDHDR_6, uc);
+      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+      s-&gt;storedCombinedCRC = 0;
+      GET_UCHAR(BZ_X_CCRC_1, uc);
+      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_2, uc);
+      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_3, uc);
+      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
+      GET_UCHAR(BZ_X_CCRC_4, uc);
+      s-&gt;storedCombinedCRC = (s-&gt;storedCombinedCRC &lt;&lt; 8) | ((UInt32)uc);
+
+      s-&gt;state = BZ_X_IDLE;
+      RETURN(BZ_STREAM_END);
+
+      default: AssertH ( False, 4001 );
+   }
+
+   AssertH ( False, 4002 );
+
+   save_state_and_return:
+
+   s-&gt;save_i           = i;
+   s-&gt;save_j           = j;
+   s-&gt;save_t           = t;
+   s-&gt;save_alphaSize   = alphaSize;
+   s-&gt;save_nGroups     = nGroups;
+   s-&gt;save_nSelectors  = nSelectors;
+   s-&gt;save_EOB         = EOB;
+   s-&gt;save_groupNo     = groupNo;
+   s-&gt;save_groupPos    = groupPos;
+   s-&gt;save_nextSym     = nextSym;
+   s-&gt;save_nblockMAX   = nblockMAX;
+   s-&gt;save_nblock      = nblock;
+   s-&gt;save_es          = es;
+   s-&gt;save_N           = N;
+   s-&gt;save_curr        = curr;
+   s-&gt;save_zt          = zt;
+   s-&gt;save_zn          = zn;
+   s-&gt;save_zvec        = zvec;
+   s-&gt;save_zj          = zj;
+   s-&gt;save_gSel        = gSel;
+   s-&gt;save_gMinlen     = gMinlen;
+   s-&gt;save_gLimit      = gLimit;
+   s-&gt;save_gBase       = gBase;
+   s-&gt;save_gPerm       = gPerm;
+
+   return retVal;   
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                      decompress.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/decompress.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,175 +1,175 @@
-/*
-   minibz2
-      libbz2.dll test program.
-      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
-      This file is Public Domain.  Welcome any email to me.
-
-   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
-*/
-
-#define BZ_IMPORT
-#include &lt;stdio.h&gt;
-#include &lt;stdlib.h&gt;
-#include &quot;bzlib.h&quot;
-#ifdef _WIN32
-#include &lt;io.h&gt;
-#endif
-
-
-#ifdef _WIN32
-
-#define BZ2_LIBNAME &quot;libbz2-1.0.2.DLL&quot; 
-
-#include &lt;windows.h&gt;
-static int BZ2DLLLoaded = 0;
-static HINSTANCE BZ2DLLhLib;
-int BZ2DLLLoadLibrary(void)
-{
-   HINSTANCE hLib;
-
-   if(BZ2DLLLoaded==1){return 0;}
-   hLib=LoadLibrary(BZ2_LIBNAME);
-   if(hLib == NULL){
-      fprintf(stderr,&quot;Can't load %s\n&quot;,BZ2_LIBNAME);
-      return -1;
-   }
-   BZ2_bzlibVersion=GetProcAddress(hLib,&quot;BZ2_bzlibVersion&quot;);
-   BZ2_bzopen=GetProcAddress(hLib,&quot;BZ2_bzopen&quot;);
-   BZ2_bzdopen=GetProcAddress(hLib,&quot;BZ2_bzdopen&quot;);
-   BZ2_bzread=GetProcAddress(hLib,&quot;BZ2_bzread&quot;);
-   BZ2_bzwrite=GetProcAddress(hLib,&quot;BZ2_bzwrite&quot;);
-   BZ2_bzflush=GetProcAddress(hLib,&quot;BZ2_bzflush&quot;);
-   BZ2_bzclose=GetProcAddress(hLib,&quot;BZ2_bzclose&quot;);
-   BZ2_bzerror=GetProcAddress(hLib,&quot;BZ2_bzerror&quot;);
-
-   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
-       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
-       || !BZ2_bzclose || !BZ2_bzerror) {
-      fprintf(stderr,&quot;GetProcAddress failed.\n&quot;);
-      return -1;
-   }
-   BZ2DLLLoaded=1;
-   BZ2DLLhLib=hLib;
-   return 0;
-
-}
-int BZ2DLLFreeLibrary(void)
-{
-   if(BZ2DLLLoaded==0){return 0;}
-   FreeLibrary(BZ2DLLhLib);
-   BZ2DLLLoaded=0;
-}
-#endif /* WIN32 */
-
-void usage(void)
-{
-   puts(&quot;usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]&quot;);
-}
-
-int main(int argc,char *argv[])
-{
-   int decompress = 0;
-   int level = 9;
-   char *fn_r = NULL;
-   char *fn_w = NULL;
-
-#ifdef _WIN32
-   if(BZ2DLLLoadLibrary()&lt;0){
-      fprintf(stderr,&quot;Loading of %s failed.  Giving up.\n&quot;, BZ2_LIBNAME);
-      exit(1);
-   }
-   printf(&quot;Loading of %s succeeded.  Library version is %s.\n&quot;,
-          BZ2_LIBNAME, BZ2_bzlibVersion() );
-#endif
-   while(++argv,--argc){
-      if(**argv =='-' || **argv=='/'){
-         char *p;
-
-         for(p=*argv+1;*p;p++){
-            if(*p=='d'){
-               decompress = 1;
-            }else if('1'&lt;=*p &amp;&amp; *p&lt;='9'){
-               level = *p - '0';
-            }else{
-               usage();
-               exit(1);
-            }
-         }
-      }else{
-         break;
-      }
-   }
-   if(argc&gt;=1){
-      fn_r = *argv;
-      argc--;argv++;
-   }else{
-      fn_r = NULL;
-   }
-   if(argc&gt;=1){
-      fn_w = *argv;
-      argc--;argv++;
-   }else{
-      fn_w = NULL;
-   }
-   {
-      int len;
-      char buff[0x1000];
-      char mode[10];
-
-      if(decompress){
-         BZFILE *BZ2fp_r = NULL;
-         FILE *fp_w = NULL;
-
-         if(fn_w){
-            if((fp_w = fopen(fn_w,&quot;wb&quot;))==NULL){
-               printf(&quot;can't open [%s]\n&quot;,fn_w);
-               perror(&quot;reason:&quot;);
-               exit(1);
-            }
-         }else{
-            fp_w = stdout;
-         }
-         if((fn_r == NULL &amp;&amp; (BZ2fp_r = BZ2_bzdopen(fileno(stdin),&quot;rb&quot;))==NULL)
-            || (fn_r != NULL &amp;&amp; (BZ2fp_r = BZ2_bzopen(fn_r,&quot;rb&quot;))==NULL)){
-            printf(&quot;can't bz2openstream\n&quot;);
-            exit(1);
-         }
-         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))&gt;0){
-            fwrite(buff,1,len,fp_w);
-         }
-         BZ2_bzclose(BZ2fp_r);
-         if(fp_w != stdout) fclose(fp_w);
-      }else{
-         BZFILE *BZ2fp_w = NULL;
-         FILE *fp_r = NULL;
-
-         if(fn_r){
-            if((fp_r = fopen(fn_r,&quot;rb&quot;))==NULL){
-               printf(&quot;can't open [%s]\n&quot;,fn_r);
-               perror(&quot;reason:&quot;);
-               exit(1);
-            }
-         }else{
-            fp_r = stdin;
-         }
-         mode[0]='w';
-         mode[1] = '0' + level;
-         mode[2] = '\0';
-
-         if((fn_w == NULL &amp;&amp; (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
-            || (fn_w !=NULL &amp;&amp; (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
-            printf(&quot;can't bz2openstream\n&quot;);
-            exit(1);
-         }
-         while((len=fread(buff,1,0x1000,fp_r))&gt;0){
-            BZ2_bzwrite(BZ2fp_w,buff,len);
-         }
-         BZ2_bzclose(BZ2fp_w);
-         if(fp_r!=stdin)fclose(fp_r);
-      }
-   }
-#ifdef _WIN32
-   BZ2DLLFreeLibrary();
-#endif
-   return 0;
-}
+/*
+   minibz2
+      libbz2.dll test program.
+      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+      This file is Public Domain.  Welcome any email to me.
+
+   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
+*/
+
+#define BZ_IMPORT
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &quot;bzlib.h&quot;
+#ifdef _WIN32
+#include &lt;io.h&gt;
+#endif
+
+
+#ifdef _WIN32
+
+#define BZ2_LIBNAME &quot;libbz2-1.0.2.DLL&quot; 
+
+#include &lt;windows.h&gt;
+static int BZ2DLLLoaded = 0;
+static HINSTANCE BZ2DLLhLib;
+int BZ2DLLLoadLibrary(void)
+{
+   HINSTANCE hLib;
+
+   if(BZ2DLLLoaded==1){return 0;}
+   hLib=LoadLibrary(BZ2_LIBNAME);
+   if(hLib == NULL){
+      fprintf(stderr,&quot;Can't load %s\n&quot;,BZ2_LIBNAME);
+      return -1;
+   }
+   BZ2_bzlibVersion=GetProcAddress(hLib,&quot;BZ2_bzlibVersion&quot;);
+   BZ2_bzopen=GetProcAddress(hLib,&quot;BZ2_bzopen&quot;);
+   BZ2_bzdopen=GetProcAddress(hLib,&quot;BZ2_bzdopen&quot;);
+   BZ2_bzread=GetProcAddress(hLib,&quot;BZ2_bzread&quot;);
+   BZ2_bzwrite=GetProcAddress(hLib,&quot;BZ2_bzwrite&quot;);
+   BZ2_bzflush=GetProcAddress(hLib,&quot;BZ2_bzflush&quot;);
+   BZ2_bzclose=GetProcAddress(hLib,&quot;BZ2_bzclose&quot;);
+   BZ2_bzerror=GetProcAddress(hLib,&quot;BZ2_bzerror&quot;);
+
+   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
+       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
+       || !BZ2_bzclose || !BZ2_bzerror) {
+      fprintf(stderr,&quot;GetProcAddress failed.\n&quot;);
+      return -1;
+   }
+   BZ2DLLLoaded=1;
+   BZ2DLLhLib=hLib;
+   return 0;
+
+}
+int BZ2DLLFreeLibrary(void)
+{
+   if(BZ2DLLLoaded==0){return 0;}
+   FreeLibrary(BZ2DLLhLib);
+   BZ2DLLLoaded=0;
+}
+#endif /* WIN32 */
+
+void usage(void)
+{
+   puts(&quot;usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]&quot;);
+}
+
+int main(int argc,char *argv[])
+{
+   int decompress = 0;
+   int level = 9;
+   char *fn_r = NULL;
+   char *fn_w = NULL;
+
+#ifdef _WIN32
+   if(BZ2DLLLoadLibrary()&lt;0){
+      fprintf(stderr,&quot;Loading of %s failed.  Giving up.\n&quot;, BZ2_LIBNAME);
+      exit(1);
+   }
+   printf(&quot;Loading of %s succeeded.  Library version is %s.\n&quot;,
+          BZ2_LIBNAME, BZ2_bzlibVersion() );
+#endif
+   while(++argv,--argc){
+      if(**argv =='-' || **argv=='/'){
+         char *p;
+
+         for(p=*argv+1;*p;p++){
+            if(*p=='d'){
+               decompress = 1;
+            }else if('1'&lt;=*p &amp;&amp; *p&lt;='9'){
+               level = *p - '0';
+            }else{
+               usage();
+               exit(1);
+            }
+         }
+      }else{
+         break;
+      }
+   }
+   if(argc&gt;=1){
+      fn_r = *argv;
+      argc--;argv++;
+   }else{
+      fn_r = NULL;
+   }
+   if(argc&gt;=1){
+      fn_w = *argv;
+      argc--;argv++;
+   }else{
+      fn_w = NULL;
+   }
+   {
+      int len;
+      char buff[0x1000];
+      char mode[10];
+
+      if(decompress){
+         BZFILE *BZ2fp_r = NULL;
+         FILE *fp_w = NULL;
+
+         if(fn_w){
+            if((fp_w = fopen(fn_w,&quot;wb&quot;))==NULL){
+               printf(&quot;can't open [%s]\n&quot;,fn_w);
+               perror(&quot;reason:&quot;);
+               exit(1);
+            }
+         }else{
+            fp_w = stdout;
+         }
+         if((fn_r == NULL &amp;&amp; (BZ2fp_r = BZ2_bzdopen(fileno(stdin),&quot;rb&quot;))==NULL)
+            || (fn_r != NULL &amp;&amp; (BZ2fp_r = BZ2_bzopen(fn_r,&quot;rb&quot;))==NULL)){
+            printf(&quot;can't bz2openstream\n&quot;);
+            exit(1);
+         }
+         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))&gt;0){
+            fwrite(buff,1,len,fp_w);
+         }
+         BZ2_bzclose(BZ2fp_r);
+         if(fp_w != stdout) fclose(fp_w);
+      }else{
+         BZFILE *BZ2fp_w = NULL;
+         FILE *fp_r = NULL;
+
+         if(fn_r){
+            if((fp_r = fopen(fn_r,&quot;rb&quot;))==NULL){
+               printf(&quot;can't open [%s]\n&quot;,fn_r);
+               perror(&quot;reason:&quot;);
+               exit(1);
+            }
+         }else{
+            fp_r = stdin;
+         }
+         mode[0]='w';
+         mode[1] = '0' + level;
+         mode[2] = '\0';
+
+         if((fn_w == NULL &amp;&amp; (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
+            || (fn_w !=NULL &amp;&amp; (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
+            printf(&quot;can't bz2openstream\n&quot;);
+            exit(1);
+         }
+         while((len=fread(buff,1,0x1000,fp_r))&gt;0){
+            BZ2_bzwrite(BZ2fp_w,buff,len);
+         }
+         BZ2_bzclose(BZ2fp_w);
+         if(fp_r!=stdin)fclose(fp_r);
+      }
+   }
+#ifdef _WIN32
+   BZ2DLLFreeLibrary();
+#endif
+   return 0;
+}</diff>
      <filename>ipsw-patch/bzip2-1.0.5/dlltest.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,205 +1,205 @@
-
-/*-------------------------------------------------------------*/
-/*--- Huffman coding low-level stuff                        ---*/
-/*---                                             huffman.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &quot;bzlib_private.h&quot;
-
-/*---------------------------------------------------*/
-#define WEIGHTOF(zz0)  ((zz0) &amp; 0xffffff00)
-#define DEPTHOF(zz1)   ((zz1) &amp; 0x000000ff)
-#define MYMAX(zz2,zz3) ((zz2) &gt; (zz3) ? (zz2) : (zz3))
-
-#define ADDWEIGHTS(zw1,zw2)                           \
-   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
-   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
-
-#define UPHEAP(z)                                     \
-{                                                     \
-   Int32 zz, tmp;                                     \
-   zz = z; tmp = heap[zz];                            \
-   while (weight[tmp] &lt; weight[heap[zz &gt;&gt; 1]]) {      \
-      heap[zz] = heap[zz &gt;&gt; 1];                       \
-      zz &gt;&gt;= 1;                                       \
-   }                                                  \
-   heap[zz] = tmp;                                    \
-}
-
-#define DOWNHEAP(z)                                   \
-{                                                     \
-   Int32 zz, yy, tmp;                                 \
-   zz = z; tmp = heap[zz];                            \
-   while (True) {                                     \
-      yy = zz &lt;&lt; 1;                                   \
-      if (yy &gt; nHeap) break;                          \
-      if (yy &lt; nHeap &amp;&amp;                               \
-          weight[heap[yy+1]] &lt; weight[heap[yy]])      \
-         yy++;                                        \
-      if (weight[tmp] &lt; weight[heap[yy]]) break;      \
-      heap[zz] = heap[yy];                            \
-      zz = yy;                                        \
-   }                                                  \
-   heap[zz] = tmp;                                    \
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbMakeCodeLengths ( UChar *len, 
-                             Int32 *freq,
-                             Int32 alphaSize,
-                             Int32 maxLen )
-{
-   /*--
-      Nodes and heap entries run from 1.  Entry 0
-      for both the heap and nodes is a sentinel.
-   --*/
-   Int32 nNodes, nHeap, n1, n2, i, j, k;
-   Bool  tooLong;
-
-   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
-   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
-   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
-
-   for (i = 0; i &lt; alphaSize; i++)
-      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) &lt;&lt; 8;
-
-   while (True) {
-
-      nNodes = alphaSize;
-      nHeap = 0;
-
-      heap[0] = 0;
-      weight[0] = 0;
-      parent[0] = -2;
-
-      for (i = 1; i &lt;= alphaSize; i++) {
-         parent[i] = -1;
-         nHeap++;
-         heap[nHeap] = i;
-         UPHEAP(nHeap);
-      }
-
-      AssertH( nHeap &lt; (BZ_MAX_ALPHA_SIZE+2), 2001 );
-   
-      while (nHeap &gt; 1) {
-         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
-         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
-         nNodes++;
-         parent[n1] = parent[n2] = nNodes;
-         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
-         parent[nNodes] = -1;
-         nHeap++;
-         heap[nHeap] = nNodes;
-         UPHEAP(nHeap);
-      }
-
-      AssertH( nNodes &lt; (BZ_MAX_ALPHA_SIZE * 2), 2002 );
-
-      tooLong = False;
-      for (i = 1; i &lt;= alphaSize; i++) {
-         j = 0;
-         k = i;
-         while (parent[k] &gt;= 0) { k = parent[k]; j++; }
-         len[i-1] = j;
-         if (j &gt; maxLen) tooLong = True;
-      }
-      
-      if (! tooLong) break;
-
-      /* 17 Oct 04: keep-going condition for the following loop used
-         to be 'i &lt; alphaSize', which missed the last element,
-         theoretically leading to the possibility of the compressor
-         looping.  However, this count-scaling step is only needed if
-         one of the generated Huffman code words is longer than
-         maxLen, which up to and including version 1.0.2 was 20 bits,
-         which is extremely unlikely.  In version 1.0.3 maxLen was
-         changed to 17 bits, which has minimal effect on compression
-         ratio, but does mean this scaling step is used from time to
-         time, enough to verify that it works.
-
-         This means that bzip2-1.0.3 and later will only produce
-         Huffman codes with a maximum length of 17 bits.  However, in
-         order to preserve backwards compatibility with bitstreams
-         produced by versions pre-1.0.3, the decompressor must still
-         handle lengths of up to 20. */
-
-      for (i = 1; i &lt;= alphaSize; i++) {
-         j = weight[i] &gt;&gt; 8;
-         j = 1 + (j / 2);
-         weight[i] = j &lt;&lt; 8;
-      }
-   }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbAssignCodes ( Int32 *code,
-                         UChar *length,
-                         Int32 minLen,
-                         Int32 maxLen,
-                         Int32 alphaSize )
-{
-   Int32 n, vec, i;
-
-   vec = 0;
-   for (n = minLen; n &lt;= maxLen; n++) {
-      for (i = 0; i &lt; alphaSize; i++)
-         if (length[i] == n) { code[i] = vec; vec++; };
-      vec &lt;&lt;= 1;
-   }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbCreateDecodeTables ( Int32 *limit,
-                                Int32 *base,
-                                Int32 *perm,
-                                UChar *length,
-                                Int32 minLen,
-                                Int32 maxLen,
-                                Int32 alphaSize )
-{
-   Int32 pp, i, j, vec;
-
-   pp = 0;
-   for (i = minLen; i &lt;= maxLen; i++)
-      for (j = 0; j &lt; alphaSize; j++)
-         if (length[j] == i) { perm[pp] = j; pp++; };
-
-   for (i = 0; i &lt; BZ_MAX_CODE_LEN; i++) base[i] = 0;
-   for (i = 0; i &lt; alphaSize; i++) base[length[i]+1]++;
-
-   for (i = 1; i &lt; BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
-
-   for (i = 0; i &lt; BZ_MAX_CODE_LEN; i++) limit[i] = 0;
-   vec = 0;
-
-   for (i = minLen; i &lt;= maxLen; i++) {
-      vec += (base[i+1] - base[i]);
-      limit[i] = vec-1;
-      vec &lt;&lt;= 1;
-   }
-   for (i = minLen + 1; i &lt;= maxLen; i++)
-      base[i] = ((limit[i-1] + 1) &lt;&lt; 1) - base[i];
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                         huffman.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &quot;bzlib_private.h&quot;
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) &amp; 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) &amp; 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) &gt; (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2)                           \
+   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
+   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z)                                     \
+{                                                     \
+   Int32 zz, tmp;                                     \
+   zz = z; tmp = heap[zz];                            \
+   while (weight[tmp] &lt; weight[heap[zz &gt;&gt; 1]]) {      \
+      heap[zz] = heap[zz &gt;&gt; 1];                       \
+      zz &gt;&gt;= 1;                                       \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+#define DOWNHEAP(z)                                   \
+{                                                     \
+   Int32 zz, yy, tmp;                                 \
+   zz = z; tmp = heap[zz];                            \
+   while (True) {                                     \
+      yy = zz &lt;&lt; 1;                                   \
+      if (yy &gt; nHeap) break;                          \
+      if (yy &lt; nHeap &amp;&amp;                               \
+          weight[heap[yy+1]] &lt; weight[heap[yy]])      \
+         yy++;                                        \
+      if (weight[tmp] &lt; weight[heap[yy]]) break;      \
+      heap[zz] = heap[yy];                            \
+      zz = yy;                                        \
+   }                                                  \
+   heap[zz] = tmp;                                    \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len, 
+                             Int32 *freq,
+                             Int32 alphaSize,
+                             Int32 maxLen )
+{
+   /*--
+      Nodes and heap entries run from 1.  Entry 0
+      for both the heap and nodes is a sentinel.
+   --*/
+   Int32 nNodes, nHeap, n1, n2, i, j, k;
+   Bool  tooLong;
+
+   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
+   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
+
+   for (i = 0; i &lt; alphaSize; i++)
+      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) &lt;&lt; 8;
+
+   while (True) {
+
+      nNodes = alphaSize;
+      nHeap = 0;
+
+      heap[0] = 0;
+      weight[0] = 0;
+      parent[0] = -2;
+
+      for (i = 1; i &lt;= alphaSize; i++) {
+         parent[i] = -1;
+         nHeap++;
+         heap[nHeap] = i;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nHeap &lt; (BZ_MAX_ALPHA_SIZE+2), 2001 );
+   
+      while (nHeap &gt; 1) {
+         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+         nNodes++;
+         parent[n1] = parent[n2] = nNodes;
+         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+         parent[nNodes] = -1;
+         nHeap++;
+         heap[nHeap] = nNodes;
+         UPHEAP(nHeap);
+      }
+
+      AssertH( nNodes &lt; (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+      tooLong = False;
+      for (i = 1; i &lt;= alphaSize; i++) {
+         j = 0;
+         k = i;
+         while (parent[k] &gt;= 0) { k = parent[k]; j++; }
+         len[i-1] = j;
+         if (j &gt; maxLen) tooLong = True;
+      }
+      
+      if (! tooLong) break;
+
+      /* 17 Oct 04: keep-going condition for the following loop used
+         to be 'i &lt; alphaSize', which missed the last element,
+         theoretically leading to the possibility of the compressor
+         looping.  However, this count-scaling step is only needed if
+         one of the generated Huffman code words is longer than
+         maxLen, which up to and including version 1.0.2 was 20 bits,
+         which is extremely unlikely.  In version 1.0.3 maxLen was
+         changed to 17 bits, which has minimal effect on compression
+         ratio, but does mean this scaling step is used from time to
+         time, enough to verify that it works.
+
+         This means that bzip2-1.0.3 and later will only produce
+         Huffman codes with a maximum length of 17 bits.  However, in
+         order to preserve backwards compatibility with bitstreams
+         produced by versions pre-1.0.3, the decompressor must still
+         handle lengths of up to 20. */
+
+      for (i = 1; i &lt;= alphaSize; i++) {
+         j = weight[i] &gt;&gt; 8;
+         j = 1 + (j / 2);
+         weight[i] = j &lt;&lt; 8;
+      }
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+                         UChar *length,
+                         Int32 minLen,
+                         Int32 maxLen,
+                         Int32 alphaSize )
+{
+   Int32 n, vec, i;
+
+   vec = 0;
+   for (n = minLen; n &lt;= maxLen; n++) {
+      for (i = 0; i &lt; alphaSize; i++)
+         if (length[i] == n) { code[i] = vec; vec++; };
+      vec &lt;&lt;= 1;
+   }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+                                Int32 *base,
+                                Int32 *perm,
+                                UChar *length,
+                                Int32 minLen,
+                                Int32 maxLen,
+                                Int32 alphaSize )
+{
+   Int32 pp, i, j, vec;
+
+   pp = 0;
+   for (i = minLen; i &lt;= maxLen; i++)
+      for (j = 0; j &lt; alphaSize; j++)
+         if (length[j] == i) { perm[pp] = j; pp++; };
+
+   for (i = 0; i &lt; BZ_MAX_CODE_LEN; i++) base[i] = 0;
+   for (i = 0; i &lt; alphaSize; i++) base[length[i]+1]++;
+
+   for (i = 1; i &lt; BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+   for (i = 0; i &lt; BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+   vec = 0;
+
+   for (i = minLen; i &lt;= maxLen; i++) {
+      vec += (base[i+1] - base[i]);
+      limit[i] = vec-1;
+      vec &lt;&lt;= 1;
+   }
+   for (i = minLen + 1; i &lt;= maxLen; i++)
+      base[i] = ((limit[i-1] + 1) &lt;&lt; 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/huffman.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,31 +1,31 @@
-
-/* Spew out a long sequence of the byte 251.  When fed to bzip2
-   versions 1.0.0 or 1.0.1, causes it to die with internal error
-   1007 in blocksort.c.  This assertion misses an extremely rare
-   case, which is fixed in this version (1.0.2) and above.
-*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &lt;stdio.h&gt;
-
-int main ()
-{
-   int i;
-   for (i = 0; i &lt; 48500000 ; i++)
-     putchar(251);
-   return 0;
-}
+
+/* Spew out a long sequence of the byte 251.  When fed to bzip2
+   versions 1.0.0 or 1.0.1, causes it to die with internal error
+   1007 in blocksort.c.  This assertion misses an extremely rare
+   case, which is fixed in this version (1.0.2) and above.
+*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &lt;stdio.h&gt;
+
+int main ()
+{
+   int i;
+   for (i = 0; i &lt; 48500000 ; i++)
+     putchar(251);
+   return 0;
+}</diff>
      <filename>ipsw-patch/bzip2-1.0.5/mk251.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,84 +1,84 @@
-
-/*-------------------------------------------------------------*/
-/*--- Table for randomising repetitive blocks               ---*/
-/*---                                           randtable.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &quot;bzlib_private.h&quot;
-
-
-/*---------------------------------------------*/
-Int32 BZ2_rNums[512] = { 
-   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
-   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
-   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
-   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
-   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
-   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
-   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
-   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
-   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
-   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
-   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
-   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
-   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
-   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
-   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
-   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
-   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
-   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
-   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
-   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
-   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
-   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
-   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
-   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
-   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
-   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
-   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
-   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
-   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
-   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
-   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
-   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
-   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
-   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
-   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
-   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
-   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
-   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
-   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
-   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
-   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
-   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
-   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
-   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
-   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
-   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
-   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
-   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
-   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
-   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
-   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
-   936, 638
-};
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                       randtable.c ---*/
-/*-------------------------------------------------------------*/
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks               ---*/
+/*---                                           randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &quot;bzlib_private.h&quot;
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = { 
+   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
+   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
+   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
+   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
+   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
+   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
+   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
+   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
+   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
+   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
+   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
+   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
+   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
+   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
+   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
+   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
+   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
+   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
+   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
+   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
+   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
+   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
+   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
+   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
+   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
+   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
+   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
+   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
+   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
+   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
+   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
+   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
+   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
+   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
+   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
+   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
+   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
+   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
+   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
+   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
+   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
+   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
+   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
+   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
+   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
+   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
+   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
+   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
+   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
+   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
+   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
+   936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       randtable.c ---*/
+/*-------------------------------------------------------------*/</diff>
      <filename>ipsw-patch/bzip2-1.0.5/randtable.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,54 +1,54 @@
-
-/* spew out a thoroughly gigantic file designed so that bzip2
-   can compress it reasonably rapidly.  This is to help test
-   support for large files (&gt; 2GB) in a reasonable amount of time.
-   I suggest you use the undocumented --exponential option to
-   bzip2 when compressing the resulting file; this saves a bit of
-   time.  Note: *don't* bother with --exponential when compressing 
-   Real Files; it'll just waste a lot of CPU time :-)
-   (but is otherwise harmless).
-*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-	 ------------------------------------------------------------------ */
-
-
-#define _FILE_OFFSET_BITS 64
-
-#include &lt;stdio.h&gt;
-#include &lt;stdlib.h&gt;
-
-/* The number of megabytes of junk to spew out (roughly) */
-#define MEGABYTES 5000
-
-#define N_BUF 1000000
-char buf[N_BUF];
-
-int main ( int argc, char** argv )
-{
-   int ii, kk, p;
-   srandom(1);
-   setbuffer ( stdout, buf, N_BUF );
-   for (kk = 0; kk &lt; MEGABYTES * 515; kk+=3) {
-      p = 25+random()%50;
-      for (ii = 0; ii &lt; p; ii++)
-         printf ( &quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot; );
-      for (ii = 0; ii &lt; p-1; ii++)
-         printf ( &quot;bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&quot; );
-      for (ii = 0; ii &lt; p+1; ii++)
-         printf ( &quot;ccccccccccccccccccccccccccccccccccccc&quot; );
-   }
-   fflush(stdout);
-   return 0;
-}
+
+/* spew out a thoroughly gigantic file designed so that bzip2
+   can compress it reasonably rapidly.  This is to help test
+   support for large files (&gt; 2GB) in a reasonable amount of time.
+   I suggest you use the undocumented --exponential option to
+   bzip2 when compressing the resulting file; this saves a bit of
+   time.  Note: *don't* bother with --exponential when compressing 
+   Real Files; it'll just waste a lot of CPU time :-)
+   (but is otherwise harmless).
+*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+	 ------------------------------------------------------------------ */
+
+
+#define _FILE_OFFSET_BITS 64
+
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+
+/* The number of megabytes of junk to spew out (roughly) */
+#define MEGABYTES 5000
+
+#define N_BUF 1000000
+char buf[N_BUF];
+
+int main ( int argc, char** argv )
+{
+   int ii, kk, p;
+   srandom(1);
+   setbuffer ( stdout, buf, N_BUF );
+   for (kk = 0; kk &lt; MEGABYTES * 515; kk+=3) {
+      p = 25+random()%50;
+      for (ii = 0; ii &lt; p; ii++)
+         printf ( &quot;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot; );
+      for (ii = 0; ii &lt; p-1; ii++)
+         printf ( &quot;bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&quot; );
+      for (ii = 0; ii &lt; p+1; ii++)
+         printf ( &quot;ccccccccccccccccccccccccccccccccccccc&quot; );
+   }
+   fflush(stdout);
+   return 0;
+}</diff>
      <filename>ipsw-patch/bzip2-1.0.5/spewG.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,141 +1,141 @@
-
-/* A test program written to test robustness to decompression of
-   corrupted data.  Usage is 
-       unzcrash filename
-   and the program will read the specified file, compress it (in memory),
-   and then repeatedly decompress it, each time with a different bit of
-   the compressed data inverted, so as to test all possible one-bit errors.
-   This should not cause any invalid memory accesses.  If it does, 
-   I want to know about it!
-
-   PS.  As you can see from the above description, the process is
-   incredibly slow.  A file of size eg 5KB will cause it to run for
-   many hours.
-*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.0.5 of 10 December 2007
-   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
-
-   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
-   README file.
-
-   This program is released under the terms of the license contained
-   in the file LICENSE.
-   ------------------------------------------------------------------ */
-
-
-#include &lt;stdio.h&gt;
-#include &lt;assert.h&gt;
-#include &quot;bzlib.h&quot;
-
-#define M_BLOCK 1000000
-
-typedef unsigned char uchar;
-
-#define M_BLOCK_OUT (M_BLOCK + 1000000)
-uchar inbuf[M_BLOCK];
-uchar outbuf[M_BLOCK_OUT];
-uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
-
-int nIn, nOut, nZ;
-
-static char *bzerrorstrings[] = {
-       &quot;OK&quot;
-      ,&quot;SEQUENCE_ERROR&quot;
-      ,&quot;PARAM_ERROR&quot;
-      ,&quot;MEM_ERROR&quot;
-      ,&quot;DATA_ERROR&quot;
-      ,&quot;DATA_ERROR_MAGIC&quot;
-      ,&quot;IO_ERROR&quot;
-      ,&quot;UNEXPECTED_EOF&quot;
-      ,&quot;OUTBUFF_FULL&quot;
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-      ,&quot;???&quot;   /* for future */
-};
-
-void flip_bit ( int bit )
-{
-   int byteno = bit / 8;
-   int bitno  = bit % 8;
-   uchar mask = 1 &lt;&lt; bitno;
-   //fprintf ( stderr, &quot;(byte %d  bit %d  mask %d)&quot;,
-   //          byteno, bitno, (int)mask );
-   zbuf[byteno] ^= mask;
-}
-
-int main ( int argc, char** argv )
-{
-   FILE* f;
-   int   r;
-   int   bit;
-   int   i;
-
-   if (argc != 2) {
-      fprintf ( stderr, &quot;usage: unzcrash filename\n&quot; );
-      return 1;
-   }
-
-   f = fopen ( argv[1], &quot;r&quot; );
-   if (!f) {
-      fprintf ( stderr, &quot;unzcrash: can't open %s\n&quot;, argv[1] );
-      return 1;
-   }
-
-   nIn = fread ( inbuf, 1, M_BLOCK, f );
-   fprintf ( stderr, &quot;%d bytes read\n&quot;, nIn );
-
-   nZ = M_BLOCK;
-   r = BZ2_bzBuffToBuffCompress (
-         zbuf, &amp;nZ, inbuf, nIn, 9, 0, 30 );
-
-   assert (r == BZ_OK);
-   fprintf ( stderr, &quot;%d after compression\n&quot;, nZ );
-
-   for (bit = 0; bit &lt; nZ*8; bit++) {
-      fprintf ( stderr, &quot;bit %d  &quot;, bit );
-      flip_bit ( bit );
-      nOut = M_BLOCK_OUT;
-      r = BZ2_bzBuffToBuffDecompress (
-            outbuf, &amp;nOut, zbuf, nZ, 0, 0 );
-      fprintf ( stderr, &quot; %d  %s &quot;, r, bzerrorstrings[-r] );
-
-      if (r != BZ_OK) {
-         fprintf ( stderr, &quot;\n&quot; );
-      } else {
-         if (nOut != nIn) {
-           fprintf(stderr, &quot;nIn/nOut mismatch %d %d\n&quot;, nIn, nOut );
-           return 1;
-         } else {
-           for (i = 0; i &lt; nOut; i++)
-             if (inbuf[i] != outbuf[i]) { 
-                fprintf(stderr, &quot;mismatch at %d\n&quot;, i ); 
-                return 1; 
-           }
-           if (i == nOut) fprintf(stderr, &quot;really ok!\n&quot; );
-         }
-      }
-
-      flip_bit ( bit );
-   }
-
-#if 0
-   assert (nOut == nIn);
-   for (i = 0; i &lt; nOut; i++) {
-     if (inbuf[i] != outbuf[i]) {
-        fprintf ( stderr, &quot;difference at %d !\n&quot;, i );
-        return 1;
-     }
-   }
-#endif
-
-   fprintf ( stderr, &quot;all ok\n&quot; );
-   return 0;
-}
+
+/* A test program written to test robustness to decompression of
+   corrupted data.  Usage is 
+       unzcrash filename
+   and the program will read the specified file, compress it (in memory),
+   and then repeatedly decompress it, each time with a different bit of
+   the compressed data inverted, so as to test all possible one-bit errors.
+   This should not cause any invalid memory accesses.  If it does, 
+   I want to know about it!
+
+   PS.  As you can see from the above description, the process is
+   incredibly slow.  A file of size eg 5KB will cause it to run for
+   many hours.
+*/
+
+/* ------------------------------------------------------------------
+   This file is part of bzip2/libbzip2, a program and library for
+   lossless, block-sorting data compression.
+
+   bzip2/libbzip2 version 1.0.5 of 10 December 2007
+   Copyright (C) 1996-2007 Julian Seward &lt;jseward@bzip.org&gt;
+
+   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
+   README file.
+
+   This program is released under the terms of the license contained
+   in the file LICENSE.
+   ------------------------------------------------------------------ */
+
+
+#include &lt;stdio.h&gt;
+#include &lt;assert.h&gt;
+#include &quot;bzlib.h&quot;
+
+#define M_BLOCK 1000000
+
+typedef unsigned char uchar;
+
+#define M_BLOCK_OUT (M_BLOCK + 1000000)
+uchar inbuf[M_BLOCK];
+uchar outbuf[M_BLOCK_OUT];
+uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
+
+int nIn, nOut, nZ;
+
+static char *bzerrorstrings[] = {
+       &quot;OK&quot;
+      ,&quot;SEQUENCE_ERROR&quot;
+      ,&quot;PARAM_ERROR&quot;
+      ,&quot;MEM_ERROR&quot;
+      ,&quot;DATA_ERROR&quot;
+      ,&quot;DATA_ERROR_MAGIC&quot;
+      ,&quot;IO_ERROR&quot;
+      ,&quot;UNEXPECTED_EOF&quot;
+      ,&quot;OUTBUFF_FULL&quot;
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+      ,&quot;???&quot;   /* for future */
+};
+
+void flip_bit ( int bit )
+{
+   int byteno = bit / 8;
+   int bitno  = bit % 8;
+   uchar mask = 1 &lt;&lt; bitno;
+   //fprintf ( stderr, &quot;(byte %d  bit %d  mask %d)&quot;,
+   //          byteno, bitno, (int)mask );
+   zbuf[byteno] ^= mask;
+}
+
+int main ( int argc, char** argv )
+{
+   FILE* f;
+   int   r;
+   int   bit;
+   int   i;
+
+   if (argc != 2) {
+      fprintf ( stderr, &quot;usage: unzcrash filename\n&quot; );
+      return 1;
+   }
+
+   f = fopen ( argv[1], &quot;r&quot; );
+   if (!f) {
+      fprintf ( stderr, &quot;unzcrash: can't open %s\n&quot;, argv[1] );
+      return 1;
+   }
+
+   nIn = fread ( inbuf, 1, M_BLOCK, f );
+   fprintf ( stderr, &quot;%d bytes read\n&quot;, nIn );
+
+   nZ = M_BLOCK;
+   r = BZ2_bzBuffToBuffCompress (
+         zbuf, &amp;nZ, inbuf, nIn, 9, 0, 30 );
+
+   assert (r == BZ_OK);
+   fprintf ( stderr, &quot;%d after compression\n&quot;, nZ );
+
+   for (bit = 0; bit &lt; nZ*8; bit++) {
+      fprintf ( stderr, &quot;bit %d  &quot;, bit );
+      flip_bit ( bit );
+      nOut = M_BLOCK_OUT;
+      r = BZ2_bzBuffToBuffDecompress (
+            outbuf, &amp;nOut, zbuf, nZ, 0, 0 );
+      fprintf ( stderr, &quot; %d  %s &quot;, r, bzerrorstrings[-r] );
+
+      if (r != BZ_OK) {
+         fprintf ( stderr, &quot;\n&quot; );
+      } else {
+         if (nOut != nIn) {
+           fprintf(stderr, &quot;nIn/nOut mismatch %d %d\n&quot;, nIn, nOut );
+           return 1;
+         } else {
+           for (i = 0; i &lt; nOut; i++)
+             if (inbuf[i] != outbuf[i]) { 
+                fprintf(stderr, &quot;mismatch at %d\n&quot;, i ); 
+                return 1; 
+           }
+           if (i == nOut) fprintf(stderr, &quot;really ok!\n&quot; );
+         }
+      }
+
+      flip_bit ( bit );
+   }
+
+#if 0
+   assert (nOut == nIn);
+   for (i = 0; i &lt; nOut; i++) {
+     if (inbuf[i] != outbuf[i]) {
+        fprintf ( stderr, &quot;difference at %d !\n&quot;, i );
+        return 1;
+     }
+   }
+#endif
+
+   fprintf ( stderr, &quot;all ok\n&quot; );
+   return 0;
+}</diff>
      <filename>ipsw-patch/bzip2-1.0.5/unzcrash.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,314 +1,314 @@
-#include &lt;unistd.h&gt;
-#include &lt;stdlib.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;stdlib.h&gt;
 #include &lt;string.h&gt;
-#include &quot;common.h&quot;
-#include &quot;abstractfile.h&quot;
-#include &quot;ibootim.h&quot;
-#include &quot;lzss.h&quot;
-#include &lt;png.h&gt;
-#include &quot;nor_files.h&quot;
-
-void flipIBootIMHeader(IBootIMHeader* header) {
-	FLIPENDIANLE(header-&gt;unknown);
-	FLIPENDIANLE(header-&gt;compression_type);
-	FLIPENDIANLE(header-&gt;format);
-	FLIPENDIANLE(header-&gt;width);
-	FLIPENDIANLE(header-&gt;height);
-}
-
-size_t readIBootIM(AbstractFile* file, void* data, size_t len) {
-	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data); 
-	memcpy(data, (void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), len);
-	info-&gt;offset += (size_t)len;
-	return len;
-}
-
-size_t writeIBootIM(AbstractFile* file, const void* data, size_t len) {
-	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
-
-	while((info-&gt;offset + (size_t)len) &gt; info-&gt;length) {
-		info-&gt;length = info-&gt;offset + (size_t)len;
-		info-&gt;buffer = realloc(info-&gt;buffer, info-&gt;length);
-	}
-	
-	memcpy((void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), data, len);
-	info-&gt;offset += (size_t)len;
-	
-	info-&gt;dirty = TRUE;
-	
-	return len;
-}
-
-int seekIBootIM(AbstractFile* file, off_t offset) {
-	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
-	info-&gt;offset = (size_t)offset;
-	return 0;
-}
-
-off_t tellIBootIM(AbstractFile* file) {
-	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
-	return (off_t)info-&gt;offset;
-}
-
-off_t getLengthIBootIM(AbstractFile* file) {
-	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
-	return info-&gt;length;
-}
-
-void closeIBootIM(AbstractFile* file) {
-	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
-	uint32_t cksum;
-	uint8_t *compressed;
-	if(info-&gt;dirty) {
-		compressed = malloc(info-&gt;length * 2);
-		info-&gt;compLength = (uint32_t)(compress_lzss(compressed, info-&gt;length * 2, info-&gt;buffer, info-&gt;length) - compressed);
-		
-		flipIBootIMHeader(&amp;(info-&gt;header));
-		info-&gt;file-&gt;seek(info-&gt;file, 0);
-		info-&gt;file-&gt;write(info-&gt;file, &amp;(info-&gt;header), sizeof(info-&gt;header));
-		
-		info-&gt;file-&gt;seek(info-&gt;file, sizeof(info-&gt;header));
-		info-&gt;file-&gt;write(info-&gt;file, compressed, info-&gt;compLength);
-		free(compressed);
-		
-	}
-	
-	free(info-&gt;buffer);
-	info-&gt;file-&gt;close(info-&gt;file);
-	free(info);
-	free(file);
-}
-
-
-AbstractFile* createAbstractFileFromIBootIM(AbstractFile* file) {
-	InfoIBootIM* info;
-	AbstractFile* toReturn;
-	uint8_t *compressed;
-
-	if(!file) {
-		return NULL;
-	}
-	
-	info = (InfoIBootIM*) malloc(sizeof(InfoIBootIM));
-	info-&gt;file = file;
-	file-&gt;seek(file, 0);
-	file-&gt;read(file, &amp;(info-&gt;header), sizeof(info-&gt;header));
-	flipIBootIMHeader(&amp;(info-&gt;header));
-	if(strcmp(info-&gt;header.signature, IBOOTIM_SIGNATURE) != 0) {
-		free(info);
-		return NULL;
-	}
-	
-	info-&gt;compLength = file-&gt;getLength(file) - sizeof(info-&gt;header);
-	if(info-&gt;header.compression_type != IBOOTIM_LZSS_TYPE) {
-		free(info);
-		return NULL;
-	}
-	
-	if(info-&gt;header.format == IBOOTIM_ARGB) {
-		info-&gt;length = 4 * info-&gt;header.width * info-&gt;header.height;
-	} else if(info-&gt;header.format == IBOOTIM_GREY) {
-		info-&gt;length = 2 * info-&gt;header.width * info-&gt;header.height;
-	} else {
-		free(info);
-		return NULL;
-	}
-	
-	info-&gt;buffer = malloc(info-&gt;length);
-	compressed = malloc(info-&gt;compLength);
-	file-&gt;read(file, compressed, info-&gt;compLength);
-
-	if(decompress_lzss(info-&gt;buffer, compressed, info-&gt;compLength) != info-&gt;length) {
-		free(compressed);
-		free(info);
-		return NULL;
-	}
-
-	free(compressed);
-	
-	info-&gt;dirty = FALSE;
-	
-	info-&gt;offset = 0;
-	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
-	toReturn-&gt;data = info;
-	toReturn-&gt;read = readIBootIM;
-	toReturn-&gt;write = writeIBootIM;
-	toReturn-&gt;seek = seekIBootIM;
-	toReturn-&gt;tell = tellIBootIM;
-	toReturn-&gt;getLength = getLengthIBootIM;
-	toReturn-&gt;close = closeIBootIM;
-	
-	return toReturn;
-}
-
-AbstractFile* duplicateIBootIMFile(AbstractFile* file, AbstractFile* backing) {
-	InfoIBootIM* info;
-	unsigned char* copyCertificate;
-	AbstractFile* toReturn;
-
-	if(!file) {
-		return NULL;
-	}
-
-	info = (InfoIBootIM*) malloc(sizeof(InfoIBootIM));
-	memcpy(info, file-&gt;data, sizeof(InfoIBootIM));
-	
-	info-&gt;file = backing;
-	info-&gt;buffer = malloc(1);
-	info-&gt;length = 0;
-	info-&gt;dirty = TRUE;
-	info-&gt;offset = 0;
-	
-	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
-	toReturn-&gt;data = info;
-	toReturn-&gt;read = readIBootIM;
-	toReturn-&gt;write = writeIBootIM;
-	toReturn-&gt;seek = seekIBootIM;
-	toReturn-&gt;tell = tellIBootIM;
-	toReturn-&gt;getLength = getLengthIBootIM;
-	toReturn-&gt;close = closeIBootIM;
-	
-	return toReturn;
-}
-
-void pngRead(png_structp png_ptr, png_bytep data, png_size_t length) {
-	AbstractFile* imageFile;
-	imageFile = png_get_io_ptr(png_ptr);
-	imageFile-&gt;read(imageFile, data, length);
-}
-
-void pngError(png_structp png_ptr, png_const_charp error_msg) {
-	printf(&quot;error: %s\n&quot;, error_msg);
-	exit(0);
-}
-
-void* replaceBootImage(AbstractFile* imageWrapper, AbstractFile* png, size_t *fileSize) {
-	AbstractFile* imageFile;
-	char header[8];
-	InfoIBootIM* info;
-	png_uint_32 i;
-	png_bytepp row_pointers;
-	
-	uint8_t* imageBuffer;
-	void* buffer;
-
-	png-&gt;read(png, header, 8);
-	if(png_sig_cmp(header, 0, 8) != 0) {
-		printf(&quot;error: not a valid png file\n&quot;);
-		return NULL;
-	}
-	png-&gt;seek(png, 0);
-
-	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, pngError, pngError);
-	if (!png_ptr) {
-		return NULL;
-	}
-
-	png_infop info_ptr = png_create_info_struct(png_ptr);
-	if (!info_ptr)
-	{
-		png_destroy_read_struct(&amp;png_ptr, (png_infopp)NULL, (png_infopp)NULL);
-		return NULL;
-	}
-
-	png_infop end_info = png_create_info_struct(png_ptr);
-	if (!end_info)
-	{
-		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, (png_infopp)NULL);
-		return NULL;
-	}
-
-	if (setjmp(png_jmpbuf(png_ptr)))
-	{
-		printf(&quot;error reading png\n&quot;);
-		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
-		free(buffer);
-		return NULL;
-	}
-
-	png_set_read_fn(png_ptr, png, pngRead);
-
-	png_read_info(png_ptr, info_ptr);
-	
-	if(info_ptr-&gt;bit_depth &gt; 8) {
-		printf(&quot;warning: bit depth per channel is greater than 8 (%d). Attempting to strip, but image quality will be degraded.\n&quot;, info_ptr-&gt;bit_depth);
-	}
-	
-	if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_GRAY || info_ptr-&gt;color_type == PNG_COLOR_TYPE_RGB) {
-		printf(&quot;notice: attempting to add dummy transparency channel\n&quot;);
-	}
-	
-	if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_PALETTE) {
-		printf(&quot;notice: attempting to expand palette into full rgb\n&quot;);
-	}
-	
-  png_set_expand(png_ptr);
-	png_set_strip_16(png_ptr);
-	png_set_bgr(png_ptr);
-	png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
-	png_set_invert_alpha(png_ptr);
-	
-	png_read_update_info(png_ptr, info_ptr);
-	
-
-	if(info_ptr-&gt;width &gt; 320 || info_ptr-&gt;height &gt; 480) {
-		printf(&quot;error: dimensions out of range, must be within 320x480, not %dx%d\n&quot;, info_ptr-&gt;width, info_ptr-&gt;height);
-		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
-		return NULL;
-	}
-
-	if(info_ptr-&gt;bit_depth != 8) {
-		printf(&quot;error: bit depth per channel must be 8 not %d!\n&quot;, info_ptr-&gt;bit_depth);
-		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
-		return NULL;
-	}
-
-	if(info_ptr-&gt;color_type != PNG_COLOR_TYPE_GRAY_ALPHA &amp;&amp; info_ptr-&gt;color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
-		printf(&quot;error: incorrect color type, must be greyscale with alpha, or rgb with alpha\n&quot;);
-		if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_GRAY || info_ptr-&gt;color_type == PNG_COLOR_TYPE_RGB) {
-			printf(&quot;It appears you're missing an alpha channel. Add transparency to your image\n&quot;);
-		}
-		if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_PALETTE) {
-			printf(&quot;This PNG is saved with the palette color type rather than ARGB.\n&quot;);
-		}
-		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
-
-		return NULL;
-	}
-
-	row_pointers = (png_bytepp) malloc(sizeof(png_bytep) * info_ptr-&gt;height);
-	imageBuffer = malloc(info_ptr-&gt;height * info_ptr-&gt;rowbytes);
-	for(i = 0; i &lt; info_ptr-&gt;height; i++) {
-		row_pointers[i] = imageBuffer + (info_ptr-&gt;rowbytes * i);
-	}
-
-  png_read_image(png_ptr, row_pointers);
-	png_read_end(png_ptr, end_info);
-	
-	buffer = malloc(1);
-	*fileSize = 0;
-	
-	imageFile = duplicateAbstractFile(imageWrapper, createAbstractFileFromMemoryFile((void**)&amp;buffer, fileSize));
-	info = (InfoIBootIM*) (imageFile-&gt;data);
-	
-	info-&gt;header.width = (uint16_t) info_ptr-&gt;width;
-	info-&gt;header.height = (uint16_t) info_ptr-&gt;height;
-	if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
-		info-&gt;header.format = IBOOTIM_GREY;
-	} else {
-		info-&gt;header.format = IBOOTIM_ARGB;
-	}
-	
-	imageFile-&gt;write(imageFile, imageBuffer, info_ptr-&gt;height * info_ptr-&gt;rowbytes);
-	
-	imageFile-&gt;close(imageFile);
-
-	png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
-
-	png-&gt;close(png);
-	
-	free(row_pointers);
-
-	return buffer;
-}
-
+#include &quot;common.h&quot;
+#include &quot;abstractfile.h&quot;
+#include &quot;ibootim.h&quot;
+#include &quot;lzss.h&quot;
+#include &lt;png.h&gt;
+#include &quot;nor_files.h&quot;
+
+void flipIBootIMHeader(IBootIMHeader* header) {
+	FLIPENDIANLE(header-&gt;unknown);
+	FLIPENDIANLE(header-&gt;compression_type);
+	FLIPENDIANLE(header-&gt;format);
+	FLIPENDIANLE(header-&gt;width);
+	FLIPENDIANLE(header-&gt;height);
+}
+
+size_t readIBootIM(AbstractFile* file, void* data, size_t len) {
+	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data); 
+	memcpy(data, (void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), len);
+	info-&gt;offset += (size_t)len;
+	return len;
+}
+
+size_t writeIBootIM(AbstractFile* file, const void* data, size_t len) {
+	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
+
+	while((info-&gt;offset + (size_t)len) &gt; info-&gt;length) {
+		info-&gt;length = info-&gt;offset + (size_t)len;
+		info-&gt;buffer = realloc(info-&gt;buffer, info-&gt;length);
+	}
+	
+	memcpy((void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), data, len);
+	info-&gt;offset += (size_t)len;
+	
+	info-&gt;dirty = TRUE;
+	
+	return len;
+}
+
+int seekIBootIM(AbstractFile* file, off_t offset) {
+	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
+	info-&gt;offset = (size_t)offset;
+	return 0;
+}
+
+off_t tellIBootIM(AbstractFile* file) {
+	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
+	return (off_t)info-&gt;offset;
+}
+
+off_t getLengthIBootIM(AbstractFile* file) {
+	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
+	return info-&gt;length;
+}
+
+void closeIBootIM(AbstractFile* file) {
+	InfoIBootIM* info = (InfoIBootIM*) (file-&gt;data);
+	uint32_t cksum;
+	uint8_t *compressed;
+	if(info-&gt;dirty) {
+		compressed = malloc(info-&gt;length * 2);
+		info-&gt;compLength = (uint32_t)(compress_lzss(compressed, info-&gt;length * 2, info-&gt;buffer, info-&gt;length) - compressed);
+		
+		flipIBootIMHeader(&amp;(info-&gt;header));
+		info-&gt;file-&gt;seek(info-&gt;file, 0);
+		info-&gt;file-&gt;write(info-&gt;file, &amp;(info-&gt;header), sizeof(info-&gt;header));
+		
+		info-&gt;file-&gt;seek(info-&gt;file, sizeof(info-&gt;header));
+		info-&gt;file-&gt;write(info-&gt;file, compressed, info-&gt;compLength);
+		free(compressed);
+		
+	}
+	
+	free(info-&gt;buffer);
+	info-&gt;file-&gt;close(info-&gt;file);
+	free(info);
+	free(file);
+}
+
+
+AbstractFile* createAbstractFileFromIBootIM(AbstractFile* file) {
+	InfoIBootIM* info;
+	AbstractFile* toReturn;
+	uint8_t *compressed;
+
+	if(!file) {
+		return NULL;
+	}
+	
+	info = (InfoIBootIM*) malloc(sizeof(InfoIBootIM));
+	info-&gt;file = file;
+	file-&gt;seek(file, 0);
+	file-&gt;read(file, &amp;(info-&gt;header), sizeof(info-&gt;header));
+	flipIBootIMHeader(&amp;(info-&gt;header));
+	if(strcmp(info-&gt;header.signature, IBOOTIM_SIGNATURE) != 0) {
+		free(info);
+		return NULL;
+	}
+	
+	info-&gt;compLength = file-&gt;getLength(file) - sizeof(info-&gt;header);
+	if(info-&gt;header.compression_type != IBOOTIM_LZSS_TYPE) {
+		free(info);
+		return NULL;
+	}
+	
+	if(info-&gt;header.format == IBOOTIM_ARGB) {
+		info-&gt;length = 4 * info-&gt;header.width * info-&gt;header.height;
+	} else if(info-&gt;header.format == IBOOTIM_GREY) {
+		info-&gt;length = 2 * info-&gt;header.width * info-&gt;header.height;
+	} else {
+		free(info);
+		return NULL;
+	}
+	
+	info-&gt;buffer = malloc(info-&gt;length);
+	compressed = malloc(info-&gt;compLength);
+	file-&gt;read(file, compressed, info-&gt;compLength);
+
+	if(decompress_lzss(info-&gt;buffer, compressed, info-&gt;compLength) != info-&gt;length) {
+		free(compressed);
+		free(info);
+		return NULL;
+	}
+
+	free(compressed);
+	
+	info-&gt;dirty = FALSE;
+	
+	info-&gt;offset = 0;
+	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
+	toReturn-&gt;data = info;
+	toReturn-&gt;read = readIBootIM;
+	toReturn-&gt;write = writeIBootIM;
+	toReturn-&gt;seek = seekIBootIM;
+	toReturn-&gt;tell = tellIBootIM;
+	toReturn-&gt;getLength = getLengthIBootIM;
+	toReturn-&gt;close = closeIBootIM;
+	
+	return toReturn;
+}
+
+AbstractFile* duplicateIBootIMFile(AbstractFile* file, AbstractFile* backing) {
+	InfoIBootIM* info;
+	unsigned char* copyCertificate;
+	AbstractFile* toReturn;
+
+	if(!file) {
+		return NULL;
+	}
+
+	info = (InfoIBootIM*) malloc(sizeof(InfoIBootIM));
+	memcpy(info, file-&gt;data, sizeof(InfoIBootIM));
+	
+	info-&gt;file = backing;
+	info-&gt;buffer = malloc(1);
+	info-&gt;length = 0;
+	info-&gt;dirty = TRUE;
+	info-&gt;offset = 0;
+	
+	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
+	toReturn-&gt;data = info;
+	toReturn-&gt;read = readIBootIM;
+	toReturn-&gt;write = writeIBootIM;
+	toReturn-&gt;seek = seekIBootIM;
+	toReturn-&gt;tell = tellIBootIM;
+	toReturn-&gt;getLength = getLengthIBootIM;
+	toReturn-&gt;close = closeIBootIM;
+	
+	return toReturn;
+}
+
+void pngRead(png_structp png_ptr, png_bytep data, png_size_t length) {
+	AbstractFile* imageFile;
+	imageFile = png_get_io_ptr(png_ptr);
+	imageFile-&gt;read(imageFile, data, length);
+}
+
+void pngError(png_structp png_ptr, png_const_charp error_msg) {
+	printf(&quot;error: %s\n&quot;, error_msg);
+	exit(0);
+}
+
+void* replaceBootImage(AbstractFile* imageWrapper, AbstractFile* png, size_t *fileSize) {
+	AbstractFile* imageFile;
+	char header[8];
+	InfoIBootIM* info;
+	png_uint_32 i;
+	png_bytepp row_pointers;
+	
+	uint8_t* imageBuffer;
+	void* buffer;
+
+	png-&gt;read(png, header, 8);
+	if(png_sig_cmp(header, 0, 8) != 0) {
+		printf(&quot;error: not a valid png file\n&quot;);
+		return NULL;
+	}
+	png-&gt;seek(png, 0);
+
+	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, pngError, pngError);
+	if (!png_ptr) {
+		return NULL;
+	}
+
+	png_infop info_ptr = png_create_info_struct(png_ptr);
+	if (!info_ptr)
+	{
+		png_destroy_read_struct(&amp;png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+		return NULL;
+	}
+
+	png_infop end_info = png_create_info_struct(png_ptr);
+	if (!end_info)
+	{
+		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, (png_infopp)NULL);
+		return NULL;
+	}
+
+	if (setjmp(png_jmpbuf(png_ptr)))
+	{
+		printf(&quot;error reading png\n&quot;);
+		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
+		free(buffer);
+		return NULL;
+	}
+
+	png_set_read_fn(png_ptr, png, pngRead);
+
+	png_read_info(png_ptr, info_ptr);
+	
+	if(info_ptr-&gt;bit_depth &gt; 8) {
+		printf(&quot;warning: bit depth per channel is greater than 8 (%d). Attempting to strip, but image quality will be degraded.\n&quot;, info_ptr-&gt;bit_depth);
+	}
+	
+	if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_GRAY || info_ptr-&gt;color_type == PNG_COLOR_TYPE_RGB) {
+		printf(&quot;notice: attempting to add dummy transparency channel\n&quot;);
+	}
+	
+	if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_PALETTE) {
+		printf(&quot;notice: attempting to expand palette into full rgb\n&quot;);
+	}
+	
+  png_set_expand(png_ptr);
+	png_set_strip_16(png_ptr);
+	png_set_bgr(png_ptr);
+	png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);
+	png_set_invert_alpha(png_ptr);
+	
+	png_read_update_info(png_ptr, info_ptr);
+	
+
+	if(info_ptr-&gt;width &gt; 320 || info_ptr-&gt;height &gt; 480) {
+		printf(&quot;error: dimensions out of range, must be within 320x480, not %dx%d\n&quot;, info_ptr-&gt;width, info_ptr-&gt;height);
+		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
+		return NULL;
+	}
+
+	if(info_ptr-&gt;bit_depth != 8) {
+		printf(&quot;error: bit depth per channel must be 8 not %d!\n&quot;, info_ptr-&gt;bit_depth);
+		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
+		return NULL;
+	}
+
+	if(info_ptr-&gt;color_type != PNG_COLOR_TYPE_GRAY_ALPHA &amp;&amp; info_ptr-&gt;color_type != PNG_COLOR_TYPE_RGB_ALPHA) {
+		printf(&quot;error: incorrect color type, must be greyscale with alpha, or rgb with alpha\n&quot;);
+		if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_GRAY || info_ptr-&gt;color_type == PNG_COLOR_TYPE_RGB) {
+			printf(&quot;It appears you're missing an alpha channel. Add transparency to your image\n&quot;);
+		}
+		if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_PALETTE) {
+			printf(&quot;This PNG is saved with the palette color type rather than ARGB.\n&quot;);
+		}
+		png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
+
+		return NULL;
+	}
+
+	row_pointers = (png_bytepp) malloc(sizeof(png_bytep) * info_ptr-&gt;height);
+	imageBuffer = malloc(info_ptr-&gt;height * info_ptr-&gt;rowbytes);
+	for(i = 0; i &lt; info_ptr-&gt;height; i++) {
+		row_pointers[i] = imageBuffer + (info_ptr-&gt;rowbytes * i);
+	}
+
+  png_read_image(png_ptr, row_pointers);
+	png_read_end(png_ptr, end_info);
+	
+	buffer = malloc(1);
+	*fileSize = 0;
+	
+	imageFile = duplicateAbstractFile(imageWrapper, createAbstractFileFromMemoryFile((void**)&amp;buffer, fileSize));
+	info = (InfoIBootIM*) (imageFile-&gt;data);
+	
+	info-&gt;header.width = (uint16_t) info_ptr-&gt;width;
+	info-&gt;header.height = (uint16_t) info_ptr-&gt;height;
+	if(info_ptr-&gt;color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+		info-&gt;header.format = IBOOTIM_GREY;
+	} else {
+		info-&gt;header.format = IBOOTIM_ARGB;
+	}
+	
+	imageFile-&gt;write(imageFile, imageBuffer, info_ptr-&gt;height * info_ptr-&gt;rowbytes);
+	
+	imageFile-&gt;close(imageFile);
+
+	png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
+
+	png-&gt;close(png);
+	
+	free(row_pointers);
+
+	return buffer;
+}
+</diff>
      <filename>ipsw-patch/ibootim.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,34 +1,34 @@
-#include &lt;stdint.h&gt;
-#include &quot;abstractfile.h&quot;
-
-#define IMG2_SIGNATURE 0x496D6732
-
-typedef struct Img2Header {
-	uint32_t signature;        /* 0x0 */
-	uint32_t imageType;        /* 0x4 */
-	uint16_t unknown1;         /* 0x8 */
-	uint16_t security_epoch;   /* 0xa */
-	uint32_t flags1;           /* 0xc */
-	uint32_t dataLenPadded;    /* 0x10 */
-	uint32_t dataLen;          /* 0x14 */
-	uint32_t unknown3;         /* 0x18 */
-	uint32_t flags2;           /* 0x1c */ /* 0x01000000 has to be unset */
-	uint8_t  reserved[0x40];   /* 0x20 */
-	uint32_t unknown4;         /* 0x60 */ /* some sort of length field? */
-	uint32_t header_checksum;  /* 0x64 */ /* standard crc32 on first 0x64 bytes */
-	uint32_t checksum2;        /* 0x68 */
-	uint8_t  unknown5[0x394]; /* 0x68 */
-} __attribute__((__packed__)) Img2Header;
-
-typedef struct InfoImg2 {
-	AbstractFile*		file;
-	
-	Img2Header      header;
-	size_t          offset;
-	void*           buffer;
-
-	char            dirty;
-} InfoImg2;
-
-AbstractFile* createAbstractFileFromImg2(AbstractFile* file);
-AbstractFile* duplicateImg2File(AbstractFile* file, AbstractFile* backing);
+#include &lt;stdint.h&gt;
+#include &quot;abstractfile.h&quot;
+
+#define IMG2_SIGNATURE 0x496D6732
+
+typedef struct Img2Header {
+	uint32_t signature;        /* 0x0 */
+	uint32_t imageType;        /* 0x4 */
+	uint16_t unknown1;         /* 0x8 */
+	uint16_t security_epoch;   /* 0xa */
+	uint32_t flags1;           /* 0xc */
+	uint32_t dataLenPadded;    /* 0x10 */
+	uint32_t dataLen;          /* 0x14 */
+	uint32_t unknown3;         /* 0x18 */
+	uint32_t flags2;           /* 0x1c */ /* 0x01000000 has to be unset */
+	uint8_t  reserved[0x40];   /* 0x20 */
+	uint32_t unknown4;         /* 0x60 */ /* some sort of length field? */
+	uint32_t header_checksum;  /* 0x64 */ /* standard crc32 on first 0x64 bytes */
+	uint32_t checksum2;        /* 0x68 */
+	uint8_t  unknown5[0x394]; /* 0x68 */
+} __attribute__((__packed__)) Img2Header;
+
+typedef struct InfoImg2 {
+	AbstractFile*		file;
+	
+	Img2Header      header;
+	size_t          offset;
+	void*           buffer;
+
+	char            dirty;
+} InfoImg2;
+
+AbstractFile* createAbstractFileFromImg2(AbstractFile* file);
+AbstractFile* duplicateImg2File(AbstractFile* file, AbstractFile* backing);</diff>
      <filename>ipsw-patch/img2.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,29 +1,29 @@
-//---------------------------------------------------------------------------
-#include &lt;windows.h&gt;
-//---------------------------------------------------------------------------
-//   Important note about DLL memory management when your DLL uses the
-//   static version of the RunTime Library:
-//
-//   If your DLL exports any functions that pass String objects (or structs/
-//   classes containing nested Strings) as parameter or function results,
-//   you will need to add the library MEMMGR.LIB to both the DLL project and
-//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
-//   if any other projects which use the DLL will be performing new or delete
-//   operations on any non-TObject-derived classes which are exported from the
-//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
-//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
-//   the file BORLNDMM.DLL should be deployed along with your DLL.
-//
-//   To avoid using BORLNDMM.DLL, pass string information using &quot;char *&quot; or
-//   ShortString parameters.
-//
-//   If your DLL uses the dynamic version of the RTL, you do not need to
-//   explicitly add MEMMGR.LIB as this will be done implicitly for you
-//---------------------------------------------------------------------------
-
-int WINAPI DllEntryPoint(HINSTANCE, unsigned long, void*)
-{
-    return 1;
-}
-//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+#include &lt;windows.h&gt;
+//---------------------------------------------------------------------------
+//   Important note about DLL memory management when your DLL uses the
+//   static version of the RunTime Library:
+//
+//   If your DLL exports any functions that pass String objects (or structs/
+//   classes containing nested Strings) as parameter or function results,
+//   you will need to add the library MEMMGR.LIB to both the DLL project and
+//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
+//   if any other projects which use the DLL will be performing new or delete
+//   operations on any non-TObject-derived classes which are exported from the
+//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
+//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
+//   the file BORLNDMM.DLL should be deployed along with your DLL.
+//
+//   To avoid using BORLNDMM.DLL, pass string information using &quot;char *&quot; or
+//   ShortString parameters.
+//
+//   If your DLL uses the dynamic version of the RTL, you do not need to
+//   explicitly add MEMMGR.LIB as this will be done implicitly for you
+//---------------------------------------------------------------------------
+
+int WINAPI DllEntryPoint(HINSTANCE, unsigned long, void*)
+{
+    return 1;
+}
+//---------------------------------------------------------------------------
  
\ No newline at end of file</diff>
      <filename>ipsw-patch/libpng-1.2.28/projects/cbuilder5/libpng.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -1,352 +1,352 @@
 #include &lt;stdint.h&gt;
 #include &lt;string.h&gt;
-#include &lt;stdlib.h&gt;
-#include &quot;lzss.h&quot;
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5000  
-// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) &lt;= 2^32-1
-
-#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf)   DO8(buf,0); DO8(buf,8);
-
-uint32_t lzadler32(uint8_t *buf, int32_t len)
-{
-    unsigned long s1 = 1; // adler &amp; 0xffff;
-    unsigned long s2 = 0; // (adler &gt;&gt; 16) &amp; 0xffff;
-    int k;
-
-    while (len &gt; 0) {
-        k = len &lt; NMAX ? len : NMAX;
-        len -= k;
-        while (k &gt;= 16) {
-            DO16(buf);
-            buf += 16;
-            k -= 16;
-        }
-        if (k != 0) do {
-            s1 += *buf++;
-            s2 += s1;
-        } while (--k);
-        s1 %= BASE;
-        s2 %= BASE;
-    }
-    return (s2 &lt;&lt; 16) | s1;
-}
-
-
-
-/**************************************************************
- LZSS.C -- A Data Compression Program
-***************************************************************
-    4/6/1989 Haruhiko Okumura
-    Use, distribute, and modify this program freely.
-    Please send me your improved versions.
-        PC-VAN      SCIENCE
-        NIFTY-Serve PAF01022
-        CompuServe  74050,1022
-
-**************************************************************/
-
-#define N         4096  /* size of ring buffer - must be power of 2 */
-#define F         18    /* upper limit for match_length */
-#define THRESHOLD 2     /* encode string into position and length
-                           if match_length is greater than this */
-#define NIL       N     /* index for root of binary search trees */
-
-struct encode_state {
-    /*
-     * left &amp; right children &amp; parent. These constitute binary search trees.
-     */
-    int lchild[N + 1], rchild[N + 257], parent[N + 1];
-
-    /* ring buffer of size N, with extra F-1 bytes to aid string comparison */
-    uint8_t text_buf[N + F - 1];
-
-    /*
-     * match_length of longest match.
-     * These are set by the insert_node() procedure.
-     */
-    int match_position, match_length;
-};
-
-
-int
-decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen)
-{
-    /* ring buffer of size N, with extra F-1 bytes to aid string comparison */
-    uint8_t text_buf[N + F - 1];
-    uint8_t *dststart = dst;
-    uint8_t *srcend = src + srclen;
-    int  i, j, k, r, c;
-    unsigned int flags;
-    
-    dst = dststart;
-    srcend = src + srclen;
-    for (i = 0; i &lt; N - F; i++)
-        text_buf[i] = ' ';
-    r = N - F;
-    flags = 0;
-    for ( ; ; ) {
-        if (((flags &gt;&gt;= 1) &amp; 0x100) == 0) {
-            if (src &lt; srcend) c = *src++; else break;
-            flags = c | 0xFF00;  /* uses higher byte cleverly */
-        }   /* to count eight */
-        if (flags &amp; 1) {
-            if (src &lt; srcend) c = *src++; else break;
-            *dst++ = c;
-            text_buf[r++] = c;
-            r &amp;= (N - 1);
-        } else {
-            if (src &lt; srcend) i = *src++; else break;
-            if (src &lt; srcend) j = *src++; else break;
-            i |= ((j &amp; 0xF0) &lt;&lt; 4);
-            j  =  (j &amp; 0x0F) + THRESHOLD;
-            for (k = 0; k &lt;= j; k++) {
-                c = text_buf[(i + k) &amp; (N - 1)];
-                *dst++ = c;
-                text_buf[r++] = c;
-                r &amp;= (N - 1);
-            }
-        }
-    }
-    
-    return dst - dststart;
-}
-
-/*
- * initialize state, mostly the trees
- *
- * For i = 0 to N - 1, rchild[i] and lchild[i] will be the right and left 
- * children of node i.  These nodes need not be initialized.  Also, parent[i] 
- * is the parent of node i.  These are initialized to NIL (= N), which stands 
- * for 'not used.'  For i = 0 to 255, rchild[N + i + 1] is the root of the 
- * tree for strings that begin with character i.  These are initialized to NIL. 
- * Note there are 256 trees. */
-static void init_state(struct encode_state *sp)
-{
-    int  i;
-
-    memset(sp, 0, sizeof(*sp));
-
-    for (i = 0; i &lt; N - F; i++)
-        sp-&gt;text_buf[i] = ' ';
-    for (i = N + 1; i &lt;= N + 256; i++)
-        sp-&gt;rchild[i] = NIL;
-    for (i = 0; i &lt; N; i++)
-        sp-&gt;parent[i] = NIL;
-}
-
-/*
- * Inserts string of length F, text_buf[r..r+F-1], into one of the trees
- * (text_buf[r]'th tree) and returns the longest-match position and length
- * via the global variables match_position and match_length.
- * If match_length = F, then removes the old node in favor of the new one,
- * because the old one will be deleted sooner. Note r plays double role,
- * as tree node and position in buffer.
- */
-static void insert_node(struct encode_state *sp, int r)
-{
-    int  i, p, cmp;
-    uint8_t  *key;
-
-    cmp = 1;
-    key = &amp;sp-&gt;text_buf[r];
-    p = N + 1 + key[0];
-    sp-&gt;rchild[r] = sp-&gt;lchild[r] = NIL;
-    sp-&gt;match_length = 0;
-    for ( ; ; ) {
-        if (cmp &gt;= 0) {
-            if (sp-&gt;rchild[p] != NIL)
-                p = sp-&gt;rchild[p];
-            else {
-                sp-&gt;rchild[p] = r; 
-                sp-&gt;parent[r] = p;
-                return;
-            }
-        } else {
-            if (sp-&gt;lchild[p] != NIL)
-                p = sp-&gt;lchild[p];
-            else {
-                sp-&gt;lchild[p] = r;
-                sp-&gt;parent[r] = p;
-                return;
-            }
-        }
-        for (i = 1; i &lt; F; i++) {
-            if ((cmp = key[i] - sp-&gt;text_buf[p + i]) != 0)
-                break;
-        }
-        if (i &gt; sp-&gt;match_length) {
-            sp-&gt;match_position = p;
-            if ((sp-&gt;match_length = i) &gt;= F)
-                break;
-        }
-    }
-    sp-&gt;parent[r] = sp-&gt;parent[p];
-    sp-&gt;lchild[r] = sp-&gt;lchild[p];
-    sp-&gt;rchild[r] = sp-&gt;rchild[p];
-    sp-&gt;parent[sp-&gt;lchild[p]] = r;
-    sp-&gt;parent[sp-&gt;rchild[p]] = r;
-    if (sp-&gt;rchild[sp-&gt;parent[p]] == p)
-        sp-&gt;rchild[sp-&gt;parent[p]] = r;
-    else
-        sp-&gt;lchild[sp-&gt;parent[p]] = r;
-    sp-&gt;parent[p] = NIL;  /* remove p */
-}
-
-/* deletes node p from tree */
-static void delete_node(struct encode_state *sp, int p)
-{
-    int  q;
-    
-    if (sp-&gt;parent[p] == NIL)
-        return;  /* not in tree */
-    if (sp-&gt;rchild[p] == NIL)
-        q = sp-&gt;lchild[p];
-    else if (sp-&gt;lchild[p] == NIL)
-        q = sp-&gt;rchild[p];
-    else {
-        q = sp-&gt;lchild[p];
-        if (sp-&gt;rchild[q] != NIL) {
-            do {
-                q = sp-&gt;rchild[q];
-            } while (sp-&gt;rchild[q] != NIL);
-            sp-&gt;rchild[sp-&gt;parent[q]] = sp-&gt;lchild[q];
-            sp-&gt;parent[sp-&gt;lchild[q]] = sp-&gt;parent[q];
-            sp-&gt;lchild[q] = sp-&gt;lchild[p];
-            sp-&gt;parent[sp-&gt;lchild[p]] = q;
-        }
-        sp-&gt;rchild[q] = sp-&gt;rchild[p];
-        sp-&gt;parent[sp-&gt;rchild[p]] = q;
-    }
-    sp-&gt;parent[q] = sp-&gt;parent[p];
-    if (sp-&gt;rchild[sp-&gt;parent[p]] == p)
-        sp-&gt;rchild[sp-&gt;parent[p]] = q;
-    else
-        sp-&gt;lchild[sp-&gt;parent[p]] = q;
-    sp-&gt;parent[p] = NIL;
-}
-
-uint8_t *
-compress_lzss(uint8_t *dst, uint32_t dstlen, uint8_t *src, uint32_t srcLen)
-{
-    /* Encoding state, mostly tree but some current match stuff */
-    struct encode_state *sp;
-
-    int  i, c, len, r, s, last_match_length, code_buf_ptr;
-    uint8_t code_buf[17], mask;
-    uint8_t *srcend = src + srcLen;
-    uint8_t *dstend = dst + dstlen;
-
-    /* initialize trees */
-    sp = (struct encode_state *) malloc(sizeof(*sp));
-    init_state(sp);
-
-    /*
-     * code_buf[1..16] saves eight units of code, and code_buf[0] works
-     * as eight flags, &quot;1&quot; representing that the unit is an unencoded
-     * letter (1 byte), &quot;&quot; a position-and-length pair (2 bytes).
-     * Thus, eight units require at most 16 bytes of code.
-     */
-    code_buf[0] = 0;
-    code_buf_ptr = mask = 1;
-
-    /* Clear the buffer with any character that will appear often. */
-    s = 0;  r = N - F;
-
-    /* Read F bytes into the last F bytes of the buffer */
-    for (len = 0; len &lt; F &amp;&amp; src &lt; srcend; len++)
-        sp-&gt;text_buf[r + len] = *src++;  
+#include &lt;stdlib.h&gt;
+#include &quot;lzss.h&quot;
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5000  
+// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) &lt;= 2^32-1
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+uint32_t lzadler32(uint8_t *buf, int32_t len)
+{
+    unsigned long s1 = 1; // adler &amp; 0xffff;
+    unsigned long s2 = 0; // (adler &gt;&gt; 16) &amp; 0xffff;
+    int k;
+
+    while (len &gt; 0) {
+        k = len &lt; NMAX ? len : NMAX;
+        len -= k;
+        while (k &gt;= 16) {
+            DO16(buf);
+            buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+            s2 += s1;
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 &lt;&lt; 16) | s1;
+}
+
+
+
+/**************************************************************
+ LZSS.C -- A Data Compression Program
+***************************************************************
+    4/6/1989 Haruhiko Okumura
+    Use, distribute, and modify this program freely.
+    Please send me your improved versions.
+        PC-VAN      SCIENCE
+        NIFTY-Serve PAF01022
+        CompuServe  74050,1022
+
+**************************************************************/
+
+#define N         4096  /* size of ring buffer - must be power of 2 */
+#define F         18    /* upper limit for match_length */
+#define THRESHOLD 2     /* encode string into position and length
+                           if match_length is greater than this */
+#define NIL       N     /* index for root of binary search trees */
+
+struct encode_state {
+    /*
+     * left &amp; right children &amp; parent. These constitute binary search trees.
+     */
+    int lchild[N + 1], rchild[N + 257], parent[N + 1];
+
+    /* ring buffer of size N, with extra F-1 bytes to aid string comparison */
+    uint8_t text_buf[N + F - 1];
+
+    /*
+     * match_length of longest match.
+     * These are set by the insert_node() procedure.
+     */
+    int match_position, match_length;
+};
+
+
+int
+decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen)
+{
+    /* ring buffer of size N, with extra F-1 bytes to aid string comparison */
+    uint8_t text_buf[N + F - 1];
+    uint8_t *dststart = dst;
+    uint8_t *srcend = src + srclen;
+    int  i, j, k, r, c;
+    unsigned int flags;
+    
+    dst = dststart;
+    srcend = src + srclen;
+    for (i = 0; i &lt; N - F; i++)
+        text_buf[i] = ' ';
+    r = N - F;
+    flags = 0;
+    for ( ; ; ) {
+        if (((flags &gt;&gt;= 1) &amp; 0x100) == 0) {
+            if (src &lt; srcend) c = *src++; else break;
+            flags = c | 0xFF00;  /* uses higher byte cleverly */
+        }   /* to count eight */
+        if (flags &amp; 1) {
+            if (src &lt; srcend) c = *src++; else break;
+            *dst++ = c;
+            text_buf[r++] = c;
+            r &amp;= (N - 1);
+        } else {
+            if (src &lt; srcend) i = *src++; else break;
+            if (src &lt; srcend) j = *src++; else break;
+            i |= ((j &amp; 0xF0) &lt;&lt; 4);
+            j  =  (j &amp; 0x0F) + THRESHOLD;
+            for (k = 0; k &lt;= j; k++) {
+                c = text_buf[(i + k) &amp; (N - 1)];
+                *dst++ = c;
+                text_buf[r++] = c;
+                r &amp;= (N - 1);
+            }
+        }
+    }
+    
+    return dst - dststart;
+}
+
+/*
+ * initialize state, mostly the trees
+ *
+ * For i = 0 to N - 1, rchild[i] and lchild[i] will be the right and left 
+ * children of node i.  These nodes need not be initialized.  Also, parent[i] 
+ * is the parent of node i.  These are initialized to NIL (= N), which stands 
+ * for 'not used.'  For i = 0 to 255, rchild[N + i + 1] is the root of the 
+ * tree for strings that begin with character i.  These are initialized to NIL. 
+ * Note there are 256 trees. */
+static void init_state(struct encode_state *sp)
+{
+    int  i;
+
+    memset(sp, 0, sizeof(*sp));
+
+    for (i = 0; i &lt; N - F; i++)
+        sp-&gt;text_buf[i] = ' ';
+    for (i = N + 1; i &lt;= N + 256; i++)
+        sp-&gt;rchild[i] = NIL;
+    for (i = 0; i &lt; N; i++)
+        sp-&gt;parent[i] = NIL;
+}
+
+/*
+ * Inserts string of length F, text_buf[r..r+F-1], into one of the trees
+ * (text_buf[r]'th tree) and returns the longest-match position and length
+ * via the global variables match_position and match_length.
+ * If match_length = F, then removes the old node in favor of the new one,
+ * because the old one will be deleted sooner. Note r plays double role,
+ * as tree node and position in buffer.
+ */
+static void insert_node(struct encode_state *sp, int r)
+{
+    int  i, p, cmp;
+    uint8_t  *key;
+
+    cmp = 1;
+    key = &amp;sp-&gt;text_buf[r];
+    p = N + 1 + key[0];
+    sp-&gt;rchild[r] = sp-&gt;lchild[r] = NIL;
+    sp-&gt;match_length = 0;
+    for ( ; ; ) {
+        if (cmp &gt;= 0) {
+            if (sp-&gt;rchild[p] != NIL)
+                p = sp-&gt;rchild[p];
+            else {
+                sp-&gt;rchild[p] = r; 
+                sp-&gt;parent[r] = p;
+                return;
+            }
+        } else {
+            if (sp-&gt;lchild[p] != NIL)
+                p = sp-&gt;lchild[p];
+            else {
+                sp-&gt;lchild[p] = r;
+                sp-&gt;parent[r] = p;
+                return;
+            }
+        }
+        for (i = 1; i &lt; F; i++) {
+            if ((cmp = key[i] - sp-&gt;text_buf[p + i]) != 0)
+                break;
+        }
+        if (i &gt; sp-&gt;match_length) {
+            sp-&gt;match_position = p;
+            if ((sp-&gt;match_length = i) &gt;= F)
+                break;
+        }
+    }
+    sp-&gt;parent[r] = sp-&gt;parent[p];
+    sp-&gt;lchild[r] = sp-&gt;lchild[p];
+    sp-&gt;rchild[r] = sp-&gt;rchild[p];
+    sp-&gt;parent[sp-&gt;lchild[p]] = r;
+    sp-&gt;parent[sp-&gt;rchild[p]] = r;
+    if (sp-&gt;rchild[sp-&gt;parent[p]] == p)
+        sp-&gt;rchild[sp-&gt;parent[p]] = r;
+    else
+        sp-&gt;lchild[sp-&gt;parent[p]] = r;
+    sp-&gt;parent[p] = NIL;  /* remove p */
+}
+
+/* deletes node p from tree */
+static void delete_node(struct encode_state *sp, int p)
+{
+    int  q;
+    
+    if (sp-&gt;parent[p] == NIL)
+        return;  /* not in tree */
+    if (sp-&gt;rchild[p] == NIL)
+        q = sp-&gt;lchild[p];
+    else if (sp-&gt;lchild[p] == NIL)
+        q = sp-&gt;rchild[p];
+    else {
+        q = sp-&gt;lchild[p];
+        if (sp-&gt;rchild[q] != NIL) {
+            do {
+                q = sp-&gt;rchild[q];
+            } while (sp-&gt;rchild[q] != NIL);
+            sp-&gt;rchild[sp-&gt;parent[q]] = sp-&gt;lchild[q];
+            sp-&gt;parent[sp-&gt;lchild[q]] = sp-&gt;parent[q];
+            sp-&gt;lchild[q] = sp-&gt;lchild[p];
+            sp-&gt;parent[sp-&gt;lchild[p]] = q;
+        }
+        sp-&gt;rchild[q] = sp-&gt;rchild[p];
+        sp-&gt;parent[sp-&gt;rchild[p]] = q;
+    }
+    sp-&gt;parent[q] = sp-&gt;parent[p];
+    if (sp-&gt;rchild[sp-&gt;parent[p]] == p)
+        sp-&gt;rchild[sp-&gt;parent[p]] = q;
+    else
+        sp-&gt;lchild[sp-&gt;parent[p]] = q;
+    sp-&gt;parent[p] = NIL;
+}
+
+uint8_t *
+compress_lzss(uint8_t *dst, uint32_t dstlen, uint8_t *src, uint32_t srcLen)
+{
+    /* Encoding state, mostly tree but some current match stuff */
+    struct encode_state *sp;
+
+    int  i, c, len, r, s, last_match_length, code_buf_ptr;
+    uint8_t code_buf[17], mask;
+    uint8_t *srcend = src + srcLen;
+    uint8_t *dstend = dst + dstlen;
+
+    /* initialize trees */
+    sp = (struct encode_state *) malloc(sizeof(*sp));
+    init_state(sp);
+
+    /*
+     * code_buf[1..16] saves eight units of code, and code_buf[0] works
+     * as eight flags, &quot;1&quot; representing that the unit is an unencoded
+     * letter (1 byte), &quot;&quot; a position-and-length pair (2 bytes).
+     * Thus, eight units require at most 16 bytes of code.
+     */
+    code_buf[0] = 0;
+    code_buf_ptr = mask = 1;
+
+    /* Clear the buffer with any character that will appear often. */
+    s = 0;  r = N - F;
+
+    /* Read F bytes into the last F bytes of the buffer */
+    for (len = 0; len &lt; F &amp;&amp; src &lt; srcend; len++)
+        sp-&gt;text_buf[r + len] = *src++;  
     if (!len) {
-        free(sp);
-        return (void *) 0;  /* text of size zero */
-    }
-    /*
-     * Insert the F strings, each of which begins with one or more
-     * 'space' characters.  Note the order in which these strings are
-     * inserted.  This way, degenerate trees will be less likely to occur.
-     */
-    for (i = 1; i &lt;= F; i++)
-        insert_node(sp, r - i); 
-
-    /*
-     * Finally, insert the whole string just read.
-     * The global variables match_length and match_position are set.
-     */
-    insert_node(sp, r);
-    do {
-        /* match_length may be spuriously long near the end of text. */
-        if (sp-&gt;match_length &gt; len)
-            sp-&gt;match_length = len;
-        if (sp-&gt;match_length &lt;= THRESHOLD) {
-            sp-&gt;match_length = 1;  /* Not long enough match.  Send one byte. */
-            code_buf[0] |= mask;  /* 'send one byte' flag */
-            code_buf[code_buf_ptr++] = sp-&gt;text_buf[r];  /* Send uncoded. */
-        } else {
-            /* Send position and length pair. Note match_length &gt; THRESHOLD. */
-            code_buf[code_buf_ptr++] = (uint8_t) sp-&gt;match_position;
-            code_buf[code_buf_ptr++] = (uint8_t)
-                ( ((sp-&gt;match_position &gt;&gt; 4) &amp; 0xF0)
-                |  (sp-&gt;match_length - (THRESHOLD + 1)) );
-        }
-        if ((mask &lt;&lt;= 1) == 0) {  /* Shift mask left one bit. */
-                /* Send at most 8 units of code together */
-            for (i = 0; i &lt; code_buf_ptr; i++)
-                if (dst &lt; dstend)
-                    *dst++ = code_buf[i]; 
+        free(sp);
+        return (void *) 0;  /* text of size zero */
+    }
+    /*
+     * Insert the F strings, each of which begins with one or more
+     * 'space' characters.  Note the order in which these strings are
+     * inserted.  This way, degenerate trees will be less likely to occur.
+     */
+    for (i = 1; i &lt;= F; i++)
+        insert_node(sp, r - i); 
+
+    /*
+     * Finally, insert the whole string just read.
+     * The global variables match_length and match_position are set.
+     */
+    insert_node(sp, r);
+    do {
+        /* match_length may be spuriously long near the end of text. */
+        if (sp-&gt;match_length &gt; len)
+            sp-&gt;match_length = len;
+        if (sp-&gt;match_length &lt;= THRESHOLD) {
+            sp-&gt;match_length = 1;  /* Not long enough match.  Send one byte. */
+            code_buf[0] |= mask;  /* 'send one byte' flag */
+            code_buf[code_buf_ptr++] = sp-&gt;text_buf[r];  /* Send uncoded. */
+        } else {
+            /* Send position and length pair. Note match_length &gt; THRESHOLD. */
+            code_buf[code_buf_ptr++] = (uint8_t) sp-&gt;match_position;
+            code_buf[code_buf_ptr++] = (uint8_t)
+                ( ((sp-&gt;match_position &gt;&gt; 4) &amp; 0xF0)
+                |  (sp-&gt;match_length - (THRESHOLD + 1)) );
+        }
+        if ((mask &lt;&lt;= 1) == 0) {  /* Shift mask left one bit. */
+                /* Send at most 8 units of code together */
+            for (i = 0; i &lt; code_buf_ptr; i++)
+                if (dst &lt; dstend)
+                    *dst++ = code_buf[i]; 
                 else {
-                    free(sp);
+                    free(sp);
                     return (void *) 0;
-                }
-            code_buf[0] = 0;
-            code_buf_ptr = mask = 1;
-        }
-        last_match_length = sp-&gt;match_length;
-        for (i = 0; i &lt; last_match_length &amp;&amp; src &lt; srcend; i++) {
-            delete_node(sp, s);    /* Delete old strings and */
-            c = *src++;
-            sp-&gt;text_buf[s] = c;    /* read new bytes */
-
-            /*
-             * If the position is near the end of buffer, extend the buffer
-             * to make string comparison easier.
-             */
-            if (s &lt; F - 1)
-                sp-&gt;text_buf[s + N] = c;
-
-            /* Since this is a ring buffer, increment the position modulo N. */
-            s = (s + 1) &amp; (N - 1);
-            r = (r + 1) &amp; (N - 1);
-
-            /* Register the string in text_buf[r..r+F-1] */
-            insert_node(sp, r); 
-        }
-        while (i++ &lt; last_match_length) {
-        delete_node(sp, s);
-
-            /* After the end of text, no need to read, */
-            s = (s + 1) &amp; (N - 1); 
-            r = (r + 1) &amp; (N - 1);
-            /* but buffer may not be empty. */
-            if (--len)
-                insert_node(sp, r);
-        }
-    } while (len &gt; 0);   /* until length of string to be processed is zero */
-
-    if (code_buf_ptr &gt; 1) {    /* Send remaining code. */
-        for (i = 0; i &lt; code_buf_ptr; i++)
-            if (dst &lt; dstend)
-                *dst++ = code_buf[i]; 
+                }
+            code_buf[0] = 0;
+            code_buf_ptr = mask = 1;
+        }
+        last_match_length = sp-&gt;match_length;
+        for (i = 0; i &lt; last_match_length &amp;&amp; src &lt; srcend; i++) {
+            delete_node(sp, s);    /* Delete old strings and */
+            c = *src++;
+            sp-&gt;text_buf[s] = c;    /* read new bytes */
+
+            /*
+             * If the position is near the end of buffer, extend the buffer
+             * to make string comparison easier.
+             */
+            if (s &lt; F - 1)
+                sp-&gt;text_buf[s + N] = c;
+
+            /* Since this is a ring buffer, increment the position modulo N. */
+            s = (s + 1) &amp; (N - 1);
+            r = (r + 1) &amp; (N - 1);
+
+            /* Register the string in text_buf[r..r+F-1] */
+            insert_node(sp, r); 
+        }
+        while (i++ &lt; last_match_length) {
+        delete_node(sp, s);
+
+            /* After the end of text, no need to read, */
+            s = (s + 1) &amp; (N - 1); 
+            r = (r + 1) &amp; (N - 1);
+            /* but buffer may not be empty. */
+            if (--len)
+                insert_node(sp, r);
+        }
+    } while (len &gt; 0);   /* until length of string to be processed is zero */
+
+    if (code_buf_ptr &gt; 1) {    /* Send remaining code. */
+        for (i = 0; i &lt; code_buf_ptr; i++)
+            if (dst &lt; dstend)
+                *dst++ = code_buf[i]; 
             else {
-                free(sp);
+                free(sp);
                 return (void *) 0;
-            }
-    }
+            }
+    }
 
-    free(sp);
-    return dst;
-}
+    free(sp);
+    return dst;
+}</diff>
      <filename>ipsw-patch/lzss.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
-#include &lt;stdint.h&gt;
-
-uint32_t lzadler32(uint8_t *buf, int32_t len);
-int decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen);
-uint8_t *compress_lzss(uint8_t *dst, uint32_t dstlen, uint8_t *src, uint32_t srcLen);
+#include &lt;stdint.h&gt;
+
+uint32_t lzadler32(uint8_t *buf, int32_t len);
+int decompress_lzss(uint8_t *dst, uint8_t *src, uint32_t srclen);
+uint8_t *compress_lzss(uint8_t *dst, uint32_t dstlen, uint8_t *src, uint32_t srcLen);</diff>
      <filename>ipsw-patch/lzss.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,162 +1,162 @@
-#include &lt;stdlib.h&gt;
-#include &lt;string.h&gt;
-#include &quot;common.h&quot;
-#include &quot;abstractfile.h&quot;
-#include &quot;lzssfile.h&quot;
-#include &quot;lzss.h&quot;
-
-void flipCompHeader(CompHeader* header) {
-	FLIPENDIAN(header-&gt;signature);
-	FLIPENDIAN(header-&gt;compression_type);
-	FLIPENDIAN(header-&gt;checksum);
-	FLIPENDIAN(header-&gt;length_uncompressed);
-	FLIPENDIAN(header-&gt;length_compressed);
-}
-
-size_t readComp(AbstractFile* file, void* data, size_t len) {
-	InfoComp* info = (InfoComp*) (file-&gt;data); 
-	memcpy(data, (void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), len);
-	info-&gt;offset += (size_t)len;
-	return len;
-}
-
-size_t writeComp(AbstractFile* file, const void* data, size_t len) {
-	InfoComp* info = (InfoComp*) (file-&gt;data);
-
-	while((info-&gt;offset + (size_t)len) &gt; info-&gt;header.length_uncompressed) {
-		info-&gt;header.length_uncompressed = info-&gt;offset + (size_t)len;
-		info-&gt;buffer = realloc(info-&gt;buffer, info-&gt;header.length_uncompressed);
-	}
-	
-	memcpy((void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), data, len);
-	info-&gt;offset += (size_t)len;
-	
-	info-&gt;dirty = TRUE;
-	
-	return len;
-}
-
-int seekComp(AbstractFile* file, off_t offset) {
-	InfoComp* info = (InfoComp*) (file-&gt;data);
-	info-&gt;offset = (size_t)offset;
-	return 0;
-}
-
-off_t tellComp(AbstractFile* file) {
-	InfoComp* info = (InfoComp*) (file-&gt;data);
-	return (off_t)info-&gt;offset;
-}
-
-off_t getLengthComp(AbstractFile* file) {
-	InfoComp* info = (InfoComp*) (file-&gt;data);
-	return info-&gt;header.length_uncompressed;
-}
-
-void closeComp(AbstractFile* file) {
-	InfoComp* info = (InfoComp*) (file-&gt;data);
-	uint32_t cksum;
-	uint8_t *compressed;
-	if(info-&gt;dirty) {
-		info-&gt;header.checksum = lzadler32((uint8_t*)info-&gt;buffer, info-&gt;header.length_uncompressed);
-		
-		compressed = malloc(info-&gt;header.length_uncompressed * 2);
-		info-&gt;header.length_compressed = (uint32_t)(compress_lzss(compressed, info-&gt;header.length_uncompressed * 2, info-&gt;buffer, info-&gt;header.length_uncompressed) - compressed);
-		
-		info-&gt;file-&gt;seek(info-&gt;file, sizeof(info-&gt;header));
-		info-&gt;file-&gt;write(info-&gt;file, compressed, info-&gt;header.length_compressed);
-		free(compressed);
-			
-		flipCompHeader(&amp;(info-&gt;header));
-		info-&gt;file-&gt;seek(info-&gt;file, 0);
-		info-&gt;file-&gt;write(info-&gt;file, &amp;(info-&gt;header), sizeof(info-&gt;header));
-	}
-	
-	free(info-&gt;buffer);
-	info-&gt;file-&gt;close(info-&gt;file);
-	free(info);
-	free(file);
-}
-
-
-AbstractFile* createAbstractFileFromComp(AbstractFile* file) {
-	InfoComp* info;
-	AbstractFile* toReturn;
-	uint8_t *compressed;
-
-	if(!file) {
-		return NULL;
-	}
-
-	info = (InfoComp*) malloc(sizeof(InfoComp));
-	info-&gt;file = file;
-	file-&gt;seek(file, 0);
-	file-&gt;read(file, &amp;(info-&gt;header), sizeof(info-&gt;header));
-	flipCompHeader(&amp;(info-&gt;header));
-	if(info-&gt;header.signature != COMP_SIGNATURE) {
-		free(info);
-		return NULL;
-	}
-	
-	if(info-&gt;header.compression_type != LZSS_SIGNATURE) {
-		free(info);
-		return NULL;
-	}
-	
-	info-&gt;buffer = malloc(info-&gt;header.length_uncompressed);
-	compressed = malloc(info-&gt;header.length_compressed);
-	file-&gt;read(file, compressed, info-&gt;header.length_compressed);
-	
-	if(decompress_lzss(info-&gt;buffer, compressed, info-&gt;header.length_compressed) != info-&gt;header.length_uncompressed) {
-		free(compressed);
-		free(info);
-		return NULL;
-	}
-	
-	free(compressed);
-
-	info-&gt;dirty = FALSE;
-	
-	info-&gt;offset = 0;
-	
-	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
-	toReturn-&gt;data = info;
-	toReturn-&gt;read = readComp;
-	toReturn-&gt;write = writeComp;
-	toReturn-&gt;seek = seekComp;
-	toReturn-&gt;tell = tellComp;
-	toReturn-&gt;getLength = getLengthComp;
-	toReturn-&gt;close = closeComp;
-
-	return toReturn;
-}
-
-AbstractFile* duplicateCompFile(AbstractFile* file, AbstractFile* backing) {
-	InfoComp* info;
-	unsigned char* copyCertificate;
-	AbstractFile* toReturn;
-
-	if(!file) {
-		return NULL;
-	}
-
-	info = (InfoComp*) malloc(sizeof(InfoComp));
-	memcpy(info, file-&gt;data, sizeof(InfoComp));
-	
-	info-&gt;file = backing;
-	info-&gt;buffer = malloc(1);
-	info-&gt;header.length_uncompressed = 0;
-	info-&gt;dirty = TRUE;
-	info-&gt;offset = 0;
-	
-	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
-	toReturn-&gt;data = info;
-	toReturn-&gt;read = readComp;
-	toReturn-&gt;write = writeComp;
-	toReturn-&gt;seek = seekComp;
-	toReturn-&gt;tell = tellComp;
-	toReturn-&gt;getLength = getLengthComp;
-	toReturn-&gt;close = closeComp;
-	
-	return toReturn;
-}
-
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &quot;common.h&quot;
+#include &quot;abstractfile.h&quot;
+#include &quot;lzssfile.h&quot;
+#include &quot;lzss.h&quot;
+
+void flipCompHeader(CompHeader* header) {
+	FLIPENDIAN(header-&gt;signature);
+	FLIPENDIAN(header-&gt;compression_type);
+	FLIPENDIAN(header-&gt;checksum);
+	FLIPENDIAN(header-&gt;length_uncompressed);
+	FLIPENDIAN(header-&gt;length_compressed);
+}
+
+size_t readComp(AbstractFile* file, void* data, size_t len) {
+	InfoComp* info = (InfoComp*) (file-&gt;data); 
+	memcpy(data, (void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), len);
+	info-&gt;offset += (size_t)len;
+	return len;
+}
+
+size_t writeComp(AbstractFile* file, const void* data, size_t len) {
+	InfoComp* info = (InfoComp*) (file-&gt;data);
+
+	while((info-&gt;offset + (size_t)len) &gt; info-&gt;header.length_uncompressed) {
+		info-&gt;header.length_uncompressed = info-&gt;offset + (size_t)len;
+		info-&gt;buffer = realloc(info-&gt;buffer, info-&gt;header.length_uncompressed);
+	}
+	
+	memcpy((void*)((uint8_t*)info-&gt;buffer + (uint32_t)info-&gt;offset), data, len);
+	info-&gt;offset += (size_t)len;
+	
+	info-&gt;dirty = TRUE;
+	
+	return len;
+}
+
+int seekComp(AbstractFile* file, off_t offset) {
+	InfoComp* info = (InfoComp*) (file-&gt;data);
+	info-&gt;offset = (size_t)offset;
+	return 0;
+}
+
+off_t tellComp(AbstractFile* file) {
+	InfoComp* info = (InfoComp*) (file-&gt;data);
+	return (off_t)info-&gt;offset;
+}
+
+off_t getLengthComp(AbstractFile* file) {
+	InfoComp* info = (InfoComp*) (file-&gt;data);
+	return info-&gt;header.length_uncompressed;
+}
+
+void closeComp(AbstractFile* file) {
+	InfoComp* info = (InfoComp*) (file-&gt;data);
+	uint32_t cksum;
+	uint8_t *compressed;
+	if(info-&gt;dirty) {
+		info-&gt;header.checksum = lzadler32((uint8_t*)info-&gt;buffer, info-&gt;header.length_uncompressed);
+		
+		compressed = malloc(info-&gt;header.length_uncompressed * 2);
+		info-&gt;header.length_compressed = (uint32_t)(compress_lzss(compressed, info-&gt;header.length_uncompressed * 2, info-&gt;buffer, info-&gt;header.length_uncompressed) - compressed);
+		
+		info-&gt;file-&gt;seek(info-&gt;file, sizeof(info-&gt;header));
+		info-&gt;file-&gt;write(info-&gt;file, compressed, info-&gt;header.length_compressed);
+		free(compressed);
+			
+		flipCompHeader(&amp;(info-&gt;header));
+		info-&gt;file-&gt;seek(info-&gt;file, 0);
+		info-&gt;file-&gt;write(info-&gt;file, &amp;(info-&gt;header), sizeof(info-&gt;header));
+	}
+	
+	free(info-&gt;buffer);
+	info-&gt;file-&gt;close(info-&gt;file);
+	free(info);
+	free(file);
+}
+
+
+AbstractFile* createAbstractFileFromComp(AbstractFile* file) {
+	InfoComp* info;
+	AbstractFile* toReturn;
+	uint8_t *compressed;
+
+	if(!file) {
+		return NULL;
+	}
+
+	info = (InfoComp*) malloc(sizeof(InfoComp));
+	info-&gt;file = file;
+	file-&gt;seek(file, 0);
+	file-&gt;read(file, &amp;(info-&gt;header), sizeof(info-&gt;header));
+	flipCompHeader(&amp;(info-&gt;header));
+	if(info-&gt;header.signature != COMP_SIGNATURE) {
+		free(info);
+		return NULL;
+	}
+	
+	if(info-&gt;header.compression_type != LZSS_SIGNATURE) {
+		free(info);
+		return NULL;
+	}
+	
+	info-&gt;buffer = malloc(info-&gt;header.length_uncompressed);
+	compressed = malloc(info-&gt;header.length_compressed);
+	file-&gt;read(file, compressed, info-&gt;header.length_compressed);
+	
+	if(decompress_lzss(info-&gt;buffer, compressed, info-&gt;header.length_compressed) != info-&gt;header.length_uncompressed) {
+		free(compressed);
+		free(info);
+		return NULL;
+	}
+	
+	free(compressed);
+
+	info-&gt;dirty = FALSE;
+	
+	info-&gt;offset = 0;
+	
+	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
+	toReturn-&gt;data = info;
+	toReturn-&gt;read = readComp;
+	toReturn-&gt;write = writeComp;
+	toReturn-&gt;seek = seekComp;
+	toReturn-&gt;tell = tellComp;
+	toReturn-&gt;getLength = getLengthComp;
+	toReturn-&gt;close = closeComp;
+
+	return toReturn;
+}
+
+AbstractFile* duplicateCompFile(AbstractFile* file, AbstractFile* backing) {
+	InfoComp* info;
+	unsigned char* copyCertificate;
+	AbstractFile* toReturn;
+
+	if(!file) {
+		return NULL;
+	}
+
+	info = (InfoComp*) malloc(sizeof(InfoComp));
+	memcpy(info, file-&gt;data, sizeof(InfoComp));
+	
+	info-&gt;file = backing;
+	info-&gt;buffer = malloc(1);
+	info-&gt;header.length_uncompressed = 0;
+	info-&gt;dirty = TRUE;
+	info-&gt;offset = 0;
+	
+	toReturn = (AbstractFile*) malloc(sizeof(AbstractFile));
+	toReturn-&gt;data = info;
+	toReturn-&gt;read = readComp;
+	toReturn-&gt;write = writeComp;
+	toReturn-&gt;seek = seekComp;
+	toReturn-&gt;tell = tellComp;
+	toReturn-&gt;getLength = getLengthComp;
+	toReturn-&gt;close = closeComp;
+	
+	return toReturn;
+}
+</diff>
      <filename>ipsw-patch/lzssfile.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,27 +1,27 @@
-#include &lt;stdint.h&gt;
-#include &quot;abstractfile.h&quot;
-
-#define COMP_SIGNATURE 0x636F6D70
-#define LZSS_SIGNATURE 0x6C7A7373
-
-typedef struct CompHeader {
-	uint32_t signature;
-	uint32_t compression_type;
-	uint32_t checksum;
-	uint32_t length_uncompressed;
-	uint32_t length_compressed;
-	uint8_t  padding[0x16C];
-} __attribute__((__packed__)) CompHeader;
-
-typedef struct InfoComp {
-	AbstractFile*		file;
-	
-	CompHeader      header;
-	size_t          offset;
-	void*           buffer;
-
-	char            dirty;
-} InfoComp;
-
-AbstractFile* createAbstractFileFromComp(AbstractFile* file);
-AbstractFile* duplicateCompFile(AbstractFile* file, AbstractFile* backing);
+#include &lt;stdint.h&gt;
+#include &quot;abstractfile.h&quot;
+
+#define COMP_SIGNATURE 0x636F6D70
+#define LZSS_SIGNATURE 0x6C7A7373
+
+typedef struct CompHeader {
+	uint32_t signature;
+	uint32_t compression_type;
+	uint32_t checksum;
+	uint32_t length_uncompressed;
+	uint32_t length_compressed;
+	uint8_t  padding[0x16C];
+} __attribute__((__packed__)) CompHeader;
+
+typedef struct InfoComp {
+	AbstractFile*		file;
+	
+	CompHeader      header;
+	size_t          offset;
+	void*           buffer;
+
+	char            dirty;
+} InfoComp;
+
+AbstractFile* createAbstractFileFromComp(AbstractFile* file);
+AbstractFile* duplicateCompFile(AbstractFile* file, AbstractFile* backing);</diff>
      <filename>ipsw-patch/lzssfile.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,59 +1,59 @@
-#include &quot;../hfs/common.h&quot;
-#include &quot;8900.h&quot;
-#include &quot;img2.h&quot;
-#include &quot;lzssfile.h&quot;
-#include &quot;ibootim.h&quot;
-
-AbstractFile* openAbstractFile(AbstractFile* file) {
-	uint32_t signatureBE;
-	uint32_t signatureLE;
-	
-	file-&gt;seek(file, 0);
-	file-&gt;read(file, &amp;signatureBE, sizeof(signatureBE));
-	signatureLE = signatureBE;
-	FLIPENDIAN(signatureBE);
-	FLIPENDIANLE(signatureLE);
-	file-&gt;seek(file, 0);
-	
-	if(signatureBE == SIGNATURE_8900) {
-		return openAbstractFile(createAbstractFileFrom8900(file));
-	} else if(signatureLE == IMG2_SIGNATURE) {
-		return openAbstractFile(createAbstractFileFromImg2(file));
-	} else if(signatureBE == COMP_SIGNATURE) {
-		return openAbstractFile(createAbstractFileFromComp(file));
-	} else if(signatureBE == IBOOTIM_SIG_UINT) {
-		return openAbstractFile(createAbstractFileFromIBootIM(file));
-	} else {
-		return file;
-	}
-}
-
-AbstractFile* duplicateAbstractFile(AbstractFile* file, AbstractFile* backing) {
-	uint32_t signatureBE;
-	uint32_t signatureLE;
-	AbstractFile* orig;
-	
-	file-&gt;seek(file, 0);
-	file-&gt;read(file, &amp;signatureBE, sizeof(signatureBE));
-	signatureLE = signatureBE;
-	FLIPENDIAN(signatureBE);
-	FLIPENDIANLE(signatureLE);
-	file-&gt;seek(file, 0);
-	
-	if(signatureBE == SIGNATURE_8900) {
-		orig = createAbstractFileFrom8900(file);
-		return duplicateAbstractFile(orig, duplicate8900File(orig, backing));
-	} else if(signatureLE == IMG2_SIGNATURE) {
-		orig = createAbstractFileFromImg2(file);
-		return duplicateAbstractFile(orig, duplicateImg2File(orig, backing));
-	} else if(signatureBE == COMP_SIGNATURE) {
-		orig = createAbstractFileFromComp(file);
-		return duplicateAbstractFile(orig, duplicateCompFile(orig, backing));
-	} else if(signatureBE == IBOOTIM_SIG_UINT) {
-		orig = createAbstractFileFromIBootIM(file);
-		return duplicateAbstractFile(orig, duplicateIBootIMFile(orig, backing));
-	} else {
-		file-&gt;close(file);
-		return backing;
-	}
-}
+#include &quot;../hfs/common.h&quot;
+#include &quot;8900.h&quot;
+#include &quot;img2.h&quot;
+#include &quot;lzssfile.h&quot;
+#include &quot;ibootim.h&quot;
+
+AbstractFile* openAbstractFile(AbstractFile* file) {
+	uint32_t signatureBE;
+	uint32_t signatureLE;
+	
+	file-&gt;seek(file, 0);
+	file-&gt;read(file, &amp;signatureBE, sizeof(signatureBE));
+	signatureLE = signatureBE;
+	FLIPENDIAN(signatureBE);
+	FLIPENDIANLE(signatureLE);
+	file-&gt;seek(file, 0);
+	
+	if(signatureBE == SIGNATURE_8900) {
+		return openAbstractFile(createAbstractFileFrom8900(file));
+	} else if(signatureLE == IMG2_SIGNATURE) {
+		return openAbstractFile(createAbstractFileFromImg2(file));
+	} else if(signatureBE == COMP_SIGNATURE) {
+		return openAbstractFile(createAbstractFileFromComp(file));
+	} else if(signatureBE == IBOOTIM_SIG_UINT) {
+		return openAbstractFile(createAbstractFileFromIBootIM(file));
+	} else {
+		return file;
+	}
+}
+
+AbstractFile* duplicateAbstractFile(AbstractFile* file, AbstractFile* backing) {
+	uint32_t signatureBE;
+	uint32_t signatureLE;
+	AbstractFile* orig;
+	
+	file-&gt;seek(file, 0);
+	file-&gt;read(file, &amp;signatureBE, sizeof(signatureBE));
+	signatureLE = signatureBE;
+	FLIPENDIAN(signatureBE);
+	FLIPENDIANLE(signatureLE);
+	file-&gt;seek(file, 0);
+	
+	if(signatureBE == SIGNATURE_8900) {
+		orig = createAbstractFileFrom8900(file);
+		return duplicateAbstractFile(orig, duplicate8900File(orig, backing));
+	} else if(signatureLE == IMG2_SIGNATURE) {
+		orig = createAbstractFileFromImg2(file);
+		return duplicateAbstractFile(orig, duplicateImg2File(orig, backing));
+	} else if(signatureBE == COMP_SIGNATURE) {
+		orig = createAbstractFileFromComp(file);
+		return duplicateAbstractFile(orig, duplicateCompFile(orig, backing));
+	} else if(signatureBE == IBOOTIM_SIG_UINT) {
+		orig = createAbstractFileFromIBootIM(file);
+		return duplicateAbstractFile(orig, duplicateIBootIMFile(orig, backing));
+	} else {
+		file-&gt;close(file);
+		return backing;
+	}
+}</diff>
      <filename>ipsw-patch/nor_files.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,19 +1,19 @@
 #ifndef NOR_FILES_H
 #define NOR_FILES_H
 
-#include &quot;abstractfile.h&quot;
-#include &quot;8900.h&quot;
-#include &quot;img2.h&quot;
-#include &quot;lzssfile.h&quot;
+#include &quot;abstractfile.h&quot;
+#include &quot;8900.h&quot;
+#include &quot;img2.h&quot;
+#include &quot;lzssfile.h&quot;
 
 #ifdef __cplusplus
 extern &quot;C&quot; {
-#endif
-	AbstractFile* openAbstractFile(AbstractFile* file);
+#endif
+	AbstractFile* openAbstractFile(AbstractFile* file);
 	AbstractFile* duplicateAbstractFile(AbstractFile* file, AbstractFile* backing);
 #ifdef __cplusplus
 }
 #endif
-
+
 #endif
 </diff>
      <filename>ipsw-patch/nor_files.h</filename>
    </modified>
    <modified>
      <diff>@@ -3,12 +3,12 @@
 
 #include &quot;abstractfile.h&quot;
 
-typedef struct OutputState {
-	char* fileName;
-	void* buffer;
-	size_t bufferSize;
-	struct OutputState* next;
-	struct OutputState* prev;
+typedef struct OutputState {
+	char* fileName;
+	void* buffer;
+	size_t bufferSize;
+	struct OutputState* next;
+	struct OutputState* prev;
 } OutputState;
 
 #ifdef __cplusplus
@@ -16,7 +16,7 @@ extern &quot;C&quot; {
 #endif
 	void addToOutput(OutputState** state, char* fileName, void* buffer, size_t bufferSize);
 	AbstractFile* getFileFromOutputState(OutputState** state, const char* fileName);
-	AbstractFile* getFileFromOutputStateForOverwrite(OutputState** state, const char* fileName);
+	AbstractFile* getFileFromOutputStateForOverwrite(OutputState** state, const char* fileName);
 	void writeOutput(OutputState** state, char* ipsw);
 	void releaseOutput(OutputState** state);
 	OutputState* loadZip(const char* ipsw);</diff>
      <filename>ipsw-patch/outputstate.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,494 +1,494 @@
-#include &lt;stdlib.h&gt;
-#include &lt;sys/types.h&gt;
-#include &lt;string.h&gt;
-#include &quot;common.h&quot;
-#include &quot;nor_files.h&quot;
-#include &quot;dmg.h&quot;
-#include &quot;filevault.h&quot;
-#include &quot;ibootim.h&quot;
-#include &quot;plist.h&quot;
-#include &quot;outputstate.h&quot;
-#include &quot;hfslib.h&quot;
-#include &quot;dmglib.h&quot;
-#include &quot;pwnutil.h&quot;
-
-char endianness;
-
-void TestByteOrder()
-{
-	short int word = 0x0001;
-	char *byte = (char *) &amp;word;
-	endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
-}
-
-int doPatch(StringValue* patchValue, StringValue* fileValue, const char* bundlePath, OutputState** state) {
-	char* patchPath;
-	size_t bufferSize;
-	void* buffer;
-	
-	AbstractFile* patchFile;
-	AbstractFile* file;
-	AbstractFile* out;
-
-	buffer = malloc(1);
-			
-	patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue-&gt;value) + 2));
-	strcpy(patchPath, bundlePath);
-	strcat(patchPath, &quot;/&quot;);
-	strcat(patchPath, patchValue-&gt;value);
-	
-	printf(&quot;%s (%s)... &quot;, fileValue-&gt;value, patchPath); fflush(stdout);
-	
-	patchFile = createAbstractFileFromFile(fopen(patchPath, &quot;rb&quot;));
-	
-	bufferSize = 0;
-
-	out = duplicateAbstractFile(getFileFromOutputState(state, fileValue-&gt;value), createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;bufferSize));
-	
-	file = openAbstractFile(getFileFromOutputState(state, fileValue-&gt;value));
-	
-	if(!patchFile || !file || !out) {
-		printf(&quot;file error\n&quot;);
-		exit(0);
-	}
-
-	if(patch(file, out, patchFile) != 0) {
-		printf(&quot;patch failed\n&quot;);
-		exit(0);
-	}
-	
-	printf(&quot;writing... &quot;); fflush(stdout);
-	
-/*	out = createAbstractFileFromFile(fopen(filePath, &quot;wb&quot;));
-	out-&gt;write(out, buffer, bufferSize);
-	out-&gt;close(out);*/
-
-	addToOutput(state, fileValue-&gt;value, buffer, bufferSize);
-
-	printf(&quot;success\n&quot;); fflush(stdout);
-
-	free(patchPath);
-}
-
-void doPatchInPlace(Volume* volume, char* filePath, char* patchPath) {
-	void* buffer;
-	void* buffer2;
-	size_t bufferSize;
-	size_t bufferSize2;
-	AbstractFile* bufferFile;
-	AbstractFile* patchFile;
-	AbstractFile* out;
-
-	
-	buffer = malloc(1);
-	bufferSize = 0;
-	bufferFile = createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;bufferSize);
-
-	printf(&quot;retrieving...&quot;); fflush(stdout);
-	get_hfs(volume, filePath, bufferFile);
-	
-	printf(&quot;patching...&quot;); fflush(stdout);
-				
-	patchFile = createAbstractFileFromFile(fopen(patchPath, &quot;rb&quot;));
-
-	buffer2 = malloc(1);
-	bufferSize2 = 0;
-	out = duplicateAbstractFile(createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;bufferSize), createAbstractFileFromMemoryFile((void**)&amp;buffer2, &amp;bufferSize2));
-	
-	if(!patchFile || !bufferFile || !out) {
-		printf(&quot;file error\n&quot;);
-		exit(0);
-	}
-
-	if(patch(bufferFile, out, patchFile) != 0) {
-		printf(&quot;patch failed\n&quot;);
-		exit(0);
-	}
-	
-	printf(&quot;writing... &quot;); fflush(stdout);
-	add_hfs(volume, createAbstractFileFromMemoryFile((void**)&amp;buffer2, &amp;bufferSize2), filePath);
-	free(buffer2);
-	free(buffer);
-
-	printf(&quot;success\n&quot;); fflush(stdout);
-}
-
-
-
-void fixupBootNeuterArgs(Volume* volume, char unlockBaseband, char selfDestruct, char use39, char use46) {
-	char bootNeuterPlist[] = &quot;/System/Library/LaunchDaemons/com.devteam.bootneuter.auto.plist&quot;;
-	AbstractFile* plistFile;
-	char* plist;
-	Dictionary* info;
-	size_t bufferSize;
-	ArrayValue* arguments;
-	
-	printf(&quot;fixing up BootNeuter arguments...\n&quot;);
-	
-	plist = malloc(1);
-	bufferSize = 0;
-	plistFile = createAbstractFileFromMemoryFile((void**)&amp;plist, &amp;bufferSize);
-	get_hfs(volume, bootNeuterPlist, plistFile);	
-	plistFile-&gt;close(plistFile);
-	info = createRoot(plist);
-	free(plist);
-
-	arguments = (ArrayValue*) getValueByKey(info, &quot;ProgramArguments&quot;);
-	addStringToArray(arguments, &quot;-autoMode&quot;);
-	addStringToArray(arguments, &quot;YES&quot;);
-	
-	if(unlockBaseband) {
-		addStringToArray(arguments, &quot;-unlockBaseband&quot;);
-		addStringToArray(arguments, &quot;YES&quot;);
-	}
-	
-	if(selfDestruct) {
-		addStringToArray(arguments, &quot;-selfDestruct&quot;);
-		addStringToArray(arguments, &quot;YES&quot;);
-	}
-	
-	if(use39) {
-		addStringToArray(arguments, &quot;-bootLoader&quot;);
-		addStringToArray(arguments, &quot;3.9&quot;);
-	} else if(use46) {
-		addStringToArray(arguments, &quot;-bootLoader&quot;);
-		addStringToArray(arguments, &quot;4.6&quot;);
-	}
-	
-	plist = getXmlFromRoot(info);
-	releaseDictionary(info);
-	
-	plistFile = createAbstractFileFromMemory((void**)&amp;plist, sizeof(char) * strlen(plist));
-	add_hfs(volume, plistFile, bootNeuterPlist);
-	free(plist);
-}
-
-int main(int argc, char* argv[]) {
-	TestByteOrder();
-	
-	Dictionary* info;
-	Dictionary* firmwarePatches;
-	Dictionary* patchDict;
-	ArrayValue* patchArray;
-	
-	void* buffer;
-	
-	StringValue* actionValue;
-	StringValue* pathValue;
-	
-	StringValue* fileValue;
-	
-	StringValue* patchValue;
-	char* patchPath;
-
-	char* rootFSPathInIPSW;
-	io_func* rootFS;
-	Volume* rootVolume;
-	size_t rootSize;
-	
-	char* ramdiskFSPathInIPSW;
-	io_func* ramdiskFS;
-	Volume* ramdiskVolume;
-	
-	int i;
-
-	OutputState* outputState;
-
-	char* bundlePath;
-	char* bundleRoot = &quot;FirmwareBundles/&quot;;
-
-	int mergePaths;
-	char* outputIPSW;
-
-	void* imageBuffer;	
-	size_t imageSize;
-
-	FILE* temp;
-
-	AbstractFile* bootloader39;
-	AbstractFile* bootloader46;
-	AbstractFile* applelogo;
-	AbstractFile* recoverymode;
-	
-	char unlockBaseband;
-	char selfDestruct;
-	char use39;
-	char use46;
-	char doBootNeuter;
-	char noBB;
-
-	applelogo = NULL;
-	recoverymode = NULL;
-	bootloader39 = NULL;
-	bootloader46 = NULL;
-
-	unlockBaseband = FALSE;
-	selfDestruct = FALSE;
-	use39 = FALSE;
-	use46 = FALSE;
-	doBootNeuter = FALSE;
-	noBB = FALSE;
-
-	if(argc &lt; 3) {
-		printf(&quot;usage %s &lt;input.ipsw&gt; &lt;target.ipsw&gt; [-b &lt;bootimage.png&gt;] [-r &lt;recoveryimage.png&gt;] [-e \&quot;&lt;action to exclude&gt;\&quot;] [-nobbupdate] [[-unlock] [-use39] [-use46] [-cleanup] -3 &lt;bootloader 3.9 file&gt; -4 &lt;bootloader 4.6 file&gt;] &lt;path/to/merge1&gt; &lt;path/to/merge2&gt;...\n&quot;, argv[0]);
-		return 0;
-	}
-
-	outputIPSW = argv[2];
-
-	info = parseIPSW(argv[1], bundleRoot, &amp;bundlePath, &amp;outputState);
-	if(info == NULL) {
-		printf(&quot;error: Could not load IPSW\n&quot;);
-		exit(1);
-	}
-
-	firmwarePatches = (Dictionary*)getValueByKey(info, &quot;FilesystemPatches&quot;);
-	for(i = 3; i &lt; argc; i++) {
-		if(argv[i][0] != '-') {
-			break;
-		}
-
-		if(strcmp(argv[i], &quot;-e&quot;) == 0) {
-			removeKey(firmwarePatches, argv[i + 1]);
-			i++;
-			continue;
-		}
-		
-		if(strcmp(argv[i], &quot;-unlock&quot;) == 0) {
-			unlockBaseband = TRUE;
-			continue;
-		}
-
-		if(strcmp(argv[i], &quot;-cleanup&quot;) == 0) {
-			selfDestruct = TRUE;
-			continue;
-		}
-
-		if(strcmp(argv[i], &quot;-nobbupdate&quot;) == 0) {
-			noBB = TRUE;
-			continue;
-		}
-		
-		if(strcmp(argv[i], &quot;-use39&quot;) == 0) {
-			if(use46) {
-				printf(&quot;error: select only one of -use39 and -use46\n&quot;);
-				exit(1);
-			}
-			use39 = TRUE;
-			continue;
-		}
-		
-		if(strcmp(argv[i], &quot;-use46&quot;) == 0) {
-			if(use39) {
-				printf(&quot;error: select only one of -use39 and -use46\n&quot;);
-				exit(1);
-			}
-			use46 = TRUE;
-			continue;
-		}
-
-		if(strcmp(argv[i], &quot;-b&quot;) == 0) {
-			applelogo = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
-			if(!applelogo) {
-				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
-				exit(1);
-			}
-			i++;
-			continue;
-		}
-
-		if(strcmp(argv[i], &quot;-r&quot;) == 0) {
-			recoverymode = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
-			if(!recoverymode) {
-				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
-				exit(1);
-			}
-			i++;
-			continue;
-		}
-
-		if(strcmp(argv[i], &quot;-3&quot;) == 0) {
-			bootloader39 = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
-			if(!bootloader39) {
-				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
-				exit(1);
-			}
-			i++;
-			continue;
-		}
-
-		if(strcmp(argv[i], &quot;-4&quot;) == 0) {
-			bootloader46 = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
-			if(!bootloader46) {
-				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
-				exit(1);
-			}
-			i++;
-			continue;
-		}
-	}
-	
-	if(use39 || use46 || unlockBaseband || selfDestruct || bootloader39 || bootloader46) {
-		if(noBB) {
-			printf(&quot;error: bbupdate must be enabled for bootneuter\n&quot;);
-			exit(1);
-		} else {
-			if(!(bootloader39) || !(bootloader46)) {
-				printf(&quot;error: you must specify both bootloader files.\n&quot;);
-				exit(1);
-			} else {
-				doBootNeuter = TRUE;
-			}
-		}
-	}
-
-	mergePaths = i;
-
-	
-	firmwarePatches = (Dictionary*)getValueByKey(info, &quot;FirmwarePatches&quot;);
-	patchDict = (Dictionary*) firmwarePatches-&gt;values;
-	while(patchDict != NULL) {
-		fileValue = (StringValue*) getValueByKey(patchDict, &quot;File&quot;);
-
-		if(strcmp(patchDict-&gt;dValue.key, &quot;Restore Ramdisk&quot;) == 0) {
-			ramdiskFSPathInIPSW = fileValue-&gt;value;
-		}
-
-		patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch2&quot;);
-		if(patchValue) {
-			if(!noBB) {
-				printf(&quot;%s: &quot;, patchDict-&gt;dValue.key); fflush(stdout);
-				doPatch(patchValue, fileValue, bundlePath, &amp;outputState);
-				patchDict = (Dictionary*) patchDict-&gt;dValue.next;
-				continue; /* skip over the normal Patch */
-			}
-		}
-
-		patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch&quot;);
-		if(patchValue) {
-			printf(&quot;%s: &quot;, patchDict-&gt;dValue.key); fflush(stdout);
-			doPatch(patchValue, fileValue, bundlePath, &amp;outputState);
-		}
-		
-		if(strcmp(patchDict-&gt;dValue.key, &quot;AppleLogo&quot;) == 0 &amp;&amp; applelogo) {
-			printf(&quot;replacing %s\n&quot;, fileValue-&gt;value); fflush(stdout);
-			ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&amp;outputState, fileValue-&gt;value), applelogo, &amp;imageSize)) != NULL, &quot;failed to use new image&quot;);
-			addToOutput(&amp;outputState, fileValue-&gt;value, imageBuffer, imageSize);
-		}
-
-		if(strcmp(patchDict-&gt;dValue.key, &quot;RecoveryMode&quot;) == 0 &amp;&amp; recoverymode) {
-			printf(&quot;replacing %s\n&quot;, fileValue-&gt;value); fflush(stdout);
-			ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&amp;outputState, fileValue-&gt;value), recoverymode, &amp;imageSize)) != NULL, &quot;failed to use new image&quot;);
-			addToOutput(&amp;outputState, fileValue-&gt;value, imageBuffer, imageSize);
-		}
-		
-		patchDict = (Dictionary*) patchDict-&gt;dValue.next;
-	}
-	
-	fileValue = (StringValue*) getValueByKey(info, &quot;RootFilesystem&quot;);
-	rootFSPathInIPSW = fileValue-&gt;value;
-		
-	sscanf(((StringValue*) getValueByKey(info, &quot;RootFilesystemResize&quot;))-&gt;value, &quot;%d&quot;, &amp;rootSize);
-	rootSize *= 1024 * 1024;
-	buffer = malloc(rootSize);
-
-	extractDmg(
-		createAbstractFileFromFileVault(getFileFromOutputState(&amp;outputState, rootFSPathInIPSW), ((StringValue*)getValueByKey(info, &quot;RootFilesystemKey&quot;))-&gt;value),
-		createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;rootSize), -1);
-
-	
-	rootFS = IOFuncFromAbstractFile(createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;rootSize));
-	rootVolume = openVolume(rootFS);
-	printf(&quot;Growing root: %d\n&quot;, rootSize); fflush(stdout);
-	grow_hfs(rootVolume, rootSize);
-	
-	firmwarePatches = (Dictionary*)getValueByKey(info, &quot;FilesystemPatches&quot;);
-	patchArray = (ArrayValue*) firmwarePatches-&gt;values;
-	while(patchArray != NULL) {
-		for(i = 0; i &lt; patchArray-&gt;size; i++) {
-			patchDict = (Dictionary*) patchArray-&gt;values[i];
-			fileValue = (StringValue*) getValueByKey(patchDict, &quot;File&quot;);
-					
-			actionValue = (StringValue*) getValueByKey(patchDict, &quot;Action&quot;); 
-			if(strcmp(actionValue-&gt;value, &quot;ReplaceKernel&quot;) == 0) {
-				pathValue = (StringValue*) getValueByKey(patchDict, &quot;Path&quot;);
-				printf(&quot;replacing kernel... %s -&gt; %s\n&quot;, fileValue-&gt;value, pathValue-&gt;value); fflush(stdout);
-				add_hfs(rootVolume, getFileFromOutputState(&amp;outputState, fileValue-&gt;value), pathValue-&gt;value);
-			} if(strcmp(actionValue-&gt;value, &quot;Patch&quot;) == 0) {
-				patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch&quot;);
-				patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue-&gt;value) + 2));
-				strcpy(patchPath, bundlePath);
-				strcat(patchPath, &quot;/&quot;);
-				strcat(patchPath, patchValue-&gt;value);
-				
-				printf(&quot;patching %s (%s)... &quot;, fileValue-&gt;value, patchPath);
-				doPatchInPlace(rootVolume, fileValue-&gt;value, patchPath);
-				free(patchPath);
-			}
-		}
-		
-		patchArray = (ArrayValue*) patchArray-&gt;dValue.next;
-	}
-	
-	for(mergePaths; mergePaths &lt; argc; mergePaths++) {
-		addall_hfs(rootVolume, argv[mergePaths], &quot;/&quot;);
-	}
-	
-	if(doBootNeuter) {
-		ramdiskFS = IOFuncFromAbstractFile(openAbstractFile(getFileFromOutputState(&amp;outputState, ramdiskFSPathInIPSW)));
-		ramdiskVolume = openVolume(ramdiskFS);
-		firmwarePatches = (Dictionary*)getValueByKey(info, &quot;BasebandPatches&quot;);
-		if(firmwarePatches != NULL) {
-			patchDict = (Dictionary*) firmwarePatches-&gt;values;
-			while(patchDict != NULL) {
-				pathValue = (StringValue*) getValueByKey(patchDict, &quot;Path&quot;);
-
-				fileValue = (StringValue*) getValueByKey(patchDict, &quot;File&quot;);		
-				if(fileValue) {
-					printf(&quot;copying %s -&gt; %s... &quot;, fileValue-&gt;value, pathValue-&gt;value); fflush(stdout);
-					if(copyAcrossVolumes(ramdiskVolume, rootVolume, fileValue-&gt;value, pathValue-&gt;value)) {
-						patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch&quot;);
-						if(patchValue) {
-							patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue-&gt;value) + 2));
-							strcpy(patchPath, bundlePath);
-							strcat(patchPath, &quot;/&quot;);
-							strcat(patchPath, patchValue-&gt;value);
-							printf(&quot;patching %s (%s)... &quot;, pathValue-&gt;value, patchPath); fflush(stdout);
-							doPatchInPlace(rootVolume, pathValue-&gt;value, patchPath);
-							free(patchPath);
-						}
-					}
-				}
-
-				if(strcmp(patchDict-&gt;dValue.key, &quot;Bootloader 3.9&quot;) == 0 &amp;&amp; bootloader39 != NULL) {
-					add_hfs(rootVolume, bootloader39, pathValue-&gt;value);
-				}
-
-				if(strcmp(patchDict-&gt;dValue.key, &quot;Bootloader 4.6&quot;) == 0 &amp;&amp; bootloader46 != NULL) {
-					add_hfs(rootVolume, bootloader46, pathValue-&gt;value);
-				}
-				
-				patchDict = (Dictionary*) patchDict-&gt;dValue.next;
-			}
-		}
-		closeVolume(ramdiskVolume);
-		CLOSE(ramdiskFS);
-	
-		fixupBootNeuterArgs(rootVolume, unlockBaseband, selfDestruct, use39, use46);
-	}
-
-	closeVolume(rootVolume);
-	CLOSE(rootFS);
-
-	buildDmg(createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;rootSize), getFileFromOutputStateForOverwrite(&amp;outputState, rootFSPathInIPSW));
-	free(buffer);
-
-
-	writeOutput(&amp;outputState, outputIPSW);
-	
-	releaseDictionary(info);
-
-	free(bundlePath);
-	
-	return 0;
-}
+#include &lt;stdlib.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;string.h&gt;
+#include &quot;common.h&quot;
+#include &quot;nor_files.h&quot;
+#include &quot;dmg.h&quot;
+#include &quot;filevault.h&quot;
+#include &quot;ibootim.h&quot;
+#include &quot;plist.h&quot;
+#include &quot;outputstate.h&quot;
+#include &quot;hfslib.h&quot;
+#include &quot;dmglib.h&quot;
+#include &quot;pwnutil.h&quot;
+
+char endianness;
+
+void TestByteOrder()
+{
+	short int word = 0x0001;
+	char *byte = (char *) &amp;word;
+	endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
+}
+
+int doPatch(StringValue* patchValue, StringValue* fileValue, const char* bundlePath, OutputState** state) {
+	char* patchPath;
+	size_t bufferSize;
+	void* buffer;
+	
+	AbstractFile* patchFile;
+	AbstractFile* file;
+	AbstractFile* out;
+
+	buffer = malloc(1);
+			
+	patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue-&gt;value) + 2));
+	strcpy(patchPath, bundlePath);
+	strcat(patchPath, &quot;/&quot;);
+	strcat(patchPath, patchValue-&gt;value);
+	
+	printf(&quot;%s (%s)... &quot;, fileValue-&gt;value, patchPath); fflush(stdout);
+	
+	patchFile = createAbstractFileFromFile(fopen(patchPath, &quot;rb&quot;));
+	
+	bufferSize = 0;
+
+	out = duplicateAbstractFile(getFileFromOutputState(state, fileValue-&gt;value), createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;bufferSize));
+	
+	file = openAbstractFile(getFileFromOutputState(state, fileValue-&gt;value));
+	
+	if(!patchFile || !file || !out) {
+		printf(&quot;file error\n&quot;);
+		exit(0);
+	}
+
+	if(patch(file, out, patchFile) != 0) {
+		printf(&quot;patch failed\n&quot;);
+		exit(0);
+	}
+	
+	printf(&quot;writing... &quot;); fflush(stdout);
+	
+/*	out = createAbstractFileFromFile(fopen(filePath, &quot;wb&quot;));
+	out-&gt;write(out, buffer, bufferSize);
+	out-&gt;close(out);*/
+
+	addToOutput(state, fileValue-&gt;value, buffer, bufferSize);
+
+	printf(&quot;success\n&quot;); fflush(stdout);
+
+	free(patchPath);
+}
+
+void doPatchInPlace(Volume* volume, char* filePath, char* patchPath) {
+	void* buffer;
+	void* buffer2;
+	size_t bufferSize;
+	size_t bufferSize2;
+	AbstractFile* bufferFile;
+	AbstractFile* patchFile;
+	AbstractFile* out;
+
+	
+	buffer = malloc(1);
+	bufferSize = 0;
+	bufferFile = createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;bufferSize);
+
+	printf(&quot;retrieving...&quot;); fflush(stdout);
+	get_hfs(volume, filePath, bufferFile);
+	
+	printf(&quot;patching...&quot;); fflush(stdout);
+				
+	patchFile = createAbstractFileFromFile(fopen(patchPath, &quot;rb&quot;));
+
+	buffer2 = malloc(1);
+	bufferSize2 = 0;
+	out = duplicateAbstractFile(createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;bufferSize), createAbstractFileFromMemoryFile((void**)&amp;buffer2, &amp;bufferSize2));
+	
+	if(!patchFile || !bufferFile || !out) {
+		printf(&quot;file error\n&quot;);
+		exit(0);
+	}
+
+	if(patch(bufferFile, out, patchFile) != 0) {
+		printf(&quot;patch failed\n&quot;);
+		exit(0);
+	}
+	
+	printf(&quot;writing... &quot;); fflush(stdout);
+	add_hfs(volume, createAbstractFileFromMemoryFile((void**)&amp;buffer2, &amp;bufferSize2), filePath);
+	free(buffer2);
+	free(buffer);
+
+	printf(&quot;success\n&quot;); fflush(stdout);
+}
+
+
+
+void fixupBootNeuterArgs(Volume* volume, char unlockBaseband, char selfDestruct, char use39, char use46) {
+	char bootNeuterPlist[] = &quot;/System/Library/LaunchDaemons/com.devteam.bootneuter.auto.plist&quot;;
+	AbstractFile* plistFile;
+	char* plist;
+	Dictionary* info;
+	size_t bufferSize;
+	ArrayValue* arguments;
+	
+	printf(&quot;fixing up BootNeuter arguments...\n&quot;);
+	
+	plist = malloc(1);
+	bufferSize = 0;
+	plistFile = createAbstractFileFromMemoryFile((void**)&amp;plist, &amp;bufferSize);
+	get_hfs(volume, bootNeuterPlist, plistFile);	
+	plistFile-&gt;close(plistFile);
+	info = createRoot(plist);
+	free(plist);
+
+	arguments = (ArrayValue*) getValueByKey(info, &quot;ProgramArguments&quot;);
+	addStringToArray(arguments, &quot;-autoMode&quot;);
+	addStringToArray(arguments, &quot;YES&quot;);
+	
+	if(unlockBaseband) {
+		addStringToArray(arguments, &quot;-unlockBaseband&quot;);
+		addStringToArray(arguments, &quot;YES&quot;);
+	}
+	
+	if(selfDestruct) {
+		addStringToArray(arguments, &quot;-selfDestruct&quot;);
+		addStringToArray(arguments, &quot;YES&quot;);
+	}
+	
+	if(use39) {
+		addStringToArray(arguments, &quot;-bootLoader&quot;);
+		addStringToArray(arguments, &quot;3.9&quot;);
+	} else if(use46) {
+		addStringToArray(arguments, &quot;-bootLoader&quot;);
+		addStringToArray(arguments, &quot;4.6&quot;);
+	}
+	
+	plist = getXmlFromRoot(info);
+	releaseDictionary(info);
+	
+	plistFile = createAbstractFileFromMemory((void**)&amp;plist, sizeof(char) * strlen(plist));
+	add_hfs(volume, plistFile, bootNeuterPlist);
+	free(plist);
+}
+
+int main(int argc, char* argv[]) {
+	TestByteOrder();
+	
+	Dictionary* info;
+	Dictionary* firmwarePatches;
+	Dictionary* patchDict;
+	ArrayValue* patchArray;
+	
+	void* buffer;
+	
+	StringValue* actionValue;
+	StringValue* pathValue;
+	
+	StringValue* fileValue;
+	
+	StringValue* patchValue;
+	char* patchPath;
+
+	char* rootFSPathInIPSW;
+	io_func* rootFS;
+	Volume* rootVolume;
+	size_t rootSize;
+	
+	char* ramdiskFSPathInIPSW;
+	io_func* ramdiskFS;
+	Volume* ramdiskVolume;
+	
+	int i;
+
+	OutputState* outputState;
+
+	char* bundlePath;
+	char* bundleRoot = &quot;FirmwareBundles/&quot;;
+
+	int mergePaths;
+	char* outputIPSW;
+
+	void* imageBuffer;	
+	size_t imageSize;
+
+	FILE* temp;
+
+	AbstractFile* bootloader39;
+	AbstractFile* bootloader46;
+	AbstractFile* applelogo;
+	AbstractFile* recoverymode;
+	
+	char unlockBaseband;
+	char selfDestruct;
+	char use39;
+	char use46;
+	char doBootNeuter;
+	char noBB;
+
+	applelogo = NULL;
+	recoverymode = NULL;
+	bootloader39 = NULL;
+	bootloader46 = NULL;
+
+	unlockBaseband = FALSE;
+	selfDestruct = FALSE;
+	use39 = FALSE;
+	use46 = FALSE;
+	doBootNeuter = FALSE;
+	noBB = FALSE;
+
+	if(argc &lt; 3) {
+		printf(&quot;usage %s &lt;input.ipsw&gt; &lt;target.ipsw&gt; [-b &lt;bootimage.png&gt;] [-r &lt;recoveryimage.png&gt;] [-e \&quot;&lt;action to exclude&gt;\&quot;] [-nobbupdate] [[-unlock] [-use39] [-use46] [-cleanup] -3 &lt;bootloader 3.9 file&gt; -4 &lt;bootloader 4.6 file&gt;] &lt;path/to/merge1&gt; &lt;path/to/merge2&gt;...\n&quot;, argv[0]);
+		return 0;
+	}
+
+	outputIPSW = argv[2];
+
+	info = parseIPSW(argv[1], bundleRoot, &amp;bundlePath, &amp;outputState);
+	if(info == NULL) {
+		printf(&quot;error: Could not load IPSW\n&quot;);
+		exit(1);
+	}
+
+	firmwarePatches = (Dictionary*)getValueByKey(info, &quot;FilesystemPatches&quot;);
+	for(i = 3; i &lt; argc; i++) {
+		if(argv[i][0] != '-') {
+			break;
+		}
+
+		if(strcmp(argv[i], &quot;-e&quot;) == 0) {
+			removeKey(firmwarePatches, argv[i + 1]);
+			i++;
+			continue;
+		}
+		
+		if(strcmp(argv[i], &quot;-unlock&quot;) == 0) {
+			unlockBaseband = TRUE;
+			continue;
+		}
+
+		if(strcmp(argv[i], &quot;-cleanup&quot;) == 0) {
+			selfDestruct = TRUE;
+			continue;
+		}
+
+		if(strcmp(argv[i], &quot;-nobbupdate&quot;) == 0) {
+			noBB = TRUE;
+			continue;
+		}
+		
+		if(strcmp(argv[i], &quot;-use39&quot;) == 0) {
+			if(use46) {
+				printf(&quot;error: select only one of -use39 and -use46\n&quot;);
+				exit(1);
+			}
+			use39 = TRUE;
+			continue;
+		}
+		
+		if(strcmp(argv[i], &quot;-use46&quot;) == 0) {
+			if(use39) {
+				printf(&quot;error: select only one of -use39 and -use46\n&quot;);
+				exit(1);
+			}
+			use46 = TRUE;
+			continue;
+		}
+
+		if(strcmp(argv[i], &quot;-b&quot;) == 0) {
+			applelogo = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
+			if(!applelogo) {
+				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
+				exit(1);
+			}
+			i++;
+			continue;
+		}
+
+		if(strcmp(argv[i], &quot;-r&quot;) == 0) {
+			recoverymode = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
+			if(!recoverymode) {
+				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
+				exit(1);
+			}
+			i++;
+			continue;
+		}
+
+		if(strcmp(argv[i], &quot;-3&quot;) == 0) {
+			bootloader39 = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
+			if(!bootloader39) {
+				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
+				exit(1);
+			}
+			i++;
+			continue;
+		}
+
+		if(strcmp(argv[i], &quot;-4&quot;) == 0) {
+			bootloader46 = createAbstractFileFromFile(fopen(argv[i + 1], &quot;rb&quot;));
+			if(!bootloader46) {
+				printf(&quot;cannot open %s\n&quot;, argv[i + 1]);
+				exit(1);
+			}
+			i++;
+			continue;
+		}
+	}
+	
+	if(use39 || use46 || unlockBaseband || selfDestruct || bootloader39 || bootloader46) {
+		if(noBB) {
+			printf(&quot;error: bbupdate must be enabled for bootneuter\n&quot;);
+			exit(1);
+		} else {
+			if(!(bootloader39) || !(bootloader46)) {
+				printf(&quot;error: you must specify both bootloader files.\n&quot;);
+				exit(1);
+			} else {
+				doBootNeuter = TRUE;
+			}
+		}
+	}
+
+	mergePaths = i;
+
+	
+	firmwarePatches = (Dictionary*)getValueByKey(info, &quot;FirmwarePatches&quot;);
+	patchDict = (Dictionary*) firmwarePatches-&gt;values;
+	while(patchDict != NULL) {
+		fileValue = (StringValue*) getValueByKey(patchDict, &quot;File&quot;);
+
+		if(strcmp(patchDict-&gt;dValue.key, &quot;Restore Ramdisk&quot;) == 0) {
+			ramdiskFSPathInIPSW = fileValue-&gt;value;
+		}
+
+		patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch2&quot;);
+		if(patchValue) {
+			if(!noBB) {
+				printf(&quot;%s: &quot;, patchDict-&gt;dValue.key); fflush(stdout);
+				doPatch(patchValue, fileValue, bundlePath, &amp;outputState);
+				patchDict = (Dictionary*) patchDict-&gt;dValue.next;
+				continue; /* skip over the normal Patch */
+			}
+		}
+
+		patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch&quot;);
+		if(patchValue) {
+			printf(&quot;%s: &quot;, patchDict-&gt;dValue.key); fflush(stdout);
+			doPatch(patchValue, fileValue, bundlePath, &amp;outputState);
+		}
+		
+		if(strcmp(patchDict-&gt;dValue.key, &quot;AppleLogo&quot;) == 0 &amp;&amp; applelogo) {
+			printf(&quot;replacing %s\n&quot;, fileValue-&gt;value); fflush(stdout);
+			ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&amp;outputState, fileValue-&gt;value), applelogo, &amp;imageSize)) != NULL, &quot;failed to use new image&quot;);
+			addToOutput(&amp;outputState, fileValue-&gt;value, imageBuffer, imageSize);
+		}
+
+		if(strcmp(patchDict-&gt;dValue.key, &quot;RecoveryMode&quot;) == 0 &amp;&amp; recoverymode) {
+			printf(&quot;replacing %s\n&quot;, fileValue-&gt;value); fflush(stdout);
+			ASSERT((imageBuffer = replaceBootImage(getFileFromOutputState(&amp;outputState, fileValue-&gt;value), recoverymode, &amp;imageSize)) != NULL, &quot;failed to use new image&quot;);
+			addToOutput(&amp;outputState, fileValue-&gt;value, imageBuffer, imageSize);
+		}
+		
+		patchDict = (Dictionary*) patchDict-&gt;dValue.next;
+	}
+	
+	fileValue = (StringValue*) getValueByKey(info, &quot;RootFilesystem&quot;);
+	rootFSPathInIPSW = fileValue-&gt;value;
+		
+	sscanf(((StringValue*) getValueByKey(info, &quot;RootFilesystemResize&quot;))-&gt;value, &quot;%d&quot;, &amp;rootSize);
+	rootSize *= 1024 * 1024;
+	buffer = malloc(rootSize);
+
+	extractDmg(
+		createAbstractFileFromFileVault(getFileFromOutputState(&amp;outputState, rootFSPathInIPSW), ((StringValue*)getValueByKey(info, &quot;RootFilesystemKey&quot;))-&gt;value),
+		createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;rootSize), -1);
+
+	
+	rootFS = IOFuncFromAbstractFile(createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;rootSize));
+	rootVolume = openVolume(rootFS);
+	printf(&quot;Growing root: %d\n&quot;, rootSize); fflush(stdout);
+	grow_hfs(rootVolume, rootSize);
+	
+	firmwarePatches = (Dictionary*)getValueByKey(info, &quot;FilesystemPatches&quot;);
+	patchArray = (ArrayValue*) firmwarePatches-&gt;values;
+	while(patchArray != NULL) {
+		for(i = 0; i &lt; patchArray-&gt;size; i++) {
+			patchDict = (Dictionary*) patchArray-&gt;values[i];
+			fileValue = (StringValue*) getValueByKey(patchDict, &quot;File&quot;);
+					
+			actionValue = (StringValue*) getValueByKey(patchDict, &quot;Action&quot;); 
+			if(strcmp(actionValue-&gt;value, &quot;ReplaceKernel&quot;) == 0) {
+				pathValue = (StringValue*) getValueByKey(patchDict, &quot;Path&quot;);
+				printf(&quot;replacing kernel... %s -&gt; %s\n&quot;, fileValue-&gt;value, pathValue-&gt;value); fflush(stdout);
+				add_hfs(rootVolume, getFileFromOutputState(&amp;outputState, fileValue-&gt;value), pathValue-&gt;value);
+			} if(strcmp(actionValue-&gt;value, &quot;Patch&quot;) == 0) {
+				patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch&quot;);
+				patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue-&gt;value) + 2));
+				strcpy(patchPath, bundlePath);
+				strcat(patchPath, &quot;/&quot;);
+				strcat(patchPath, patchValue-&gt;value);
+				
+				printf(&quot;patching %s (%s)... &quot;, fileValue-&gt;value, patchPath);
+				doPatchInPlace(rootVolume, fileValue-&gt;value, patchPath);
+				free(patchPath);
+			}
+		}
+		
+		patchArray = (ArrayValue*) patchArray-&gt;dValue.next;
+	}
+	
+	for(mergePaths; mergePaths &lt; argc; mergePaths++) {
+		addall_hfs(rootVolume, argv[mergePaths], &quot;/&quot;);
+	}
+	
+	if(doBootNeuter) {
+		ramdiskFS = IOFuncFromAbstractFile(openAbstractFile(getFileFromOutputState(&amp;outputState, ramdiskFSPathInIPSW)));
+		ramdiskVolume = openVolume(ramdiskFS);
+		firmwarePatches = (Dictionary*)getValueByKey(info, &quot;BasebandPatches&quot;);
+		if(firmwarePatches != NULL) {
+			patchDict = (Dictionary*) firmwarePatches-&gt;values;
+			while(patchDict != NULL) {
+				pathValue = (StringValue*) getValueByKey(patchDict, &quot;Path&quot;);
+
+				fileValue = (StringValue*) getValueByKey(patchDict, &quot;File&quot;);		
+				if(fileValue) {
+					printf(&quot;copying %s -&gt; %s... &quot;, fileValue-&gt;value, pathValue-&gt;value); fflush(stdout);
+					if(copyAcrossVolumes(ramdiskVolume, rootVolume, fileValue-&gt;value, pathValue-&gt;value)) {
+						patchValue = (StringValue*) getValueByKey(patchDict, &quot;Patch&quot;);
+						if(patchValue) {
+							patchPath = malloc(sizeof(char) * (strlen(bundlePath) + strlen(patchValue-&gt;value) + 2));
+							strcpy(patchPath, bundlePath);
+							strcat(patchPath, &quot;/&quot;);
+							strcat(patchPath, patchValue-&gt;value);
+							printf(&quot;patching %s (%s)... &quot;, pathValue-&gt;value, patchPath); fflush(stdout);
+							doPatchInPlace(rootVolume, pathValue-&gt;value, patchPath);
+							free(patchPath);
+						}
+					}
+				}
+
+				if(strcmp(patchDict-&gt;dValue.key, &quot;Bootloader 3.9&quot;) == 0 &amp;&amp; bootloader39 != NULL) {
+					add_hfs(rootVolume, bootloader39, pathValue-&gt;value);
+				}
+
+				if(strcmp(patchDict-&gt;dValue.key, &quot;Bootloader 4.6&quot;) == 0 &amp;&amp; bootloader46 != NULL) {
+					add_hfs(rootVolume, bootloader46, pathValue-&gt;value);
+				}
+				
+				patchDict = (Dictionary*) patchDict-&gt;dValue.next;
+			}
+		}
+		closeVolume(ramdiskVolume);
+		CLOSE(ramdiskFS);
+	
+		fixupBootNeuterArgs(rootVolume, unlockBaseband, selfDestruct, use39, use46);
+	}
+
+	closeVolume(rootVolume);
+	CLOSE(rootFS);
+
+	buildDmg(createAbstractFileFromMemoryFile((void**)&amp;buffer, &amp;rootSize), getFileFromOutputStateForOverwrite(&amp;outputState, rootFSPathInIPSW));
+	free(buffer);
+
+
+	writeOutput(&amp;outputState, outputIPSW);
+	
+	releaseDictionary(info);
+
+	free(bundlePath);
+	
+	return 0;
+}</diff>
      <filename>ipsw-patch/patch.c</filename>
    </modified>
    <modified>
      <diff>@@ -2,499 +2,499 @@
 #include &lt;string.h&gt;
 #include &quot;plist.h&quot;
 #include &quot;common.h&quot;
-
-Tag* getNextTag(char** xmlPtr) {
-	char* xml;
-	char* tagEnd;
-	char* curChar;
-	Tag* tag;
-	int tagDepth;
-	
-	xml = *xmlPtr;
-	xml = strchr(xml, '&lt;');
-	
-	if(xml == NULL) {
-		return NULL;
-	}
-	
-	tag = (Tag*) malloc(sizeof(Tag));	
-
-	tagEnd = strchr(xml, '&gt;');
-	tag-&gt;name = (char*) malloc(sizeof(char) * (tagEnd -  xml));
-	memcpy(tag-&gt;name, xml + 1, tagEnd -  xml - 1);
-	tag-&gt;name[tagEnd -  xml - 1] = '\0';
-	if((tagEnd -  xml - 1) &gt; 0) {
-		if(tag-&gt;name[tagEnd -  xml - 2] == '/') {
-			tag-&gt;xml = malloc(sizeof(char) * 1);
-			tag-&gt;xml[0] = '\0';
-			*xmlPtr = tagEnd + 1;
-			return tag;
-		}
-	}
-	
-	xml = tagEnd;
-	curChar = xml;
-	tagDepth = 1;
-	while(*curChar != '\0') {
-		if(*curChar == '&lt;') {
-			if(*(curChar + 1) == '/') {
-				tagDepth--;
-				if(tagDepth == 0) {
-					break;
-				}
-			} else {
-				tagDepth++;
-			}
-		} else if(*curChar == '&gt;') {
-			if(*(curChar - 1) == '/') {
-				tagDepth--;
-			}
-		}
-		curChar++;
-	}
-	
-	tag-&gt;xml = (char*) malloc(sizeof(char) * (curChar -  xml));
-	memcpy(tag-&gt;xml, xml + 1, curChar -  xml - 1);
-	tag-&gt;xml[curChar -  xml - 1] = '\0';
-	
-	*xmlPtr = strchr(curChar, '&gt;') + 1;
-	
-	return tag;
-}
-
-void releaseTag(Tag* tag) {
-	free(tag-&gt;name);
-	free(tag-&gt;xml);
-	free(tag);
-}
-
-void releaseArray(ArrayValue* myself) {
-	int i;
-	
-	free(myself-&gt;dValue.key);
-	for(i = 0; i &lt; myself-&gt;size; i++) {
-		switch(myself-&gt;values[i]-&gt;type) {
-			case DictionaryType:
-				releaseDictionary((Dictionary*) myself-&gt;values[i]);
-				break;
-			case ArrayType:
-				releaseArray((ArrayValue*) myself-&gt;values[i]);
-				break;
-			case StringType:
-				free(((StringValue*)(myself-&gt;values[i]))-&gt;value);
-			case BoolType:
-			case IntegerType:
-				free(myself-&gt;values[i]-&gt;key);
-				free(myself-&gt;values[i]);
-				break;
-		}
-	}
-	free(myself-&gt;values);
-	free(myself);
-}
-
-void releaseDictionary(Dictionary* myself) {
-	DictValue* next;
-	DictValue* toRelease;
-	
-	free(myself-&gt;dValue.key);
-	next = myself-&gt;values;
-	while(next != NULL) {
-		toRelease = next;
-		next = next-&gt;next;
-		
-		switch(toRelease-&gt;type) {
-			case DictionaryType:
-				releaseDictionary((Dictionary*) toRelease);
-				break;
-			case ArrayType:
-				releaseArray((ArrayValue*) toRelease);
-				break;
-			case StringType:
-				free(((StringValue*)(toRelease))-&gt;value);
-			case IntegerType:
-			case BoolType:
-				free(toRelease-&gt;key);
-				free(toRelease);
-				break;
-		}
-	}
-	free(myself);
-}
-void createArray(ArrayValue* myself, char* xml) {
-	Tag* valueTag;
-	DictValue* curValue;
-	
-	int i;
-	
-	myself-&gt;values = NULL;
-	myself-&gt;size = 0;
-	while(*xml != '\0') {
-		valueTag = getNextTag(&amp;xml);
-		if(valueTag == NULL)  {
-			break;
-		}
-		
-		myself-&gt;size++;
-		myself-&gt;values = realloc(myself-&gt;values, sizeof(DictValue*) * myself-&gt;size);
-		curValue = (DictValue*) malloc(sizeof(DictValue));
-
-		curValue-&gt;key = (char*) malloc(sizeof(&quot;arraykey&quot;));
-		strcpy(curValue-&gt;key, &quot;arraykey&quot;);
-		curValue-&gt;next = NULL;
-
-		if(strcmp(valueTag-&gt;name, &quot;dict&quot;) == 0) {
-			curValue-&gt;type = DictionaryType;
-			curValue = (DictValue*) realloc(curValue, sizeof(Dictionary));
-			createDictionary((Dictionary*) curValue, valueTag-&gt;xml);
-		} else if(strcmp(valueTag-&gt;name, &quot;string&quot;) == 0) {
-			curValue-&gt;type = StringType;
-			curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
-			((StringValue*)curValue)-&gt;value = (char*) malloc(sizeof(char) * (strlen(valueTag-&gt;xml) + 1));
-			strcpy(((StringValue*)curValue)-&gt;value, valueTag-&gt;xml);
-		} else if(strcmp(valueTag-&gt;name, &quot;integer&quot;) == 0) {
-			curValue-&gt;type = IntegerType;
-			curValue = (DictValue*) realloc(curValue, sizeof(IntegerValue));
-			sscanf(valueTag-&gt;xml, &quot;%d&quot;, &amp;(((IntegerValue*)curValue)-&gt;value));
-		} else if(strcmp(valueTag-&gt;name, &quot;array&quot;) == 0) {
-			curValue-&gt;type = ArrayType;
-			curValue = (DictValue*) realloc(curValue, sizeof(ArrayValue));
-			createArray((ArrayValue*) curValue, valueTag-&gt;xml);
-		} else if(strcmp(valueTag-&gt;name, &quot;true/&quot;) == 0) {
-			curValue-&gt;type = BoolType;
-			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
-			((BoolValue*)curValue)-&gt;value = TRUE;
-		} else if(strcmp(valueTag-&gt;name, &quot;false/&quot;) == 0) {
-			curValue-&gt;type = BoolType;
-			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
-			((BoolValue*)curValue)-&gt;value = FALSE;
-		}
-		
-		myself-&gt;values[myself-&gt;size - 1] = curValue;
-		
-		releaseTag(valueTag);
-	}
-}
-
-void removeKey(Dictionary* dict, char* key) {
-	DictValue* next;
-	DictValue* toRelease;
-	next = dict-&gt;values;
-	while(next != NULL) {
-		if(strcmp(next-&gt;key, key) == 0) {
-			toRelease = next;
-			if(toRelease-&gt;prev) {
-				toRelease-&gt;prev-&gt;next = toRelease-&gt;next;
-			} else {
-				dict-&gt;values = toRelease-&gt;next;
-			}
-			if(toRelease-&gt;next) {
-				toRelease-&gt;next-&gt;prev = toRelease-&gt;prev;
-			}
-			switch(toRelease-&gt;type) {
-				case DictionaryType:
-					releaseDictionary((Dictionary*) toRelease);
-					break;
-				case ArrayType:
-					releaseArray((ArrayValue*) toRelease);
-					break;
-				case StringType:
-					free(((StringValue*)(toRelease))-&gt;value);
-				case IntegerType:
-				case BoolType:
-					free(toRelease-&gt;key);
-					free(toRelease);
-					break;
-			}
-			return;
-		}
-		next = next-&gt;next;
-	}
-
-	return;
-}
-
-void createDictionary(Dictionary* myself, char* xml) {
-	Tag* keyTag;
-	Tag* valueTag;
-	DictValue* curValue;
-	DictValue* lastValue;
-	
-	curValue = NULL;
-	lastValue = NULL;
-	
-	while(*xml != '\0') {
-		keyTag = getNextTag(&amp;xml);
-		if(keyTag == NULL)  {
-			break;
-		}
-		
-		if(strcmp(keyTag-&gt;name, &quot;key&quot;) != 0) {
-			releaseTag(keyTag);
-			continue;
-		}
-		
-		curValue = (DictValue*) malloc(sizeof(DictValue));
-		curValue-&gt;key = (char*) malloc(sizeof(char) * (strlen(keyTag-&gt;xml) + 1));
-		strcpy(curValue-&gt;key, keyTag-&gt;xml);
-		curValue-&gt;next = NULL;
-		releaseTag(keyTag);
-		
-		
-		valueTag = getNextTag(&amp;xml);
-		if(valueTag == NULL)  {
-			break;
-		}
-		
-		if(strcmp(valueTag-&gt;name, &quot;dict&quot;) == 0) {
-			curValue-&gt;type = DictionaryType;
-			curValue = (DictValue*) realloc(curValue, sizeof(Dictionary));
-			createDictionary((Dictionary*) curValue, valueTag-&gt;xml);
-		} else if(strcmp(valueTag-&gt;name, &quot;string&quot;) == 0) {
-			curValue-&gt;type = StringType;
-			curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
-			((StringValue*)curValue)-&gt;value = (char*) malloc(sizeof(char) * (strlen(valueTag-&gt;xml) + 1));
-			strcpy(((StringValue*)curValue)-&gt;value, valueTag-&gt;xml);
-		} else if(strcmp(valueTag-&gt;name, &quot;integer&quot;) == 0) {
-			curValue-&gt;type = IntegerType;
-			curValue = (DictValue*) realloc(curValue, sizeof(IntegerValue));
-			sscanf(valueTag-&gt;xml, &quot;%d&quot;, &amp;(((IntegerValue*)curValue)-&gt;value));
-		} else if(strcmp(valueTag-&gt;name, &quot;array&quot;) == 0) {
-			curValue-&gt;type = ArrayType;
-			curValue = (DictValue*) realloc(curValue, sizeof(ArrayValue));
-			createArray((ArrayValue*) curValue, valueTag-&gt;xml);
-		} else if(strcmp(valueTag-&gt;name, &quot;true/&quot;) == 0) {
-			curValue-&gt;type = BoolType;
-			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
-			((BoolValue*)curValue)-&gt;value = TRUE;
-		} else if(strcmp(valueTag-&gt;name, &quot;false/&quot;) == 0) {
-			curValue-&gt;type = BoolType;
-			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
-			((BoolValue*)curValue)-&gt;value = FALSE;
-		}
-
-		curValue-&gt;prev = lastValue;
-		if(lastValue == NULL) {
-			myself-&gt;values = curValue;
-		} else {
-			lastValue-&gt;next = curValue;
-		}
-		
-		lastValue = curValue;
-		
-		releaseTag(valueTag);
-	}
-}
-
-char* getXmlFromArrayValue(ArrayValue* myself, int tabsCount) {
-	char tabs[100];
-	char buffer[4096];
-	char* toReturn;
-	char* ret;
-	size_t toReturnSize;
-	int i;
-	DictValue* curValue;
-	
-	tabs[0] = '\0';
-	for(i = 0; i &lt; tabsCount; i++) {
-		strcat(tabs, &quot;\t&quot;);
-	}
-
-	
-	sprintf(buffer, &quot;%s&lt;array&gt;\n&quot;, tabs);
-	toReturnSize = sizeof(char) * (strlen(buffer) + 1);
-	toReturn = malloc(toReturnSize);
-	toReturn = strcpy(toReturn, buffer);
-	
-	for(i = 0; i &lt; myself-&gt;size; i++) {
-		curValue = myself-&gt;values[i];
-
-		if(curValue-&gt;type == DictionaryType) {
-			ret = getXmlFromDictionary((Dictionary*)curValue, tabsCount + 1);
-			toReturnSize += sizeof(char) * (strlen(ret) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, ret);
-			free(ret);
-		} else if(curValue-&gt;type == StringType) {
-			sprintf(buffer, &quot;%s\t&lt;string&gt;%s&lt;/string&gt;\n&quot;, tabs, ((StringValue*)curValue)-&gt;value);
-			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, buffer);
-		} else if(curValue-&gt;type == IntegerType) {
-			sprintf(buffer, &quot;%s\t&lt;string&gt;%d&lt;/string&gt;\n&quot;, tabs, ((IntegerValue*)curValue)-&gt;value);
-			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, buffer);
-		} else if(curValue-&gt;type == ArrayType) {
-			ret = getXmlFromArrayValue((ArrayValue*)curValue, tabsCount + 1);
-			toReturnSize += sizeof(char) * (strlen(ret) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, ret);
-			free(ret);
-		} else if(curValue-&gt;type == BoolType) {
-			if(((BoolValue*)curValue)-&gt;value) {
-				sprintf(buffer, &quot;%s\t&lt;true/&gt;\n&quot;, tabs);
-			} else {
-				sprintf(buffer, &quot;%s\t&lt;false/&gt;\n&quot;, tabs);
-			}
-			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, buffer);
-		}
-	}
-	
-	sprintf(buffer, &quot;%s&lt;/array&gt;\n&quot;, tabs);
-	toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-	toReturn = realloc(toReturn, toReturnSize);
-	toReturn = strcat(toReturn, buffer);
-	
-	return toReturn;
-}
-
-char* getXmlFromDictionary(Dictionary* myself, int tabsCount) {
-	char tabs[100];
-	char buffer[4096];
-	char* toReturn;
-	char* ret;
-	size_t toReturnSize;
-	int i;
-	DictValue* curValue;
-	
-	tabs[0] = '\0';
-	for(i = 0; i &lt; tabsCount; i++) {
-		strcat(tabs, &quot;\t&quot;);
-	}
-
-	
-	sprintf(buffer, &quot;%s&lt;dict&gt;\n&quot;, tabs);
-	toReturnSize = sizeof(char) * (strlen(buffer) + 1);
-	toReturn = malloc(toReturnSize);
-	toReturn = strcpy(toReturn, buffer);
-	
-	curValue = myself-&gt;values;
-	while(curValue != NULL) {
-		sprintf(buffer, &quot;%s\t&lt;key&gt;%s&lt;/key&gt;\n&quot;, tabs, curValue-&gt;key);
-		toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-		toReturn = realloc(toReturn, toReturnSize);
-		toReturn = strcat(toReturn, buffer);
-		
-		if(curValue-&gt;type == DictionaryType) {
-			ret = getXmlFromDictionary((Dictionary*)curValue, tabsCount + 1);
-			toReturnSize += sizeof(char) * (strlen(ret) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, ret);
-			free(ret);
-		} else if(curValue-&gt;type == StringType) {
-			sprintf(buffer, &quot;%s\t&lt;string&gt;%s&lt;/string&gt;\n&quot;, tabs, ((StringValue*)curValue)-&gt;value);
-			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, buffer);
-		} else if(curValue-&gt;type == IntegerType) {
-			sprintf(buffer, &quot;%s\t&lt;string&gt;%d&lt;/string&gt;\n&quot;, tabs, ((IntegerValue*)curValue)-&gt;value);
-			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, buffer);
-		} else if(curValue-&gt;type == ArrayType) {
-			ret = getXmlFromArrayValue((ArrayValue*)curValue, tabsCount + 1);
-			toReturnSize += sizeof(char) * (strlen(ret) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, ret);
-			free(ret);
-		} else if(curValue-&gt;type == BoolType) {
-			if(((BoolValue*)curValue)-&gt;value) {
-				sprintf(buffer, &quot;%s\t&lt;true/&gt;\n&quot;, tabs);
-			} else {
-				sprintf(buffer, &quot;%s\t&lt;false/&gt;\n&quot;, tabs);
-			}
-			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-			toReturn = realloc(toReturn, toReturnSize);
-			toReturn = strcat(toReturn, buffer);
-		}
-		
-		curValue = curValue-&gt;next;
-	}
-	
-	sprintf(buffer, &quot;%s&lt;/dict&gt;\n&quot;, tabs);
-	toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-	toReturn = realloc(toReturn, toReturnSize);
-	toReturn = strcat(toReturn, buffer);
-	
-	return toReturn;
-}
-
-Dictionary* createRoot(char* xml) {
-	Tag* tag;
-	Dictionary* dict;
-	
-	xml = strstr(xml, &quot;&lt;dict&gt;&quot;);
-	tag = getNextTag(&amp;xml);
-	dict = malloc(sizeof(Dictionary));
-	dict-&gt;dValue.next = NULL;
-	dict-&gt;dValue.key = malloc(sizeof(&quot;root&quot;));
-	strcpy(dict-&gt;dValue.key, &quot;root&quot;);
-	createDictionary(dict, tag-&gt;xml);
-	releaseTag(tag);
-	return dict;
-}
-
-char* getXmlFromRoot(Dictionary* root) {
-	char buffer[4096];
-	char* toReturn;
-	char* ret;
-	size_t toReturnSize;
-	
-	sprintf(buffer, &quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot;?&gt;\n&lt;!DOCTYPE plist PUBLIC \&quot;-//Apple//DTD PLIST 1.0//EN\&quot; \&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd\&quot;&gt;\n&lt;plist version=\&quot;1.0\&quot;&gt;\n&quot;);
-	toReturnSize = sizeof(char) * (strlen(buffer) + 1);
-	toReturn = malloc(toReturnSize);
-	toReturn = strcpy(toReturn, buffer);
-	
-	ret = getXmlFromDictionary(root, 0);
-	toReturnSize += sizeof(char) * (strlen(ret) + 1);
-	toReturn = realloc(toReturn, toReturnSize);
-	toReturn = strcat(toReturn, ret);
-	free(ret);
-	
-	sprintf(buffer, &quot;&lt;/plist&gt;\n&quot;);
-	toReturnSize += sizeof(char) * (strlen(buffer) + 1);
-	toReturn = realloc(toReturn, toReturnSize);
-	toReturn = strcat(toReturn, buffer);
-	
-	return toReturn;
-
-}
-
-DictValue* getValueByKey(Dictionary* myself, const char* key) {
+
+Tag* getNextTag(char** xmlPtr) {
+	char* xml;
+	char* tagEnd;
+	char* curChar;
+	Tag* tag;
+	int tagDepth;
+	
+	xml = *xmlPtr;
+	xml = strchr(xml, '&lt;');
+	
+	if(xml == NULL) {
+		return NULL;
+	}
+	
+	tag = (Tag*) malloc(sizeof(Tag));	
+
+	tagEnd = strchr(xml, '&gt;');
+	tag-&gt;name = (char*) malloc(sizeof(char) * (tagEnd -  xml));
+	memcpy(tag-&gt;name, xml + 1, tagEnd -  xml - 1);
+	tag-&gt;name[tagEnd -  xml - 1] = '\0';
+	if((tagEnd -  xml - 1) &gt; 0) {
+		if(tag-&gt;name[tagEnd -  xml - 2] == '/') {
+			tag-&gt;xml = malloc(sizeof(char) * 1);
+			tag-&gt;xml[0] = '\0';
+			*xmlPtr = tagEnd + 1;
+			return tag;
+		}
+	}
+	
+	xml = tagEnd;
+	curChar = xml;
+	tagDepth = 1;
+	while(*curChar != '\0') {
+		if(*curChar == '&lt;') {
+			if(*(curChar + 1) == '/') {
+				tagDepth--;
+				if(tagDepth == 0) {
+					break;
+				}
+			} else {
+				tagDepth++;
+			}
+		} else if(*curChar == '&gt;') {
+			if(*(curChar - 1) == '/') {
+				tagDepth--;
+			}
+		}
+		curChar++;
+	}
+	
+	tag-&gt;xml = (char*) malloc(sizeof(char) * (curChar -  xml));
+	memcpy(tag-&gt;xml, xml + 1, curChar -  xml - 1);
+	tag-&gt;xml[curChar -  xml - 1] = '\0';
+	
+	*xmlPtr = strchr(curChar, '&gt;') + 1;
+	
+	return tag;
+}
+
+void releaseTag(Tag* tag) {
+	free(tag-&gt;name);
+	free(tag-&gt;xml);
+	free(tag);
+}
+
+void releaseArray(ArrayValue* myself) {
+	int i;
+	
+	free(myself-&gt;dValue.key);
+	for(i = 0; i &lt; myself-&gt;size; i++) {
+		switch(myself-&gt;values[i]-&gt;type) {
+			case DictionaryType:
+				releaseDictionary((Dictionary*) myself-&gt;values[i]);
+				break;
+			case ArrayType:
+				releaseArray((ArrayValue*) myself-&gt;values[i]);
+				break;
+			case StringType:
+				free(((StringValue*)(myself-&gt;values[i]))-&gt;value);
+			case BoolType:
+			case IntegerType:
+				free(myself-&gt;values[i]-&gt;key);
+				free(myself-&gt;values[i]);
+				break;
+		}
+	}
+	free(myself-&gt;values);
+	free(myself);
+}
+
+void releaseDictionary(Dictionary* myself) {
+	DictValue* next;
+	DictValue* toRelease;
+	
+	free(myself-&gt;dValue.key);
+	next = myself-&gt;values;
+	while(next != NULL) {
+		toRelease = next;
+		next = next-&gt;next;
+		
+		switch(toRelease-&gt;type) {
+			case DictionaryType:
+				releaseDictionary((Dictionary*) toRelease);
+				break;
+			case ArrayType:
+				releaseArray((ArrayValue*) toRelease);
+				break;
+			case StringType:
+				free(((StringValue*)(toRelease))-&gt;value);
+			case IntegerType:
+			case BoolType:
+				free(toRelease-&gt;key);
+				free(toRelease);
+				break;
+		}
+	}
+	free(myself);
+}
+void createArray(ArrayValue* myself, char* xml) {
+	Tag* valueTag;
+	DictValue* curValue;
+	
+	int i;
+	
+	myself-&gt;values = NULL;
+	myself-&gt;size = 0;
+	while(*xml != '\0') {
+		valueTag = getNextTag(&amp;xml);
+		if(valueTag == NULL)  {
+			break;
+		}
+		
+		myself-&gt;size++;
+		myself-&gt;values = realloc(myself-&gt;values, sizeof(DictValue*) * myself-&gt;size);
+		curValue = (DictValue*) malloc(sizeof(DictValue));
+
+		curValue-&gt;key = (char*) malloc(sizeof(&quot;arraykey&quot;));
+		strcpy(curValue-&gt;key, &quot;arraykey&quot;);
+		curValue-&gt;next = NULL;
+
+		if(strcmp(valueTag-&gt;name, &quot;dict&quot;) == 0) {
+			curValue-&gt;type = DictionaryType;
+			curValue = (DictValue*) realloc(curValue, sizeof(Dictionary));
+			createDictionary((Dictionary*) curValue, valueTag-&gt;xml);
+		} else if(strcmp(valueTag-&gt;name, &quot;string&quot;) == 0) {
+			curValue-&gt;type = StringType;
+			curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
+			((StringValue*)curValue)-&gt;value = (char*) malloc(sizeof(char) * (strlen(valueTag-&gt;xml) + 1));
+			strcpy(((StringValue*)curValue)-&gt;value, valueTag-&gt;xml);
+		} else if(strcmp(valueTag-&gt;name, &quot;integer&quot;) == 0) {
+			curValue-&gt;type = IntegerType;
+			curValue = (DictValue*) realloc(curValue, sizeof(IntegerValue));
+			sscanf(valueTag-&gt;xml, &quot;%d&quot;, &amp;(((IntegerValue*)curValue)-&gt;value));
+		} else if(strcmp(valueTag-&gt;name, &quot;array&quot;) == 0) {
+			curValue-&gt;type = ArrayType;
+			curValue = (DictValue*) realloc(curValue, sizeof(ArrayValue));
+			createArray((ArrayValue*) curValue, valueTag-&gt;xml);
+		} else if(strcmp(valueTag-&gt;name, &quot;true/&quot;) == 0) {
+			curValue-&gt;type = BoolType;
+			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
+			((BoolValue*)curValue)-&gt;value = TRUE;
+		} else if(strcmp(valueTag-&gt;name, &quot;false/&quot;) == 0) {
+			curValue-&gt;type = BoolType;
+			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
+			((BoolValue*)curValue)-&gt;value = FALSE;
+		}
+		
+		myself-&gt;values[myself-&gt;size - 1] = curValue;
+		
+		releaseTag(valueTag);
+	}
+}
+
+void removeKey(Dictionary* dict, char* key) {
+	DictValue* next;
+	DictValue* toRelease;
+	next = dict-&gt;values;
+	while(next != NULL) {
+		if(strcmp(next-&gt;key, key) == 0) {
+			toRelease = next;
+			if(toRelease-&gt;prev) {
+				toRelease-&gt;prev-&gt;next = toRelease-&gt;next;
+			} else {
+				dict-&gt;values = toRelease-&gt;next;
+			}
+			if(toRelease-&gt;next) {
+				toRelease-&gt;next-&gt;prev = toRelease-&gt;prev;
+			}
+			switch(toRelease-&gt;type) {
+				case DictionaryType:
+					releaseDictionary((Dictionary*) toRelease);
+					break;
+				case ArrayType:
+					releaseArray((ArrayValue*) toRelease);
+					break;
+				case StringType:
+					free(((StringValue*)(toRelease))-&gt;value);
+				case IntegerType:
+				case BoolType:
+					free(toRelease-&gt;key);
+					free(toRelease);
+					break;
+			}
+			return;
+		}
+		next = next-&gt;next;
+	}
+
+	return;
+}
+
+void createDictionary(Dictionary* myself, char* xml) {
+	Tag* keyTag;
+	Tag* valueTag;
+	DictValue* curValue;
+	DictValue* lastValue;
+	
+	curValue = NULL;
+	lastValue = NULL;
+	
+	while(*xml != '\0') {
+		keyTag = getNextTag(&amp;xml);
+		if(keyTag == NULL)  {
+			break;
+		}
+		
+		if(strcmp(keyTag-&gt;name, &quot;key&quot;) != 0) {
+			releaseTag(keyTag);
+			continue;
+		}
+		
+		curValue = (DictValue*) malloc(sizeof(DictValue));
+		curValue-&gt;key = (char*) malloc(sizeof(char) * (strlen(keyTag-&gt;xml) + 1));
+		strcpy(curValue-&gt;key, keyTag-&gt;xml);
+		curValue-&gt;next = NULL;
+		releaseTag(keyTag);
+		
+		
+		valueTag = getNextTag(&amp;xml);
+		if(valueTag == NULL)  {
+			break;
+		}
+		
+		if(strcmp(valueTag-&gt;name, &quot;dict&quot;) == 0) {
+			curValue-&gt;type = DictionaryType;
+			curValue = (DictValue*) realloc(curValue, sizeof(Dictionary));
+			createDictionary((Dictionary*) curValue, valueTag-&gt;xml);
+		} else if(strcmp(valueTag-&gt;name, &quot;string&quot;) == 0) {
+			curValue-&gt;type = StringType;
+			curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
+			((StringValue*)curValue)-&gt;value = (char*) malloc(sizeof(char) * (strlen(valueTag-&gt;xml) + 1));
+			strcpy(((StringValue*)curValue)-&gt;value, valueTag-&gt;xml);
+		} else if(strcmp(valueTag-&gt;name, &quot;integer&quot;) == 0) {
+			curValue-&gt;type = IntegerType;
+			curValue = (DictValue*) realloc(curValue, sizeof(IntegerValue));
+			sscanf(valueTag-&gt;xml, &quot;%d&quot;, &amp;(((IntegerValue*)curValue)-&gt;value));
+		} else if(strcmp(valueTag-&gt;name, &quot;array&quot;) == 0) {
+			curValue-&gt;type = ArrayType;
+			curValue = (DictValue*) realloc(curValue, sizeof(ArrayValue));
+			createArray((ArrayValue*) curValue, valueTag-&gt;xml);
+		} else if(strcmp(valueTag-&gt;name, &quot;true/&quot;) == 0) {
+			curValue-&gt;type = BoolType;
+			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
+			((BoolValue*)curValue)-&gt;value = TRUE;
+		} else if(strcmp(valueTag-&gt;name, &quot;false/&quot;) == 0) {
+			curValue-&gt;type = BoolType;
+			curValue = (DictValue*) realloc(curValue, sizeof(BoolValue));
+			((BoolValue*)curValue)-&gt;value = FALSE;
+		}
+
+		curValue-&gt;prev = lastValue;
+		if(lastValue == NULL) {
+			myself-&gt;values = curValue;
+		} else {
+			lastValue-&gt;next = curValue;
+		}
+		
+		lastValue = curValue;
+		
+		releaseTag(valueTag);
+	}
+}
+
+char* getXmlFromArrayValue(ArrayValue* myself, int tabsCount) {
+	char tabs[100];
+	char buffer[4096];
+	char* toReturn;
+	char* ret;
+	size_t toReturnSize;
+	int i;
+	DictValue* curValue;
+	
+	tabs[0] = '\0';
+	for(i = 0; i &lt; tabsCount; i++) {
+		strcat(tabs, &quot;\t&quot;);
+	}
+
+	
+	sprintf(buffer, &quot;%s&lt;array&gt;\n&quot;, tabs);
+	toReturnSize = sizeof(char) * (strlen(buffer) + 1);
+	toReturn = malloc(toReturnSize);
+	toReturn = strcpy(toReturn, buffer);
+	
+	for(i = 0; i &lt; myself-&gt;size; i++) {
+		curValue = myself-&gt;values[i];
+
+		if(curValue-&gt;type == DictionaryType) {
+			ret = getXmlFromDictionary((Dictionary*)curValue, tabsCount + 1);
+			toReturnSize += sizeof(char) * (strlen(ret) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, ret);
+			free(ret);
+		} else if(curValue-&gt;type == StringType) {
+			sprintf(buffer, &quot;%s\t&lt;string&gt;%s&lt;/string&gt;\n&quot;, tabs, ((StringValue*)curValue)-&gt;value);
+			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, buffer);
+		} else if(curValue-&gt;type == IntegerType) {
+			sprintf(buffer, &quot;%s\t&lt;string&gt;%d&lt;/string&gt;\n&quot;, tabs, ((IntegerValue*)curValue)-&gt;value);
+			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, buffer);
+		} else if(curValue-&gt;type == ArrayType) {
+			ret = getXmlFromArrayValue((ArrayValue*)curValue, tabsCount + 1);
+			toReturnSize += sizeof(char) * (strlen(ret) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, ret);
+			free(ret);
+		} else if(curValue-&gt;type == BoolType) {
+			if(((BoolValue*)curValue)-&gt;value) {
+				sprintf(buffer, &quot;%s\t&lt;true/&gt;\n&quot;, tabs);
+			} else {
+				sprintf(buffer, &quot;%s\t&lt;false/&gt;\n&quot;, tabs);
+			}
+			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, buffer);
+		}
+	}
+	
+	sprintf(buffer, &quot;%s&lt;/array&gt;\n&quot;, tabs);
+	toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+	toReturn = realloc(toReturn, toReturnSize);
+	toReturn = strcat(toReturn, buffer);
+	
+	return toReturn;
+}
+
+char* getXmlFromDictionary(Dictionary* myself, int tabsCount) {
+	char tabs[100];
+	char buffer[4096];
+	char* toReturn;
+	char* ret;
+	size_t toReturnSize;
+	int i;
+	DictValue* curValue;
+	
+	tabs[0] = '\0';
+	for(i = 0; i &lt; tabsCount; i++) {
+		strcat(tabs, &quot;\t&quot;);
+	}
+
+	
+	sprintf(buffer, &quot;%s&lt;dict&gt;\n&quot;, tabs);
+	toReturnSize = sizeof(char) * (strlen(buffer) + 1);
+	toReturn = malloc(toReturnSize);
+	toReturn = strcpy(toReturn, buffer);
+	
+	curValue = myself-&gt;values;
+	while(curValue != NULL) {
+		sprintf(buffer, &quot;%s\t&lt;key&gt;%s&lt;/key&gt;\n&quot;, tabs, curValue-&gt;key);
+		toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+		toReturn = realloc(toReturn, toReturnSize);
+		toReturn = strcat(toReturn, buffer);
+		
+		if(curValue-&gt;type == DictionaryType) {
+			ret = getXmlFromDictionary((Dictionary*)curValue, tabsCount + 1);
+			toReturnSize += sizeof(char) * (strlen(ret) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, ret);
+			free(ret);
+		} else if(curValue-&gt;type == StringType) {
+			sprintf(buffer, &quot;%s\t&lt;string&gt;%s&lt;/string&gt;\n&quot;, tabs, ((StringValue*)curValue)-&gt;value);
+			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, buffer);
+		} else if(curValue-&gt;type == IntegerType) {
+			sprintf(buffer, &quot;%s\t&lt;string&gt;%d&lt;/string&gt;\n&quot;, tabs, ((IntegerValue*)curValue)-&gt;value);
+			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, buffer);
+		} else if(curValue-&gt;type == ArrayType) {
+			ret = getXmlFromArrayValue((ArrayValue*)curValue, tabsCount + 1);
+			toReturnSize += sizeof(char) * (strlen(ret) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, ret);
+			free(ret);
+		} else if(curValue-&gt;type == BoolType) {
+			if(((BoolValue*)curValue)-&gt;value) {
+				sprintf(buffer, &quot;%s\t&lt;true/&gt;\n&quot;, tabs);
+			} else {
+				sprintf(buffer, &quot;%s\t&lt;false/&gt;\n&quot;, tabs);
+			}
+			toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+			toReturn = realloc(toReturn, toReturnSize);
+			toReturn = strcat(toReturn, buffer);
+		}
+		
+		curValue = curValue-&gt;next;
+	}
+	
+	sprintf(buffer, &quot;%s&lt;/dict&gt;\n&quot;, tabs);
+	toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+	toReturn = realloc(toReturn, toReturnSize);
+	toReturn = strcat(toReturn, buffer);
+	
+	return toReturn;
+}
+
+Dictionary* createRoot(char* xml) {
+	Tag* tag;
+	Dictionary* dict;
+	
+	xml = strstr(xml, &quot;&lt;dict&gt;&quot;);
+	tag = getNextTag(&amp;xml);
+	dict = malloc(sizeof(Dictionary));
+	dict-&gt;dValue.next = NULL;
+	dict-&gt;dValue.key = malloc(sizeof(&quot;root&quot;));
+	strcpy(dict-&gt;dValue.key, &quot;root&quot;);
+	createDictionary(dict, tag-&gt;xml);
+	releaseTag(tag);
+	return dict;
+}
+
+char* getXmlFromRoot(Dictionary* root) {
+	char buffer[4096];
+	char* toReturn;
+	char* ret;
+	size_t toReturnSize;
+	
+	sprintf(buffer, &quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot;?&gt;\n&lt;!DOCTYPE plist PUBLIC \&quot;-//Apple//DTD PLIST 1.0//EN\&quot; \&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd\&quot;&gt;\n&lt;plist version=\&quot;1.0\&quot;&gt;\n&quot;);
+	toReturnSize = sizeof(char) * (strlen(buffer) + 1);
+	toReturn = malloc(toReturnSize);
+	toReturn = strcpy(toReturn, buffer);
+	
+	ret = getXmlFromDictionary(root, 0);
+	toReturnSize += sizeof(char) * (strlen(ret) + 1);
+	toReturn = realloc(toReturn, toReturnSize);
+	toReturn = strcat(toReturn, ret);
+	free(ret);
+	
+	sprintf(buffer, &quot;&lt;/plist&gt;\n&quot;);
+	toReturnSize += sizeof(char) * (strlen(buffer) + 1);
+	toReturn = realloc(toReturn, toReturnSize);
+	toReturn = strcat(toReturn, buffer);
+	
+	return toReturn;
+
+}
+
+DictValue* getValueByKey(Dictionary* myself, const char* key) {
 	DictValue* next;
 
 	if(myself == NULL) {
 		return NULL;
 	}
-
-	next = myself-&gt;values;
-	while(next != NULL) {
-		if(strcmp(next-&gt;key, key) == 0)
-			return next;
-		next = next-&gt;next;
-	}
-	return NULL;
-}
 
-void addStringToArray(ArrayValue* array, char* str) {
-	DictValue* curValue;
-	
-	array-&gt;size++;
-	array-&gt;values = realloc(array-&gt;values, sizeof(DictValue*) * array-&gt;size);
-	curValue = (DictValue*) malloc(sizeof(StringValue));
-	
-	curValue-&gt;key = (char*) malloc(sizeof(&quot;arraykey&quot;));
-	strcpy(curValue-&gt;key, &quot;arraykey&quot;);
-	curValue-&gt;next = NULL;
-	curValue-&gt;prev = NULL;
-	curValue-&gt;type = StringType;
-	curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
-	((StringValue*)curValue)-&gt;value = (char*) malloc(sizeof(char) * (strlen(str) + 1));
-	strcpy(((StringValue*)curValue)-&gt;value, str);
-	
-	array-&gt;values[array-&gt;size - 1] = curValue;
-}
+	next = myself-&gt;values;
+	while(next != NULL) {
+		if(strcmp(next-&gt;key, key) == 0)
+			return next;
+		next = next-&gt;next;
+	}
+	return NULL;
+}
+
+void addStringToArray(ArrayValue* array, char* str) {
+	DictValue* curValue;
+	
+	array-&gt;size++;
+	array-&gt;values = realloc(array-&gt;values, sizeof(DictValue*) * array-&gt;size);
+	curValue = (DictValue*) malloc(sizeof(StringValue));
+	
+	curValue-&gt;key = (char*) malloc(sizeof(&quot;arraykey&quot;));
+	strcpy(curValue-&gt;key, &quot;arraykey&quot;);
+	curValue-&gt;next = NULL;
+	curValue-&gt;prev = NULL;
+	curValue-&gt;type = StringType;
+	curValue = (DictValue*) realloc(curValue, sizeof(StringValue));
+	((StringValue*)curValue)-&gt;value = (char*) malloc(sizeof(char) * (strlen(str) + 1));
+	strcpy(((StringValue*)curValue)-&gt;value, str);
+	
+	array-&gt;values[array-&gt;size - 1] = curValue;
+}
 </diff>
      <filename>ipsw-patch/plist.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,62 +1,62 @@
 #ifndef PLIST_H
 #define PLIST_H
 
-enum DictTypes {
-	DictionaryType = 1,
-	ArrayType,
-	StringType,
-	IntegerType,
-	BoolType
-};
-
-typedef struct DictValue {
-	int type;
-	char* key;
-	struct DictValue* next;
-	struct DictValue* prev;
-} DictValue;
-
-typedef struct StringValue {
-	DictValue dValue;
-	char* value;
-} StringValue;
-
-typedef struct IntegerValue {
-	DictValue dValue;
-	int value;
-} IntegerValue;
-
-typedef struct BoolValue {
-	DictValue dValue;
-	char value;
-} BoolValue;
-
-typedef struct ArrayValue {
-	DictValue dValue;
-	int size;
-	DictValue** values;
-} ArrayValue;
-
-typedef struct Dictionary {
-	DictValue dValue;
-	DictValue* values;
-} Dictionary;
-
-typedef struct Tag {
-	char* name;
-	char* xml;
-} Tag;
+enum DictTypes {
+	DictionaryType = 1,
+	ArrayType,
+	StringType,
+	IntegerType,
+	BoolType
+};
+
+typedef struct DictValue {
+	int type;
+	char* key;
+	struct DictValue* next;
+	struct DictValue* prev;
+} DictValue;
+
+typedef struct StringValue {
+	DictValue dValue;
+	char* value;
+} StringValue;
+
+typedef struct IntegerValue {
+	DictValue dValue;
+	int value;
+} IntegerValue;
+
+typedef struct BoolValue {
+	DictValue dValue;
+	char value;
+} BoolValue;
+
+typedef struct ArrayValue {
+	DictValue dValue;
+	int size;
+	DictValue** values;
+} ArrayValue;
+
+typedef struct Dictionary {
+	DictValue dValue;
+	DictValue* values;
+} Dictionary;
+
+typedef struct Tag {
+	char* name;
+	char* xml;
+} Tag;
 
 #ifdef __cplusplus
 extern &quot;C&quot; {
 #endif
-	void createArray(ArrayValue* myself, char* xml);
-	void createDictionary(Dictionary* myself, char* xml);
-	void releaseArray(ArrayValue* myself);
-	void releaseDictionary(Dictionary* myself);
-	char* getXmlFromArrayValue(ArrayValue* myself, int tabsCount);
+	void createArray(ArrayValue* myself, char* xml);
+	void createDictionary(Dictionary* myself, char* xml);
+	void releaseArray(ArrayValue* myself);
+	void releaseDictionary(Dictionary* myself);
+	char* getXmlFromArrayValue(ArrayValue* myself, int tabsCount);
 	char* getXmlFromDictionary(Dictionary* myself, int tabsCount);
-	Dictionary* createRoot(char* xml);
+	Dictionary* createRoot(char* xml);
 	char* getXmlFromRoot(Dictionary* root);
 	char* getXmlFromRoot(Dictionary* root);
 	DictValue* getValueByKey(Dictionary* myself, const char* key);</diff>
      <filename>ipsw-patch/plist.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
-#include &lt;stdlib.h&gt;
-
-#ifdef WIN32
-blahfs-o_f-0-(){ {}A
-#else
-int main(int argc, char* argv[]) {
-  return 0;
-}
-#endif
+#include &lt;stdlib.h&gt;
+
+#ifdef WIN32
+blahfs-o_f-0-(){ {}A
+#else
+int main(int argc, char* argv[]) {
+  return 0;
+}
+#endif</diff>
      <filename>ipsw-patch/win32test.c</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ CFLAGS=-O3
 
 LIBUSB=`if $(CC) ../win32test.c -o /dev/null 2&gt;/dev/null ; then echo &quot;../libusb-0.1.12/.libs/libusb.a&quot;; else echo &quot;../libusb-win32/libusb.a&quot;; fi`
 LIBUSBH=`if $(CC) win32test.c -o /dev/null 2&gt;/dev/null ; then echo &quot;-I./libusb-0.1.12/&quot;; else echo &quot;-I./libusb-win32/src/&quot;; fi`
-INC=-I./include/ $(LIBUSBH)
+INC=-I./include/ $(LIBUSBH) -I../hfs -I../dmg
 
 SRCDIR=src
 OBJDIR=build</diff>
      <filename>xpwn/Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,263 +1,263 @@
-# LIBUSB-WIN32, Generic Windows USB Library
-# Copyright (c) 2002-2005 Stephan Meyer &lt;ste_meyer@web.de&gt;
-#
-# 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
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-
-# If you're cross-compiling and your mingw32 tools are called
-# i586-mingw32msvc-gcc and so on, then you can compile libusb-win32
-# by running
-#    make host_prefix=i586-mingw32msvc all
-
-
-ifdef host_prefix
-	override host_prefix := $(host_prefix)-
-endif
-
-CC = $(host_prefix)gcc
-LD = $(host_prefix)ld
-WINDRES = $(host_prefix)windres
-DLLTOOL = $(host_prefix)dlltool
-
-MAKE = make
-CP = cp
-CD = cd
-MV = mv
-RM = -rm -fr
-TAR = tar
-ISCC = iscc
-INSTALL = install
-LIB = lib
-IMPLIB = implib
-UNIX2DOS = unix2dos
-
-VERSION_MAJOR = 0
-VERSION_MINOR = 1
-VERSION_MICRO = 12
-VERSION_NANO = 1
-
-VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_MICRO).$(VERSION_NANO)
-RC_VERSION = $(VERSION_MAJOR),$(VERSION_MINOR),$(VERSION_MICRO),$(VERSION_NANO)
-RC_VERSION_STR = '\&quot;$(VERSION)\&quot;'
-INST_VERSION = $(VERSION)
-
-INF_DATE = $(shell date +&quot;%m/%d/%Y&quot;)
-DATE = $(shell date +&quot;%Y%m%d&quot;)
-
-DDK_MAKE_DIR = ./ddk_make
-
-TARGET = libusb
-DLL_TARGET = $(TARGET)$(VERSION_MAJOR)
-LIB_TARGET = $(TARGET)
-DRIVER_TARGET = $(TARGET)$(VERSION_MAJOR).sys
-
-DLL_TARGET_X64 = $(TARGET)$(VERSION_MAJOR)_x64
-DRIVER_TARGET_X64 = $(TARGET)$(VERSION_MAJOR)_x64.sys
-
-INSTALL_DIR = /usr
-DLL_OBJECTS = usb.o error.o descriptors.o windows.o resource.o install.o \
-	registry.o 
-
-DRIVER_OBJECTS = abort_endpoint.o claim_interface.o clear_feature.o \
-	dispatch.o get_configuration.o \
-	get_descriptor.o get_interface.o get_status.o \
-	ioctl.o libusb_driver.o pnp.o release_interface.o reset_device.o \
-	reset_endpoint.o set_configuration.o set_descriptor.o \
-	set_feature.o set_interface.o transfer.o vendor_request.o \
-	power.o driver_registry.o driver_debug.o libusb_driver_rc.o 
-
-INSTALLER_NAME = $(TARGET)-win32-filter-bin-$(INST_VERSION).exe
-SRC_DIST_DIR = $(TARGET)-win32-src-$(INST_VERSION)
-BIN_DIST_DIR = $(TARGET)-win32-device-bin-$(INST_VERSION)
-
-
-DIST_SOURCE_FILES = ./src
-DIST_MISC_FILES = COPYING_LGPL.txt COPYING_GPL.txt AUTHORS.txt
-
-SRC_DIR = ./src
-DRIVER_SRC_DIR = $(SRC_DIR)/driver
-
-VPATH = .:./src:./src/driver:./tests
-
-INCLUDES = -I./src -I./src/driver -I.
-
-CFLAGS = -O2 -Wall -mno-cygwin
-WIN_CFLAGS = $(CFLAGS) -mwindows
-
-CPPFLAGS = -DVERSION_MAJOR=$(VERSION_MAJOR) \
-	-DVERSION_MINOR=$(VERSION_MINOR) \
-	-DVERSION_MICRO=$(VERSION_MICRO) \
-	-DVERSION_NANO=$(VERSION_NANO) \
-	-DINF_DATE='$(INF_DATE)' \
-	-DINF_VERSION='$(VERSION)' \
-  -DDBG
-
-WINDRES_FLAGS = -I./src -DRC_VERSION='$(RC_VERSION)' \
-								-DRC_VERSION_STR=$(RC_VERSION_STR)
-
-LDFLAGS = -s -mno-cygwin -L. -lusb -lgdi32 -luser32 -lcfgmgr32 \
-	 				-lsetupapi -lcomctl32
-WIN_LDFLAGS = $(LDFLAGS) -mwindows
-
-
-DLL_LDFLAGS = -s -mdll -mno-cygwin \
-	-Wl,--kill-at \
-	-Wl,--out-implib,$(LIB_TARGET).a \
-	-Wl,--enable-stdcall-fixup \
-	-L. -lcfgmgr32 -lsetupapi 
-
-
-DRIVER_LDFLAGS = -s -shared -Wl,--entry,_DriverEntry@8 \
-	-nostartfiles -nostdlib -L. -lusbd -lntoskrnl -lhal
-
-
-EXE_FILES = testlibusb.exe testlibusb-win.exe inf-wizard.exe install-filter.exe
-
-
-.PHONY: all
-all: $(DLL_TARGET).dll $(EXE_FILES) $(DRIVER_TARGET) README.txt
-
-$(DLL_TARGET).dll: $(DLL_OBJECTS)
-	$(CC) -o $@ $(DLL_OBJECTS) $(DLL_TARGET).def $(DLL_LDFLAGS)
-
-
-$(DRIVER_TARGET): libusbd.a $(DRIVER_OBJECTS)
-	$(CC) -o $@ $(DRIVER_OBJECTS) $(DLL_TARGET)_drv.def $(DRIVER_LDFLAGS)
-
-libusbd.a:
-	$(DLLTOOL) --dllname usbd.sys --add-underscore --def ./src/driver/usbd.def \
-		--output-lib libusbd.a
-
-inf-wizard.exe: inf_wizard_rc.o inf_wizard.o registry.o error.o
-	$(CC) $(WIN_CFLAGS) -o $@ -I./src  $^ $(WIN_LDFLAGS)
-
-testlibusb.exe: testlibusb.o
-	$(CC) $(CFLAGS) -o $@ -I./src  $^ $(LDFLAGS)
-
-install-filter.exe: install_filter.o
-	$(CC) $(CFLAGS) -o $@ -I./src  $^ $(WIN_LDFLAGS)
-
-testlibusb-win.exe: testlibusb_win.o testlibusb_win_rc.o
-	$(CC) $(WIN_CFLAGS) -o $@ -I./src  $^ $(WIN_LDFLAGS)
-
-%.o: %.c libusb_driver.h driver_api.h
-	$(CC) -c $&lt; -o $@ $(CFLAGS) $(CPPFLAGS) $(INCLUDES) 
-
-%.o: %.rc
-	$(WINDRES) $(WINDRES_FLAGS) $&lt; -o $@
-
-README.txt: README.in
-	sed -e 's/@VERSION@/$(INST_VERSION)/' $&lt; &gt; $@
-
-
-.PHONY: bcc_implib
-bcc_lib:
-	$(IMPLIB) -a $(LIB_TARGET).lib $(DLL_TARGET).dll
-
-.PHONY: msvc_lib
-msvc_lib:
-	$(LIB) /machine:i386 /def:$(DLL_TARGET).def 
-	$(MV) $(DLL_TARGET).lib $(LIB_TARGET).lib
-
-.PHONY: bin_dist
-bin_dist: all
-	$(INSTALL) -d $(BIN_DIST_DIR)/lib/gcc
-	$(INSTALL) -d $(BIN_DIST_DIR)/lib/bcc
-	$(INSTALL) -d $(BIN_DIST_DIR)/lib/msvc
-	$(INSTALL) -d $(BIN_DIST_DIR)/lib/msvc_x64
-	$(INSTALL) -d $(BIN_DIST_DIR)/lib/dynamic
-	$(INSTALL) -d $(BIN_DIST_DIR)/include
-	$(INSTALL) -d $(BIN_DIST_DIR)/bin
-	$(INSTALL) -d $(BIN_DIST_DIR)/examples
-
-	$(INSTALL) $(EXE_FILES) $(BIN_DIST_DIR)/bin
-
-	$(INSTALL) $(DRIVER_TARGET) $(BIN_DIST_DIR)/bin
-	$(INSTALL) $(DLL_TARGET).dll $(BIN_DIST_DIR)/bin
-
-	$(INSTALL) $(DDK_MAKE_DIR)/$(DRIVER_TARGET) $(BIN_DIST_DIR)/bin/$(DRIVER_TARGET_X64)
-	$(INSTALL) $(DDK_MAKE_DIR)/$(DLL_TARGET).dll $(BIN_DIST_DIR)/bin/$(DLL_TARGET_X64).dll
-
-	$(INSTALL) $(SRC_DIR)/usb.h $(BIN_DIST_DIR)/include
-	$(INSTALL) $(LIB_TARGET).a $(BIN_DIST_DIR)/lib/gcc
-	$(MAKE) bcc_lib 
-	$(INSTALL) $(LIB_TARGET).lib $(BIN_DIST_DIR)/lib/bcc
-	$(MAKE) msvc_lib
-	$(INSTALL) $(LIB_TARGET).lib $(BIN_DIST_DIR)/lib/msvc
-	$(INSTALL) $(DDK_MAKE_DIR)/$(LIB_TARGET).lib $(BIN_DIST_DIR)/lib/msvc_x64
-	$(INSTALL) $(SRC_DIR)/libusb_dyn.c $(BIN_DIST_DIR)/lib/dynamic
-	$(INSTALL) $(DIST_MISC_FILES) README.txt $(BIN_DIST_DIR)
-	$(INSTALL) ./examples/*.iss $(BIN_DIST_DIR)/examples
-	$(INSTALL) ./examples/*.c $(BIN_DIST_DIR)/examples
-	$(UNIX2DOS) $(BIN_DIST_DIR)/examples/*.iss
-	$(UNIX2DOS) $(BIN_DIST_DIR)/*.txt
-
-.PHONY: src_dist
-src_dist:
-	$(INSTALL) -d $(SRC_DIST_DIR)/src
-	$(INSTALL) -d $(SRC_DIST_DIR)/src/driver
-	$(INSTALL) -d $(SRC_DIST_DIR)/tests
-	$(INSTALL) -d $(SRC_DIST_DIR)/examples
-	$(INSTALL) -d $(SRC_DIST_DIR)/ddk_make
-
-	$(INSTALL) $(SRC_DIR)/*.c $(SRC_DIST_DIR)/src
-	$(INSTALL) $(SRC_DIR)/*.h $(SRC_DIST_DIR)/src
-	$(INSTALL) $(SRC_DIR)/*.rc $(SRC_DIST_DIR)/src
-
-	$(INSTALL) ./examples/*.iss $(SRC_DIST_DIR)/examples
-	$(INSTALL) ./ddk_make/sources* $(SRC_DIST_DIR)/ddk_make
-	$(INSTALL) ./ddk_make/makefile $(SRC_DIST_DIR)/ddk_make
-	$(INSTALL) ./ddk_make/*.txt $(SRC_DIST_DIR)/ddk_make
-	$(INSTALL) ./ddk_make/*.bat $(SRC_DIST_DIR)/ddk_make
-	$(UNIX2DOS)	$(SRC_DIST_DIR)/ddk_make/*
-
-	$(INSTALL) $(SRC_DIR)/driver/*.h $(SRC_DIST_DIR)/src/driver
-	$(INSTALL) $(SRC_DIR)/driver/*.c $(SRC_DIST_DIR)/src/driver
-	$(INSTALL) $(SRC_DIR)/driver/*.def $(SRC_DIST_DIR)/src/driver
-	$(INSTALL) $(SRC_DIR)/driver/*.rc $(SRC_DIST_DIR)/src/driver
-
-	$(INSTALL) ./tests/*.c $(SRC_DIST_DIR)/tests
-	$(INSTALL) ./tests/*.rc $(SRC_DIST_DIR)/tests
-	$(INSTALL) $(DIST_MISC_FILES) *.in Makefile manifest.txt *.def \
-		installer_license.txt $(SRC_DIST_DIR)
-	$(UNIX2DOS) $(SRC_DIST_DIR)/*.txt
-
-
-.PHONY: dist
-dist: bin_dist src_dist
-	sed -e 's/@VERSION@/$(INST_VERSION)/' \
-		-e 's/@BIN_DIST_DIR@/$(BIN_DIST_DIR)/' \
-		-e 's/@SRC_DIST_DIR@/$(SRC_DIST_DIR)/' \
-		-e 's/@INSTALLER_TARGET@/$(INSTALLER_TARGET)/' \
-		install.iss.in &gt; install.iss
-	$(UNIX2DOS) install.iss
-	$(TAR) -czf $(SRC_DIST_DIR).tar.gz $(SRC_DIST_DIR) 
-	$(TAR) -czf $(BIN_DIST_DIR).tar.gz $(BIN_DIST_DIR)
-	$(ISCC) install.iss
-	$(RM) $(SRC_DIST_DIR)
-	$(RM) $(BIN_DIST_DIR)
-
-.PHONY: snapshot
-snapshot: INST_VERSION = $(DATE)
-snapshot: dist
-
-.PHONY: clean
-clean:	
-	$(RM) *.o *.dll *.a *.exp *.lib *.exe *.tar.gz *~ *.iss *.rc *.h
-	$(RM) ./src/*~ *.sys *.log
-	$(RM) $(DRIVER_SRC_DIR)/*~
-	$(RM) README.txt
-
+# LIBUSB-WIN32, Generic Windows USB Library
+# Copyright (c) 2002-2005 Stephan Meyer &lt;ste_meyer@web.de&gt;
+#
+# 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
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+
+# If you're cross-compiling and your mingw32 tools are called
+# i586-mingw32msvc-gcc and so on, then you can compile libusb-win32
+# by running
+#    make host_prefix=i586-mingw32msvc all
+
+
+ifdef host_prefix
+	override host_prefix := $(host_prefix)-
+endif
+
+CC = $(host_prefix)gcc
+LD = $(host_prefix)ld
+WINDRES = $(host_prefix)windres
+DLLTOOL = $(host_prefix)dlltool
+
+MAKE = make
+CP = cp
+CD = cd
+MV = mv
+RM = -rm -fr
+TAR = tar
+ISCC = iscc
+INSTALL = install
+LIB = lib
+IMPLIB = implib
+UNIX2DOS = unix2dos
+
+VERSION_MAJOR = 0
+VERSION_MINOR = 1
+VERSION_MICRO = 12
+VERSION_NANO = 1
+
+VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_MICRO).$(VERSION_NANO)
+RC_VERSION = $(VERSION_MAJOR),$(VERSION_MINOR),$(VERSION_MICRO),$(VERSION_NANO)
+RC_VERSION_STR = '\&quot;$(VERSION)\&quot;'
+INST_VERSION = $(VERSION)
+
+INF_DATE = $(shell date +&quot;%m/%d/%Y&quot;)
+DATE = $(shell date +&quot;%Y%m%d&quot;)
+
+DDK_MAKE_DIR = ./ddk_make
+
+TARGET = libusb
+DLL_TARGET = $(TARGET)$(VERSION_MAJOR)
+LIB_TARGET = $(TARGET)
+DRIVER_TARGET = $(TARGET)$(VERSION_MAJOR).sys
+
+DLL_TARGET_X64 = $(TARGET)$(VERSION_MAJOR)_x64
+DRIVER_TARGET_X64 = $(TARGET)$(VERSION_MAJOR)_x64.sys
+
+INSTALL_DIR = /usr
+DLL_OBJECTS = usb.o error.o descriptors.o windows.o resource.o install.o \
+	registry.o 
+
+DRIVER_OBJECTS = abort_endpoint.o claim_interface.o clear_feature.o \
+	dispatch.o get_configuration.o \
+	get_descriptor.o get_interface.o get_status.o \
+	ioctl.o libusb_driver.o pnp.o release_interface.o reset_device.o \
+	reset_endpoint.o set_configuration.o set_descriptor.o \
+	set_feature.o set_interface.o transfer.o vendor_request.o \
+	power.o driver_registry.o driver_debug.o libusb_driver_rc.o 
+
+INSTALLER_NAME = $(TARGET)-win32-filter-bin-$(INST_VERSION).exe
+SRC_DIST_DIR = $(TARGET)-win32-src-$(INST_VERSION)
+BIN_DIST_DIR = $(TARGET)-win32-device-bin-$(INST_VERSION)
+
+
+DIST_SOURCE_FILES = ./src
+DIST_MISC_FILES = COPYING_LGPL.txt COPYING_GPL.txt AUTHORS.txt
+
+SRC_DIR = ./src
+DRIVER_SRC_DIR = $(SRC_DIR)/driver
+
+VPATH = .:./src:./src/driver:./tests
+
+INCLUDES = -I./src -I./src/driver -I.
+
+CFLAGS = -O2 -Wall -mno-cygwin
+WIN_CFLAGS = $(CFLAGS) -mwindows
+
+CPPFLAGS = -DVERSION_MAJOR=$(VERSION_MAJOR) \
+	-DVERSION_MINOR=$(VERSION_MINOR) \
+	-DVERSION_MICRO=$(VERSION_MICRO) \
+	-DVERSION_NANO=$(VERSION_NANO) \
+	-DINF_DATE='$(INF_DATE)' \
+	-DINF_VERSION='$(VERSION)' \
+  -DDBG
+
+WINDRES_FLAGS = -I./src -DRC_VERSION='$(RC_VERSION)' \
+								-DRC_VERSION_STR=$(RC_VERSION_STR)
+
+LDFLAGS = -s -mno-cygwin -L. -lusb -lgdi32 -luser32 -lcfgmgr32 \
+	 				-lsetupapi -lcomctl32
+WIN_LDFLAGS = $(LDFLAGS) -mwindows
+
+
+DLL_LDFLAGS = -s -mdll -mno-cygwin \
+	-Wl,--kill-at \
+	-Wl,--out-implib,$(LIB_TARGET).a \
+	-Wl,--enable-stdcall-fixup \
+	-L. -lcfgmgr32 -lsetupapi 
+
+
+DRIVER_LDFLAGS = -s -shared -Wl,--entry,_DriverEntry@8 \
+	-nostartfiles -nostdlib -L. -lusbd -lntoskrnl -lhal
+
+
+EXE_FILES = testlibusb.exe testlibusb-win.exe inf-wizard.exe install-filter.exe
+
+
+.PHONY: all
+all: $(DLL_TARGET).dll $(EXE_FILES) $(DRIVER_TARGET) README.txt
+
+$(DLL_TARGET).dll: $(DLL_OBJECTS)
+	$(CC) -o $@ $(DLL_OBJECTS) $(DLL_TARGET).def $(DLL_LDFLAGS)
+
+
+$(DRIVER_TARGET): libusbd.a $(DRIVER_OBJECTS)
+	$(CC) -o $@ $(DRIVER_OBJECTS) $(DLL_TARGET)_drv.def $(DRIVER_LDFLAGS)
+
+libusbd.a:
+	$(DLLTOOL) --dllname usbd.sys --add-underscore --def ./src/driver/usbd.def \
+		--output-lib libusbd.a
+
+inf-wizard.exe: inf_wizard_rc.o inf_wizard.o registry.o error.o
+	$(CC) $(WIN_CFLAGS) -o $@ -I./src  $^ $(WIN_LDFLAGS)
+
+testlibusb.exe: testlibusb.o
+	$(CC) $(CFLAGS) -o $@ -I./src  $^ $(LDFLAGS)
+
+install-filter.exe: install_filter.o
+	$(CC) $(CFLAGS) -o $@ -I./src  $^ $(WIN_LDFLAGS)
+
+testlibusb-win.exe: testlibusb_win.o testlibusb_win_rc.o
+	$(CC) $(WIN_CFLAGS) -o $@ -I./src  $^ $(WIN_LDFLAGS)
+
+%.o: %.c libusb_driver.h driver_api.h
+	$(CC) -c $&lt; -o $@ $(CFLAGS) $(CPPFLAGS) $(INCLUDES) 
+
+%.o: %.rc
+	$(WINDRES) $(WINDRES_FLAGS) $&lt; -o $@
+
+README.txt: README.in
+	sed -e 's/@VERSION@/$(INST_VERSION)/' $&lt; &gt; $@
+
+
+.PHONY: bcc_implib
+bcc_lib:
+	$(IMPLIB) -a $(LIB_TARGET).lib $(DLL_TARGET).dll
+
+.PHONY: msvc_lib
+msvc_lib:
+	$(LIB) /machine:i386 /def:$(DLL_TARGET).def 
+	$(MV) $(DLL_TARGET).lib $(LIB_TARGET).lib
+
+.PHONY: bin_dist
+bin_dist: all
+	$(INSTALL) -d $(BIN_DIST_DIR)/lib/gcc
+	$(INSTALL) -d $(BIN_DIST_DIR)/lib/bcc
+	$(INSTALL) -d $(BIN_DIST_DIR)/lib/msvc
+	$(INSTALL) -d $(BIN_DIST_DIR)/lib/msvc_x64
+	$(INSTALL) -d $(BIN_DIST_DIR)/lib/dynamic
+	$(INSTALL) -d $(BIN_DIST_DIR)/include
+	$(INSTALL) -d $(BIN_DIST_DIR)/bin
+	$(INSTALL) -d $(BIN_DIST_DIR)/examples
+
+	$(INSTALL) $(EXE_FILES) $(BIN_DIST_DIR)/bin
+
+	$(INSTALL) $(DRIVER_TARGET) $(BIN_DIST_DIR)/bin
+	$(INSTALL) $(DLL_TARGET).dll $(BIN_DIST_DIR)/bin
+
+	$(INSTALL) $(DDK_MAKE_DIR)/$(DRIVER_TARGET) $(BIN_DIST_DIR)/bin/$(DRIVER_TARGET_X64)
+	$(INSTALL) $(DDK_MAKE_DIR)/$(DLL_TARGET).dll $(BIN_DIST_DIR)/bin/$(DLL_TARGET_X64).dll
+
+	$(INSTALL) $(SRC_DIR)/usb.h $(BIN_DIST_DIR)/include
+	$(INSTALL) $(LIB_TARGET).a $(BIN_DIST_DIR)/lib/gcc
+	$(MAKE) bcc_lib 
+	$(INSTALL) $(LIB_TARGET).lib $(BIN_DIST_DIR)/lib/bcc
+	$(MAKE) msvc_lib
+	$(INSTALL) $(LIB_TARGET).lib $(BIN_DIST_DIR)/lib/msvc
+	$(INSTALL) $(DDK_MAKE_DIR)/$(LIB_TARGET).lib $(BIN_DIST_DIR)/lib/msvc_x64
+	$(INSTALL) $(SRC_DIR)/libusb_dyn.c $(BIN_DIST_DIR)/lib/dynamic
+	$(INSTALL) $(DIST_MISC_FILES) README.txt $(BIN_DIST_DIR)
+	$(INSTALL) ./examples/*.iss $(BIN_DIST_DIR)/examples
+	$(INSTALL) ./examples/*.c $(BIN_DIST_DIR)/examples
+	$(UNIX2DOS) $(BIN_DIST_DIR)/examples/*.iss
+	$(UNIX2DOS) $(BIN_DIST_DIR)/*.txt
+
+.PHONY: src_dist
+src_dist:
+	$(INSTALL) -d $(SRC_DIST_DIR)/src
+	$(INSTALL) -d $(SRC_DIST_DIR)/src/driver
+	$(INSTALL) -d $(SRC_DIST_DIR)/tests
+	$(INSTALL) -d $(SRC_DIST_DIR)/examples
+	$(INSTALL) -d $(SRC_DIST_DIR)/ddk_make
+
+	$(INSTALL) $(SRC_DIR)/*.c $(SRC_DIST_DIR)/src
+	$(INSTALL) $(SRC_DIR)/*.h $(SRC_DIST_DIR)/src
+	$(INSTALL) $(SRC_DIR)/*.rc $(SRC_DIST_DIR)/src
+
+	$(INSTALL) ./examples/*.iss $(SRC_DIST_DIR)/examples
+	$(INSTALL) ./ddk_make/sources* $(SRC_DIST_DIR)/ddk_make
+	$(INSTALL) ./ddk_make/makefile $(SRC_DIST_DIR)/ddk_make
+	$(INSTALL) ./ddk_make/*.txt $(SRC_DIST_DIR)/ddk_make
+	$(INSTALL) ./ddk_make/*.bat $(SRC_DIST_DIR)/ddk_make
+	$(UNIX2DOS)	$(SRC_DIST_DIR)/ddk_make/*
+
+	$(INSTALL) $(SRC_DIR)/driver/*.h $(SRC_DIST_DIR)/src/driver
+	$(INSTALL) $(SRC_DIR)/driver/*.c $(SRC_DIST_DIR)/src/driver
+	$(INSTALL) $(SRC_DIR)/driver/*.def $(SRC_DIST_DIR)/src/driver
+	$(INSTALL) $(SRC_DIR)/driver/*.rc $(SRC_DIST_DIR)/src/driver
+
+	$(INSTALL) ./tests/*.c $(SRC_DIST_DIR)/tests
+	$(INSTALL) ./tests/*.rc $(SRC_DIST_DIR)/tests
+	$(INSTALL) $(DIST_MISC_FILES) *.in Makefile manifest.txt *.def \
+		installer_license.txt $(SRC_DIST_DIR)
+	$(UNIX2DOS) $(SRC_DIST_DIR)/*.txt
+
+
+.PHONY: dist
+dist: bin_dist src_dist
+	sed -e 's/@VERSION@/$(INST_VERSION)/' \
+		-e 's/@BIN_DIST_DIR@/$(BIN_DIST_DIR)/' \
+		-e 's/@SRC_DIST_DIR@/$(SRC_DIST_DIR)/' \
+		-e 's/@INSTALLER_TARGET@/$(INSTALLER_TARGET)/' \
+		install.iss.in &gt; install.iss
+	$(UNIX2DOS) install.iss
+	$(TAR) -czf $(SRC_DIST_DIR).tar.gz $(SRC_DIST_DIR) 
+	$(TAR) -czf $(BIN_DIST_DIR).tar.gz $(BIN_DIST_DIR)
+	$(ISCC) install.iss
+	$(RM) $(SRC_DIST_DIR)
+	$(RM) $(BIN_DIST_DIR)
+
+.PHONY: snapshot
+snapshot: INST_VERSION = $(DATE)
+snapshot: dist
+
+.PHONY: clean
+clean:	
+	$(RM) *.o *.dll *.a *.exp *.lib *.exe *.tar.gz *~ *.iss *.rc *.h
+	$(RM) ./src/*~ *.sys *.log
+	$(RM) $(DRIVER_SRC_DIR)/*~
+	$(RM) README.txt
+</diff>
      <filename>xpwn/libusb-win32/Makefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,165 +1,165 @@
-/* LIBUSB-WIN32, Generic Windows USB Library
- * Copyright (c) 2002-2005 Stephan Meyer &lt;ste_meyer@web.de&gt;
- *
- * 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
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef __DRIVER_API_H__
-#define __DRIVER_API_H__
-
-enum {
-  LIBUSB_DEBUG_OFF,
-  LIBUSB_DEBUG_ERR,
-  LIBUSB_DEBUG_MSG,
-};
-
-
-/* 64k */
-#define LIBUSB_MAX_READ_WRITE 0x10000
-
-#define LIBUSB_MAX_NUMBER_OF_DEVICES 256
-#define LIBUSB_MAX_NUMBER_OF_CHILDREN 32
-
-#define LIBUSB_IOCTL_SET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_GET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_SET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_GET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_SET_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_CLEAR_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_GET_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_SET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_GET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x80A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x80B, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_VENDOR_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_VENDOR_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_RESET_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_ABORT_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_SET_DEBUG_LEVEL CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x811, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x812, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_ISOCHRONOUS_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x813, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_ISOCHRONOUS_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x814, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_CLAIM_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x815, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define LIBUSB_IOCTL_RELEASE_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
-0x816, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#include &lt;pshpack1.h&gt; 
-
-
-typedef struct {
-  unsigned int timeout;
-  union {
-    struct
-    {
-      unsigned int configuration;
-    } configuration;
-    struct
-    {
-      unsigned int interface;
-      unsigned int altsetting;
-    } interface;
-    struct
-    {
-      unsigned int endpoint;
-      unsigned int packet_size;
-    } endpoint;    
-    struct
-    {
-      unsigned int type;
-      unsigned int recipient;
-      unsigned int request;
-      unsigned int value;
-      unsigned int index;
-    } vendor;
-    struct
-    {
-      unsigned int recipient;
-      unsigned int feature;
-      unsigned int index;
-    } feature;
-    struct
-    {
-      unsigned int recipient;
-      unsigned int index;
-      unsigned int status;
-    } status;
-    struct
-    {
-      unsigned int type;
-      unsigned int index;
-      unsigned int language_id;
-      unsigned int recipient;
-    } descriptor;    
-    struct
-    {
-      unsigned int level;
-    } debug;
-    struct
-    {
-      unsigned int major;
-      unsigned int minor;
-      unsigned int micro;
-      unsigned int nano;
-    } version;
-  };
-} libusb_request;
-    
-#include &lt;poppack.h&gt;
-
-#endif
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer &lt;ste_meyer@web.de&gt;
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef __DRIVER_API_H__
+#define __DRIVER_API_H__
+
+enum {
+  LIBUSB_DEBUG_OFF,
+  LIBUSB_DEBUG_ERR,
+  LIBUSB_DEBUG_MSG,
+};
+
+
+/* 64k */
+#define LIBUSB_MAX_READ_WRITE 0x10000
+
+#define LIBUSB_MAX_NUMBER_OF_DEVICES 256
+#define LIBUSB_MAX_NUMBER_OF_CHILDREN 32
+
+#define LIBUSB_IOCTL_SET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_GET_CONFIGURATION CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_SET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_GET_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_SET_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_CLEAR_FEATURE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_GET_STATUS CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_SET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_GET_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80A, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80B, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_VENDOR_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_VENDOR_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_RESET_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_ABORT_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x810, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_SET_DEBUG_LEVEL CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x811, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x812, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_ISOCHRONOUS_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x813, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_ISOCHRONOUS_READ CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x814, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_CLAIM_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x815, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define LIBUSB_IOCTL_RELEASE_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN,\
+0x816, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#include &lt;pshpack1.h&gt; 
+
+
+typedef struct {
+  unsigned int timeout;
+  union {
+    struct
+    {
+      unsigned int configuration;
+    } configuration;
+    struct
+    {
+      unsigned int interface;
+      unsigned int altsetting;
+    } interface;
+    struct
+    {
+      unsigned int endpoint;
+      unsigned int packet_size;
+    } endpoint;    
+    struct
+    {
+      unsigned int type;
+      unsigned int recipient;
+      unsigned int request;
+      unsigned int value;
+      unsigned int index;
+    } vendor;
+    struct
+    {
+      unsigned int recipient;
+      unsigned int feature;
+      unsigned int index;
+    } feature;
+    struct
+    {
+      unsigned int recipient;
+      unsigned int index;
+      unsigned int status;
+    } status;
+    struct
+    {
+      unsigned int type;
+      unsigned int index;
+      unsigned int language_id;
+      unsigned int recipient;
+    } descriptor;    
+    struct
+    {
+      unsigned int level;
+    } debug;
+    struct
+    {
+      unsigned int major;
+      unsigned int minor;
+      unsigned int micro;
+      unsigned int nano;
+    } version;
+  };
+} libusb_request;
+    
+#include &lt;poppack.h&gt;
+
+#endif</diff>
      <filename>xpwn/libusb-win32/src/driver/driver_api.h</filename>
    </modified>
    <modified>
      <diff>@@ -1,1248 +1,1248 @@
-/* LIBUSB-WIN32, Generic Windows USB Library
- * Copyright (c) 2002-2005 Stephan Meyer &lt;ste_meyer@web.de&gt;
- * Copyright (c) 2000-2005 Johannes Erdfelt &lt;johannes@erdfelt.com&gt;
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include &lt;stdlib.h&gt;
-#include &lt;string.h&gt;
-#include &lt;stdio.h&gt; 
-#include &lt;errno.h&gt;
-#include &lt;ctype.h&gt;
-#include &lt;windows.h&gt;
-#include &lt;winioctl.h&gt;
-#include &lt;setupapi.h&gt;
-
-#include &quot;usb.h&quot;
-#include &quot;error.h&quot;
-#include &quot;usbi.h&quot;
-#include &quot;driver_api.h&quot;
-#include &quot;registry.h&quot;
-
-
-
-#define LIBUSB_DEFAULT_TIMEOUT 5000
-#define LIBUSB_DEVICE_NAME &quot;\\\\.\\libusb0-&quot;
-#define LIBUSB_BUS_NAME &quot;bus-0&quot;
-#define LIBUSB_MAX_DEVICES 256
-
-extern int __usb_debug;
-
-typedef struct {
-  usb_dev_handle *dev;
-  libusb_request req;
-  char *bytes;
-  int size;
-  DWORD control_code;
-  OVERLAPPED ol;
-} usb_context_t;
-
-
-static struct usb_version _usb_version = {
-  { VERSION_MAJOR, 
-    VERSION_MINOR, 
-    VERSION_MICRO, 
-    VERSION_NANO },
-  { -1, -1, -1, -1 }
-};
-
-
-static int _usb_setup_async(usb_dev_handle *dev, void **context, 
-                            DWORD control_code,
-                            unsigned char ep, int pktsize);
-static int _usb_transfer_sync(usb_dev_handle *dev, int control_code,
-                              int ep, int pktsize, char *bytes, int size, 
-                              int timeout);
-
-/* static int usb_get_configuration(usb_dev_handle *dev); */
-static int _usb_cancel_io(usb_context_t *context);
-static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep);
-
-static int _usb_io_sync(HANDLE dev, unsigned int code, void *in, int in_size,
-                        void *out, int out_size, int *ret);
-static int _usb_reap_async(void *context, int timeout, int cancel);
-static int _usb_add_virtual_hub(struct usb_bus *bus);
-
-static void _usb_free_bus_list(struct usb_bus *bus);
-static void _usb_free_dev_list(struct usb_device *dev);
-static void _usb_deinit(void);
-
-/* DLL main entry point */
-BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved)
-{
-  switch(reason)
-    {
-    case DLL_PROCESS_ATTACH:
-      break;
-    case DLL_PROCESS_DETACH:
-      _usb_deinit();
-      break;
-    case DLL_THREAD_ATTACH:
-      break;
-    case DLL_THREAD_DETACH:
-      break;
-    default:
-      break;
-    }
-  return TRUE;
-}
-
-/* static int usb_get_configuration(usb_dev_handle *dev) */
-/* { */
-/*   int ret; */
-/*   char config; */
-
-/*   ret = usb_control_msg(dev, USB_RECIP_DEVICE | USB_ENDPOINT_IN,  */
-/*                         USB_REQ_GET_CONFIGURATION, 0, 0, &amp;config, 1,  */
-/*                         LIBUSB_DEFAULT_TIMEOUT); */
-  
-/*   if(ret &gt;= 0) */
-/*     { */
-/*       return config; */
-/*     } */
-
-/*   return ret; */
-/* } */
-
-int usb_os_open(usb_dev_handle *dev)
-{
-  char dev_name[LIBUSB_PATH_MAX];
-  char *p;
-  /*   int config; */
-
-  if(!dev)
-    {
-      usb_error(&quot;usb_os_open: invalid device handle %p&quot;, dev);
-      return -EINVAL;
-    }
-
-  dev-&gt;impl_info = INVALID_HANDLE_VALUE;
-  dev-&gt;config = 0;
-  dev-&gt;interface = -1;
-  dev-&gt;altsetting = -1;
-
-  if(!dev-&gt;device-&gt;filename)
-    {
-      usb_error(&quot;usb_os_open: invalid file name&quot;);
-      return -ENOENT;
-    }
-
-  /* build the Windows file name from the unique device name */ 
-  strcpy(dev_name, dev-&gt;device-&gt;filename);
-
-  p = strstr(dev_name, &quot;--&quot;);
-
-  if(!p)
-    {
-      usb_error(&quot;usb_os_open: invalid file name %s&quot;, dev-&gt;device-&gt;filename);
-      return -ENOENT;
-    }
-  
-  *p = 0;
-
-  dev-&gt;impl_info = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
-                              FILE_FLAG_OVERLAPPED, NULL);
-      
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE) 
-    {
-      usb_error(&quot;usb_os_open: failed to open %s: win error: %s&quot;,
-                dev-&gt;device-&gt;filename, usb_win_error_to_string());
-      return -ENOENT;
-    }
-  
-  /* now, retrieve the device's current configuration, except from hubs */
-  /*   if(dev-&gt;device-&gt;config &amp;&amp; dev-&gt;device-&gt;config-&gt;interface */
-  /*      &amp;&amp; dev-&gt;device-&gt;config-&gt;interface[0].altsetting */
-  /*      &amp;&amp; dev-&gt;device-&gt;config-&gt;interface[0].altsetting[0].bInterfaceClass  */
-  /*      != USB_CLASS_HUB) */
-  /*     { */
-  /*       config = usb_get_configuration(dev); */
-      
-  /*       if(config &gt; 0) */
-  /*         { */
-  /*           dev-&gt;config = config; */
-  /*         } */
-  /*     } */
-
-  return 0;
-}
-
-int usb_os_close(usb_dev_handle *dev)
-{
-  if(dev-&gt;impl_info != INVALID_HANDLE_VALUE)
-    {
-      if(dev-&gt;interface &gt;= 0)
-        {
-          usb_release_interface(dev, dev-&gt;interface);
-        }
-
-      CloseHandle(dev-&gt;impl_info);
-      dev-&gt;impl_info = INVALID_HANDLE_VALUE;
-      dev-&gt;interface = -1;
-      dev-&gt;altsetting = -1;
-    }
-
-  return 0;
-}
-
-int usb_set_configuration(usb_dev_handle *dev, int configuration)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_set_configuration: error: device not open&quot;);
-      return -EINVAL;
-    }
-
-  if(dev-&gt;config == configuration)
-    {
-      return 0;
-    }
-
-  if(dev-&gt;interface &gt;= 0)
-    {
-      usb_error(&quot;usb_set_configuration: can't change configuration, &quot;
-                &quot;an interface is still in use (claimed)&quot;);
-      return -EINVAL;
-    }
-
-  req.configuration.configuration = configuration;
-  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_SET_CONFIGURATION, 
-                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_set_configuration: could not set config %d: &quot;
-                &quot;win error: %s&quot;, configuration, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  
-  dev-&gt;config = configuration;
-  dev-&gt;interface = -1;
-  dev-&gt;altsetting = -1;
-  
-  return 0;
-}
-
-int usb_claim_interface(usb_dev_handle *dev, int interface)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_claim_interface: device not open&quot;);
-      return -EINVAL;
-    }
-
-  if(!dev-&gt;config)
-    {
-      usb_error(&quot;usb_claim_interface: could not claim interface %d, invalid &quot;
-                &quot;configuration %d&quot;, interface, dev-&gt;config);
-      return -EINVAL;
-    }
-  
-  if(dev-&gt;interface == interface)
-    {
-      return 0;
-    }
-
-  req.interface.interface = interface;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_CLAIM_INTERFACE, 
-                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_claim_interface: could not claim interface %d, &quot;
-                &quot;win error: %s&quot;, interface, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  else
-    {
-      dev-&gt;interface = interface;
-      dev-&gt;altsetting = 0;
-      return 0;
-    }
-}
-
-int usb_release_interface(usb_dev_handle *dev, int interface)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_release_interface: device not open&quot;);
-      return -EINVAL;
-    }
-
-  if(!dev-&gt;config)
-    {
-      usb_error(&quot;usb_release_interface: could not release interface %d, &quot;
-                &quot;invalid configuration %d&quot;, interface, dev-&gt;config);
-      return -EINVAL;
-    }
-
-  req.interface.interface = interface;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RELEASE_INTERFACE, 
-                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_release_interface: could not release interface %d, &quot;
-                &quot;win error: %s&quot;, interface, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  else
-    {
-      dev-&gt;interface = -1;
-      dev-&gt;altsetting = -1;
-      
-      return 0;
-    }
-}
-
-int usb_set_altinterface(usb_dev_handle *dev, int alternate)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_set_altinterface: device not open&quot;);
-      return -EINVAL;
-    }
-
-  if(dev-&gt;config &lt;= 0)
-    {
-      usb_error(&quot;usb_set_altinterface: could not set alt interface %d: &quot;
-                &quot;invalid configuration %d&quot;, alternate, dev-&gt;config);
-      return -EINVAL;
-    }
-
-  if(dev-&gt;interface &lt; 0)
-    {
-      usb_error(&quot;usb_set_altinterface: could not set alt interface %d: &quot;
-                &quot;no interface claimed&quot;, alternate);
-      return -EINVAL;
-    }
-
-  req.interface.interface = dev-&gt;interface;
-  req.interface.altsetting = alternate;
-  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-  
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_SET_INTERFACE, 
-                   &amp;req, sizeof(libusb_request), 
-                   NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_set_altinterface: could not set alt interface &quot;
-                &quot;%d/%d: win error: %s&quot;,
-                dev-&gt;interface, alternate, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  
-  dev-&gt;altsetting = alternate;
-
-  return 0;
-}
-
-static int _usb_setup_async(usb_dev_handle *dev, void **context, 
-                            DWORD control_code,
-                            unsigned char ep, int pktsize)
-{
-  usb_context_t **c = (usb_context_t **)context;
-  
-  if(((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE)
-      || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_WRITE)) 
-     &amp;&amp; (ep &amp; USB_ENDPOINT_IN))
-    {
-      usb_error(&quot;_usb_setup_async: invalid endpoint 0x%02x&quot;, ep);
-      return -EINVAL;
-    }
-
-  if(((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ)
-      || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_READ))
-     &amp;&amp; !(ep &amp; USB_ENDPOINT_IN))
-    {
-      usb_error(&quot;_usb_setup_async: invalid endpoint 0x%02x&quot;, ep);
-      return -EINVAL;
-    }
-
-  *c = malloc(sizeof(usb_context_t));
-  
-  if(!*c)
-    {
-      usb_error(&quot;_usb_setup_async: memory allocation error&quot;);
-      return -ENOMEM;
-    }
-
-  memset(*c, 0, sizeof(usb_context_t));
-
-  (*c)-&gt;dev = dev;
-  (*c)-&gt;req.endpoint.endpoint = ep;
-  (*c)-&gt;req.endpoint.packet_size = pktsize;
-  (*c)-&gt;control_code = control_code;
-
-  (*c)-&gt;ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
-  if(!(*c)-&gt;ol.hEvent)
-    {
-      free(*c);
-      *c = NULL;
-      usb_error(&quot;_usb_setup_async: creating event failed: win error: %s&quot;, 
-                usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-
-  return 0;
-}
-
-int usb_submit_async(void *context, char *bytes, int size)
-{
-  usb_context_t *c = (usb_context_t *)context;
-
-  if(!c)
-    {
-      usb_error(&quot;usb_submit_async: invalid context&quot;);
-      return -EINVAL;
-    }
-    
-  if(c-&gt;dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_submit_async: device not open&quot;);
-      return -EINVAL;
-    }
-
-  if(c-&gt;dev-&gt;config &lt;= 0)
-    {
-      usb_error(&quot;usb_submit_async: invalid configuration %d&quot;, c-&gt;dev-&gt;config);
-      return -EINVAL;
-    }
-
-  if(c-&gt;dev-&gt;interface &lt; 0)
-    {
-      usb_error(&quot;usb_submit_async: invalid interface %d&quot;, c-&gt;dev-&gt;interface);
-      return -EINVAL;
-    }
-  
-  
-  c-&gt;ol.Offset = 0;
-  c-&gt;ol.OffsetHigh = 0;
-  c-&gt;bytes = bytes;
-  c-&gt;size = size;
-
-  ResetEvent(c-&gt;ol.hEvent);
-  
-  if(!DeviceIoControl(c-&gt;dev-&gt;impl_info, 
-                      c-&gt;control_code, 
-                      &amp;c-&gt;req, sizeof(libusb_request), 
-                      c-&gt;bytes, 
-                      c-&gt;size, NULL, &amp;c-&gt;ol))
-    {
-      if(GetLastError() != ERROR_IO_PENDING)
-        {
-          usb_error(&quot;usb_submit_async: submitting request failed, &quot;
-                    &quot;win error: %s&quot;, usb_win_error_to_string());
-          return -usb_win_error_to_errno();
-        }
-    }
-
-  return 0;
-}
-
-static int _usb_reap_async(void *context, int timeout, int cancel)
-{
-  usb_context_t *c = (usb_context_t *)context;
-  ULONG ret = 0;
-    
-  if(!c)
-    {
-      usb_error(&quot;usb_reap: invalid context&quot;);
-      return -EINVAL;
-    }
-
-  if(WaitForSingleObject(c-&gt;ol.hEvent, timeout) == WAIT_TIMEOUT)
-    {
-      /* request timed out */
-      if(cancel)
-        {
-          _usb_cancel_io(c);
-        }
-
-      usb_error(&quot;usb_reap: timeout error&quot;);
-      return -ETIMEDOUT;
-    }
-  
-  if(!GetOverlappedResult(c-&gt;dev-&gt;impl_info, &amp;c-&gt;ol, &amp;ret, TRUE))
-    {
-      usb_error(&quot;usb_reap: reaping request failed, win error: %s&quot;, 
-                usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-
-  return ret;
-}
-
-int usb_reap_async(void *context, int timeout)
-{
-  return _usb_reap_async(context, timeout, TRUE);
-}
-
-int usb_reap_async_nocancel(void *context, int timeout)
-{
-  return _usb_reap_async(context, timeout, FALSE);
-}
-
-
-int usb_cancel_async(void *context)
-{
-  /* NOTE that this function will cancel all pending URBs */
-  /* on the same endpoint as this particular context, or even */
-  /* all pending URBs for this particular device. */
-  
-  usb_context_t *c = (usb_context_t *)context;
-  
-  if(!c)
-    {
-      usb_error(&quot;usb_cancel_async: invalid context&quot;);
-      return -EINVAL;
-    }
-
-  if(c-&gt;dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_cancel_async: device not open&quot;);
-      return -EINVAL;
-    }
-  
-  _usb_cancel_io(c);
-
-  return 0;
-}
-
-int usb_free_async(void **context)
-{
-  usb_context_t **c = (usb_context_t **)context;
-
-  if(!*c)
-    {
-      usb_error(&quot;usb_free_async: invalid context&quot;);
-      return -EINVAL;
-    }
-
-  CloseHandle((*c)-&gt;ol.hEvent);
-
-  free(*c);
-  *c = NULL;
-
-  return 0;
-}
-
-static int _usb_transfer_sync(usb_dev_handle *dev, int control_code,
-                              int ep, int pktsize, char *bytes, int size,
-                              int timeout)
-{
-  void *context = NULL;
-  int transmitted = 0;
-  int ret;
-  int requested;
-
-  ret = _usb_setup_async(dev, &amp;context, control_code, (unsigned char )ep, 
-                         pktsize);
-
-  if(ret &lt; 0)
-    {
-      return ret;
-    }
-
-  do {
-    requested = size &gt; LIBUSB_MAX_READ_WRITE ? LIBUSB_MAX_READ_WRITE : size;
-
-    ret = usb_submit_async(context, bytes, requested);
-    
-    if(ret &lt; 0)
-      {
-        transmitted = ret;
-        break;
-      }
-
-    ret = usb_reap_async(context, timeout);
-
-    if(ret &lt; 0)
-      {
-        transmitted = ret;
-        break;
-      }
-
-    transmitted += ret;
-    bytes += ret;
-    size -= ret;
-  } while(size &gt; 0 &amp;&amp; ret == requested);
-  
-  usb_free_async(&amp;context);
-
-  return transmitted;
-}
-
-int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
-                   int timeout)
-{
-  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
-                            ep, 0, bytes, size, timeout);
-}
-
-int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
-                  int timeout)
-{
-  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
-                            ep, 0, bytes, size, timeout);
-}
-
-int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
-                        int timeout)
-{
-  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
-                            ep, 0, bytes, size, timeout);
-}
-
-int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
-                       int timeout)
-{
-  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
-                            ep, 0, bytes, size, timeout);
-}
-
-int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, 
-                                unsigned char ep, int pktsize)
-{
-  if(ep &amp; 0x80)
-    return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_READ,
-                            ep, pktsize);
-  else
-    return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_WRITE,
-                            ep, pktsize);    
-}
-
-int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep)
-{
-  if(ep &amp; 0x80)
-    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
-                            ep, 0);
-  else
-    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
-                            ep, 0);    
-}
-
-int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, 
-                              unsigned char ep)
-{
-  if(ep &amp; 0x80)
-    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
-                            ep, 0);
-  else
-    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
-                            ep, 0);    
-}
-
-int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
-                    int value, int index, char *bytes, int size, int timeout)
-{
-  int read = 0;
-  libusb_request req;
-  void *out = &amp;req;
-  int out_size = sizeof(libusb_request);
-  void *in = bytes;
-  int in_size = size;
-  int code;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_control_msg: device not open&quot;);
-      return -EINVAL;
-    }
-
-  req.timeout = timeout;
-
-  /* windows doesn't support generic control messages, so it needs to be */
-  /* split up */ 
-  switch(requesttype &amp; (0x03 &lt;&lt; 5))
-    {
-    case USB_TYPE_STANDARD:      
-      switch(request)
-        {
-        case USB_REQ_GET_STATUS: 
-          req.status.recipient = requesttype &amp; 0x1F;
-          req.status.index = index;
-          code = LIBUSB_IOCTL_GET_STATUS;
-          break;
-      
-        case USB_REQ_CLEAR_FEATURE:
-          req.feature.recipient = requesttype &amp; 0x1F;
-          req.feature.feature = value;
-          req.feature.index = index;
-          code = LIBUSB_IOCTL_CLEAR_FEATURE;
-          break;
-	  
-        case USB_REQ_SET_FEATURE:
-          req.feature.recipient = requesttype &amp; 0x1F;
-          req.feature.feature = value;
-          req.feature.index = index;
-          code = LIBUSB_IOCTL_SET_FEATURE;
-          break;
-
-        case USB_REQ_GET_DESCRIPTOR:
-          req.descriptor.recipient = requesttype &amp; 0x1F;
-          req.descriptor.type = (value &gt;&gt; 8) &amp; 0xFF;
-          req.descriptor.index = value &amp; 0xFF;
-          req.descriptor.language_id = index;
-          code = LIBUSB_IOCTL_GET_DESCRIPTOR;
-          break;
-	  
-        case USB_REQ_SET_DESCRIPTOR:
-          req.descriptor.recipient = requesttype &amp; 0x1F;
-          req.descriptor.type = (value &gt;&gt; 8) &amp; 0xFF;
-          req.descriptor.index = value &amp; 0xFF;
-          req.descriptor.language_id = index;
-          code = LIBUSB_IOCTL_SET_DESCRIPTOR;
-          break;
-	  
-        case USB_REQ_GET_CONFIGURATION:
-          code = LIBUSB_IOCTL_GET_CONFIGURATION;
-          break;
-      
-        case USB_REQ_SET_CONFIGURATION:	  
-          req.configuration.configuration = value;
-          code = LIBUSB_IOCTL_SET_CONFIGURATION;
-          break;
-	  
-        case USB_REQ_GET_INTERFACE:
-          req.interface.interface = index;
-          code = LIBUSB_IOCTL_GET_INTERFACE;	  
-          break;
-      
-        case USB_REQ_SET_INTERFACE:
-          req.interface.interface = index;
-          req.interface.altsetting = value;
-          code = LIBUSB_IOCTL_SET_INTERFACE;	  
-          break;
-	  
-        default:
-          usb_error(&quot;usb_control_msg: invalid request 0x%x&quot;, request);
-          return -EINVAL;
-        }
-      break;
-
-    case USB_TYPE_VENDOR:  
-    case USB_TYPE_CLASS:
-
-      req.vendor.type = (requesttype &gt;&gt; 5) &amp; 0x03;
-      req.vendor.recipient = requesttype &amp; 0x1F;
-      req.vendor.request = request;
-      req.vendor.value = value;
-      req.vendor.index = index;
-
-      if(requesttype &amp; 0x80)
-        code = LIBUSB_IOCTL_VENDOR_READ;
-      else
-        code = LIBUSB_IOCTL_VENDOR_WRITE;
-      break;
-
-    case USB_TYPE_RESERVED:
-    default:
-      usb_error(&quot;usb_control_msg: invalid or unsupported request type: %x&quot;, 
-                requesttype);
-      return -EINVAL;
-    }
-  
-  /* out request? */
-  if(!(requesttype &amp; USB_ENDPOINT_IN))
-    {
-      if(!(out = malloc(sizeof(libusb_request) + size)))
-        {
-          usb_error(&quot;usb_control_msg: memory allocation failed&quot;); 
-          return -ENOMEM;
-        }
-      
-      memcpy(out, &amp;req, sizeof(libusb_request));
-      memcpy((char *)out + sizeof(libusb_request), bytes, size);
-      out_size = sizeof(libusb_request) + size;
-      in = NULL; in_size = 0;
-    }
-
-  if(!_usb_io_sync(dev-&gt;impl_info, code, out, out_size, in, in_size, &amp;read))
-    {
-      usb_error(&quot;usb_control_msg: sending control message failed, &quot;
-                &quot;win error: %s&quot;, usb_win_error_to_string());
-      if(!(requesttype &amp; USB_ENDPOINT_IN))
-        {
-          free(out);
-        }
-      return -usb_win_error_to_errno();
-    }
-
-  /* out request? */
-  if(!(requesttype &amp; USB_ENDPOINT_IN))
-    {
-      free(out);
-      return size;
-    }
-  else
-    return read;
-}
-
-
-int usb_os_find_busses(struct usb_bus **busses)
-{
-  struct usb_bus *bus = NULL;
-
-  /* create one 'virtual' bus */
-  
-  bus = malloc(sizeof(struct usb_bus));
-
-  if(!bus)
-    {
-      usb_error(&quot;usb_os_find_busses: memory allocation failed&quot;);
-      return -ENOMEM;
-    }
-  
-  memset(bus, 0, sizeof(*bus));
-  strcpy(bus-&gt;dirname, LIBUSB_BUS_NAME);
-  
-  usb_message(&quot;usb_os_find_busses: found %s&quot;, bus-&gt;dirname);
-  
-  *busses = bus;
-
-  return 0;
-}
-
-int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
-{
-  int i;
-  struct usb_device *dev, *fdev = NULL;
-  char dev_name[LIBUSB_PATH_MAX];
-  int ret;
-  HANDLE handle;
-  libusb_request req;
-
-  for(i = 1; i &lt; LIBUSB_MAX_DEVICES; i++)
-    {
-      ret = 0;
-
-      _snprintf(dev_name, sizeof(dev_name) - 1,&quot;%s%04d&quot;, 
-                LIBUSB_DEVICE_NAME, i);
-
-      if(!(dev = malloc(sizeof(*dev)))) 
-        {
-          usb_error(&quot;usb_os_find_devices: memory allocation failed&quot;);
-          return -ENOMEM;
-        }
-      
-      memset(dev, 0, sizeof(*dev));
-      dev-&gt;bus = bus;
-      dev-&gt;devnum = (unsigned char)i;
-
-      handle = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
-                          FILE_FLAG_OVERLAPPED, NULL);
-
-      if(handle == INVALID_HANDLE_VALUE) 
-        {
-          free(dev);
-          continue;
-        }
-
-      /* retrieve device descriptor */
-      req.descriptor.type = USB_DT_DEVICE;
-      req.descriptor.recipient = USB_RECIP_DEVICE;
-      req.descriptor.index = 0;
-      req.descriptor.language_id = 0;
-      req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-      
-      _usb_io_sync(handle, LIBUSB_IOCTL_GET_DESCRIPTOR, 
-                   &amp;req, sizeof(libusb_request), 
-                   &amp;dev-&gt;descriptor, USB_DT_DEVICE_SIZE, &amp;ret);
-      
-      if(ret &lt; USB_DT_DEVICE_SIZE) 
-        {
-          usb_error(&quot;usb_os_find_devices: couldn't read device descriptor&quot;);
-          free(dev);
-          CloseHandle(handle);
-          continue;
-        }
-      
-      _snprintf(dev-&gt;filename, LIBUSB_PATH_MAX - 1, &quot;%s--0x%04x-0x%04x&quot;, 
-                dev_name, dev-&gt;descriptor.idVendor, dev-&gt;descriptor.idProduct);
-
-      CloseHandle(handle);
-
-      LIST_ADD(fdev, dev);
-
-      usb_message(&quot;usb_os_find_devices: found %s on %s&quot;,
-                  dev-&gt;filename, bus-&gt;dirname);
-    }
-  
-  *devices = fdev;
-
-  return 0;
-}
-
-
-void usb_os_init(void)
-{
-  HANDLE dev;
-  libusb_request req;
-  int i;
-  int ret;
-  char dev_name[LIBUSB_PATH_MAX];
-
-  usb_message(&quot;usb_os_init: dll version: %d.%d.%d.%d&quot;,
-              VERSION_MAJOR, VERSION_MINOR,
-              VERSION_MICRO, VERSION_NANO);
-
-
-  for(i = 1; i &lt; LIBUSB_MAX_DEVICES; i++)
-    {
-      /* build the Windows file name */
-      _snprintf(dev_name, sizeof(dev_name) - 1,&quot;%s%04d&quot;, 
-                LIBUSB_DEVICE_NAME, i);
-
-      dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
-                       FILE_FLAG_OVERLAPPED, NULL);
-  
-      if(dev == INVALID_HANDLE_VALUE) 
-        {
-          continue;
-        }
-      
-      if(!_usb_io_sync(dev, LIBUSB_IOCTL_GET_VERSION,
-                       &amp;req, sizeof(libusb_request), 
-                       &amp;req, sizeof(libusb_request), &amp;ret) 
-         || (ret &lt; sizeof(libusb_request)))
-        {
-          usb_error(&quot;usb_os_init: getting driver version failed&quot;);
-          CloseHandle(dev);
-          continue;
-        }
-      else 
-        {
-          _usb_version.driver.major = req.version.major;
-          _usb_version.driver.minor = req.version.minor;
-          _usb_version.driver.micro = req.version.micro;
-          _usb_version.driver.nano = req.version.nano;
-	  
-          usb_message(&quot;usb_os_init: driver version: %d.%d.%d.%d&quot;,
-                      req.version.major, req.version.minor, 
-                      req.version.micro, req.version.nano);
-      
-          /* set debug level */
-          req.timeout = 0;
-          req.debug.level = __usb_debug;
-          
-          if(!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, 
-                           &amp;req, sizeof(libusb_request), 
-                           NULL, 0, NULL))
-            {
-              usb_error(&quot;usb_os_init: setting debug level failed&quot;);
-            }
-          
-          CloseHandle(dev);
-          break;
-        }
-    }
-}
-
-
-int usb_resetep(usb_dev_handle *dev, unsigned int ep)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_resetep: device not open&quot;);
-      return -EINVAL;
-    }
-
-  req.endpoint.endpoint = (int)ep;
-  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &amp;req, 
-                   sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_resetep: could not abort ep 0x%02x, win error: %s&quot;, 
-                ep, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &amp;req, 
-                   sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_resetep: could not reset ep 0x%02x, win error: %s&quot;, 
-                ep, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  
-  return 0;
-}
-
-int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_clear_halt: device not open&quot;);
-      return -EINVAL;
-    }
-
-  req.endpoint.endpoint = (int)ep;
-  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &amp;req, 
-                   sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_clear_halt: could not clear halt, ep 0x%02x, &quot;
-                &quot;win error: %s&quot;, ep, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  
-  return 0;
-}
-
-int usb_reset(usb_dev_handle *dev)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;usb_reset: device not open&quot;);
-      return -EINVAL;
-    }
-
-  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RESET_DEVICE,
-                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;usb_reset: could not reset device, win error: %s&quot;, 
-                usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-
-  return 0;
-}
-
-const struct usb_version *usb_get_version(void)
-{
-  return &amp;_usb_version;
-}
-
-void usb_set_debug(int level)
-{
-  HANDLE dev;
-  libusb_request req;
-  int i;
-  char dev_name[LIBUSB_PATH_MAX];
-
-  if(__usb_debug || level)
-    {
-      usb_message(&quot;usb_set_debug: setting debugging level to %d (%s)\n&quot;,
-                  level, level ? &quot;on&quot; : &quot;off&quot;);
-    }
-
-  __usb_debug = level;
-
-  /* find a valid device */
-  for(i = 1; i &lt; LIBUSB_MAX_DEVICES; i++)
-    {
-      /* build the Windows file name */
-      _snprintf(dev_name, sizeof(dev_name) - 1,&quot;%s%04d&quot;, 
-                LIBUSB_DEVICE_NAME, i);
-
-      dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
-                       FILE_FLAG_OVERLAPPED, NULL);
-  
-      if(dev == INVALID_HANDLE_VALUE) 
-        {
-          continue;
-        }
-      
-      /* set debug level */
-      req.timeout = 0;
-      req.debug.level = __usb_debug;
-      
-      if(!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, 
-                       &amp;req, sizeof(libusb_request), 
-                       NULL, 0, NULL))
-        {
-          usb_error(&quot;usb_os_init: setting debug level failed&quot;);
-        }
-      
-      CloseHandle(dev);
-
-      break;
-    }
-}
-
-int usb_os_determine_children(struct usb_bus *bus)
-{
-  struct usb_device *dev;
-  int i = 0;
-
-  /* add a virtual hub to the bus to emulate this feature */
-  if(_usb_add_virtual_hub(bus))
-    {
-      if(bus-&gt;root_dev-&gt;children)
-        {
-          free(bus-&gt;root_dev-&gt;children);
-        }
-
-      bus-&gt;root_dev-&gt;num_children = 0;
-      for(dev = bus-&gt;devices; dev; dev = dev-&gt;next)
-        bus-&gt;root_dev-&gt;num_children++;
-
-      bus-&gt;root_dev-&gt;children 
-        = malloc(sizeof(struct usb_device *) * bus-&gt;root_dev-&gt;num_children);
-
-      for(dev = bus-&gt;devices; dev; dev = dev-&gt;next)
-        bus-&gt;root_dev-&gt;children[i++] = dev; 
-    }
-
-  return 0;
-}
-
-static int _usb_cancel_io(usb_context_t *context)
-{
-  int ret;
-  ret = _usb_abort_ep(context-&gt;dev, context-&gt;req.endpoint.endpoint);
-  WaitForSingleObject(context-&gt;ol.hEvent, 0);
-  return ret; 
-}
-
-static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep)
-{
-  libusb_request req;
-
-  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
-    {
-      usb_error(&quot;_usb_abort_ep: device not open&quot;);
-      return -EINVAL;
-    }
-
-  req.endpoint.endpoint = (int)ep;
-  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
-
-  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &amp;req, 
-                   sizeof(libusb_request), NULL, 0, NULL))
-    {
-      usb_error(&quot;_usb_abort_ep: could not abort ep 0x%02x, win error: %s&quot;, 
-                ep, usb_win_error_to_string());
-      return -usb_win_error_to_errno();
-    }
-  
-  return 0;
-}
-
-static int _usb_io_sync(HANDLE dev, unsigned int code, void *out, int out_size,
-                        void *in, int in_size, int *ret)
-{
-  OVERLAPPED ol;
-  DWORD _ret;
-
-  memset(&amp;ol, 0, sizeof(ol));  
-
-  if(ret)
-    *ret = 0;
-
-  ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-
-  if(!ol.hEvent)
-    return FALSE;
-  
-  if(!DeviceIoControl(dev, code, out, out_size, in, in_size, NULL, &amp;ol))
-    {
-      if(GetLastError() != ERROR_IO_PENDING)
-        {
-          CloseHandle(ol.hEvent);
-          return FALSE;
-        }
-    }
-
-  if(GetOverlappedResult(dev, &amp;ol, &amp;_ret, TRUE))
-    {
-      if(ret)
-        *ret = (int)_ret;
-      CloseHandle(ol.hEvent);
-      return TRUE;
-    }
-  
-  CloseHandle(ol.hEvent);
-  return FALSE;
-}
-
-static int _usb_add_virtual_hub(struct usb_bus *bus)
-{
-  struct usb_device *dev;
-
-  if(!bus-&gt;root_dev)
-    {
-      if(!(dev = malloc(sizeof(*dev))))
-        return FALSE;
-      
-      memset(dev, 0, sizeof(*dev));
-      strcpy(dev-&gt;filename, &quot;virtual-hub&quot;);
-      dev-&gt;bus = bus;
-      
-      dev-&gt;descriptor.bLength = USB_DT_DEVICE_SIZE;
-      dev-&gt;descriptor.bDescriptorType = USB_DT_DEVICE;
-      dev-&gt;descriptor.bcdUSB = 0x0200;
-      dev-&gt;descriptor.bDeviceClass = USB_CLASS_HUB;
-      dev-&gt;descriptor.bDeviceSubClass = 0;
-      dev-&gt;descriptor.bDeviceProtocol = 0;
-      dev-&gt;descriptor.bMaxPacketSize0 = 64;
-      dev-&gt;descriptor.idVendor = 0;
-      dev-&gt;descriptor.idProduct = 0;
-      dev-&gt;descriptor.bcdDevice = 0x100;
-      dev-&gt;descriptor.iManufacturer = 0;
-      dev-&gt;descriptor.iProduct = 0;
-      dev-&gt;descriptor.iSerialNumber = 0;
-      dev-&gt;descriptor.bNumConfigurations = 0;
-      
-      bus-&gt;root_dev = dev;
-    }
-
-  return TRUE;
-}
-
-static void _usb_free_bus_list(struct usb_bus *bus)
-{
-  if(bus)
-    {
-      _usb_free_bus_list(bus-&gt;next);
-      if(bus-&gt;root_dev)
-        usb_free_dev(bus-&gt;root_dev);
-      _usb_free_dev_list(bus-&gt;devices);
-      usb_free_bus(bus);
-    }
-}
-
-static void _usb_free_dev_list(struct usb_device *dev)
-{
-  if(dev)
-    {
-      _usb_free_dev_list(dev-&gt;next);
-      usb_free_dev(dev);
-    }
-}
-
-static void _usb_deinit(void)
-{
-  _usb_free_bus_list(usb_get_busses());
-}
+/* LIBUSB-WIN32, Generic Windows USB Library
+ * Copyright (c) 2002-2005 Stephan Meyer &lt;ste_meyer@web.de&gt;
+ * Copyright (c) 2000-2005 Johannes Erdfelt &lt;johannes@erdfelt.com&gt;
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;stdio.h&gt; 
+#include &lt;errno.h&gt;
+#include &lt;ctype.h&gt;
+#include &lt;windows.h&gt;
+#include &lt;winioctl.h&gt;
+#include &lt;setupapi.h&gt;
+
+#include &quot;usb.h&quot;
+#include &quot;error.h&quot;
+#include &quot;usbi.h&quot;
+#include &quot;driver_api.h&quot;
+#include &quot;registry.h&quot;
+
+
+
+#define LIBUSB_DEFAULT_TIMEOUT 5000
+#define LIBUSB_DEVICE_NAME &quot;\\\\.\\libusb0-&quot;
+#define LIBUSB_BUS_NAME &quot;bus-0&quot;
+#define LIBUSB_MAX_DEVICES 256
+
+extern int __usb_debug;
+
+typedef struct {
+  usb_dev_handle *dev;
+  libusb_request req;
+  char *bytes;
+  int size;
+  DWORD control_code;
+  OVERLAPPED ol;
+} usb_context_t;
+
+
+static struct usb_version _usb_version = {
+  { VERSION_MAJOR, 
+    VERSION_MINOR, 
+    VERSION_MICRO, 
+    VERSION_NANO },
+  { -1, -1, -1, -1 }
+};
+
+
+static int _usb_setup_async(usb_dev_handle *dev, void **context, 
+                            DWORD control_code,
+                            unsigned char ep, int pktsize);
+static int _usb_transfer_sync(usb_dev_handle *dev, int control_code,
+                              int ep, int pktsize, char *bytes, int size, 
+                              int timeout);
+
+/* static int usb_get_configuration(usb_dev_handle *dev); */
+static int _usb_cancel_io(usb_context_t *context);
+static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep);
+
+static int _usb_io_sync(HANDLE dev, unsigned int code, void *in, int in_size,
+                        void *out, int out_size, int *ret);
+static int _usb_reap_async(void *context, int timeout, int cancel);
+static int _usb_add_virtual_hub(struct usb_bus *bus);
+
+static void _usb_free_bus_list(struct usb_bus *bus);
+static void _usb_free_dev_list(struct usb_device *dev);
+static void _usb_deinit(void);
+
+/* DLL main entry point */
+BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved)
+{
+  switch(reason)
+    {
+    case DLL_PROCESS_ATTACH:
+      break;
+    case DLL_PROCESS_DETACH:
+      _usb_deinit();
+      break;
+    case DLL_THREAD_ATTACH:
+      break;
+    case DLL_THREAD_DETACH:
+      break;
+    default:
+      break;
+    }
+  return TRUE;
+}
+
+/* static int usb_get_configuration(usb_dev_handle *dev) */
+/* { */
+/*   int ret; */
+/*   char config; */
+
+/*   ret = usb_control_msg(dev, USB_RECIP_DEVICE | USB_ENDPOINT_IN,  */
+/*                         USB_REQ_GET_CONFIGURATION, 0, 0, &amp;config, 1,  */
+/*                         LIBUSB_DEFAULT_TIMEOUT); */
+  
+/*   if(ret &gt;= 0) */
+/*     { */
+/*       return config; */
+/*     } */
+
+/*   return ret; */
+/* } */
+
+int usb_os_open(usb_dev_handle *dev)
+{
+  char dev_name[LIBUSB_PATH_MAX];
+  char *p;
+  /*   int config; */
+
+  if(!dev)
+    {
+      usb_error(&quot;usb_os_open: invalid device handle %p&quot;, dev);
+      return -EINVAL;
+    }
+
+  dev-&gt;impl_info = INVALID_HANDLE_VALUE;
+  dev-&gt;config = 0;
+  dev-&gt;interface = -1;
+  dev-&gt;altsetting = -1;
+
+  if(!dev-&gt;device-&gt;filename)
+    {
+      usb_error(&quot;usb_os_open: invalid file name&quot;);
+      return -ENOENT;
+    }
+
+  /* build the Windows file name from the unique device name */ 
+  strcpy(dev_name, dev-&gt;device-&gt;filename);
+
+  p = strstr(dev_name, &quot;--&quot;);
+
+  if(!p)
+    {
+      usb_error(&quot;usb_os_open: invalid file name %s&quot;, dev-&gt;device-&gt;filename);
+      return -ENOENT;
+    }
+  
+  *p = 0;
+
+  dev-&gt;impl_info = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
+                              FILE_FLAG_OVERLAPPED, NULL);
+      
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE) 
+    {
+      usb_error(&quot;usb_os_open: failed to open %s: win error: %s&quot;,
+                dev-&gt;device-&gt;filename, usb_win_error_to_string());
+      return -ENOENT;
+    }
+  
+  /* now, retrieve the device's current configuration, except from hubs */
+  /*   if(dev-&gt;device-&gt;config &amp;&amp; dev-&gt;device-&gt;config-&gt;interface */
+  /*      &amp;&amp; dev-&gt;device-&gt;config-&gt;interface[0].altsetting */
+  /*      &amp;&amp; dev-&gt;device-&gt;config-&gt;interface[0].altsetting[0].bInterfaceClass  */
+  /*      != USB_CLASS_HUB) */
+  /*     { */
+  /*       config = usb_get_configuration(dev); */
+      
+  /*       if(config &gt; 0) */
+  /*         { */
+  /*           dev-&gt;config = config; */
+  /*         } */
+  /*     } */
+
+  return 0;
+}
+
+int usb_os_close(usb_dev_handle *dev)
+{
+  if(dev-&gt;impl_info != INVALID_HANDLE_VALUE)
+    {
+      if(dev-&gt;interface &gt;= 0)
+        {
+          usb_release_interface(dev, dev-&gt;interface);
+        }
+
+      CloseHandle(dev-&gt;impl_info);
+      dev-&gt;impl_info = INVALID_HANDLE_VALUE;
+      dev-&gt;interface = -1;
+      dev-&gt;altsetting = -1;
+    }
+
+  return 0;
+}
+
+int usb_set_configuration(usb_dev_handle *dev, int configuration)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_set_configuration: error: device not open&quot;);
+      return -EINVAL;
+    }
+
+  if(dev-&gt;config == configuration)
+    {
+      return 0;
+    }
+
+  if(dev-&gt;interface &gt;= 0)
+    {
+      usb_error(&quot;usb_set_configuration: can't change configuration, &quot;
+                &quot;an interface is still in use (claimed)&quot;);
+      return -EINVAL;
+    }
+
+  req.configuration.configuration = configuration;
+  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_SET_CONFIGURATION, 
+                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_set_configuration: could not set config %d: &quot;
+                &quot;win error: %s&quot;, configuration, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  
+  dev-&gt;config = configuration;
+  dev-&gt;interface = -1;
+  dev-&gt;altsetting = -1;
+  
+  return 0;
+}
+
+int usb_claim_interface(usb_dev_handle *dev, int interface)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_claim_interface: device not open&quot;);
+      return -EINVAL;
+    }
+
+  if(!dev-&gt;config)
+    {
+      usb_error(&quot;usb_claim_interface: could not claim interface %d, invalid &quot;
+                &quot;configuration %d&quot;, interface, dev-&gt;config);
+      return -EINVAL;
+    }
+  
+  if(dev-&gt;interface == interface)
+    {
+      return 0;
+    }
+
+  req.interface.interface = interface;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_CLAIM_INTERFACE, 
+                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_claim_interface: could not claim interface %d, &quot;
+                &quot;win error: %s&quot;, interface, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  else
+    {
+      dev-&gt;interface = interface;
+      dev-&gt;altsetting = 0;
+      return 0;
+    }
+}
+
+int usb_release_interface(usb_dev_handle *dev, int interface)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_release_interface: device not open&quot;);
+      return -EINVAL;
+    }
+
+  if(!dev-&gt;config)
+    {
+      usb_error(&quot;usb_release_interface: could not release interface %d, &quot;
+                &quot;invalid configuration %d&quot;, interface, dev-&gt;config);
+      return -EINVAL;
+    }
+
+  req.interface.interface = interface;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RELEASE_INTERFACE, 
+                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_release_interface: could not release interface %d, &quot;
+                &quot;win error: %s&quot;, interface, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  else
+    {
+      dev-&gt;interface = -1;
+      dev-&gt;altsetting = -1;
+      
+      return 0;
+    }
+}
+
+int usb_set_altinterface(usb_dev_handle *dev, int alternate)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_set_altinterface: device not open&quot;);
+      return -EINVAL;
+    }
+
+  if(dev-&gt;config &lt;= 0)
+    {
+      usb_error(&quot;usb_set_altinterface: could not set alt interface %d: &quot;
+                &quot;invalid configuration %d&quot;, alternate, dev-&gt;config);
+      return -EINVAL;
+    }
+
+  if(dev-&gt;interface &lt; 0)
+    {
+      usb_error(&quot;usb_set_altinterface: could not set alt interface %d: &quot;
+                &quot;no interface claimed&quot;, alternate);
+      return -EINVAL;
+    }
+
+  req.interface.interface = dev-&gt;interface;
+  req.interface.altsetting = alternate;
+  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+  
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_SET_INTERFACE, 
+                   &amp;req, sizeof(libusb_request), 
+                   NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_set_altinterface: could not set alt interface &quot;
+                &quot;%d/%d: win error: %s&quot;,
+                dev-&gt;interface, alternate, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  
+  dev-&gt;altsetting = alternate;
+
+  return 0;
+}
+
+static int _usb_setup_async(usb_dev_handle *dev, void **context, 
+                            DWORD control_code,
+                            unsigned char ep, int pktsize)
+{
+  usb_context_t **c = (usb_context_t **)context;
+  
+  if(((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE)
+      || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_WRITE)) 
+     &amp;&amp; (ep &amp; USB_ENDPOINT_IN))
+    {
+      usb_error(&quot;_usb_setup_async: invalid endpoint 0x%02x&quot;, ep);
+      return -EINVAL;
+    }
+
+  if(((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ)
+      || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_READ))
+     &amp;&amp; !(ep &amp; USB_ENDPOINT_IN))
+    {
+      usb_error(&quot;_usb_setup_async: invalid endpoint 0x%02x&quot;, ep);
+      return -EINVAL;
+    }
+
+  *c = malloc(sizeof(usb_context_t));
+  
+  if(!*c)
+    {
+      usb_error(&quot;_usb_setup_async: memory allocation error&quot;);
+      return -ENOMEM;
+    }
+
+  memset(*c, 0, sizeof(usb_context_t));
+
+  (*c)-&gt;dev = dev;
+  (*c)-&gt;req.endpoint.endpoint = ep;
+  (*c)-&gt;req.endpoint.packet_size = pktsize;
+  (*c)-&gt;control_code = control_code;
+
+  (*c)-&gt;ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+  if(!(*c)-&gt;ol.hEvent)
+    {
+      free(*c);
+      *c = NULL;
+      usb_error(&quot;_usb_setup_async: creating event failed: win error: %s&quot;, 
+                usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+
+  return 0;
+}
+
+int usb_submit_async(void *context, char *bytes, int size)
+{
+  usb_context_t *c = (usb_context_t *)context;
+
+  if(!c)
+    {
+      usb_error(&quot;usb_submit_async: invalid context&quot;);
+      return -EINVAL;
+    }
+    
+  if(c-&gt;dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_submit_async: device not open&quot;);
+      return -EINVAL;
+    }
+
+  if(c-&gt;dev-&gt;config &lt;= 0)
+    {
+      usb_error(&quot;usb_submit_async: invalid configuration %d&quot;, c-&gt;dev-&gt;config);
+      return -EINVAL;
+    }
+
+  if(c-&gt;dev-&gt;interface &lt; 0)
+    {
+      usb_error(&quot;usb_submit_async: invalid interface %d&quot;, c-&gt;dev-&gt;interface);
+      return -EINVAL;
+    }
+  
+  
+  c-&gt;ol.Offset = 0;
+  c-&gt;ol.OffsetHigh = 0;
+  c-&gt;bytes = bytes;
+  c-&gt;size = size;
+
+  ResetEvent(c-&gt;ol.hEvent);
+  
+  if(!DeviceIoControl(c-&gt;dev-&gt;impl_info, 
+                      c-&gt;control_code, 
+                      &amp;c-&gt;req, sizeof(libusb_request), 
+                      c-&gt;bytes, 
+                      c-&gt;size, NULL, &amp;c-&gt;ol))
+    {
+      if(GetLastError() != ERROR_IO_PENDING)
+        {
+          usb_error(&quot;usb_submit_async: submitting request failed, &quot;
+                    &quot;win error: %s&quot;, usb_win_error_to_string());
+          return -usb_win_error_to_errno();
+        }
+    }
+
+  return 0;
+}
+
+static int _usb_reap_async(void *context, int timeout, int cancel)
+{
+  usb_context_t *c = (usb_context_t *)context;
+  ULONG ret = 0;
+    
+  if(!c)
+    {
+      usb_error(&quot;usb_reap: invalid context&quot;);
+      return -EINVAL;
+    }
+
+  if(WaitForSingleObject(c-&gt;ol.hEvent, timeout) == WAIT_TIMEOUT)
+    {
+      /* request timed out */
+      if(cancel)
+        {
+          _usb_cancel_io(c);
+        }
+
+      usb_error(&quot;usb_reap: timeout error&quot;);
+      return -ETIMEDOUT;
+    }
+  
+  if(!GetOverlappedResult(c-&gt;dev-&gt;impl_info, &amp;c-&gt;ol, &amp;ret, TRUE))
+    {
+      usb_error(&quot;usb_reap: reaping request failed, win error: %s&quot;, 
+                usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+
+  return ret;
+}
+
+int usb_reap_async(void *context, int timeout)
+{
+  return _usb_reap_async(context, timeout, TRUE);
+}
+
+int usb_reap_async_nocancel(void *context, int timeout)
+{
+  return _usb_reap_async(context, timeout, FALSE);
+}
+
+
+int usb_cancel_async(void *context)
+{
+  /* NOTE that this function will cancel all pending URBs */
+  /* on the same endpoint as this particular context, or even */
+  /* all pending URBs for this particular device. */
+  
+  usb_context_t *c = (usb_context_t *)context;
+  
+  if(!c)
+    {
+      usb_error(&quot;usb_cancel_async: invalid context&quot;);
+      return -EINVAL;
+    }
+
+  if(c-&gt;dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_cancel_async: device not open&quot;);
+      return -EINVAL;
+    }
+  
+  _usb_cancel_io(c);
+
+  return 0;
+}
+
+int usb_free_async(void **context)
+{
+  usb_context_t **c = (usb_context_t **)context;
+
+  if(!*c)
+    {
+      usb_error(&quot;usb_free_async: invalid context&quot;);
+      return -EINVAL;
+    }
+
+  CloseHandle((*c)-&gt;ol.hEvent);
+
+  free(*c);
+  *c = NULL;
+
+  return 0;
+}
+
+static int _usb_transfer_sync(usb_dev_handle *dev, int control_code,
+                              int ep, int pktsize, char *bytes, int size,
+                              int timeout)
+{
+  void *context = NULL;
+  int transmitted = 0;
+  int ret;
+  int requested;
+
+  ret = _usb_setup_async(dev, &amp;context, control_code, (unsigned char )ep, 
+                         pktsize);
+
+  if(ret &lt; 0)
+    {
+      return ret;
+    }
+
+  do {
+    requested = size &gt; LIBUSB_MAX_READ_WRITE ? LIBUSB_MAX_READ_WRITE : size;
+
+    ret = usb_submit_async(context, bytes, requested);
+    
+    if(ret &lt; 0)
+      {
+        transmitted = ret;
+        break;
+      }
+
+    ret = usb_reap_async(context, timeout);
+
+    if(ret &lt; 0)
+      {
+        transmitted = ret;
+        break;
+      }
+
+    transmitted += ret;
+    bytes += ret;
+    size -= ret;
+  } while(size &gt; 0 &amp;&amp; ret == requested);
+  
+  usb_free_async(&amp;context);
+
+  return transmitted;
+}
+
+int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
+                   int timeout)
+{
+  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
+                            ep, 0, bytes, size, timeout);
+}
+
+int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
+                  int timeout)
+{
+  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
+                            ep, 0, bytes, size, timeout);
+}
+
+int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
+                        int timeout)
+{
+  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
+                            ep, 0, bytes, size, timeout);
+}
+
+int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
+                       int timeout)
+{
+  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
+                            ep, 0, bytes, size, timeout);
+}
+
+int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, 
+                                unsigned char ep, int pktsize)
+{
+  if(ep &amp; 0x80)
+    return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_READ,
+                            ep, pktsize);
+  else
+    return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_WRITE,
+                            ep, pktsize);    
+}
+
+int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep)
+{
+  if(ep &amp; 0x80)
+    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
+                            ep, 0);
+  else
+    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
+                            ep, 0);    
+}
+
+int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, 
+                              unsigned char ep)
+{
+  if(ep &amp; 0x80)
+    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
+                            ep, 0);
+  else
+    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
+                            ep, 0);    
+}
+
+int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
+                    int value, int index, char *bytes, int size, int timeout)
+{
+  int read = 0;
+  libusb_request req;
+  void *out = &amp;req;
+  int out_size = sizeof(libusb_request);
+  void *in = bytes;
+  int in_size = size;
+  int code;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_control_msg: device not open&quot;);
+      return -EINVAL;
+    }
+
+  req.timeout = timeout;
+
+  /* windows doesn't support generic control messages, so it needs to be */
+  /* split up */ 
+  switch(requesttype &amp; (0x03 &lt;&lt; 5))
+    {
+    case USB_TYPE_STANDARD:      
+      switch(request)
+        {
+        case USB_REQ_GET_STATUS: 
+          req.status.recipient = requesttype &amp; 0x1F;
+          req.status.index = index;
+          code = LIBUSB_IOCTL_GET_STATUS;
+          break;
+      
+        case USB_REQ_CLEAR_FEATURE:
+          req.feature.recipient = requesttype &amp; 0x1F;
+          req.feature.feature = value;
+          req.feature.index = index;
+          code = LIBUSB_IOCTL_CLEAR_FEATURE;
+          break;
+	  
+        case USB_REQ_SET_FEATURE:
+          req.feature.recipient = requesttype &amp; 0x1F;
+          req.feature.feature = value;
+          req.feature.index = index;
+          code = LIBUSB_IOCTL_SET_FEATURE;
+          break;
+
+        case USB_REQ_GET_DESCRIPTOR:
+          req.descriptor.recipient = requesttype &amp; 0x1F;
+          req.descriptor.type = (value &gt;&gt; 8) &amp; 0xFF;
+          req.descriptor.index = value &amp; 0xFF;
+          req.descriptor.language_id = index;
+          code = LIBUSB_IOCTL_GET_DESCRIPTOR;
+          break;
+	  
+        case USB_REQ_SET_DESCRIPTOR:
+          req.descriptor.recipient = requesttype &amp; 0x1F;
+          req.descriptor.type = (value &gt;&gt; 8) &amp; 0xFF;
+          req.descriptor.index = value &amp; 0xFF;
+          req.descriptor.language_id = index;
+          code = LIBUSB_IOCTL_SET_DESCRIPTOR;
+          break;
+	  
+        case USB_REQ_GET_CONFIGURATION:
+          code = LIBUSB_IOCTL_GET_CONFIGURATION;
+          break;
+      
+        case USB_REQ_SET_CONFIGURATION:	  
+          req.configuration.configuration = value;
+          code = LIBUSB_IOCTL_SET_CONFIGURATION;
+          break;
+	  
+        case USB_REQ_GET_INTERFACE:
+          req.interface.interface = index;
+          code = LIBUSB_IOCTL_GET_INTERFACE;	  
+          break;
+      
+        case USB_REQ_SET_INTERFACE:
+          req.interface.interface = index;
+          req.interface.altsetting = value;
+          code = LIBUSB_IOCTL_SET_INTERFACE;	  
+          break;
+	  
+        default:
+          usb_error(&quot;usb_control_msg: invalid request 0x%x&quot;, request);
+          return -EINVAL;
+        }
+      break;
+
+    case USB_TYPE_VENDOR:  
+    case USB_TYPE_CLASS:
+
+      req.vendor.type = (requesttype &gt;&gt; 5) &amp; 0x03;
+      req.vendor.recipient = requesttype &amp; 0x1F;
+      req.vendor.request = request;
+      req.vendor.value = value;
+      req.vendor.index = index;
+
+      if(requesttype &amp; 0x80)
+        code = LIBUSB_IOCTL_VENDOR_READ;
+      else
+        code = LIBUSB_IOCTL_VENDOR_WRITE;
+      break;
+
+    case USB_TYPE_RESERVED:
+    default:
+      usb_error(&quot;usb_control_msg: invalid or unsupported request type: %x&quot;, 
+                requesttype);
+      return -EINVAL;
+    }
+  
+  /* out request? */
+  if(!(requesttype &amp; USB_ENDPOINT_IN))
+    {
+      if(!(out = malloc(sizeof(libusb_request) + size)))
+        {
+          usb_error(&quot;usb_control_msg: memory allocation failed&quot;); 
+          return -ENOMEM;
+        }
+      
+      memcpy(out, &amp;req, sizeof(libusb_request));
+      memcpy((char *)out + sizeof(libusb_request), bytes, size);
+      out_size = sizeof(libusb_request) + size;
+      in = NULL; in_size = 0;
+    }
+
+  if(!_usb_io_sync(dev-&gt;impl_info, code, out, out_size, in, in_size, &amp;read))
+    {
+      usb_error(&quot;usb_control_msg: sending control message failed, &quot;
+                &quot;win error: %s&quot;, usb_win_error_to_string());
+      if(!(requesttype &amp; USB_ENDPOINT_IN))
+        {
+          free(out);
+        }
+      return -usb_win_error_to_errno();
+    }
+
+  /* out request? */
+  if(!(requesttype &amp; USB_ENDPOINT_IN))
+    {
+      free(out);
+      return size;
+    }
+  else
+    return read;
+}
+
+
+int usb_os_find_busses(struct usb_bus **busses)
+{
+  struct usb_bus *bus = NULL;
+
+  /* create one 'virtual' bus */
+  
+  bus = malloc(sizeof(struct usb_bus));
+
+  if(!bus)
+    {
+      usb_error(&quot;usb_os_find_busses: memory allocation failed&quot;);
+      return -ENOMEM;
+    }
+  
+  memset(bus, 0, sizeof(*bus));
+  strcpy(bus-&gt;dirname, LIBUSB_BUS_NAME);
+  
+  usb_message(&quot;usb_os_find_busses: found %s&quot;, bus-&gt;dirname);
+  
+  *busses = bus;
+
+  return 0;
+}
+
+int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
+{
+  int i;
+  struct usb_device *dev, *fdev = NULL;
+  char dev_name[LIBUSB_PATH_MAX];
+  int ret;
+  HANDLE handle;
+  libusb_request req;
+
+  for(i = 1; i &lt; LIBUSB_MAX_DEVICES; i++)
+    {
+      ret = 0;
+
+      _snprintf(dev_name, sizeof(dev_name) - 1,&quot;%s%04d&quot;, 
+                LIBUSB_DEVICE_NAME, i);
+
+      if(!(dev = malloc(sizeof(*dev)))) 
+        {
+          usb_error(&quot;usb_os_find_devices: memory allocation failed&quot;);
+          return -ENOMEM;
+        }
+      
+      memset(dev, 0, sizeof(*dev));
+      dev-&gt;bus = bus;
+      dev-&gt;devnum = (unsigned char)i;
+
+      handle = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
+                          FILE_FLAG_OVERLAPPED, NULL);
+
+      if(handle == INVALID_HANDLE_VALUE) 
+        {
+          free(dev);
+          continue;
+        }
+
+      /* retrieve device descriptor */
+      req.descriptor.type = USB_DT_DEVICE;
+      req.descriptor.recipient = USB_RECIP_DEVICE;
+      req.descriptor.index = 0;
+      req.descriptor.language_id = 0;
+      req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+      
+      _usb_io_sync(handle, LIBUSB_IOCTL_GET_DESCRIPTOR, 
+                   &amp;req, sizeof(libusb_request), 
+                   &amp;dev-&gt;descriptor, USB_DT_DEVICE_SIZE, &amp;ret);
+      
+      if(ret &lt; USB_DT_DEVICE_SIZE) 
+        {
+          usb_error(&quot;usb_os_find_devices: couldn't read device descriptor&quot;);
+          free(dev);
+          CloseHandle(handle);
+          continue;
+        }
+      
+      _snprintf(dev-&gt;filename, LIBUSB_PATH_MAX - 1, &quot;%s--0x%04x-0x%04x&quot;, 
+                dev_name, dev-&gt;descriptor.idVendor, dev-&gt;descriptor.idProduct);
+
+      CloseHandle(handle);
+
+      LIST_ADD(fdev, dev);
+
+      usb_message(&quot;usb_os_find_devices: found %s on %s&quot;,
+                  dev-&gt;filename, bus-&gt;dirname);
+    }
+  
+  *devices = fdev;
+
+  return 0;
+}
+
+
+void usb_os_init(void)
+{
+  HANDLE dev;
+  libusb_request req;
+  int i;
+  int ret;
+  char dev_name[LIBUSB_PATH_MAX];
+
+  usb_message(&quot;usb_os_init: dll version: %d.%d.%d.%d&quot;,
+              VERSION_MAJOR, VERSION_MINOR,
+              VERSION_MICRO, VERSION_NANO);
+
+
+  for(i = 1; i &lt; LIBUSB_MAX_DEVICES; i++)
+    {
+      /* build the Windows file name */
+      _snprintf(dev_name, sizeof(dev_name) - 1,&quot;%s%04d&quot;, 
+                LIBUSB_DEVICE_NAME, i);
+
+      dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
+                       FILE_FLAG_OVERLAPPED, NULL);
+  
+      if(dev == INVALID_HANDLE_VALUE) 
+        {
+          continue;
+        }
+      
+      if(!_usb_io_sync(dev, LIBUSB_IOCTL_GET_VERSION,
+                       &amp;req, sizeof(libusb_request), 
+                       &amp;req, sizeof(libusb_request), &amp;ret) 
+         || (ret &lt; sizeof(libusb_request)))
+        {
+          usb_error(&quot;usb_os_init: getting driver version failed&quot;);
+          CloseHandle(dev);
+          continue;
+        }
+      else 
+        {
+          _usb_version.driver.major = req.version.major;
+          _usb_version.driver.minor = req.version.minor;
+          _usb_version.driver.micro = req.version.micro;
+          _usb_version.driver.nano = req.version.nano;
+	  
+          usb_message(&quot;usb_os_init: driver version: %d.%d.%d.%d&quot;,
+                      req.version.major, req.version.minor, 
+                      req.version.micro, req.version.nano);
+      
+          /* set debug level */
+          req.timeout = 0;
+          req.debug.level = __usb_debug;
+          
+          if(!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, 
+                           &amp;req, sizeof(libusb_request), 
+                           NULL, 0, NULL))
+            {
+              usb_error(&quot;usb_os_init: setting debug level failed&quot;);
+            }
+          
+          CloseHandle(dev);
+          break;
+        }
+    }
+}
+
+
+int usb_resetep(usb_dev_handle *dev, unsigned int ep)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_resetep: device not open&quot;);
+      return -EINVAL;
+    }
+
+  req.endpoint.endpoint = (int)ep;
+  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &amp;req, 
+                   sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_resetep: could not abort ep 0x%02x, win error: %s&quot;, 
+                ep, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &amp;req, 
+                   sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_resetep: could not reset ep 0x%02x, win error: %s&quot;, 
+                ep, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  
+  return 0;
+}
+
+int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_clear_halt: device not open&quot;);
+      return -EINVAL;
+    }
+
+  req.endpoint.endpoint = (int)ep;
+  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &amp;req, 
+                   sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_clear_halt: could not clear halt, ep 0x%02x, &quot;
+                &quot;win error: %s&quot;, ep, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  
+  return 0;
+}
+
+int usb_reset(usb_dev_handle *dev)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;usb_reset: device not open&quot;);
+      return -EINVAL;
+    }
+
+  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_RESET_DEVICE,
+                   &amp;req, sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;usb_reset: could not reset device, win error: %s&quot;, 
+                usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+
+  return 0;
+}
+
+const struct usb_version *usb_get_version(void)
+{
+  return &amp;_usb_version;
+}
+
+void usb_set_debug(int level)
+{
+  HANDLE dev;
+  libusb_request req;
+  int i;
+  char dev_name[LIBUSB_PATH_MAX];
+
+  if(__usb_debug || level)
+    {
+      usb_message(&quot;usb_set_debug: setting debugging level to %d (%s)\n&quot;,
+                  level, level ? &quot;on&quot; : &quot;off&quot;);
+    }
+
+  __usb_debug = level;
+
+  /* find a valid device */
+  for(i = 1; i &lt; LIBUSB_MAX_DEVICES; i++)
+    {
+      /* build the Windows file name */
+      _snprintf(dev_name, sizeof(dev_name) - 1,&quot;%s%04d&quot;, 
+                LIBUSB_DEVICE_NAME, i);
+
+      dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
+                       FILE_FLAG_OVERLAPPED, NULL);
+  
+      if(dev == INVALID_HANDLE_VALUE) 
+        {
+          continue;
+        }
+      
+      /* set debug level */
+      req.timeout = 0;
+      req.debug.level = __usb_debug;
+      
+      if(!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, 
+                       &amp;req, sizeof(libusb_request), 
+                       NULL, 0, NULL))
+        {
+          usb_error(&quot;usb_os_init: setting debug level failed&quot;);
+        }
+      
+      CloseHandle(dev);
+
+      break;
+    }
+}
+
+int usb_os_determine_children(struct usb_bus *bus)
+{
+  struct usb_device *dev;
+  int i = 0;
+
+  /* add a virtual hub to the bus to emulate this feature */
+  if(_usb_add_virtual_hub(bus))
+    {
+      if(bus-&gt;root_dev-&gt;children)
+        {
+          free(bus-&gt;root_dev-&gt;children);
+        }
+
+      bus-&gt;root_dev-&gt;num_children = 0;
+      for(dev = bus-&gt;devices; dev; dev = dev-&gt;next)
+        bus-&gt;root_dev-&gt;num_children++;
+
+      bus-&gt;root_dev-&gt;children 
+        = malloc(sizeof(struct usb_device *) * bus-&gt;root_dev-&gt;num_children);
+
+      for(dev = bus-&gt;devices; dev; dev = dev-&gt;next)
+        bus-&gt;root_dev-&gt;children[i++] = dev; 
+    }
+
+  return 0;
+}
+
+static int _usb_cancel_io(usb_context_t *context)
+{
+  int ret;
+  ret = _usb_abort_ep(context-&gt;dev, context-&gt;req.endpoint.endpoint);
+  WaitForSingleObject(context-&gt;ol.hEvent, 0);
+  return ret; 
+}
+
+static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep)
+{
+  libusb_request req;
+
+  if(dev-&gt;impl_info == INVALID_HANDLE_VALUE)
+    {
+      usb_error(&quot;_usb_abort_ep: device not open&quot;);
+      return -EINVAL;
+    }
+
+  req.endpoint.endpoint = (int)ep;
+  req.timeout = LIBUSB_DEFAULT_TIMEOUT;
+
+  if(!_usb_io_sync(dev-&gt;impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &amp;req, 
+                   sizeof(libusb_request), NULL, 0, NULL))
+    {
+      usb_error(&quot;_usb_abort_ep: could not abort ep 0x%02x, win error: %s&quot;, 
+                ep, usb_win_error_to_string());
+      return -usb_win_error_to_errno();
+    }
+  
+  return 0;
+}
+
+static int _usb_io_sync(HANDLE dev, unsigned int code, void *out, int out_size,
+                        void *in, int in_size, int *ret)
+{
+  OVERLAPPED ol;
+  DWORD _ret;
+
+  memset(&amp;ol, 0, sizeof(ol));  
+
+  if(ret)
+    *ret = 0;
+
+  ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+  if(!ol.hEvent)
+    return FALSE;
+  
+  if(!DeviceIoControl(dev, code, out, out_size, in, in_size, NULL, &amp;ol))
+    {
+      if(GetLastError() != ERROR_IO_PENDING)
+        {
+          CloseHandle(ol.hEvent);
+          return FALSE;
+        }
+    }
+
+  if(GetOverlappedResult(dev, &amp;ol, &amp;_ret, TRUE))
+    {
+      if(ret)
+        *ret = (int)_ret;
+      CloseHandle(ol.hEvent);
+      return TRUE;
+    }
+  
+  CloseHandle(ol.hEvent);
+  return FALSE;
+}
+
+static int _usb_add_virtual_hub(struct usb_bus *bus)
+{
+  struct usb_device *dev;
+
+  if(!bus-&gt;root_dev)
+    {
+      if(!(dev = malloc(sizeof(*dev))))
+        return FALSE;
+      
+      memset(dev, 0, sizeof(*dev));
+      strcpy(dev-&gt;filename, &quot;virtual-hub&quot;);
+      dev-&gt;bus = bus;
+      
+      dev-&gt;descriptor.bLength = USB_DT_DEVICE_SIZE;
+      dev-&gt;descriptor.bDescriptorType = USB_DT_DEVICE;
+      dev-&gt;descriptor.bcdUSB = 0x0200;
+      dev-&gt;descriptor.bDeviceClass = USB_CLASS_HUB;
+      dev-&gt;descriptor.bDeviceSubClass = 0;
+      dev-&gt;descriptor.bDeviceProtocol = 0;
+      dev-&gt;descriptor.bMaxPacketSize0 = 64;
+      dev-&gt;descriptor.idVendor = 0;
+      dev-&gt;descriptor.idProduct = 0;
+      dev-&gt;descriptor.bcdDevice = 0x100;
+      dev-&gt;descriptor.iManufacturer = 0;
+      dev-&gt;descriptor.iProduct = 0;
+      dev-&gt;descriptor.iSerialNumber = 0;
+      dev-&gt;descriptor.bNumConfigurations = 0;
+      
+      bus-&gt;root_dev = dev;
+    }
+
+  return TRUE;
+}
+
+static void _usb_free_bus_list(struct usb_bus *bus)
+{
+  if(bus)
+    {
+      _usb_free_bus_list(bus-&gt;next);
+      if(bus-&gt;root_dev)
+        usb_free_dev(bus-&gt;root_dev);
+      _usb_free_dev_list(bus-&gt;devices);
+      usb_free_bus(bus);
+    }
+}
+
+static void _usb_free_dev_list(struct usb_device *dev)
+{
+  if(dev)
+    {
+      _usb_free_dev_list(dev-&gt;next);
+      usb_free_dev(dev);
+    }
+}
+
+static void _usb_deinit(void)
+{
+  _usb_free_bus_list(usb_get_busses());
+}</diff>
      <filename>xpwn/libusb-win32/src/windows.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
-#include &lt;stdlib.h&gt;
-
-#ifdef WIN32
-blahfs-o_f-0-(){ {}A
-#else
-int main(int argc, char* argv[]) {
-  return 0;
-}
-#endif
+#include &lt;stdlib.h&gt;
+
+#ifdef WIN32
+blahfs-o_f-0-(){ {}A
+#else
+int main(int argc, char* argv[]) {
+  return 0;
+}
+#endif</diff>
      <filename>xpwn/win32test.c</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d42404ab5c531665a8f65be4e0aa4af06e96882d</id>
    </parent>
  </parents>
  <author>
    <name>planetbeing</name>
    <email>planetbeing@gmail.com</email>
  </author>
  <url>http://github.com/planetbeing/xpwn/commit/6bf5301c167cebdb88557a8028804c07dde081f9</url>
  <id>6bf5301c167cebdb88557a8028804c07dde081f9</id>
  <committed-date>2008-05-21T07:01:39-07:00</committed-date>
  <authored-date>2008-05-21T07:01:39-07:00</authored-date>
  <message>Fix up line endings, add libxpwn.c that was necessary, made Makefile generate DOS readmes for Windows, fixed up some includes</message>
  <tree>2e25e423e3dbc7e789f9af25b05fdcd0e054990f</tree>
  <committer>
    <name>planetbeing</name>
    <email>planetbeing@gmail.com</email>
  </committer>
</commit>
