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