]> cvs.zerfleddert.de Git - rsbs2/blob - extract.c
extract all files from the firmware image.
[rsbs2] / extract.c
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
15 void extract_files(unsigned char *fw, int len)
16 {
17 unsigned char *pos;
18 unsigned int type, length;
19 char *name;
20
21 pos = fw + 0x28;
22 printf("Start of filesystem: 0x%08x\n", *((unsigned int*)pos));
23
24 pos = fw + *((unsigned int*)pos);
25
26 while (pos < (fw + len)) {
27 type = *((unsigned int*)pos);
28 pos += 4;
29 /* ??? */
30 pos++;
31 length = *((unsigned int*)pos);
32 pos += 4;
33 name = (char*)pos;
34 pos += strlen(name) + 1;
35
36 if ((pos + length) > (fw + len)) {
37 printf("EOF reached\n");
38 break;
39 }
40 printf("%s: type: 0x%x, length: %d", name, type, length);
41
42 if (length > 0) {
43 write_file(name, pos, length);
44 if (*((unsigned int*)pos) == LZ_MAGIC) {
45 char *lzname;
46
47 if ((lzname = strdup(name)) == NULL) {
48 perror("strdup");
49 exit(1);
50 }
51
52 if (!strcmp(lzname + strlen(lzname) - 4 , ".lz")) {
53 fprintf(stderr, "Ugh, can't derive filename...\n");
54 exit(1);
55 }
56 lzname[strlen(lzname) - 3] = 0x00;
57
58 printf("%s: packed file found", lzname);
59
60 extract_lz_file(pos, (unsigned char*)lzname);
61 free(lzname);
62 } else if (!strcmp(name, "firmware")) {
63 unsigned char *lzpos;
64 char lzname[128];
65
66 bzero(lzname, sizeof(lzname));
67 strcpy(lzname, "firmware.");
68
69 lzpos = pos + *((unsigned int*)(pos + 0x20));
70 memcpy(lzname + strlen(lzname), lzpos - 4, 4);
71 lzpos += 4;
72 if (*((unsigned int*)(lzpos)) == LZ_MAGIC) {
73 printf("%s: compressed firmware part found", lzname);
74 extract_lz_file(lzpos, (unsigned char*)lzname);
75 }
76 }
77 }
78
79 pos += length;
80
81 }
82 }
83
84 void mkdir_p(char *dir)
85 {
86 char *copy, *parent;
87
88 if ((dir == NULL) || (!strcmp(dir, ".")))
89 return;
90
91 if ((copy = strdup(dir)) == NULL) {
92 perror("strdup");
93 exit(1);
94 }
95 parent = dirname(copy);
96 mkdir_p(parent);
97
98 errno = 0;
99 if (mkdir(dir, 0755) == -1) {
100 if (errno != EEXIST) {
101 fprintf(stderr, "%s: ", dir);
102 perror("mkdir");
103 exit(1);
104 }
105 }
106 free(copy);
107 }
108
109 void write_file(char *fname, unsigned char *buf, int len)
110 {
111 char filename[PATH_MAX];
112 char *filename_c, *dirn;
113 int fd;
114 int remaining;
115 int ret;
116
117 strcpy(filename, "extracted/");
118 strcat(filename, fname);
119
120 if ((filename_c = strdup(filename)) == NULL) {
121 perror("strdup");
122 exit(1);
123 }
124 dirn = dirname(filename_c);
125 mkdir_p(dirn);
126 free(filename_c);
127
128 if ((fd = open(filename, O_WRONLY|O_CREAT, 0644)) == -1) {
129 fprintf(stderr, "%s: ", filename);
130 perror("open");
131 exit(1);
132 }
133
134 remaining = len;
135
136 while(remaining) {
137 ret = write(fd, buf + (len - remaining), remaining);
138 if (ret < 0) {
139 perror("write");
140 exit(1);
141 }
142 remaining -= ret;
143 }
144
145 printf(", %s written.\n", filename);
146
147 close(fd);
148 }
Impressum, Datenschutz