]> git.zerfleddert.de Git - rsbs2/blobdiff - extract.c
typo in error message
[rsbs2] / extract.c
index feab68f33570da5f068b22c1953afa9147814df2..b4208995f2bc9f8ae73ee6b8811dabfc89e29435 100644 (file)
--- a/extract.c
+++ b/extract.c
 #include "rsb-lz.h"
 #include "extract.h"
 
-void extract_files(unsigned char *fw, int len)
+struct file_entry* get_next_file(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;
+       static unsigned char *pos;
+       static unsigned char *start;
+       static unsigned char *end;
+       static struct file_entry fent;
+       int name_length;
+
+       if (fw != NULL && len != 0) {
+               pos = fw + 0x28;
+
+#if 0
+               printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
+#endif
+               start = fw;
+               pos = fw + *((unsigned int*)pos);
+               end = fw + len;
+       }
+
+       fent.unknown = *pos;
+       pos++;
+
+       if (fent.unknown == 0x00) {
+               /* EOF */
+               int fill = (4 - ((pos - start) % 4)) % 4;
+               int i;
+
+               for (i = 0; i < fill; i++) {
+                       if (*pos != 0xff) {
+                               fprintf(stderr, "Wrong fill byte after EOF: 0x%02x, aborting!\n", *pos);
+                               exit(1);
+                       }
+                       pos++;
+               }
+
+               if (pos != end) {
+                       fprintf(stderr, "EOF marker not at end-of-file %p <-> %p, aborting!\n", pos, end);
+                       exit(1);
                }
-               printf("%s: type: 0x%x, length: %d", name, type, length);
 
-               if (length > 0) {
-                       write_file(name, pos, length);
-                       if (*((unsigned int*)pos) == LZ_MAGIC) {
+               return NULL;
+       }
+
+
+       name_length = *((unsigned int*)pos);
+       pos += 4;
+
+       fent.length = *((unsigned int*)pos);
+       pos += 4;
+
+       if ((fent.length > (end - pos)) ||
+           (name_length > (end - pos))) {
+               printf("EOF reached without hitting EOF marker, aborting "
+                       "(unknown: 0x%02x, namelen: 0x%08x, contentlen: 0x%08x!\n",
+                       fent.unknown, name_length, fent.length);
+               exit(1);
+       }
+
+       fent.name = (char*)pos;
+       pos += name_length;
+
+       fent.start = pos;
+       pos += fent.length;
+
+       return &fent;
+}
+
+void extract_files(unsigned char *fw, int len)
+{
+       struct file_entry *fent;
+
+       fent = get_next_file(fw, len);
+       
+       while (fent) {
+               printf("%s: unknown: 0x%02x, length: %d",
+                       fent->name, fent->unknown, fent->length);
+
+               if (fent->length > 0) {
+                       write_file(fent->name, fent->start, fent->length);
+                       if (*((unsigned int*)fent->start) == LZ_MAGIC) {
                                char *lzname;
 
-                               if ((lzname = strdup(name)) == NULL) {
+                               if ((lzname = strdup(fent->name)) == NULL) {
                                        perror("strdup");
                                        exit(1);
                                }
@@ -57,16 +107,16 @@ void extract_files(unsigned char *fw, int len)
 
                                printf("%s: packed file found", lzname);
 
-                               extract_lz_file(pos, (unsigned char*)lzname);
+                               extract_lz_file(fent->start, (unsigned char*)lzname);
                                free(lzname);
-                       } else if (!strcmp(name, "firmware")) {
+                       } else if (!strcmp(fent->name, "firmware")) {
                                unsigned char *lzpos;
                                char lzname[128];
 
                                bzero(lzname, sizeof(lzname));
                                strcpy(lzname, "firmware.");
 
-                               lzpos = pos + *((unsigned int*)(pos + 0x20));
+                               lzpos = fent->start + *((unsigned int*)(fent->start + 0x20));
                                memcpy(lzname + strlen(lzname), lzpos - 4, 4);
                                lzpos += 4;
                                if (*((unsigned int*)(lzpos)) == LZ_MAGIC) {
@@ -74,10 +124,10 @@ void extract_files(unsigned char *fw, int len)
                                        extract_lz_file(lzpos, (unsigned char*)lzname);
                                }
                        }
+               } else {
+                       printf(", ignoring...\n");
                }
-
-               pos += length;
-
+               fent = get_next_file(NULL, 0);
        }
 }
 
Impressum, Datenschutz