aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--libbible.h3
-rw-r--r--mods.cc69
-rw-r--r--testLibbible.cc4
4 files changed, 69 insertions, 11 deletions
diff --git a/Makefile b/Makefile
index c7437b2..032e165 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC=g++
-LIBS=sword
-CFLAGS=-c -Wall -fPIC
+LIBS=sword minizip
+CFLAGS=-c -Wall -fPIC -std=c++17
LDFLAGS=
SOURCES=libbible.cc mods.cc settings.cc
OBJECTS=$(SOURCES:.cc=.o)
diff --git a/libbible.h b/libbible.h
index c1058e7..82a15ab 100644
--- a/libbible.h
+++ b/libbible.h
@@ -79,8 +79,9 @@ namespace libbible {
/**
* @param filename Path to the .zip compressed module to be installed
+ * @return true on success, false otherwise
*/
- void installModFromZip(std::string filename);
+ bool installModFromZip(std::string filename);
/**
* @param modname The name of the module to be removed
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) {
diff --git a/testLibbible.cc b/testLibbible.cc
index b8f93b3..20ff7d9 100644
--- a/testLibbible.cc
+++ b/testLibbible.cc
@@ -78,8 +78,8 @@ void TestLibbible::testGetModules(void) {
libbible::uninstallMod(pair.first);
}
CPPUNIT_ASSERT(libbible::getModules().empty());
- libbible::installModFromZip("modules/KJV.zip");
- libbible::installModFromZip("modules/JPS.zip");
+ CPPUNIT_ASSERT(libbible::installModFromZip("modules/KJV.zip"));
+ CPPUNIT_ASSERT(libbible::installModFromZip("modules/JPS.zip"));
mods = libbible::getModules();
CPPUNIT_ASSERT(mods.find("KJV") != mods.end());
CPPUNIT_ASSERT(mods["KJV"].size() == 66);