Skip to content

Commit 5b3fc0c

Browse files
committed
Merge pull request #6 from pgollor/unpack
unpack files from SPIFFS image
2 parents b5f8f80 + aa77951 commit 5b3fc0c

File tree

4 files changed

+196
-15
lines changed

4 files changed

+196
-15
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@ mkspiffs
33
mkspiffs.exe
44
out.*
55
*.tar.gz
6+
7+
# eclipse wokspace files and dirs
8+
.project
9+
.cproject
10+
.settings

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ SPIFFS_TEST_FS_CONFIG := -s 0x100000 -p 512 -b 0x2000
8484
test: $(TARGET)
8585
ls -1 spiffs > out.list0
8686
./mkspiffs -c spiffs $(SPIFFS_TEST_FS_CONFIG) out.spiffs | sort | sed s/^\\/// > out.list1
87+
./mkspiffs -u spiffs_u $(SPIFFS_TEST_FS_CONFIG) out.spiffs | sort | sed s/^\\/// > out.list_u
8788
./mkspiffs -l $(SPIFFS_TEST_FS_CONFIG) out.spiffs | cut -f 2 | sort | sed s/^\\/// > out.list2
8889
diff --strip-trailing-cr out.list0 out.list1
8990
diff --strip-trailing-cr out.list0 out.list2
90-
rm -f out.{list0,list1,list2,spiffs}
91+
diff spiffs spiffs_u
92+
rm -f out.{list0,list1,list2,list_u,spiffs}
93+
rm -R spiffs_u

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,23 @@ Tool to build and unpack [SPIFFS](https://github.com/pellepl/spiffs) images.
77

88
```
99
10-
./mkspiffs {-c <pack_dir>|-l|-i} [-b <number>] [-p <number>] [-s
10+
./mkspiffs {-c <pack_dir>|-u <dest_dir>|-l|-i} [-b <number>] [-p <number>] [-s
1111
<number>] [--] [--version] [-h] <image_file>
1212
1313
1414
Where:
1515
1616
-c <pack_dir>, --create <pack_dir>
17-
create spiffs image from a directory
17+
(OR required) create spiffs image from a directory
18+
-- OR --
19+
-u <dest_dir>, --unpack <dest_dir>
20+
(OR required) unpack spiffs image to a directory
1821
-- OR --
1922
-l, --list
20-
list files in spiffs image
23+
(OR required) list files in spiffs image
2124
-- OR --
2225
-i, --visualize
23-
visualize spiffs image
26+
(OR required) visualize spiffs image
2427
2528
2629
-b <number>, --block <number>

main.cpp

Lines changed: 180 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static int s_imageSize;
2929
static int s_pageSize;
3030
static int s_blockSize;
3131

32-
enum Action { ACTION_NONE, ACTION_PACK, ACTION_LIST, ACTION_VISUALIZE };
32+
enum Action { ACTION_NONE, ACTION_PACK, ACTION_UNPACK, ACTION_LIST, ACTION_VISUALIZE };
3333
static Action s_action = ACTION_NONE;
3434

3535
static spiffs s_fs;
@@ -190,6 +190,127 @@ void listFiles() {
190190
SPIFFS_closedir(&dir);
191191
}
192192

193+
/**
194+
* @brief Check if directory exists.
195+
* @param path Directory path.
196+
* @return True if exists otherwise false.
197+
*
198+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
199+
*/
200+
bool dirExists(const char* path) {
201+
DIR *d = opendir(path);
202+
203+
if (d) {
204+
closedir(d);
205+
return true;
206+
}
207+
208+
return false;
209+
}
210+
211+
/**
212+
* @brief Unpack file from file system.
213+
* @param spiffsFile SPIFFS dir entry pointer.
214+
* @param destPath Destination file path path.
215+
* @return True or false.
216+
*
217+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
218+
*/
219+
bool unpackFile(spiffs_dirent *spiffsFile, const char *destPath) {
220+
u8_t buffer[spiffsFile->size];
221+
std::string filename = (const char*)(spiffsFile->name);
222+
223+
// Open file from spiffs file system.
224+
spiffs_file src = SPIFFS_open(&s_fs, (char *)(filename.c_str()), SPIFFS_RDONLY, 0);
225+
226+
// read content into buffer
227+
SPIFFS_read(&s_fs, src, buffer, spiffsFile->size);
228+
229+
// Close spiffs file.
230+
SPIFFS_close(&s_fs, src);
231+
232+
// Open file.
233+
FILE* dst = fopen(destPath, "wb");
234+
235+
// Write content into file.
236+
fwrite(buffer, sizeof(u8_t), sizeof(buffer), dst);
237+
238+
// Close file.
239+
fclose(dst);
240+
241+
242+
return true;
243+
}
244+
245+
/**
246+
* @brief Unpack files from file system.
247+
* @param sDest Directory path as std::string.
248+
* @return True or false.
249+
*
250+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
251+
*
252+
* todo: Do unpack stuff for directories.
253+
*/
254+
bool unpackFiles(std::string sDest) {
255+
spiffs_DIR dir;
256+
spiffs_dirent ent;
257+
258+
// Add "./" to path if is not given.
259+
if (sDest.find("./") == std::string::npos) {
260+
sDest = "./" + sDest;
261+
}
262+
263+
// Check if directory exists. If it does not then try to create it with permissions 755.
264+
if (! dirExists(sDest.c_str())) {
265+
std::cout << "Directory " << sDest << " does not exists. Try to create it." << std::endl;
266+
267+
// Try to create directory.
268+
// platform stuff...
269+
#if defined(_WIN32)
270+
if (_mkdir(sDest.c_str()) != 0) {
271+
#else
272+
if (mkdir(sDest.c_str(), S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH) != 0) {
273+
#endif
274+
std::cerr << "Can not create directory!!!" << std::endl;
275+
return false;
276+
}
277+
}
278+
279+
// Open directory.
280+
SPIFFS_opendir(&s_fs, 0, &dir);
281+
282+
// Read content from directory.
283+
spiffs_dirent* it = SPIFFS_readdir(&dir, &ent);
284+
while (it) {
285+
// Check if content is a file.
286+
if ((int)(it->type) == 1) {
287+
std::string sDestFilePath = sDest + (const char*)(it->name);
288+
289+
// Unpack file to destination directory.
290+
if (! unpackFile(it, sDestFilePath.c_str()) ) {
291+
std::cout << "Can not unpack " << it->name << "!" << std::endl;
292+
return false;
293+
}
294+
295+
// Output stuff.
296+
std::cout
297+
<< it->name
298+
<< '\t'
299+
<< " > " << sDestFilePath
300+
<< '\t'
301+
<< "size: " << it->size << " Bytes"
302+
<< std::endl;
303+
}
304+
305+
it = SPIFFS_readdir(&dir, &ent);
306+
}
307+
308+
// Close directory.
309+
SPIFFS_closedir(&dir);
310+
311+
return true;
312+
}
313+
193314
// Actions
194315

195316
int actionPack() {
@@ -211,6 +332,43 @@ int actionPack() {
211332
return result;
212333
}
213334

335+
/**
336+
* @brief Unpack action.
337+
* @return 0 success, 1 error
338+
*
339+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
340+
*/
341+
int actionUnpack(void) {
342+
int ret = 0;
343+
s_flashmem.resize(s_imageSize, 0xff);
344+
345+
// open spiffs image
346+
FILE* fdsrc = fopen(s_imageName.c_str(), "rb");
347+
if (!fdsrc) {
348+
std::cerr << "error: failed to open image file" << std::endl;
349+
return 1;
350+
}
351+
352+
// read content into s_flashmem
353+
fread(&s_flashmem[0], 4, s_flashmem.size()/4, fdsrc);
354+
355+
// close fiel handle
356+
fclose(fdsrc);
357+
358+
// mount file system
359+
spiffsMount();
360+
361+
// unpack files
362+
if (! unpackFiles(s_dirName)) {
363+
ret = 1;
364+
}
365+
366+
// unmount file system
367+
spiffsUnmount();
368+
369+
return ret;
370+
}
371+
214372

215373
int actionList() {
216374
s_flashmem.resize(s_imageSize, 0xff);
@@ -254,6 +412,7 @@ int actionVisualize() {
254412
void processArgs(int argc, const char** argv) {
255413
TCLAP::CmdLine cmd("", ' ', VERSION);
256414
TCLAP::ValueArg<std::string> packArg( "c", "create", "create spiffs image from a directory", true, "", "pack_dir");
415+
TCLAP::ValueArg<std::string> unpackArg( "u", "unpack", "unpack spiffs image to a directory", true, "", "dest_dir");
257416
TCLAP::SwitchArg listArg( "l", "list", "list files in spiffs image", false);
258417
TCLAP::SwitchArg visualizeArg( "i", "visualize", "visualize spiffs image", false);
259418
TCLAP::UnlabeledValueArg<std::string> outNameArg( "image_file", "spiffs image file", true, "", "image_file" );
@@ -264,19 +423,20 @@ void processArgs(int argc, const char** argv) {
264423
cmd.add( imageSizeArg );
265424
cmd.add( pageSizeArg );
266425
cmd.add( blockSizeArg );
267-
std::vector<TCLAP::Arg*> args = {&packArg, &listArg, &visualizeArg};
426+
std::vector<TCLAP::Arg*> args = {&packArg, &unpackArg, &listArg, &visualizeArg};
268427
cmd.xorAdd( args );
269428
cmd.add( outNameArg );
270429
cmd.parse( argc, argv );
271430

272431
if (packArg.isSet()) {
273432
s_dirName = packArg.getValue();
274433
s_action = ACTION_PACK;
275-
}
276-
else if (listArg.isSet()) {
434+
} else if (unpackArg.isSet()) {
435+
s_dirName = unpackArg.getValue();
436+
s_action = ACTION_UNPACK;
437+
} else if (listArg.isSet()) {
277438
s_action = ACTION_LIST;
278-
}
279-
else if (visualizeArg.isSet()) {
439+
} else if (visualizeArg.isSet()) {
280440
s_action = ACTION_VISUALIZE;
281441
}
282442

@@ -296,10 +456,20 @@ int main(int argc, const char * argv[]) {
296456
}
297457

298458
switch (s_action) {
299-
case ACTION_PACK: return actionPack();
300-
case ACTION_LIST: return actionList();
301-
case ACTION_VISUALIZE: return actionVisualize();
302-
default: ;
459+
case ACTION_PACK:
460+
return actionPack();
461+
break;
462+
case ACTION_UNPACK:
463+
return actionUnpack();
464+
break;
465+
case ACTION_LIST:
466+
return actionList();
467+
break;
468+
case ACTION_VISUALIZE:
469+
return actionVisualize();
470+
break;
471+
default:
472+
break;
303473
}
304474

305475
return 1;

0 commit comments

Comments
 (0)