]> git.ipfire.org Git - location/libloc.git/blob - src/lua/network.c
lua: Don't try to free memory that was allocated by Lua
[location/libloc.git] / src / lua / network.c
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
29 typedef struct network {
30 struct loc_network* network;
31 } Network;
32
33 static 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
42 int create_network(lua_State* L, struct loc_network* network) {
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
55 static 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
75 static int Network_gc(lua_State* L) {
76 Network* self = luaL_checknetwork(L, 1);
77
78 // Free the network
79 if (self->network) {
80 loc_network_unref(self->network);
81 self->network = NULL;
82 }
83
84 return 0;
85 }
86
87 static int Network_tostring(lua_State* L) {
88 Network* self = luaL_checknetwork(L, 1);
89
90 // Push string representation of the network
91 lua_pushstring(L, loc_network_str(self->network));
92
93 return 1;
94 }
95
96 // ASN
97
98 static int Network_get_asn(lua_State* L) {
99 Network* self = luaL_checknetwork(L, 1);
100
101 uint32_t asn = loc_network_get_asn(self->network);
102
103 // Push ASN
104 if (asn)
105 lua_pushnumber(L, asn);
106 else
107 lua_pushnil(L);
108
109 return 1;
110 }
111
112 // Family
113
114 static int Network_get_family(lua_State* L) {
115 Network* self = luaL_checknetwork(L, 1);
116
117 // Push family
118 lua_pushnumber(L, loc_network_address_family(self->network));
119
120 return 1;
121 }
122
123 // Country Code
124
125 static int Network_get_country_code(lua_State* L) {
126 Network* self = luaL_checknetwork(L, 1);
127
128 const char* country_code = loc_network_get_country_code(self->network);
129
130 // Push country code
131 if (country_code && *country_code)
132 lua_pushstring(L, country_code);
133 else
134 lua_pushnil(L);
135
136 return 1;
137 }
138
139 static const struct luaL_Reg Network_functions[] = {
140 { "new", Network_new },
141 { "get_asn", Network_get_asn },
142 { "get_family", Network_get_family },
143 { "get_country_code", Network_get_country_code },
144 { "__gc", Network_gc },
145 { "__tostring", Network_tostring },
146 { NULL, NULL },
147 };
148
149 int register_network(lua_State* L) {
150 return register_class(L, "location.Network", Network_functions);
151 }