From: Michael Tremer Date: Thu, 22 Feb 2024 12:32:22 +0000 (+0000) Subject: lua: Add a Database object with a dummy lookup function X-Git-Tag: 0.9.18~165 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7eaabd1094cbb6383aea970e41017c09583cd5cf;p=location%2Flibloc.git lua: Add a Database object with a dummy lookup function Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 7c83d10..8b986a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -237,6 +237,8 @@ lua_LTLIBRARIES = \ luadir = $(LUA_INSTALL_CMOD) src_lua_location_la_SOURCES = \ + src/lua/database.c \ + src/lua/database.h \ src/lua/location.c \ src/lua/location.h @@ -257,6 +259,8 @@ src_lua_location_la_LIBADD = \ endif EXTRA_DIST += \ + src/lua/database.c \ + src/lua/database.h \ src/lua/location.c \ src/lua/location.h @@ -389,7 +393,8 @@ TESTS_LDADD = \ TESTS_ENVIRONMENT = \ LUA_CPATH="$(abs_builddir)/src/lua/.libs/?.so;;" \ PYTHONPATH=$(abs_srcdir)/src/python:$(abs_builddir)/src/python/.libs \ - TEST_DATA_DIR="$(abs_top_srcdir)/data" + TEST_DATA_DIR="$(abs_top_srcdir)/data" \ + TEST_DATABASE="$(abs_top_srcdir)/data/database.db" TESTS = \ $(check_PROGRAMS) \ diff --git a/src/lua/database.c b/src/lua/database.c new file mode 100644 index 0000000..13a81bd --- /dev/null +++ b/src/lua/database.c @@ -0,0 +1,123 @@ +/* + libloc - A library to determine the location of someone on the Internet + + Copyright (C) 2024 IPFire Development Team + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. +*/ + +#include +#include + +#include +#include + +#include + +#include "location.h" +#include "database.h" + +typedef struct database { + struct loc_database* db; +} Database; + +static Database* luaL_checkdatabase(lua_State* L, int i) { + void* userdata = luaL_checkudata(L, i, "location.Database"); + + // Throw an error if the argument doesn't match + luaL_argcheck(L, userdata, i, "Database expected"); + + return (Database*)userdata; +} + +static int Database_open(lua_State* L) { + const char* path = NULL; + FILE* f = NULL; + int r; + + // Fetch the path + path = luaL_checkstring(L, 1); + + // Allocate a new object + Database* self = (Database*)lua_newuserdata(L, sizeof(*self)); + + // Set metatable + luaL_setmetatable(L, "location.Database"); + + // Open the database file + f = fopen(path, "r"); + if (!f) + return luaL_error(L, "Could not open %s: %s\n", path, strerror(errno)); + + // Open the database + r = loc_database_new(ctx, &self->db, f); + + // Close the file descriptor + fclose(f); + + // Check for errors + if (r) + return luaL_error(L, "Could not open database %s: %s\n", path, strerror(errno)); + + return 1; +} + +static int Database_close(lua_State* L) { + Database* self = luaL_checkdatabase(L, 0); + + if (self->db) + loc_database_unref(self->db); + + free(self); + return 0; +} + +static int Database_lookup(lua_State* L) { + struct loc_network* network = NULL; + int r; + + Database* self = luaL_checkdatabase(L, 0); + + // Require a string + const char* address = luaL_checkstring(L, 1); + + // Perform lookup + r = loc_database_lookup_from_string(self->db, address, &network); + if (r) + return luaL_error(L, "Could not lookup address %s: %s\n", address, strerror(errno)); + + // XXX Return the network + + loc_network_unref(network); + + return 0; +} + +static const struct luaL_Reg database_functions[] = { + { "open", Database_open }, + { "lookup", Database_lookup }, + { "__gc", Database_close }, + { NULL, NULL }, +}; + +int register_database(lua_State* L) { + // Create a new metatable + luaL_newmetatable(L, "location.Database"); + + // Set functions + luaL_setfuncs(L, database_functions, 0); + + // Configure metatable + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + + return 1; +} diff --git a/src/lua/database.h b/src/lua/database.h new file mode 100644 index 0000000..0ac8544 --- /dev/null +++ b/src/lua/database.h @@ -0,0 +1,25 @@ +/* + libloc - A library to determine the location of someone on the Internet + + Copyright (C) 2024 IPFire Development Team + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. +*/ + +#ifndef LUA_LOCATION_DATABASE_H +#define LUA_LOCATION_DATABASE_H + +#include +#include + +int register_database(lua_State* L); + +#endif /* LUA_LOCATION_DATABASE_H */ diff --git a/src/lua/location.c b/src/lua/location.c index a61a9ae..ee9bce5 100644 --- a/src/lua/location.c +++ b/src/lua/location.c @@ -24,6 +24,7 @@ #include #include "location.h" +#include "database.h" struct loc_ctx* ctx = NULL; @@ -49,5 +50,10 @@ int luaopen_location(lua_State* L) { // Register functions luaL_newlib(L, location_functions); + // Register Database type + register_database(L); + + lua_setfield(L, -2, "Database"); + return 1; } diff --git a/src/lua/location.h b/src/lua/location.h index 1f64f5c..6eef1a6 100644 --- a/src/lua/location.h +++ b/src/lua/location.h @@ -14,6 +14,9 @@ Lesser General Public License for more details. */ +#ifndef LUA_LOCATION_LOCATION_H +#define LUA_LOCATION_LOCATION_H + #include #include @@ -21,3 +24,5 @@ extern struct loc_ctx* ctx; int luaopen_location(lua_State* L); + +#endif /* LUA_LOCATION_LOCATION_H */ diff --git a/tests/lua/main.lua b/tests/lua/main.lua index 901dd42..174bd3b 100755 --- a/tests/lua/main.lua +++ b/tests/lua/main.lua @@ -19,6 +19,8 @@ luaunit = require("luaunit") +ENV_TEST_DATABASE = os.getenv("TEST_DATABASE") + function test_load() -- Try loading the module location = require("location") @@ -27,4 +29,21 @@ function test_load() print(location.version()) end +function test_open_database() + location = require("location") + + -- Open the database + db = location.Database.open(ENV_TEST_DATABASE) +end + +function test_lookup() + location = require("location") + + -- Open the database + db = location.Database.open(ENV_TEST_DATABASE) + + -- Perform a lookup + db.lookup("81.3.27.32") +end + os.exit(luaunit.LuaUnit.run())