mirror of
https://gitlab.com/Nanolx/homebrewfilter.git
synced 2024-11-24 10:09:21 +01:00
add ability to unpack .zip files (for theme download)
... currently devkit is broken on my pc, so I can't test ...
This commit is contained in:
parent
9e5129d482
commit
156448d538
2
Makefile
2
Makefile
@ -45,7 +45,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--section-start,.init=0x8
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -ldi -lpng -lz -lfat -lntfs -lwiiuse -lbte -lasnd -logc -lvorbisidec -lfreetype -lmxml -lext2fs
|
||||
LIBS := -ldi -lpng -lz -lfat -lntfs -lwiiuse -lbte -lasnd -logc -lvorbisidec -lfreetype -lmxml -lext2fs -lzip
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
|
@ -11,8 +11,9 @@
|
||||
#include "Network/network.h"
|
||||
#include "Network/update.h"
|
||||
#include "Network/http.h"
|
||||
#include "ZipFile.h"
|
||||
|
||||
#/*** Extern variables ***/
|
||||
/*** Extern variables ***/
|
||||
extern GuiWindow * mainWindow;
|
||||
|
||||
/*** Extern functions ***/
|
||||
@ -90,22 +91,25 @@ void themeDownload(string themename)
|
||||
struct block file = downloadfile(buffer);
|
||||
if (file.data && file.size > 0)
|
||||
{
|
||||
FILE * data = fopen((Settings.device_dat + ":/config/Homebrew Filter/Themes/"+ themename + ".zip").c_str(), "wb");
|
||||
FILE * data = fopen((Settings.device_dat + ":/config/Homebrew Filter/Themes/" + themename + ".zip").c_str(), "wb");
|
||||
if(data)
|
||||
{
|
||||
fwrite(file.data, 1, file.size, data);
|
||||
fclose(data);
|
||||
}
|
||||
}
|
||||
|
||||
if(file.data)
|
||||
free(file.data);
|
||||
|
||||
|
||||
ZipFile *zipfile = new ZipFile((Settings.device_dat + ":/config/Homebrew Filter/Themes/" + themename + ".zip").c_str());
|
||||
zipfile->ExtractAll((Settings.device_dat + ":/config/Homebrew Filter/Themes/").c_str());
|
||||
|
||||
msgTxt.SetText("");
|
||||
downloadTxt.SetText(tr("finished"));
|
||||
|
||||
promptWindow.Append(&btn1);
|
||||
|
||||
|
||||
while(stop)
|
||||
{
|
||||
usleep(100);
|
||||
|
328
source/ZipFile.cpp
Normal file
328
source/ZipFile.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2009-2011 Dimok
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
//#include "../Prompts/ProgressWindow.h"
|
||||
//#include "../Prompts/PromptWindows.h"
|
||||
//#include "../Language/gettext.h"
|
||||
//#include "../Tools/ShowError.h"
|
||||
#include "ZipFile.h"
|
||||
|
||||
|
||||
ZipFile::ZipFile(const char *filepath, short mode)
|
||||
{
|
||||
if(!filepath)
|
||||
return;
|
||||
|
||||
ZipFilePath = filepath;
|
||||
OpenMode = mode;
|
||||
zFile = 0;
|
||||
uzFile = 0;
|
||||
|
||||
if(OpenMode == ZipFile::OPEN || OpenMode == ZipFile::APPEND)
|
||||
{
|
||||
uzFile = unzOpen(ZipFilePath.c_str());
|
||||
if(uzFile)
|
||||
this->LoadList();
|
||||
}
|
||||
}
|
||||
|
||||
ZipFile::~ZipFile()
|
||||
{
|
||||
ClearList();
|
||||
if(uzFile)
|
||||
unzClose(uzFile);
|
||||
if(zFile)
|
||||
zipClose(zFile, NULL);
|
||||
}
|
||||
|
||||
bool ZipFile::SwitchMode(short mode)
|
||||
{
|
||||
if(mode == ZipFile::OPEN)
|
||||
{
|
||||
if(zFile)
|
||||
{
|
||||
zipClose(zFile, NULL);
|
||||
zFile = 0;
|
||||
}
|
||||
|
||||
if(!uzFile)
|
||||
uzFile = unzOpen(ZipFilePath.c_str());
|
||||
|
||||
return (uzFile != 0);
|
||||
}
|
||||
else if(mode == ZipFile::CREATE || mode == ZipFile::APPEND)
|
||||
{
|
||||
if(uzFile)
|
||||
{
|
||||
unzClose(uzFile);
|
||||
uzFile = 0;
|
||||
}
|
||||
|
||||
if(!zFile)
|
||||
zFile = zipOpen(ZipFilePath.c_str(), mode);
|
||||
|
||||
return (zFile != 0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ZipFile::ClearList()
|
||||
{
|
||||
for(u32 i = 0; i < ZipStructure.size(); i++)
|
||||
{
|
||||
if(ZipStructure[i]->filename)
|
||||
delete [] ZipStructure[i]->filename;
|
||||
|
||||
if(ZipStructure[i])
|
||||
delete ZipStructure[i];
|
||||
}
|
||||
|
||||
ZipStructure.clear();
|
||||
std::vector<ArchiveFileStruct *>().swap(ZipStructure);
|
||||
}
|
||||
|
||||
bool ZipFile::LoadList()
|
||||
{
|
||||
ClearList();
|
||||
|
||||
if(!SwitchMode(ZipFile::OPEN))
|
||||
return false;
|
||||
|
||||
int ret = unzGoToFirstFile(uzFile);
|
||||
if(ret != UNZ_OK)
|
||||
return false;
|
||||
|
||||
char filename[1024];
|
||||
unz_file_info cur_file_info;
|
||||
RealArchiveItemCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if(unzGetCurrentFileInfo(uzFile, &cur_file_info, filename, sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK)
|
||||
{
|
||||
bool isDir = false;
|
||||
if(filename[strlen(filename)-1] == '/')
|
||||
{
|
||||
isDir = true;
|
||||
filename[strlen(filename)-1] = '\0';
|
||||
}
|
||||
|
||||
int strlength = strlen(filename)+1;
|
||||
|
||||
ArchiveFileStruct * CurArcFile = new ArchiveFileStruct;
|
||||
CurArcFile->filename = new char[strlength];
|
||||
strcpy(CurArcFile->filename, filename);
|
||||
CurArcFile->length = cur_file_info.uncompressed_size;
|
||||
CurArcFile->comp_length = cur_file_info.compressed_size;
|
||||
CurArcFile->isdir = isDir;
|
||||
CurArcFile->fileindex = RealArchiveItemCount;
|
||||
CurArcFile->ModTime = (u64) cur_file_info.dosDate;
|
||||
CurArcFile->archiveType = ZIP;
|
||||
|
||||
ZipStructure.push_back(CurArcFile);
|
||||
}
|
||||
++RealArchiveItemCount;
|
||||
}
|
||||
while(unzGoToNextFile(uzFile) == UNZ_OK);
|
||||
|
||||
PathControl();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ArchiveFileStruct * ZipFile::GetFileStruct(int ind)
|
||||
{
|
||||
if(ind < 0 || ind >= (int) ZipStructure.size())
|
||||
return NULL;
|
||||
|
||||
return ZipStructure[ind];
|
||||
}
|
||||
|
||||
bool ZipFile::SeekFile(int ind)
|
||||
{
|
||||
if(ind < 0 || ind >= (int) ZipStructure.size())
|
||||
return false;
|
||||
|
||||
if(!SwitchMode(ZipFile::OPEN))
|
||||
return false;
|
||||
|
||||
int ret = unzGoToFirstFile(uzFile);
|
||||
if(ret != UNZ_OK)
|
||||
return false;
|
||||
|
||||
while(ind > 0)
|
||||
{
|
||||
if(unzGoToNextFile(uzFile) != UNZ_OK)
|
||||
return false;
|
||||
|
||||
--ind;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ZipFile::CheckMissingPath(const char * path)
|
||||
{
|
||||
if(!path)
|
||||
return;
|
||||
|
||||
u32 i = 0;
|
||||
for(i = 0; i < ZipStructure.size(); i++)
|
||||
{
|
||||
if(strcasecmp(ZipStructure[i]->filename, path) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == ZipStructure.size())
|
||||
{
|
||||
int strlength = strlen(path)+1;
|
||||
ArchiveFileStruct * CurArcFile = new ArchiveFileStruct;
|
||||
CurArcFile->filename = new char[strlength];
|
||||
strcpy(CurArcFile->filename, path);
|
||||
CurArcFile->length = 0;
|
||||
CurArcFile->comp_length = 0;
|
||||
CurArcFile->isdir = true;
|
||||
CurArcFile->fileindex = ZipStructure.size();
|
||||
CurArcFile->ModTime = 0;
|
||||
CurArcFile->archiveType = ZIP;
|
||||
|
||||
ZipStructure.push_back(CurArcFile);
|
||||
}
|
||||
}
|
||||
|
||||
void ZipFile::PathControl()
|
||||
{
|
||||
char missingpath[1024];
|
||||
|
||||
for(u32 n = 0; n < ZipStructure.size(); n++)
|
||||
{
|
||||
const char * filepath = ZipStructure[n]->filename;
|
||||
int strlength = strlen(filepath);
|
||||
|
||||
for(int i = 0; i < strlength; i++)
|
||||
{
|
||||
if(filepath[i] == '/')
|
||||
CheckMissingPath(missingpath);
|
||||
|
||||
missingpath[i] = filepath[i];
|
||||
missingpath[i+1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ZipFile::ExtractAll(const char *dest)
|
||||
{
|
||||
if(!SwitchMode(OPEN))
|
||||
return -1;
|
||||
|
||||
bool Stop = false;
|
||||
|
||||
u32 blocksize = 1024*70;
|
||||
void *buffer = malloc(blocksize);
|
||||
|
||||
if(!buffer)
|
||||
return -5;
|
||||
|
||||
char writepath[1024];
|
||||
char filename[1024];
|
||||
memset(writepath, 0, sizeof(writepath));
|
||||
memset(filename, 0, sizeof(filename));
|
||||
|
||||
unz_file_info cur_file_info;
|
||||
|
||||
int ret = unzGoToFirstFile(uzFile);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
free(buffer);
|
||||
return -6;
|
||||
}
|
||||
|
||||
while(!Stop)
|
||||
{
|
||||
if(unzGetCurrentFileInfo(uzFile, &cur_file_info, filename, sizeof(filename), NULL, 0, NULL, 0) != UNZ_OK)
|
||||
{
|
||||
Stop = true;
|
||||
}
|
||||
|
||||
if(!Stop && filename[strlen(filename)-1] != '/')
|
||||
{
|
||||
u64 uncompressed_size = cur_file_info.uncompressed_size;
|
||||
|
||||
u64 done = 0;
|
||||
char *pointer = NULL;
|
||||
|
||||
ret = unzOpenCurrentFile(uzFile);
|
||||
|
||||
snprintf(writepath, sizeof(writepath), "%s/%s", dest, filename);
|
||||
|
||||
pointer = strrchr(writepath, '/');
|
||||
int position = pointer-writepath+2;
|
||||
|
||||
char temppath[strlen(writepath)];
|
||||
snprintf(temppath, position, "%s", writepath);
|
||||
|
||||
//CreateSubfolder(temppath);
|
||||
|
||||
if(ret == UNZ_OK)
|
||||
{
|
||||
FILE *pfile = fopen(writepath, "wb");
|
||||
if(!pfile)
|
||||
{
|
||||
free(buffer);
|
||||
fclose(pfile);
|
||||
unzCloseCurrentFile(uzFile);
|
||||
return -8;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if(uncompressed_size - done < blocksize)
|
||||
blocksize = uncompressed_size - done;
|
||||
|
||||
ret = unzReadCurrentFile(uzFile, buffer, blocksize);
|
||||
|
||||
if(ret == 0)
|
||||
break;
|
||||
|
||||
fwrite(buffer, 1, blocksize, pfile);
|
||||
|
||||
done += ret;
|
||||
|
||||
} while(done < uncompressed_size);
|
||||
|
||||
fclose(pfile);
|
||||
unzCloseCurrentFile(uzFile);
|
||||
}
|
||||
}
|
||||
if(unzGoToNextFile(uzFile) != UNZ_OK)
|
||||
{
|
||||
Stop = true;
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
64
source/ZipFile.h
Normal file
64
source/ZipFile.h
Normal file
@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2009-2011 Dimok
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _ZIPFILE_H_
|
||||
#define _ZIPFILE_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <zip/zip.h>
|
||||
#include <zip/unzip.h>
|
||||
|
||||
#include "ArchiveStruct.h"
|
||||
|
||||
class ZipFile
|
||||
{
|
||||
public:
|
||||
//!Constructor
|
||||
ZipFile(const char *filepath, short mode = ZipFile::OPEN);
|
||||
//!Destructor
|
||||
~ZipFile();
|
||||
//!Get the archive file structure
|
||||
ArchiveFileStruct * GetFileStruct(int fileIndx);
|
||||
//!Extract all files from a zip file to a directory
|
||||
int ExtractAll(const char *dest);
|
||||
//!Find a file inside the zip and return if it is existent or not
|
||||
bool FindFile(const char *filename);
|
||||
//!Load/Reload of the full item list in the zip
|
||||
bool LoadList();
|
||||
//!Enum for opening modes
|
||||
enum
|
||||
{
|
||||
CREATE = 0,
|
||||
OPEN,
|
||||
APPEND,
|
||||
};
|
||||
private:
|
||||
bool SeekFile(int ind);
|
||||
void PathControl();
|
||||
void CheckMissingPath(const char * path);
|
||||
void ClearList();
|
||||
bool SwitchMode(short mode);
|
||||
|
||||
zipFile zFile;
|
||||
unzFile uzFile;
|
||||
short OpenMode;
|
||||
int RealArchiveItemCount;
|
||||
std::string ZipFilePath;
|
||||
std::vector<ArchiveFileStruct *> ZipStructure;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user