--- /dev/null
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <libgen.h>
+#include "rsb-lz.h"
+#include "extract.h"
+
+void extract_files(unsigned char *fw, int len)
+{
+ unsigned char *pos;
+ unsigned int type, length;
+ char *name;
+
+ pos = fw + 0x28;
+ printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
+
+ pos = fw + *((unsigned int*)pos);
+
+ while (pos < (fw + len)) {
+ type = *((unsigned int*)pos);
+ pos += 4;
+ /* ??? */
+ pos++;
+ length = *((unsigned int*)pos);
+ pos += 4;
+ name = (char*)pos;
+ pos += strlen(name) + 1;
+
+ if ((pos + length) > (fw + len)) {
+ printf("EOF reached\n");
+ break;
+ }
+ printf("%s: type: 0x%x, length: %d", name, type, length);
+
+ if (length > 0) {
+ write_file(name, pos, length);
+ if (*((unsigned int*)pos) == LZ_MAGIC) {
+ char *lzname;
+
+ if ((lzname = strdup(name)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+
+ if (!strcmp(lzname + strlen(lzname) - 4 , ".lz")) {
+ fprintf(stderr, "Ugh, can't derive filename...\n");
+ exit(1);
+ }
+ lzname[strlen(lzname) - 3] = 0x00;
+
+ printf("%s: packed file found", lzname);
+
+ extract_lz_file(pos, (unsigned char*)lzname);
+ free(lzname);
+ } else if (!strcmp(name, "firmware")) {
+ unsigned char *lzpos;
+ char lzname[128];
+
+ bzero(lzname, sizeof(lzname));
+ strcpy(lzname, "firmware.");
+
+ lzpos = pos + *((unsigned int*)(pos + 0x20));
+ memcpy(lzname + strlen(lzname), lzpos - 4, 4);
+ lzpos += 4;
+ if (*((unsigned int*)(lzpos)) == LZ_MAGIC) {
+ printf("%s: compressed firmware part found", lzname);
+ extract_lz_file(lzpos, (unsigned char*)lzname);
+ }
+ }
+ }
+
+ pos += length;
+
+ }
+}
+
+void mkdir_p(char *dir)
+{
+ char *copy, *parent;
+
+ if ((dir == NULL) || (!strcmp(dir, ".")))
+ return;
+
+ if ((copy = strdup(dir)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+ parent = dirname(copy);
+ mkdir_p(parent);
+
+ errno = 0;
+ if (mkdir(dir, 0755) == -1) {
+ if (errno != EEXIST) {
+ fprintf(stderr, "%s: ", dir);
+ perror("mkdir");
+ exit(1);
+ }
+ }
+ free(copy);
+}
+
+void write_file(char *fname, unsigned char *buf, int len)
+{
+ char filename[PATH_MAX];
+ char *filename_c, *dirn;
+ int fd;
+ int remaining;
+ int ret;
+
+ strcpy(filename, "extracted/");
+ strcat(filename, fname);
+
+ if ((filename_c = strdup(filename)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+ dirn = dirname(filename_c);
+ mkdir_p(dirn);
+ free(filename_c);
+
+ if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) == -1) {
+ fprintf(stderr, "%s: ", filename);
+ perror("open");
+ exit(1);
+ }
+
+ remaining = len;
+
+ while(remaining) {
+ ret = write(fd, buf + (len - remaining), remaining);
+ if (ret < 0) {
+ perror("write");
+ exit(1);
+ }
+ remaining -= ret;
+ }
+
+ printf(", %s written.\n", filename);
+
+ close(fd);
+}