diff options
Diffstat (limited to 'src/pow_lua.c')
| -rw-r--r-- | src/pow_lua.c | 117 |
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); |
