1 #define PERL_NO_GET_CONTEXT
9 #include <loc/libloc.h>
10 #include <loc/database.h>
11 #include <loc/network.h>
12 #include <loc/country.h>
14 MODULE = Location PACKAGE = Location
21 struct loc_ctx* ctx = NULL;
23 // Initialise location context
24 int err = loc_new(&ctx);
26 croak("Could not initialize libloc context: %d\n", err);
28 // Open the database file for reading
29 FILE* f = fopen(file, "r");
33 croak("Could not open file for reading: %s: %s\n",
34 file, strerror(errno));
38 struct loc_database* db = NULL;
39 err = loc_database_new(ctx, &db, f);
41 // We can close the database file straight away
42 // because loc_database_new creates a copy of the file descriptor
48 croak("Could not read database: %s\n", file);
63 struct loc_database* db;
67 // Try to open the keyfile
68 FILE* f = fopen(keyfile, "r");
70 croak("Could not open keyfile %s: %s\n",
71 keyfile, strerror(errno));
74 // Verify the database
75 int status = loc_database_verify(db, f);
80 croak("Could not verify the database signature\n");
83 // Database was validated successfully
93 struct loc_database* db;
97 RETVAL = loc_database_get_vendor(db);
103 struct loc_database* db;
106 // Get database description
107 RETVAL = loc_database_get_description(db);
113 struct loc_database* db;
116 // Get database license
117 RETVAL = loc_database_get_license(db);
122 database_countries(db)
123 struct loc_database* db;
126 // Create Database enumerator
127 struct loc_database_enumerator* enumerator;
128 int err = loc_database_enumerator_new(&enumerator, db, LOC_DB_ENUMERATE_COUNTRIES, 0);
131 croak("Could not create a database enumerator\n");
134 // Init and enumerate first country.
135 struct loc_country* country;
136 err = loc_database_enumerator_next_country(enumerator, &country);
138 croak("Could not enumerate next country\n");
142 // Extract the country code.
143 const char* ccode = loc_country_get_code(country);
145 // Push country code.
146 XPUSHs(sv_2mortal(newSVpv(ccode, 2)));
148 // Unref country pointer.
149 loc_country_unref(country);
151 // Enumerate next item.
152 err = loc_database_enumerator_next_country(enumerator, &country);
154 croak("Could not enumerate next country\n");
158 loc_database_enumerator_unref(enumerator);
164 lookup_country_code(db, address)
165 struct loc_database* db;
169 RETVAL = &PL_sv_undef;
172 struct loc_network *network;
173 int err = loc_database_lookup_from_string(db, address, &network);
175 // Extract the country code
176 const char* country_code = loc_network_get_country_code(network);
177 RETVAL = newSVpv(country_code, strlen(country_code));
179 loc_network_unref(network);
185 lookup_network_has_flag(db, address, flag)
186 struct loc_database* db;
193 enum loc_network_flags iv = 0;
195 if (strcmp("LOC_NETWORK_FLAG_ANONYMOUS_PROXY", flag) == 0)
196 iv |= LOC_NETWORK_FLAG_ANONYMOUS_PROXY;
197 else if (strcmp("LOC_NETWORK_FLAG_SATELLITE_PROVIDER", flag) == 0)
198 iv |= LOC_NETWORK_FLAG_SATELLITE_PROVIDER;
199 else if (strcmp("LOC_NETWORK_FLAG_ANYCAST", flag) == 0)
200 iv |= LOC_NETWORK_FLAG_ANYCAST;
201 else if (strcmp("LOC_NETWORK_FLAG_DROP", flag) == 0)
202 iv |= LOC_NETWORK_FLAG_DROP;
204 croak("Invalid flag");
207 struct loc_network *network;
208 int err = loc_database_lookup_from_string(db, address, &network);
211 // Check if the network has the given flag.
212 if (loc_network_has_flag(network, iv)) {
216 loc_network_unref(network);
223 lookup_asn(db, address)
224 struct loc_database* db;
228 RETVAL = &PL_sv_undef;
231 struct loc_network *network;
232 int err = loc_database_lookup_from_string(db, address, &network);
235 unsigned int as_number = loc_network_get_asn(network);
237 RETVAL = newSViv(as_number);
240 loc_network_unref(network);
249 get_country_name(db, ccode)
250 struct loc_database* db;
254 RETVAL = &PL_sv_undef;
256 // Lookup country code
257 struct loc_country *country;
258 int err = loc_database_get_country(db, &country, ccode);
260 // Extract the name for the given country code.
261 const char* country_name = loc_country_get_name(country);
262 RETVAL = newSVpv(country_name, strlen(country_name));
264 loc_country_unref(country);
271 get_continent_code(db, ccode)
272 struct loc_database* db;
276 RETVAL = &PL_sv_undef;
278 // Lookup country code
279 struct loc_country *country;
280 int err = loc_database_get_country(db, &country, ccode);
282 //Extract the continent code for the given country code.
283 const char* continent_code = loc_country_get_continent_code(country);
284 RETVAL = newSVpv(continent_code, strlen(continent_code));
286 loc_country_unref(country);
293 get_as_name(db, as_number)
294 struct loc_database* db;
295 unsigned int as_number;
298 RETVAL = &PL_sv_undef;
302 int err = loc_database_get_as(db, &as, as_number);
304 // Get the name of the given AS number.
305 const char* as_name = loc_as_get_name(as);
307 RETVAL = newSVpv(as_name, strlen(as_name));
317 struct loc_database* db;
321 loc_database_unref(db);