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