add ability to extract 7zip and rar files

This commit is contained in:
Chee Yee
2023-02-10 01:42:03 -08:00
parent 659205267f
commit b240de455b
11 changed files with 1581 additions and 9 deletions
+3 -1
View File
@@ -46,7 +46,7 @@ add_executable(ezremote_client
add_self(ezremote_client)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.00" 32 0)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.01" 32 0)
target_link_libraries(ezremote_client
c
@@ -63,6 +63,8 @@ target_link_libraries(ezremote_client
lexbor
smb2
minizip
un7zip
unrar
kernel
SceShellCoreUtil
SceSysmodule
Binary file not shown.
+1
View File
@@ -94,3 +94,4 @@ STR_COMPRESS=Compress
STR_ZIP_FILE_PATH=Zip Filename
STR_COMPRESSING=Compressing
STR_ERROR_CREATE_ZIP=Error occured while creating zip
STR_UNSUPPORTED_FILE_FORMAT=Unsupported compressed file format
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -1029,8 +1029,6 @@ namespace Actions
client->SetCallbackBytes(1);
client->SetCallbackXferFunction(FtpCallback);
remoteclient = client;
int res = pthread_create(&ftp_keep_alive_thid, NULL, KeepAliveThread, NULL);
}
else
{
@@ -1042,6 +1040,11 @@ namespace Actions
if (remoteclient->Connect(remote_settings->server, remote_settings->username, remote_settings->password))
{
RefreshRemoteFiles(false);
if (remoteclient->clientType() == CLIENT_TYPE_FTP)
{
int res = pthread_create(&ftp_keep_alive_thid, NULL, KeepAliveThread, NULL);
}
}
else
{
+1
View File
@@ -106,6 +106,7 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Zip Filename", // STR_ZIP_FILE_PATH
"Compressing", // STR_COMPRESSING
"Error occured while creating zip" // STR_ERROR_CREATE_ZIP
"Unsupported compressed file format" // STR_UNSUPPORTED_FILE_FORMAT
};
bool needs_extended_font = false;
+3 -2
View File
@@ -99,7 +99,8 @@
FUNC(STR_COMPRESS) \
FUNC(STR_ZIP_FILE_PATH) \
FUNC(STR_COMPRESSING) \
FUNC(STR_ERROR_CREATE_ZIP)
FUNC(STR_ERROR_CREATE_ZIP) \
FUNC(STR_UNSUPPORTED_FILE_FORMAT)
#define GET_VALUE(x) x,
#define GET_STRING(x) #x,
@@ -109,7 +110,7 @@ enum
FOREACH_STR(GET_VALUE)
};
#define LANG_STRINGS_NUM 96
#define LANG_STRINGS_NUM 97
#define LANG_ID_SIZE LANG_STRINGS_NUM
#define LANG_STR_SIZE 256
extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE];
+31
View File
@@ -97,6 +97,30 @@ void InitImgui()
0,
};
static const ImWchar icons[] {
0xF07B, 0xF07B, // folder
0xF65E, 0xF65E, // new folder
0xF15B, 0xF15B, // file
0xF021, 0xF021, // refresh
0xF0CA, 0xF0CA, // select all
0xF0C9, 0xF0C9, // unselect all
0x2700, 0x2700, // cut
0xF0C5, 0xF0C5, // copy
0xF0EA, 0xF0EA, // paste
0xF31C, 0xF31C, // edit
0xE0AC, 0xE0AC, // rename
0xE5A1, 0xE5A1, // delete
0xF002, 0xF002, // search
0x2699, 0x2699, // settings
0xF0ED, 0xF0ED, // download
0xF0EE, 0xF0EE, // upload
0xF56E, 0xF56E, // extract
0xF56F, 0xF56F, // compress
0xF0F6, 0xF0F6, // properties
0xF112, 0xF112, // cancel
0,
};
std::string lang = std::string(language);
int32_t lang_idx;
sceSystemServiceParamGetInt( ORBIS_SYSTEM_SERVICE_PARAM_ID_LANG, &lang_idx );
@@ -138,6 +162,13 @@ void InitImgui()
{
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/Roboto.ttf", 26.0f, NULL, ranges);
}
ImFontConfig config;
config.MergeMode = true;
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/fa-solid-900.ttf", 20.0f, &config, icons);
io.Fonts->Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;
io.Fonts->Build();
Lang::SetTranslation(lang_idx);
auto &style = ImGui::GetStyle();
+24 -1
View File
@@ -12,6 +12,7 @@
#include "util.h"
#include "lang.h"
#include "ime_dialog.h"
#include "IconsFontAwesome6.h"
extern "C"
{
@@ -60,6 +61,7 @@ bool select_url_inprogress = false;
int favorite_url_idx = 0;
char extract_zip_folder[256];
char zip_file_path[384];
char label[256];
bool dont_prompt_overwrite = false;
bool dont_prompt_overwrite_cb = false;
@@ -198,6 +200,27 @@ namespace Windows
}
}
std::string getExtractFolder()
{
std::string zipfolder;
if (strncmp(multi_selected_local_files.begin()->directory, "/data", 5) != 0)
{
zipfolder = "/data";
}
else if (multi_selected_local_files.size() > 1)
{
zipfolder = "/data";
}
else
{
std::string filename = std::string(multi_selected_local_files.begin()->name);
size_t dot_pos = filename.find_last_of(".");
zipfolder = std::string(local_directory) + "/" + filename.substr(0, dot_pos);
}
return zipfolder;
}
void ConnectionPanel()
{
ImGuiStyle *style = &ImGui::GetStyle();
@@ -772,7 +795,7 @@ namespace Windows
if (ImGui::Selectable(lang_strings[STR_EXTRACT], false, flags | ImGuiSelectableFlags_DontClosePopups, ImVec2(220, 0)))
{
ResetImeCallbacks();
sprintf(extract_zip_folder, "%s", local_directory);
sprintf(extract_zip_folder, "%s", getExtractFolder().c_str());
ime_single_field = extract_zip_folder;
ime_field_size = 255;
ime_callback = SingleValueImeCallback;
+96 -3
View File
@@ -7,16 +7,26 @@
#include <sys/stat.h>
#include <minizip/unzip.h>
#include <minizip/zip.h>
#include <un7zip.h>
#include <unrar.h>
#include "common.h"
#include "fs.h"
#include "lang.h"
#include "rtc.h"
#include "windows.h"
#include "zip_util.h"
#define TRANSFER_SIZE (128 * 1024)
namespace ZipUtil
{
static char filename_extracted[256];
void callback_7zip(const char *fileName, unsigned long fileSize, unsigned fileNum, unsigned numFiles)
{
sprintf(activity_message, "%s %s: %s", lang_strings[STR_EXTRACTING], filename_extracted, fileName);
}
void convertToZipTime(time_t time, tm_zip *tmzip)
{
OrbisDateTime gmt;
@@ -135,7 +145,7 @@ namespace ZipUtil
// Open new file in zip
std::string folder = path.substr(filename_start);
if (folder[folder.length()-1] != '/')
if (folder[folder.length() - 1] != '/')
folder = folder + "/";
res = zipOpenNewFileInZip3_64(zf, folder.c_str(), &zi,
@@ -170,7 +180,7 @@ namespace ZipUtil
if (dirent != NULL && strcmp(dirent->d_name, ".") != 0 && strcmp(dirent->d_name, "..") != 0)
{
int new_path_length = path.length() + strlen(dirent->d_name) + 2;
char *new_path = (char*)malloc(new_path_length);
char *new_path = (char *)malloc(new_path_length);
snprintf(new_path, new_path_length, "%s%s%s", path.c_str(), FS::hasEndSlash(path.c_str()) ? "" : "/", dirent->d_name);
int ret = 0;
@@ -206,7 +216,31 @@ namespace ZipUtil
return 1;
}
int Extract(const DirEntry &file, const std::string &dir)
CompressFileType getCompressFileType(const std::string &file)
{
char buf[8];
FILE *f = FS::OpenRead(file);
if (f == nullptr)
return COMPRESS_FILE_TYPE_UNKNOWN;
memset(buf, 0, 8);
int ret = FS::Read(f, buf, 8);
FS::Close(f);
if (ret < 0)
return COMPRESS_FILE_TYPE_UNKNOWN;
if (strncmp(buf, (const char *)MAGIC_7Z_1, 6) == 0)
return COMPRESS_FILE_TYPE_7Z;
else if (strncmp(buf, (const char *)MAGIC_RAR_1, 7) == 0 || strncmp(buf, (const char *)MAGIC_RAR_2, 8) == 0)
return COMPRESS_FILE_TYPE_RAR;
else if (strncmp(buf, (const char *)MAGIC_ZIP_1, 4) == 0 || strncmp(buf, (const char *)MAGIC_ZIP_2, 4) == 0 || strncmp(buf, (const char *)MAGIC_ZIP_3, 4) == 0)
return COMPRESS_FILE_TYPE_ZIP;
return COMPRESS_FILE_TYPE_UNKNOWN;
}
int ExtractZip(const DirEntry &file, const std::string &dir)
{
unz_global_info global_info;
unz_file_info file_info;
@@ -267,4 +301,63 @@ namespace ZipUtil
unzClose(zipfile);
return 1;
}
int Extract7Zip(const DirEntry &file, const std::string &dir)
{
FS::MkDirs(dir, true);
sprintf(filename_extracted, "%s", file.name);
int res = Extract7zFileEx(file.path, dir.c_str(), callback_7zip, DEFAULT_IN_BUF_SIZE);
return res == 0;
}
int ExtractRar(const DirEntry &file, const std::string &dir)
{
HANDLE hArcData; // Archive Handle
struct RAROpenArchiveDataEx rarOpenArchiveData;
struct RARHeaderDataEx rarHeaderData;
char destPath[256];
memset(&rarOpenArchiveData, 0, sizeof(rarOpenArchiveData));
memset(&rarHeaderData, 0, sizeof(rarHeaderData));
sprintf(destPath, "%s", dir.c_str());
rarOpenArchiveData.ArcName = (char *)file.path;
rarOpenArchiveData.CmtBuf = NULL;
rarOpenArchiveData.CmtBufSize = 0;
rarOpenArchiveData.OpenMode = RAR_OM_EXTRACT;
hArcData = RAROpenArchiveEx(&rarOpenArchiveData);
if (rarOpenArchiveData.OpenResult != ERAR_SUCCESS)
{
return 0;
}
while (RARReadHeaderEx(hArcData, &rarHeaderData) == ERAR_SUCCESS)
{
sprintf(activity_message, "%s %s: %s", lang_strings[STR_EXTRACTING], file.name, rarHeaderData.FileName);
if (RARProcessFile(hArcData, RAR_EXTRACT, destPath, NULL) != ERAR_SUCCESS)
{
RARCloseArchive(hArcData);
return 0;
}
}
RARCloseArchive(hArcData);
return 1;
}
int Extract(const DirEntry &file, const std::string &dir)
{
CompressFileType fileType = getCompressFileType(file.path);
if (fileType == COMPRESS_FILE_TYPE_ZIP)
return ExtractZip(file, dir);
else if (fileType == COMPRESS_FILE_TYPE_7Z)
return Extract7Zip(file, dir);
else if (fileType == COMPRESS_FILE_TYPE_RAR)
return ExtractRar(file, dir);
else
sprintf(status_message, "%s - %s", file.name, lang_strings[STR_UNSUPPORTED_FILE_FORMAT]);
return 1;
}
}
+16
View File
@@ -8,6 +8,22 @@
#include "common.h"
#include "fs.h"
static uint8_t MAGIC_ZIP_1[4] = {0x50, 0x4B, 0x03, 0x04};
static uint8_t MAGIC_ZIP_2[4] = {0x50, 0x4B, 0x05, 0x06};
static uint8_t MAGIC_ZIP_3[4] = {0x50, 0x4B, 0x07, 0x08};
static uint8_t MAGIC_7Z_1[6] = {0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C};
static uint8_t MAGIC_RAR_1[7] = {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00};
static uint8_t MAGIC_RAR_2[8] = {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x01, 0x00};
enum CompressFileType {
COMPRESS_FILE_TYPE_7Z,
COMPRESS_FILE_TYPE_ZIP,
COMPRESS_FILE_TYPE_RAR,
COMPRESS_FILE_TYPE_UNKNOWN
};
namespace ZipUtil
{
int ZipAddPath(zipFile zf, const std::string &path, int filename_start, int level);