mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-29 14:16:40 +00:00
Add unzip command
This commit is contained in:
parent
098211f0f7
commit
d674d5d52c
@ -40,7 +40,7 @@ dispatch_conf_t dispatch_setings = {.teleperiod = 300};
|
|||||||
|
|
||||||
uint16_t dispatchSecondsToNextTeleperiod = 0;
|
uint16_t dispatchSecondsToNextTeleperiod = 0;
|
||||||
uint8_t nCommands = 0;
|
uint8_t nCommands = 0;
|
||||||
haspCommand_t commands[21];
|
haspCommand_t commands[22];
|
||||||
|
|
||||||
moodlight_t moodlight = {.brightness = 255};
|
moodlight_t moodlight = {.brightness = 255};
|
||||||
|
|
||||||
@ -1081,6 +1081,9 @@ void dispatchSetup()
|
|||||||
dispatch_add_command(PSTR("screenshot"), dispatch_screenshot);
|
dispatch_add_command(PSTR("screenshot"), dispatch_screenshot);
|
||||||
dispatch_add_command(PSTR("discovery"), dispatch_send_discovery);
|
dispatch_add_command(PSTR("discovery"), dispatch_send_discovery);
|
||||||
dispatch_add_command(PSTR("factoryreset"), dispatch_factory_reset);
|
dispatch_add_command(PSTR("factoryreset"), dispatch_factory_reset);
|
||||||
|
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
|
||||||
|
dispatch_add_command(PSTR("unzip"), filesystemUnzip);
|
||||||
|
#endif
|
||||||
#if HASP_USE_CONFIG > 0
|
#if HASP_USE_CONFIG > 0
|
||||||
dispatch_add_command(PSTR("setupap"), oobeFakeSetup);
|
dispatch_add_command(PSTR("setupap"), oobeFakeSetup);
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "hasp_debug.h"
|
#include "hasp_debug.h"
|
||||||
#include "hasp_filesystem.h"
|
#include "hasp_filesystem.h"
|
||||||
|
#include "rom/crc.h"
|
||||||
|
|
||||||
void filesystemInfo()
|
void filesystemInfo()
|
||||||
{ // Get all information of your SPIFFS
|
{ // Get all information of your SPIFFS
|
||||||
@ -25,6 +26,118 @@ void filesystemInfo()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void filesystemUnzip(const char*, const char* filename)
|
||||||
|
{
|
||||||
|
File zipfile = HASP_FS.open(filename, FILE_READ);
|
||||||
|
if(!zipfile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t head;
|
||||||
|
size_t len;
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
zipfile.seek(0);
|
||||||
|
while(!done) {
|
||||||
|
len = zipfile.read((uint8_t*)&head, sizeof(head));
|
||||||
|
if(len != sizeof(head)) {
|
||||||
|
done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(head) {
|
||||||
|
case 0x04034b50: {
|
||||||
|
zip_file_header_t fh;
|
||||||
|
zipfile.seek(zipfile.position() - 2, SeekSet); // rewind for struct alignment (26-28)
|
||||||
|
len = zipfile.read((uint8_t*)(&fh), sizeof(zip_file_header_t));
|
||||||
|
if(len != sizeof(zip_file_header_t)) {
|
||||||
|
done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fh.filename_length >= 31) {
|
||||||
|
LOG_WARNING(TAG_FILE, F("filename length too long %d"), fh.filename_length);
|
||||||
|
zipfile.seek(fh.filename_length + fh.extra_length, SeekCur); // skip extra field
|
||||||
|
continue;
|
||||||
|
// } else {
|
||||||
|
// LOG_WARNING(TAG_FILE, F("min %d - flag %d - len %d - xtra %d"), fh.min_version, fh.flags,
|
||||||
|
// fh.filename_length, fh.extra_length);
|
||||||
|
}
|
||||||
|
char name[32] = {0};
|
||||||
|
name[0] = '/';
|
||||||
|
|
||||||
|
len = zipfile.read((uint8_t*)&name[1], fh.filename_length);
|
||||||
|
if(len != fh.filename_length) {
|
||||||
|
LOG_WARNING(TAG_FILE, F("filename read failed %d != %d"), fh.filename_length, len);
|
||||||
|
done = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
zipfile.seek(fh.extra_length, SeekCur); // skip extra field
|
||||||
|
|
||||||
|
if(fh.compression_method != ZIP_NO_COMPRESSION) {
|
||||||
|
LOG_WARNING(TAG_FILE, F("Compression is not supported %d"), fh.compression_method);
|
||||||
|
zipfile.seek(fh.compressed_size, SeekCur); // skip compressed file
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(HASP_FS.exists(name)) HASP_FS.remove(name);
|
||||||
|
|
||||||
|
File f = HASP_FS.open(name, FILE_WRITE);
|
||||||
|
if(f) {
|
||||||
|
uint8_t buffer[512];
|
||||||
|
uint32_t crc32 = 0;
|
||||||
|
|
||||||
|
while(!done && fh.compressed_size >= 512) {
|
||||||
|
len = zipfile.readBytes((char*)&buffer, 512);
|
||||||
|
if(len != 512) done = true;
|
||||||
|
fh.compressed_size -= len;
|
||||||
|
crc32 = crc32_le(crc32, buffer, len);
|
||||||
|
// crc2 = crc32_be(crc2, buffer, len);
|
||||||
|
f.write(buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!done && fh.compressed_size > 0) {
|
||||||
|
len = zipfile.readBytes((char*)&buffer, fh.compressed_size);
|
||||||
|
if(len != fh.compressed_size) done = true;
|
||||||
|
fh.compressed_size -= len;
|
||||||
|
crc32 = crc32_le(crc32, buffer, len);
|
||||||
|
// crc2 = crc32_be(crc2, buffer, len);
|
||||||
|
f.write(buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(crc32 != fh.crc) done = true;
|
||||||
|
|
||||||
|
if(!done) {
|
||||||
|
Parser::format_bytes(fh.uncompressed_size, (char*)buffer, sizeof(buffer));
|
||||||
|
LOG_VERBOSE(TAG_FILE, F(D_BULLET "%s (%s)"), name, buffer);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(TAG_FILE, F(D_FILE_SAVE_FAILED), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x02014b50:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
case 0x06054b50:
|
||||||
|
// end of file
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
char outputString[9];
|
||||||
|
itoa(head, outputString, 16);
|
||||||
|
LOG_WARNING(TAG_FILE, F("invalid %s"), outputString);
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zipfile.close();
|
||||||
|
LOG_VERBOSE(TAG_FILE, F("extracting %s complete"), filename);
|
||||||
|
}
|
||||||
|
|
||||||
void filesystemList()
|
void filesystemList()
|
||||||
{
|
{
|
||||||
#if HASP_USE_SPIFFS > 0
|
#if HASP_USE_SPIFFS > 0
|
||||||
|
@ -10,6 +10,25 @@ bool filesystemSetup(void);
|
|||||||
|
|
||||||
void filesystemList();
|
void filesystemList();
|
||||||
void filesystemInfo();
|
void filesystemInfo();
|
||||||
|
void filesystemUnzip(const char*, const char* filename);
|
||||||
|
|
||||||
|
enum { ZIP_NO_COMPRESSION = 0, ZIP_DEFLTATE = 8 };
|
||||||
|
typedef uint16_t zip_compression_method_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t dummy_bytes; // total struct needs to be a multiple of 4 bytes
|
||||||
|
uint16_t min_version;
|
||||||
|
uint16_t flags;
|
||||||
|
zip_compression_method_t compression_method;
|
||||||
|
uint16_t time_modified;
|
||||||
|
uint16_t date_modified;
|
||||||
|
uint32_t crc;
|
||||||
|
uint32_t compressed_size;
|
||||||
|
uint32_t uncompressed_size;
|
||||||
|
uint16_t filename_length; // OK
|
||||||
|
uint16_t extra_length;
|
||||||
|
} zip_file_header_t;
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
#if HASP_USE_SPIFFS > 0
|
#if HASP_USE_SPIFFS > 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user