]> git.ipfire.org Git - people/ms/libloc.git/blame - src/lua/network.c
lua: network: Add a __close method
[people/ms/libloc.git] / src / lua / network.c
CommitLineData
e914e3ca
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 <stdlib.h>
19#include <string.h>
20
21#include <lua.h>
22#include <lauxlib.h>
23
24#include <libloc/network.h>
25
26#include "location.h"
27#include "network.h"
28
29typedef struct network {
30 struct loc_network* network;
31} Network;
32
33static Network* luaL_checknetwork(lua_State* L, int i) {
34 void* userdata = luaL_checkudata(L, i, "location.Network");
35
36 // Throw an error if the argument doesn't match
37 luaL_argcheck(L, userdata, i, "Network expected");
38
39 return (Network*)userdata;
40}
41
9fac2ef2 42int create_network(lua_State* L, struct loc_network* network) {
e914e3ca
MT
43 // Allocate a new object
44 Network* self = (Network*)lua_newuserdata(L, sizeof(*self));
45
46 // Set metatable
47 luaL_setmetatable(L, "location.Network");
48
49 // Store network
50 self->network = loc_network_ref(network);
51
52 return 1;
53}
54
55static int Network_new(lua_State* L) {
56 struct loc_network* network = NULL;
57 const char* n = NULL;
58 int r;
59
60 // Fetch the network
61 n = luaL_checkstring(L, 1);
62
63 // Parse the string
64 r = loc_network_new_from_string(ctx, &network, n);
65 if (r)
66 return luaL_error(L, "Could not create network %s: %s\n", n, strerror(errno));
67
68 // Return the network
69 r = create_network(L, network);
70 loc_network_unref(network);
71
72 return r;
73}
74
6b296c60
MT
75static int Network_close(lua_State* L) {
76 Network* self = luaL_checknetwork(L, 1);
e914e3ca 77
6b296c60
MT
78 // Free the network
79 if (self->network) {
e914e3ca 80 loc_network_unref(self->network);
6b296c60
MT
81 self->network = NULL;
82 }
83
84 return 0;
85}
e914e3ca 86
6b296c60
MT
87static int Network_gc(lua_State* L) {
88 Network* self = luaL_checknetwork(L, 1);
89
90 // Free the object
e914e3ca 91 free(self);
6b296c60 92
e914e3ca
MT
93 return 0;
94}
95
96static int Network_tostring(lua_State* L) {
97 Network* self = luaL_checknetwork(L, 1);
98
99 // Push string representation of the network
100 lua_pushstring(L, loc_network_str(self->network));
101
102 return 1;
103}
104
105// ASN
106
107static int Network_get_asn(lua_State* L) {
108 Network* self = luaL_checknetwork(L, 0);
109
110 uint32_t asn = loc_network_get_asn(self->network);
111
112 // Push ASN
113 if (asn)
114 lua_pushnumber(L, asn);
115 else
116 lua_pushnil(L);
117
118 return 1;
119}
120
121// Family
122
123static int Network_get_family(lua_State* L) {
124 Network* self = luaL_checknetwork(L, 0);
125
126 // Push family
127 lua_pushnumber(L, loc_network_address_family(self->network));
128
129 return 1;
130}
131
132// Country Code
133
134static int Network_get_country_code(lua_State* L) {
135 Network* self = luaL_checknetwork(L, 0);
136
137 const char* country_code = loc_network_get_country_code(self->network);
138
139 // Push country code
140 if (country_code && *country_code)
141 lua_pushstring(L, country_code);
142 else
143 lua_pushnil(L);
144
145 return 1;
146}
147
148static const struct luaL_Reg Network_functions[] = {
149 { "new", Network_new },
150 { "get_asn", Network_get_asn },
151 { "get_family", Network_get_family },
152 { "get_country_code", Network_get_country_code },
6b296c60 153 { "__close", Network_close },
e914e3ca
MT
154 { "__gc", Network_gc },
155 { "__tostring", Network_tostring },
156 { NULL, NULL },
157};
158
159int register_network(lua_State* L) {
160 return register_class(L, "location.Network", Network_functions);
161}