@@ -29,7 +29,7 @@ static int s_imageSize;
29
29
static int s_pageSize;
30
30
static int s_blockSize;
31
31
32
- enum Action { ACTION_NONE, ACTION_PACK, ACTION_LIST, ACTION_VISUALIZE };
32
+ enum Action { ACTION_NONE, ACTION_PACK, ACTION_UNPACK, ACTION_LIST, ACTION_VISUALIZE };
33
33
static Action s_action = ACTION_NONE;
34
34
35
35
static spiffs s_fs;
@@ -190,6 +190,137 @@ void listFiles() {
190
190
SPIFFS_closedir (&dir);
191
191
}
192
192
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
+
193
324
// Actions
194
325
195
326
int actionPack () {
@@ -211,6 +342,45 @@ int actionPack() {
211
342
return result;
212
343
}
213
344
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
+
214
384
215
385
int actionList () {
216
386
s_flashmem.resize (s_imageSize, 0xff );
@@ -254,6 +424,7 @@ int actionVisualize() {
254
424
void processArgs (int argc, const char ** argv) {
255
425
TCLAP::CmdLine cmd (" " , ' ' , VERSION);
256
426
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" );
257
428
TCLAP::SwitchArg listArg ( " l" , " list" , " list files in spiffs image" , false );
258
429
TCLAP::SwitchArg visualizeArg ( " i" , " visualize" , " visualize spiffs image" , false );
259
430
TCLAP::UnlabeledValueArg<std::string> outNameArg ( " image_file" , " spiffs image file" , true , " " , " image_file" );
@@ -264,19 +435,27 @@ void processArgs(int argc, const char** argv) {
264
435
cmd.add ( imageSizeArg );
265
436
cmd.add ( pageSizeArg );
266
437
cmd.add ( blockSizeArg );
267
- std::vector<TCLAP::Arg*> args = {&packArg, &listArg, &visualizeArg};
438
+ std::vector<TCLAP::Arg*> args = {&packArg, &unpackArg, & listArg, &visualizeArg};
268
439
cmd.xorAdd ( args );
269
440
cmd.add ( outNameArg );
270
441
cmd.parse ( argc, argv );
271
442
272
- if (packArg.isSet ()) {
443
+ if (packArg.isSet ())
444
+ {
273
445
s_dirName = packArg.getValue ();
274
446
s_action = ACTION_PACK;
275
447
}
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
+ {
277
455
s_action = ACTION_LIST;
278
456
}
279
- else if (visualizeArg.isSet ()) {
457
+ else if (visualizeArg.isSet ())
458
+ {
280
459
s_action = ACTION_VISUALIZE;
281
460
}
282
461
@@ -295,11 +474,22 @@ int main(int argc, const char * argv[]) {
295
474
return 1 ;
296
475
}
297
476
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 ;
303
493
}
304
494
305
495
return 1 ;
0 commit comments