]> git.zerfleddert.de Git - rsbs2/blame - extract.c
more paranoia (check consistency after patching the image, too)
[rsbs2] / extract.c
CommitLineData
1f1fa7b6
MG
1#include <sys/stat.h>
2#include <sys/types.h>
3#include <limits.h>
4#include <fcntl.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <strings.h>
8#include <string.h>
9#include <unistd.h>
10#include <errno.h>
11#include <libgen.h>
12#include "rsb-lz.h"
13#include "extract.h"
14
81a1093d
MG
15struct file_entry* get_next_file(unsigned char *fw, int len)
16{
17 static unsigned char *pos;
18 static unsigned char *end;
19 static struct file_entry fent;
20 int name_length;
21
22 if (fw != NULL && len != 0) {
23 pos = fw + 0x28;
24
8658e967 25#if 0
81a1093d 26 printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
8658e967 27#endif
81a1093d
MG
28 pos = fw + *((unsigned int*)pos);
29 end = fw + len;
30 }
31
32 fent.unknown = *pos;
33 pos++;
34
35 name_length = *((unsigned int*)pos);
36 pos += 4;
37
38 fent.length = *((unsigned int*)pos);
39 pos += 4;
40
41 if ((fent.length > (end - pos)) ||
42 (name_length > (end - pos))) {
8658e967 43#if 0
81a1093d 44 printf("EOF reached\n");
8658e967 45#endif
81a1093d
MG
46 return NULL;
47 }
48
49 fent.name = (char*)pos;
50 pos += name_length;
51
52 fent.start = pos;
53 pos += fent.length;
54
55 return &fent;
56}
57
1f1fa7b6
MG
58void extract_files(unsigned char *fw, int len)
59{
81a1093d 60 struct file_entry *fent;
358935b6 61
81a1093d
MG
62 fent = get_next_file(fw, len);
63
64 while (fent) {
358935b6 65 printf("%s: unknown: 0x%02x, length: %d",
81a1093d 66 fent->name, fent->unknown, fent->length);
1f1fa7b6 67
81a1093d
MG
68 if (fent->length > 0) {
69 write_file(fent->name, fent->start, fent->length);
70 if (*((unsigned int*)fent->start) == LZ_MAGIC) {
1f1fa7b6
MG
71 char *lzname;
72
81a1093d 73 if ((lzname = strdup(fent->name)) == NULL) {
1f1fa7b6
MG
74 perror("strdup");
75 exit(1);
76 }
77
78 if (!strcmp(lzname + strlen(lzname) - 4 , ".lz")) {
79 fprintf(stderr, "Ugh, can't derive filename...\n");
80 exit(1);
81 }
82 lzname[strlen(lzname) - 3] = 0x00;
83
84 printf("%s: packed file found", lzname);
85
81a1093d 86 extract_lz_file(fent->start, (unsigned char*)lzname);
1f1fa7b6 87 free(lzname);
81a1093d 88 } else if (!strcmp(fent->name, "firmware")) {
1f1fa7b6
MG
89 unsigned char *lzpos;
90 char lzname[128];
91
92 bzero(lzname, sizeof(lzname));
93 strcpy(lzname, "firmware.");
94
81a1093d 95 lzpos = fent->start + *((unsigned int*)(fent->start + 0x20));
1f1fa7b6
MG
96 memcpy(lzname + strlen(lzname), lzpos - 4, 4);
97 lzpos += 4;
98 if (*((unsigned int*)(lzpos)) == LZ_MAGIC) {
99 printf("%s: compressed firmware part found", lzname);
100 extract_lz_file(lzpos, (unsigned char*)lzname);
101 }
102 }
395daefd
MG
103 } else {
104 printf(", ignoring...\n");
1f1fa7b6 105 }
81a1093d 106 fent = get_next_file(NULL, 0);
1f1fa7b6
MG
107 }
108}
109
110void mkdir_p(char *dir)
111{
112 char *copy, *parent;
113
114 if ((dir == NULL) || (!strcmp(dir, ".")))
115 return;
116
117 if ((copy = strdup(dir)) == NULL) {
118 perror("strdup");
119 exit(1);
120 }
121 parent = dirname(copy);
122 mkdir_p(parent);
123
124 errno = 0;
125 if (mkdir(dir, 0755) == -1) {
126 if (errno != EEXIST) {
127 fprintf(stderr, "%s: ", dir);
128 perror("mkdir");
129 exit(1);
130 }
131 }
132 free(copy);
133}
134
135void write_file(char *fname, unsigned char *buf, int len)
136{
137 char filename[PATH_MAX];
138 char *filename_c, *dirn;
139 int fd;
140 int remaining;
141 int ret;
142
143 strcpy(filename, "extracted/");
144 strcat(filename, fname);
145
146 if ((filename_c = strdup(filename)) == NULL) {
147 perror("strdup");
148 exit(1);
149 }
150 dirn = dirname(filename_c);
151 mkdir_p(dirn);
152 free(filename_c);
153
154 if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) == -1) {
155 fprintf(stderr, "%s: ", filename);
156 perror("open");
157 exit(1);
158 }
159
160 remaining = len;
161
162 while(remaining) {
163 ret = write(fd, buf + (len - remaining), remaining);
164 if (ret < 0) {
165 perror("write");
166 exit(1);
167 }
168 remaining -= ret;
169 }
170
171 printf(", %s written.\n", filename);
172
173 close(fd);
174}
Impressum, Datenschutz