diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-07-11 15:50:46 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-07-11 15:50:46 +0000 |
commit | 14c7f45cdae826f88dc539c8c38dd95caf305731 (patch) | |
tree | 832da054b7cfb2dc6fd63339af736625f31d21aa /utils/zenutils/source/firmware_extract | |
parent | 7c84ede3781c27db73403bd6302f320c76a58c8c (diff) | |
download | rockbox-14c7f45cdae826f88dc539c8c38dd95caf305731.tar.gz rockbox-14c7f45cdae826f88dc539c8c38dd95caf305731.zip |
Add zook's ZenUtils to SVN
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18010 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils/zenutils/source/firmware_extract')
-rwxr-xr-x | utils/zenutils/source/firmware_extract/CMakeLists.txt | 3 | ||||
-rwxr-xr-x | utils/zenutils/source/firmware_extract/main.cpp | 243 |
2 files changed, 246 insertions, 0 deletions
diff --git a/utils/zenutils/source/firmware_extract/CMakeLists.txt b/utils/zenutils/source/firmware_extract/CMakeLists.txt new file mode 100755 index 0000000000..3814f03612 --- /dev/null +++ b/utils/zenutils/source/firmware_extract/CMakeLists.txt | |||
@@ -0,0 +1,3 @@ | |||
1 | ADD_EXECUTABLE(firmware_extract main.cpp) | ||
2 | |||
3 | TARGET_LINK_LIBRARIES(firmware_extract shared) | ||
diff --git a/utils/zenutils/source/firmware_extract/main.cpp b/utils/zenutils/source/firmware_extract/main.cpp new file mode 100755 index 0000000000..c677a91a75 --- /dev/null +++ b/utils/zenutils/source/firmware_extract/main.cpp | |||
@@ -0,0 +1,243 @@ | |||
1 | /* zenutils - Utilities for working with creative firmwares. | ||
2 | * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <iostream> | ||
20 | #include <ctime> | ||
21 | #include <getpot/getpot.hpp> | ||
22 | #include <utils.h> | ||
23 | #include <firmware.h> | ||
24 | |||
25 | |||
26 | static const char VERSION[] = "0.1"; | ||
27 | |||
28 | |||
29 | void print_version() | ||
30 | { | ||
31 | std::cout | ||
32 | << "firmware_extract - Extracts files from a Creative firmware." | ||
33 | << std::endl | ||
34 | << "Version " << VERSION << std::endl | ||
35 | << "Copyright (c) 2007 Rasmus Ry" << std::endl; | ||
36 | } | ||
37 | |||
38 | void print_help() | ||
39 | { | ||
40 | print_version(); | ||
41 | std::cout | ||
42 | << "Usage: firmware_extract [command] [options]" << std::endl | ||
43 | << std::endl | ||
44 | << " Commands:" << std::endl | ||
45 | << " -h,--help" << std::endl | ||
46 | << " prints this message." << std::endl | ||
47 | << " -f,--firmware [file]" << std::endl | ||
48 | << " specifies the firmware arhive file name." << std::endl | ||
49 | << std::endl | ||
50 | << " Options:" << std::endl | ||
51 | << " -V,--verbose" << std::endl | ||
52 | << " prints verbose messages." << std::endl | ||
53 | << " -p,--prefix [prefix]" << std::endl | ||
54 | << " specifies a file name prefix for the extracted files." << std::endl | ||
55 | << std::endl | ||
56 | ; | ||
57 | } | ||
58 | |||
59 | |||
60 | struct save_entry_functor | ||
61 | { | ||
62 | save_entry_functor(const std::string& fileprefix) | ||
63 | : _fileprefix(fileprefix) {} | ||
64 | |||
65 | bool operator()(const zen::firmware_entry& entry) | ||
66 | { | ||
67 | std::string filename = _fileprefix + entry.get_content_name(); | ||
68 | std::ofstream ofs; | ||
69 | ofs.open(filename.c_str(), std::ios::binary); | ||
70 | if (!ofs) | ||
71 | false; | ||
72 | |||
73 | size_t off = entry.get_content_offset(); | ||
74 | std::streamsize size = entry.get_bytes().size() - off; | ||
75 | ofs.write((const char*)&entry.get_bytes()[off], size); | ||
76 | |||
77 | return ofs.good(); | ||
78 | } | ||
79 | |||
80 | const std::string& _fileprefix; | ||
81 | }; //struct save_entry_functor | ||
82 | |||
83 | struct print_entry_functor | ||
84 | { | ||
85 | print_entry_functor(std::ostream& os, const std::string& fileprefix) | ||
86 | : _os(os), _fileprefix(fileprefix), num(0) {} | ||
87 | |||
88 | bool operator()(const zen::firmware_entry& entry) | ||
89 | { | ||
90 | std::string filename = _fileprefix + entry.get_content_name(); | ||
91 | if (!num) | ||
92 | _os << "[./" << num++ << "]" << std::endl; | ||
93 | else | ||
94 | _os << "[../" << num++ << "]" << std::endl; | ||
95 | _os << "tag = " << entry.get_name() << std::endl; | ||
96 | |||
97 | if (entry.get_content_offset()) | ||
98 | _os << "name = " << entry.get_content_name() << std::endl; | ||
99 | |||
100 | _os << "file = \'" << shared::double_quote(filename) << "\'" | ||
101 | << std::endl; | ||
102 | |||
103 | return _os.good(); | ||
104 | } | ||
105 | |||
106 | std::ostream& _os; | ||
107 | const std::string& _fileprefix; | ||
108 | int num; | ||
109 | }; //struct print_entry_functor | ||
110 | |||
111 | |||
112 | int process_arguments(int argc, char* argv[]) | ||
113 | { | ||
114 | //-------------------------------------------------------------------- | ||
115 | // Parse input variables. | ||
116 | //-------------------------------------------------------------------- | ||
117 | |||
118 | GetPot cl(argc, argv); | ||
119 | if (cl.size() == 1 || cl.search(2, "-h", "--help")) | ||
120 | { | ||
121 | print_help(); | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | std::string firmwarename; | ||
126 | if (cl.search("-f") || cl.search("--firmware")) | ||
127 | firmwarename = cl.next(""); | ||
128 | if (firmwarename.empty()) | ||
129 | { | ||
130 | std::cerr << "Firmware archive must be specified." << std::endl; | ||
131 | return 2; | ||
132 | } | ||
133 | |||
134 | bool verbose = false; | ||
135 | if (cl.search("-V") || cl.search("--verbose")) | ||
136 | verbose = true; | ||
137 | |||
138 | std::string prefixname = shared::remove_extension(firmwarename) + "_"; | ||
139 | if (cl.search("-p") || cl.search("--prefix")) | ||
140 | prefixname = cl.next(prefixname.c_str()); | ||
141 | |||
142 | |||
143 | //-------------------------------------------------------------------- | ||
144 | // Read the firmware archive. | ||
145 | //-------------------------------------------------------------------- | ||
146 | |||
147 | if (verbose) | ||
148 | std::cout << "[*] Reading firmware archive..." << std::endl; | ||
149 | |||
150 | zen::firmware_archive archive(false); | ||
151 | std::ifstream ifs; | ||
152 | ifs.open(firmwarename.c_str(), std::ios::binary); | ||
153 | if (!ifs) | ||
154 | { | ||
155 | std::cerr << "Failed to open the firmware archive." << std::endl; | ||
156 | return 3; | ||
157 | } | ||
158 | |||
159 | if (!archive.read(ifs)) | ||
160 | { | ||
161 | std::cerr << "Failed to read the firmware archive." << std::endl; | ||
162 | return 4; | ||
163 | } | ||
164 | |||
165 | |||
166 | //-------------------------------------------------------------------- | ||
167 | // Generate a make file for the extracted firmware archive. | ||
168 | //-------------------------------------------------------------------- | ||
169 | |||
170 | // Get make filename for the given input file. | ||
171 | std::string makefile = shared::replace_extension(firmwarename, ".mk"); | ||
172 | |||
173 | if (verbose) | ||
174 | std::cout << "[*] Producing make file..." << std::endl; | ||
175 | |||
176 | |||
177 | // Produce make file for the given input file. | ||
178 | std::ofstream ofs; | ||
179 | ofs.open(makefile.c_str(), std::ios::binary); | ||
180 | if (!ofs) | ||
181 | { | ||
182 | std::cerr << "Failed to create firmware archive make file." | ||
183 | << std::endl; | ||
184 | return 5; | ||
185 | } | ||
186 | |||
187 | time_t timeval = time(NULL); | ||
188 | ofs << "# Make file generated at: " << ctime(&timeval); | ||
189 | ofs << "endian = " << (archive.is_big_endian() ? "big" : "little") | ||
190 | << std::endl; | ||
191 | ofs << "signed = " << (archive.is_signed() ? "true" : "false") | ||
192 | << std::endl; | ||
193 | |||
194 | ofs << "[children]" << std::endl; | ||
195 | ofs << "count = " << archive.get_children().size() << std::endl; | ||
196 | |||
197 | std::for_each(archive.get_children().begin(), | ||
198 | archive.get_children().end(), | ||
199 | print_entry_functor(ofs, prefixname)); | ||
200 | |||
201 | ofs << "[neighbours]" << std::endl; | ||
202 | ofs << "count = " << archive.get_neighbours().size() << std::endl; | ||
203 | std::for_each(archive.get_neighbours().begin(), | ||
204 | archive.get_neighbours().end(), | ||
205 | print_entry_functor(ofs, prefixname)); | ||
206 | |||
207 | |||
208 | //-------------------------------------------------------------------- | ||
209 | // Save firmware entries. | ||
210 | //-------------------------------------------------------------------- | ||
211 | |||
212 | if (verbose) | ||
213 | std::cout << "[*] Saving firmware entries..." << std::endl; | ||
214 | |||
215 | std::for_each(archive.get_children().begin(), | ||
216 | archive.get_children().end(), | ||
217 | save_entry_functor(prefixname)); | ||
218 | |||
219 | std::for_each(archive.get_neighbours().begin(), | ||
220 | archive.get_neighbours().end(), | ||
221 | save_entry_functor(prefixname)); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | int main(int argc, char* argv[]) | ||
227 | { | ||
228 | try | ||
229 | { | ||
230 | return process_arguments(argc, argv); | ||
231 | } | ||
232 | catch (const std::exception& xcpt) | ||
233 | { | ||
234 | std::cerr << "Exception caught: " << xcpt.what() << std::endl; | ||
235 | return -1; | ||
236 | } | ||
237 | catch (...) | ||
238 | { | ||
239 | std::cerr << "Unknown exception caught." << std::endl; | ||
240 | return -2; | ||
241 | } | ||
242 | return -3; | ||
243 | } | ||