@@ -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,127 @@ 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
+ 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
+
193
314
// Actions
194
315
195
316
int actionPack () {
@@ -211,6 +332,43 @@ int actionPack() {
211
332
return result;
212
333
}
213
334
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
+
214
372
215
373
int actionList () {
216
374
s_flashmem.resize (s_imageSize, 0xff );
@@ -254,6 +412,7 @@ int actionVisualize() {
254
412
void processArgs (int argc, const char ** argv) {
255
413
TCLAP::CmdLine cmd (" " , ' ' , VERSION);
256
414
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" );
257
416
TCLAP::SwitchArg listArg ( " l" , " list" , " list files in spiffs image" , false );
258
417
TCLAP::SwitchArg visualizeArg ( " i" , " visualize" , " visualize spiffs image" , false );
259
418
TCLAP::UnlabeledValueArg<std::string> outNameArg ( " image_file" , " spiffs image file" , true , " " , " image_file" );
@@ -264,19 +423,20 @@ void processArgs(int argc, const char** argv) {
264
423
cmd.add ( imageSizeArg );
265
424
cmd.add ( pageSizeArg );
266
425
cmd.add ( blockSizeArg );
267
- std::vector<TCLAP::Arg*> args = {&packArg, &listArg, &visualizeArg};
426
+ std::vector<TCLAP::Arg*> args = {&packArg, &unpackArg, & listArg, &visualizeArg};
268
427
cmd.xorAdd ( args );
269
428
cmd.add ( outNameArg );
270
429
cmd.parse ( argc, argv );
271
430
272
431
if (packArg.isSet ()) {
273
432
s_dirName = packArg.getValue ();
274
433
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 ()) {
277
438
s_action = ACTION_LIST;
278
- }
279
- else if (visualizeArg.isSet ()) {
439
+ } else if (visualizeArg.isSet ()) {
280
440
s_action = ACTION_VISUALIZE;
281
441
}
282
442
@@ -296,10 +456,20 @@ int main(int argc, const char * argv[]) {
296
456
}
297
457
298
458
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 ;
303
473
}
304
474
305
475
return 1 ;
0 commit comments