Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedded lua scripts into FTL #1492

Merged
merged 6 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ tools/macvendor.db
# Test Leftovers
dig.log
ptr.log

# Compiled LUA scripts
/src/lua/scripts/*.hex
8 changes: 8 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ if [[ -n "${clean}" ]]; then
fi
fi

# Remove compiled LUA scripts if older than the plain ones
for scriptname in src/lua/scripts/*.lua; do
if [ -f "${scriptname}.hex" ] && [ "${scriptname}.hex" -ot "${scriptname}" ]; then
echo "INFO: ${scriptname} is outdated and will be recompiled"
rm "${scriptname}.hex"
fi
done

# Configure build, pass CMake CACHE entries if present
# Wrap multiple options in "" as first argument to ./build.sh:
# ./build.sh "-DA=1 -DB=2" install
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -250,5 +250,6 @@ add_subdirectory(api)
add_subdirectory(database)
add_subdirectory(dnsmasq)
add_subdirectory(lua)
add_subdirectory(lua/scripts)
add_subdirectory(tre-regex)
add_subdirectory(syscalls)
4 changes: 3 additions & 1 deletion src/args.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ void parse_args(int argc, char* argv[])
printf("\n");
printf("******************************** LUA ********************************\n");
printf(LUA_COPYRIGHT"\n");
printf("\n");
printf("Embedded libraries: ");
print_embedded_scripts();
printf("\n\n");
printf("***************************** LIBNETTLE *****************************\n");
printf("Version: %d.%d\n", NETTLE_VERSION_MAJOR, NETTLE_VERSION_MINOR);
printf("GMP: %s\n", NETTLE_USE_MINI_GMP ? "Mini" : "Full");
Expand Down
51 changes: 48 additions & 3 deletions src/lua/ftl_lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "../log.h"
#include <readline/history.h>
#include <wordexp.h>
#include "scripts/scripts.h"

int run_lua_interpreter(const int argc, char **argv, bool dnsmasq_debug)
{
Expand Down Expand Up @@ -98,9 +99,53 @@ LUAMOD_API int luaopen_pihole(lua_State *L) {
return LUA_YIELD;
}

// Load bundled libraries and make the available globally
static bool ftl_lua_load_embedded_script(lua_State *L, const char *name, const char *script, const size_t script_len, const bool make_global)
{
// Explanation:
// luaL_dostring(L, script) expands to (luaL_loadstring(L, script) || lua_pcall(L, 0, LUA_MULTRET, 0))
// luaL_loadstring(L, script) calls luaL_loadbuffer(L, s, strlen(s), s)
if (luaL_loadbufferx(L, script, script_len, name, NULL) || lua_pcall(L, 0, LUA_MULTRET, 0) != 0)
{
const char *lua_err = lua_tostring(L, -1);
printf("LUA error while trying to import %s.lua: %s\n", name, lua_err);
return false;
}

if(make_global)
{
/* Set global[name] = luaL_dostring return */
lua_setglobal(L, name);
}

return true;
}

struct {
const char *name;
const char *content;
const size_t contentlen;
const bool global;
} scripts[] =
{
{"inspect", inspect_lua, sizeof(inspect_lua), true},
};

// Loop over bundled LUA libraries and print their names on the console
void print_embedded_scripts(void)
{
for(unsigned int i = 0; i < sizeof(scripts)/sizeof(scripts[0]); i++)
{
char prefix[2] = { 0 };
double formatted = 0.0;
format_memory_size(prefix, scripts[i].contentlen, &formatted);

printf("%s.lua (%.2f %sB) ", scripts[i].name, formatted, prefix);
}
}

// Loop over bundled LUA libraries and load them
void ftl_lua_init(lua_State *L)
{
if(dolibrary(L, "inspect") != LUA_OK)
printf("Failed to load library inspect.lua\n");
for(unsigned int i = 0; i < sizeof(scripts)/sizeof(scripts[0]); i++)
ftl_lua_load_embedded_script(L, scripts[i].name, scripts[i].content, scripts[i].contentlen, scripts[i].global);
}
3 changes: 1 addition & 2 deletions src/lua/ftl_lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ int run_luac(const int argc, char **argv);
int lua_main (int argc, char **argv);
int luac_main (int argc, char **argv);

extern int dolibrary (lua_State *L, const char *name);

void print_embedded_scripts(void);
void ftl_lua_init(lua_State *L);

#endif //FTL_LUA_H
4 changes: 1 addition & 3 deletions src/lua/lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,7 @@ static int dostring (lua_State *L, const char *s, const char *name) {
** Calls 'require(name)' and stores the result in a global variable
** with the given name.
*/
/************** Pi-hole modification ***************/
int dolibrary (lua_State *L, const char *name) {
/***************************************************/
static int dolibrary (lua_State *L, const char *name) {
int status;
lua_getglobal(L, "require");
lua_pushstring(L, name);
Expand Down
35 changes: 35 additions & 0 deletions src/lua/scripts/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Pi-hole: A black hole for Internet advertisements
# (c) 2022 Pi-hole, LLC (https://pi-hole.net)
# Network-wide ad blocking via your own hardware.
#
# FTL Engine
# /src/lua/scripts/CMakeList.txt
#
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.

set(sources
inspect.lua.hex
scripts.h
)

# Compile files from raw/ into hex/
find_program(RESOURCE_COMPILER xxd)
file(GLOB_RECURSE COMPILED_RESOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/" "./*.lua")
foreach(INPUT_FILE ${COMPILED_RESOURCES})
set(IN ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE})
set(OUTPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE}.hex)
add_custom_command(
OUTPUT ${INPUT_FILE}.hex
COMMAND ${RESOURCE_COMPILER} -i < ${IN} > ${OUTPUT_FILE}
COMMENT "Compiling ${INPUT_FILE} to binary"
VERBATIM)
list(APPEND COMPILED_RESOURCES ${OUTPUT_FILE})
endforeach()

# Ensure target lua_scripts is build before target lua
add_dependencies(lua lua_scripts)

add_library(lua_scripts OBJECT ${sources})
target_compile_options(lua_scripts PRIVATE ${EXTRAWARN})
target_include_directories(lua_scripts PRIVATE ${PROJECT_SOURCE_DIR}/src)
Loading