aboutsummaryrefslogtreecommitdiff
path: root/src/pow_lua.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pow_lua.c')
-rw-r--r--src/pow_lua.c117
1 files changed, 114 insertions, 3 deletions
diff --git a/src/pow_lua.c b/src/pow_lua.c
index 0d0214d..70b32ad 100644
--- a/src/pow_lua.c
+++ b/src/pow_lua.c
@@ -1,11 +1,122 @@
#include "pow_lua.h"
+#include "archive.h"
+#include "archive_entry.h"
#include "lauxlib.h"
-#include "lualib.h"
+#include "stdlib.h"
+#include "string.h"
-int pow_lua_hello(lua_State *L) { printf("hi\n"); }
+int pow_lua_extract(lua_State *L) {
+ int r;
+ ssize_t size;
-luaL_Reg libpow[] = {{"hello", pow_lua_hello}};
+ struct archive *a;
+ struct archive_entry *entry;
+
+ if (!lua_isstring(L, 1)) {
+ lua_pushnil(L);
+ lua_pushstring(L, "arg 1 must be string (src)");
+
+ return 2;
+ }
+
+ if (!lua_isstring(L, 2)) {
+ lua_pushnil(L);
+ lua_pushstring(L, "arg 2 must be string (dest)");
+
+ return 2;
+ }
+
+ const char *filename = lua_tostring(L, 1);
+ const char *dest = lua_tostring(L, 2);
+
+ a = archive_read_new();
+
+ archive_read_support_filter_all(a);
+ archive_read_support_format_all(a);
+
+ if ((r = archive_read_open_filename(a, filename, 10240))) {
+ return 0;
+ }
+
+ for (;;) {
+ r = archive_read_next_header(a, &entry);
+
+ if (r == ARCHIVE_EOF)
+ break;
+ if (r < ARCHIVE_OK)
+ printf("warn while unpacking: %s\n", archive_error_string(a));
+ if (r < ARCHIVE_WARN) {
+ printf("error while unpacking: %s\n", archive_error_string(a));
+
+ lua_pop(L, 1);
+
+ char *error_msg = malloc(256);
+
+ lua_pushnil(L);
+
+ if (!error_msg) {
+ lua_pushstring(L, "error while unpacking and failed to malloc to push "
+ "real error message");
+ printf("error while unpacking and failed to push real error message\n");
+
+ return 2;
+ }
+
+ snprintf(error_msg, 256, "error while unpacking: %s",
+ archive_error_string(a));
+
+ lua_pushstring(L, error_msg);
+
+ free(error_msg);
+
+ return 2;
+ }
+
+ const char *cur = archive_entry_pathname(entry);
+
+ if (cur) {
+ size_t need = strlen(dest) + strlen(cur) + 2;
+
+ char *full = malloc(need);
+
+ if (!full) {
+ lua_pushnil(L);
+ lua_pushstring(L, "failed to malloc entry path\n");
+
+ archive_read_close(a);
+ archive_read_free(a);
+
+ return 2;
+ }
+
+ snprintf(full, need, "%s/%s", dest, cur);
+ archive_entry_set_pathname(entry, full);
+ }
+
+ r = archive_read_extract(a, entry, 0);
+
+ if (r < ARCHIVE_WARN) {
+ lua_pushnil(L);
+ lua_pushfstring(
+ L, "failed to extract '%s': %s", archive_entry_pathname(entry),
+ archive_error_string(a) ? archive_error_string(a) : "unknown");
+ archive_read_close(a);
+ archive_read_free(a);
+
+ return 2;
+ }
+ }
+
+ archive_read_close(a);
+ archive_read_free(a);
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+}
+
+luaL_Reg libpow[] = {{"extract", pow_lua_extract}, {NULL, NULL}};
int pow_lua_load(lua_State *L) {
luaL_newlib(L, libpow);