#include "pow_lua.h" #include "archive.h" #include "archive_entry.h" #include "lauxlib.h" #include "stdlib.h" #include "string.h" int pow_lua_extract(lua_State *L) { int r; ssize_t size; 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); lua_setglobal(L, "pow"); return 0; }