Skip to content

Commit 952ad68

Browse files
committed
unpack files from spiffs image
1 parent b5f8f80 commit 952ad68

File tree

3 files changed

+211
-13
lines changed

3 files changed

+211
-13
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

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ Tool to build and unpack [SPIFFS](https://github.com/pellepl/spiffs) images.
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: 200 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,137 @@ 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+
{
202+
DIR *d = opendir(path);
203+
204+
if (d)
205+
{
206+
closedir(d);
207+
return true;
208+
}
209+
210+
return false;
211+
}
212+
213+
/**
214+
* @brief Unpack file from file system.
215+
* @param srcName Filename.
216+
* @param destPath Destination file path path.
217+
* @return True or false.
218+
*
219+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
220+
*/
221+
//bool unpackFile(const char *srcName, const char *destPath)
222+
bool unpackFile(spiffs_dirent *spiffsFile, const char *destPath)
223+
{
224+
char buffer[spiffsFile->size];
225+
std::string filename = (const char*)(spiffsFile->name);
226+
227+
// Open file from spiffs file system.
228+
spiffs_file src = SPIFFS_open(&s_fs, (char *)(filename.c_str()), SPIFFS_RDONLY, 0);
229+
230+
// read content into buffer
231+
SPIFFS_read(&s_fs, src, buffer, spiffsFile->size);
232+
233+
// Close spiffs file.
234+
SPIFFS_close(&s_fs, src);
235+
236+
// Open file.
237+
FILE* dst = fopen(destPath, "wb");
238+
239+
// Write content into file.
240+
fputs(buffer, dst);
241+
242+
// Close file.
243+
fclose(dst);
244+
245+
246+
return true;
247+
}
248+
249+
/**
250+
* @brief Unpack files from file system.
251+
* @param sDest Directory path as std::string.
252+
* @return True or false.
253+
*
254+
* @author Pascal Gollor (http://www.pgollor.de/cms/)
255+
*
256+
* todo: Do unpack stuff for directories.
257+
*/
258+
bool unpackFiles(std::string sDest)
259+
{
260+
spiffs_DIR dir;
261+
spiffs_dirent ent;
262+
263+
// Add "./" to path if is not given.
264+
if (sDest.find("./") == std::string::npos)
265+
{
266+
sDest = "./" + sDest;
267+
}
268+
269+
// Check if directory exists. If it does not then try to create it with permissions 755.
270+
if (! dirExists(sDest.c_str()))
271+
{
272+
std::cout << "Directory " << sDest << " does not exists. Try to create it." << std::endl;
273+
274+
// Try to create dir.
275+
if (mkdir(sDest.c_str(), S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH) != 0)
276+
{
277+
std::cerr << "Can not create directory!!!" << std::endl;
278+
return false;
279+
}
280+
}
281+
282+
// Open directory.
283+
SPIFFS_opendir(&s_fs, 0, &dir);
284+
285+
// Read content from directory.
286+
spiffs_dirent* it = SPIFFS_readdir(&dir, &ent);
287+
while (it)
288+
{
289+
// Check if content is a file.
290+
if ((int)(it->type) == 1)
291+
{
292+
//std::string sDestFile = (const char*)(it->name);
293+
//std::string sDestFilePath = sDest + "/" + sDestFile;
294+
//std::string sDestFilePath = sDest + sDestFile;
295+
std::string sDestFilePath = sDest + (const char*)(it->name);
296+
297+
// Unpack file to destination directory.
298+
//if (! unpackFile(sDestFile.c_str(), sDestFilePath.c_str()) )
299+
if (! unpackFile(it, sDestFilePath.c_str()) )
300+
{
301+
std::cout << "Can not unpack " << it->name << "!" << std::endl;
302+
return false;
303+
}
304+
305+
// Output stuff.
306+
std::cout
307+
<< it->name
308+
<< '\t'
309+
<< " > " << sDestFilePath
310+
<< '\t'
311+
<< "size: " << it->size << " Bytes"
312+
<< std::endl;
313+
}
314+
315+
it = SPIFFS_readdir(&dir, &ent);
316+
}
317+
318+
// Close directory.
319+
SPIFFS_closedir(&dir);
320+
321+
return true;
322+
}
323+
193324
// Actions
194325

195326
int actionPack() {
@@ -211,6 +342,45 @@ int actionPack() {
211342
return result;
212343
}
213344

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

215385
int actionList() {
216386
s_flashmem.resize(s_imageSize, 0xff);
@@ -254,6 +424,7 @@ int actionVisualize() {
254424
void processArgs(int argc, const char** argv) {
255425
TCLAP::CmdLine cmd("", ' ', VERSION);
256426
TCLAP::ValueArg<std::string> packArg( "c", "create", "create spiffs image from a directory", true, "", "pack_dir");
427+
TCLAP::ValueArg<std::string> unpackArg( "u", "unpack", "unpack spiffs image to a directory", true, "", "dest_dir");
257428
TCLAP::SwitchArg listArg( "l", "list", "list files in spiffs image", false);
258429
TCLAP::SwitchArg visualizeArg( "i", "visualize", "visualize spiffs image", false);
259430
TCLAP::UnlabeledValueArg<std::string> outNameArg( "image_file", "spiffs image file", true, "", "image_file" );
@@ -264,19 +435,27 @@ void processArgs(int argc, const char** argv) {
264435
cmd.add( imageSizeArg );
265436
cmd.add( pageSizeArg );
266437
cmd.add( blockSizeArg );
267-
std::vector<TCLAP::Arg*> args = {&packArg, &listArg, &visualizeArg};
438+
std::vector<TCLAP::Arg*> args = {&packArg, &unpackArg, &listArg, &visualizeArg};
268439
cmd.xorAdd( args );
269440
cmd.add( outNameArg );
270441
cmd.parse( argc, argv );
271442

272-
if (packArg.isSet()) {
443+
if (packArg.isSet())
444+
{
273445
s_dirName = packArg.getValue();
274446
s_action = ACTION_PACK;
275447
}
276-
else if (listArg.isSet()) {
448+
else if (unpackArg.isSet())
449+
{
450+
s_dirName = unpackArg.getValue();
451+
s_action = ACTION_UNPACK;
452+
}
453+
else if (listArg.isSet())
454+
{
277455
s_action = ACTION_LIST;
278456
}
279-
else if (visualizeArg.isSet()) {
457+
else if (visualizeArg.isSet())
458+
{
280459
s_action = ACTION_VISUALIZE;
281460
}
282461

@@ -295,11 +474,22 @@ int main(int argc, const char * argv[]) {
295474
return 1;
296475
}
297476

298-
switch (s_action) {
299-
case ACTION_PACK: return actionPack();
300-
case ACTION_LIST: return actionList();
301-
case ACTION_VISUALIZE: return actionVisualize();
302-
default: ;
477+
switch (s_action)
478+
{
479+
case ACTION_PACK:
480+
return actionPack();
481+
break;
482+
case ACTION_UNPACK:
483+
return actionUnpack();
484+
break;
485+
case ACTION_LIST:
486+
return actionList();
487+
break;
488+
case ACTION_VISUALIZE:
489+
return actionVisualize();
490+
break;
491+
default:
492+
break;
303493
}
304494

305495
return 1;

0 commit comments

Comments
 (0)