From f113371523bc26e320e5ef8799e6ab123af9618e Mon Sep 17 00:00:00 2001 From: forever2k38 Date: Wed, 30 Sep 2026 22:01:45 +0200 Subject: initial install support, better readme, relicense, and more! --- src/pow_lua.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 5 deletions(-) (limited to 'src/pow_lua.c') diff --git a/src/pow_lua.c b/src/pow_lua.c index 7cf14b4..1d2f81a 100644 --- a/src/pow_lua.c +++ b/src/pow_lua.c @@ -1,10 +1,36 @@ +/* + + pow! - the pow!erful package manager + + Copyright (C) 2026 forever2k38 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + #include "pow_lua.h" +#include "config.h" +#include "log.h" #include "archive.h" +#include "stdio.h" #include "archive_entry.h" #include "lauxlib.h" #include "stdlib.h" +#include "unistd.h" #include "string.h" +#include "sys/sendfile.h" int pow_lua_extract(lua_State *L) { int r; @@ -45,9 +71,9 @@ int pow_lua_extract(lua_State *L) { if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) - printf("warn while unpacking: %s\n", archive_error_string(a)); + pow_log_info("warn while unpacking: %s", archive_error_string(a)); if (r < ARCHIVE_WARN) { - printf("error while unpacking: %s\n", archive_error_string(a)); + pow_log_error("error while unpacking: %s", archive_error_string(a)); lua_pop(L, 1); @@ -58,7 +84,7 @@ int pow_lua_extract(lua_State *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"); + pow_log_error("error while unpacking and failed to push real error message"); return 2; } @@ -119,11 +145,101 @@ int pow_lua_extract(lua_State *L) { return 1; } -luaL_Reg libpow[] = {{"extract", pow_lua_extract}, {NULL, NULL}}; -int pow_lua_load(lua_State *L) { +int pow_lua_install(lua_State *L) { + 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; + } + + char *src = strdup(lua_tostring(L, 1)); + + if (!src) { + pow_log_error("failed to strdup source string"); + + return 2; + } + + char *dest = strdup(lua_tostring(L, 2)); + + if (!dest) { + free(src); + + pow_log_error("failed to strdup dest string"); + + return 2; + } + + pow_log_info("installing: %s to %s", src, dest); + + FILE *src_stream = fopen(src, "r"); + + if (!src_stream) { + free(src); + free(dest); + + pow_log_error("failed to open source file %s while installing", src); + + return 2; + } + + FILE *dest_stream = fopen(dest, "w"); + + if (!dest_stream) { + free(src); + free(dest); + + fclose(src_stream); + + pow_log_error("failed to open destination file %s for writing while installing", dest); + + return 2; + } + + int src_fd = fileno(src_stream); + int dest_fd = fileno(dest_stream); + + struct stat src_stat = {0}; + int result = fstat(src_fd, &src_stat); + + off_t copied = 0; + while (result == 0 && copied < src_stat.st_size) { + ssize_t written = sendfile(dest_fd, src_fd, &copied, SIZE_MAX); + copied += written; + + if (written == -1) { + result = -1; + } + } + + if (fchmod(dest_fd, src_stat.st_mode) == -1) { + pow_log_error("failed to set permission bits, expect breakage!"); + } + + return 1; +} + +luaL_Reg libpow[] = {{"extract", pow_lua_extract}, {"install", pow_lua_install}, {NULL, NULL}}; + +int pow_lua_load(lua_State *L, pow_config *cfg) { luaL_newlib(L, libpow); + lua_createtable(L, 0, 1); + + lua_pushstring(L, cfg->makeopts); + lua_setfield(L, -2, "makeopts"); + + lua_setfield(L, -2, "config"); + lua_setglobal(L, "pow"); return 0; -- cgit v1.3