]> git.ipfire.org Git - people/ms/libloc.git/blame - src/lua/location.c
lua: Implement setting a log callback function
[people/ms/libloc.git] / src / lua / location.c
CommitLineData
6ae775f9
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2024 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15*/
16
f51350bb 17#include <errno.h>
63762921 18#include <stdlib.h>
f51350bb
MT
19#include <string.h>
20
6ae775f9 21#include <lua.h>
03b9c3a4
MT
22#include <lauxlib.h>
23#include <lualib.h>
6ae775f9 24
f51350bb 25#include <libloc/libloc.h>
db80a494 26#include <libloc/network.h>
f51350bb 27
6ae775f9 28#include "location.h"
67675dc3 29#include "as.h"
031bae06 30#include "compat.h"
0ddfebb3 31#include "country.h"
7eaabd10 32#include "database.h"
e914e3ca 33#include "network.h"
6ae775f9 34
f51350bb
MT
35struct loc_ctx* ctx = NULL;
36
63762921
MT
37static int log_callback_ref = 0;
38
39static void log_callback(struct loc_ctx* _ctx, void* data, int priority, const char* file,
40 int line, const char* fn, const char* format, va_list args) {
41 char* message = NULL;
42 int r;
43
44 lua_State* L = data;
45
46 // Format the log message
47 r = vasprintf(&message, format, args);
48 if (r < 0)
49 return;
50
51 // Fetch the Lua callback function
52 lua_rawgeti(L, LUA_REGISTRYINDEX, log_callback_ref);
53
54 // Pass the priority as first argument
55 lua_pushnumber(L, priority);
56
57 // Pass the message as second argument
58 lua_pushstring(L, message);
59
60 // Call the function
61 lua_call(L, 2, 0);
62
63 free(message);
64}
65
66static int set_log_callback(lua_State* L) {
67 // Check if we have received a function
68 luaL_checktype(L, 1, LUA_TFUNCTION);
69
70 // Store a reference to the callback function
71 log_callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);
72
73 // Register our callback helper
74 if (ctx)
75 loc_set_log_callback(ctx, log_callback, L);
76
77 return 0;
78}
79
80static int set_log_level(lua_State* L) {
81 const int level = luaL_checknumber(L, 1);
82
83 // Store the new log level
84 if (ctx)
85 loc_set_log_priority(ctx, level);
86
87 return 0;
88}
89
03b9c3a4
MT
90static int version(lua_State* L) {
91 lua_pushstring(L, PACKAGE_VERSION);
92 return 1;
93}
94
95static const struct luaL_Reg location_functions[] = {
63762921
MT
96 { "set_log_callback", set_log_callback },
97 { "set_log_level", set_log_level },
03b9c3a4
MT
98 { "version", version },
99 { NULL, NULL },
100};
101
6ae775f9 102int luaopen_location(lua_State* L) {
f51350bb
MT
103 int r;
104
105 // Initialize the context
106 r = loc_new(&ctx);
107 if (r)
108 return luaL_error(L,
109 "Could not initialize location context: %s\n", strerror(errno));
110
111 // Register functions
03b9c3a4
MT
112 luaL_newlib(L, location_functions);
113
67675dc3
MT
114 // Register AS type
115 register_as(L);
116
117 lua_setfield(L, -2, "AS");
118
0ddfebb3
MT
119 // Register Country type
120 register_country(L);
121
122 lua_setfield(L, -2, "Country");
123
7eaabd10
MT
124 // Register Database type
125 register_database(L);
126
127 lua_setfield(L, -2, "Database");
128
42173573
MT
129 // Register DatabaseEnumerator type
130 register_database_enumerator(L);
131
132 lua_setfield(L, -2, "DatabaseEnumerator");
133
e914e3ca
MT
134 // Register Network type
135 register_network(L);
136
137 lua_setfield(L, -2, "Network");
138
726553e6
MT
139 // Set DATABASE_PATH
140 lua_pushstring(L, LIBLOC_DEFAULT_DATABASE_PATH);
141 lua_setfield(L, -2, "DATABASE_PATH");
142
db80a494
MT
143 // Add flags
144 lua_pushnumber(L, LOC_NETWORK_FLAG_ANONYMOUS_PROXY);
145 lua_setfield(L, -2, "NETWORK_FLAG_ANONYMOUS_PROXY");
146
147 lua_pushnumber(L, LOC_NETWORK_FLAG_SATELLITE_PROVIDER);
148 lua_setfield(L, -2, "NETWORK_FLAG_SATELLITE_PROVIDER");
149
150 lua_pushnumber(L, LOC_NETWORK_FLAG_ANYCAST);
151 lua_setfield(L, -2, "NETWORK_FLAG_ANYCAST");
152
153 lua_pushnumber(L, LOC_NETWORK_FLAG_DROP);
154 lua_setfield(L, -2, "NETWORK_FLAG_DROP");
155
03b9c3a4 156 return 1;
6ae775f9 157}