]> git.ipfire.org Git - people/ms/libloc.git/blame - src/lua/database.c
lua: database: Implement fetching countries
[people/ms/libloc.git] / src / lua / database.c
CommitLineData
7eaabd10
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
17#include <errno.h>
18#include <string.h>
19
20#include <lua.h>
21#include <lauxlib.h>
22
23#include <libloc/database.h>
24
25#include "location.h"
77ee9330 26#include "as.h"
49463375 27#include "country.h"
7eaabd10 28#include "database.h"
9fac2ef2 29#include "network.h"
7eaabd10
MT
30
31typedef struct database {
32 struct loc_database* db;
33} Database;
34
35static Database* luaL_checkdatabase(lua_State* L, int i) {
36 void* userdata = luaL_checkudata(L, i, "location.Database");
37
38 // Throw an error if the argument doesn't match
39 luaL_argcheck(L, userdata, i, "Database expected");
40
41 return (Database*)userdata;
42}
43
44static int Database_open(lua_State* L) {
45 const char* path = NULL;
46 FILE* f = NULL;
47 int r;
48
49 // Fetch the path
50 path = luaL_checkstring(L, 1);
51
52 // Allocate a new object
53 Database* self = (Database*)lua_newuserdata(L, sizeof(*self));
54
55 // Set metatable
56 luaL_setmetatable(L, "location.Database");
57
58 // Open the database file
59 f = fopen(path, "r");
60 if (!f)
61 return luaL_error(L, "Could not open %s: %s\n", path, strerror(errno));
62
63 // Open the database
64 r = loc_database_new(ctx, &self->db, f);
65
66 // Close the file descriptor
67 fclose(f);
68
69 // Check for errors
70 if (r)
71 return luaL_error(L, "Could not open database %s: %s\n", path, strerror(errno));
72
73 return 1;
74}
75
75448a02 76static int Database_gc(lua_State* L) {
3b06229b 77 Database* self = luaL_checkdatabase(L, 1);
7eaabd10 78
3b06229b
MT
79 // Free database
80 if (self->db) {
7eaabd10 81 loc_database_unref(self->db);
3b06229b
MT
82 self->db = NULL;
83 }
84
85 return 0;
86}
87
77ee9330
MT
88static int Database_get_as(lua_State* L) {
89 struct loc_as* as = NULL;
90 int r;
91
92 Database* self = luaL_checkdatabase(L, 1);
93
94 // Fetch number
95 uint32_t asn = luaL_checknumber(L, 2);
96
97 // Fetch the AS
98 r = loc_database_get_as(self->db, &as, asn);
99 if (r) {
100 lua_pushnil(L);
101 return 1;
102 }
103
104 // Create a new AS object
105 r = create_as(L, as);
106 loc_as_unref(as);
107
108 return r;
109}
110
49463375
MT
111static int Database_get_country(lua_State* L) {
112 struct loc_country* country = NULL;
113 int r;
114
115 Database* self = luaL_checkdatabase(L, 1);
116
117 // Fetch code
118 const char* code = luaL_checkstring(L, 2);
119
120 // Fetch the country
121 r = loc_database_get_country(self->db, &country, code);
122 if (r) {
123 lua_pushnil(L);
124 return 1;
125 }
126
127 // Create a new country object
128 r = create_country(L, country);
129 loc_country_unref(country);
130
131 return r;
132}
133
7eaabd10
MT
134static int Database_lookup(lua_State* L) {
135 struct loc_network* network = NULL;
136 int r;
137
b49c59d2 138 Database* self = luaL_checkdatabase(L, 1);
7eaabd10
MT
139
140 // Require a string
b49c59d2 141 const char* address = luaL_checkstring(L, 2);
7eaabd10
MT
142
143 // Perform lookup
144 r = loc_database_lookup_from_string(self->db, address, &network);
145 if (r)
146 return luaL_error(L, "Could not lookup address %s: %s\n", address, strerror(errno));
147
9fac2ef2
MT
148 // Create a network object
149 r = create_network(L, network);
7eaabd10
MT
150 loc_network_unref(network);
151
9fac2ef2 152 return r;
7eaabd10
MT
153}
154
155static const struct luaL_Reg database_functions[] = {
77ee9330 156 { "get_as", Database_get_as },
49463375 157 { "get_country", Database_get_country },
7eaabd10
MT
158 { "open", Database_open },
159 { "lookup", Database_lookup },
e1c9275c 160 { "__gc", Database_gc },
7eaabd10
MT
161 { NULL, NULL },
162};
163
164int register_database(lua_State* L) {
e914e3ca 165 return register_class(L, "location.Database", database_functions);
7eaabd10 166}