aboutsummaryrefslogtreecommitdiff
path: root/mods.cc
diff options
context:
space:
mode:
authorYour Name <you@example.com>2020-11-24 16:49:29 -0500
committerYour Name <you@example.com>2020-11-24 16:49:29 -0500
commitde89946f5fe78323f113c6216c8b994a1eba49fe (patch)
treead2c59484b5a4d6588e5efc0cc304172245aeeb4 /mods.cc
parent51734065a38cf6db48fe9fb4b16461ce424cad90 (diff)
downloadlibbible-de89946f5fe78323f113c6216c8b994a1eba49fe.tar.gz
libbible-de89946f5fe78323f113c6216c8b994a1eba49fe.tar.bz2
libbible-de89946f5fe78323f113c6216c8b994a1eba49fe.zip
Removed dependency on unzip
Diffstat (limited to 'mods.cc')
-rw-r--r--mods.cc69
1 files changed, 63 insertions, 6 deletions
diff --git a/mods.cc b/mods.cc
index 9c9483e..2c9cf22 100644
--- a/mods.cc
+++ b/mods.cc
@@ -4,6 +4,8 @@
#include <sword/installmgr.h>
#include <sword/filemgr.h>
#include <sword/remotetrans.h>
+#include <unzip.h>
+#include <filesystem>
using namespace std;
@@ -116,16 +118,71 @@ bool libbible::installModFromInternet(string language, string name) {
return false;
}
-void libbible::installModFromZip(string filename) {
+#define READ_SIZE 8192
+#define delim '/'
+
+bool libbible::installModFromZip(string filename) {
// So... turns out it's a mite unsupported to install from a .zip
// Here's the deal. We do a syscall to unzip. We fancy like that.
// TODO: Use the ZipCompress module from SWORD instead.
- string command = "unzip -o " + filename + " -d " + basedir + "&> /dev/null";
- if(system(command.c_str())) {
- //Uh oh...
- printf("Something bad happened when unpacking %s\n. Is unzip installed?", filename.c_str());
+ /*string command = "unzip -o " + filename + " -d " + basedir + "&> /dev/null";
+ if(system(command.c_str())) {
+ //Uh oh...
+ printf("Something bad happened when unpacking %s\n. Is unzip installed?", filename.c_str());
+ }*/
+ unzFile zipfile = unzOpen(filename.c_str());
+ if(zipfile == NULL) {
+ return false;
}
-
+ unz_global_info global_info;
+ if(unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK) {
+ unzClose(zipfile);
+ return false;
+ }
+ char read_buffer[READ_SIZE];
+ ulong i;
+ for(i = 0; i < global_info.number_entry; i++) {
+ unz_file_info file_info;
+ if(unzGetCurrentFileInfo(zipfile, &file_info, read_buffer, READ_SIZE, NULL, 0, NULL, 0) != UNZ_OK) {
+ unzClose(zipfile);
+ return false;
+ }
+ string fname = basedir + string(read_buffer);
+ size_t pos = fname.find_last_of(delim);
+ if(pos != string::npos) {
+ string path = fname.substr(0, pos);
+ filesystem::create_directories(path);
+ }
+ if(unzOpenCurrentFile(zipfile) != UNZ_OK) {
+ unzCloseCurrentFile(zipfile);
+ unzClose(zipfile);
+ return false;
+ }
+ FILE *out = fopen(fname.c_str(), "wb");
+ if(out == NULL) {
+ unzCloseCurrentFile(zipfile);
+ unzClose(zipfile);
+ return false;
+ }
+ int bytesRead;
+ do {
+ bytesRead = unzReadCurrentFile(zipfile, read_buffer, READ_SIZE);
+ if(bytesRead < 0) {
+ printf("error %d\n", bytesRead);
+ unzCloseCurrentFile(zipfile);
+ unzClose(zipfile);
+ return false;
+ }
+ if(bytesRead > 0) {
+ fwrite(read_buffer, bytesRead, 1, out);
+ }
+ } while(bytesRead > 0);
+ fclose(out);
+ unzCloseCurrentFile(zipfile);
+ unzGoToNextFile(zipfile);
+ }
+ unzClose(zipfile);
+ return true;
}
void libbible::uninstallMod(string modname) {