]>
Commit | Line | Data |
---|---|---|
1ea740e9 SS |
1 | #define PERL_NO_GET_CONTEXT |
2 | #include "EXTERN.h" | |
3 | #include "perl.h" | |
4 | #include "XSUB.h" | |
5 | ||
6 | #include <stdio.h> | |
7 | #include <string.h> | |
8 | ||
1ea740e9 SS |
9 | #include <loc/libloc.h> |
10 | #include <loc/database.h> | |
11 | #include <loc/network.h> | |
c1590ddd | 12 | #include <loc/country.h> |
1ea740e9 SS |
13 | |
14 | MODULE = Location PACKAGE = Location | |
15 | ||
16 | struct loc_database * | |
3bbf013a | 17 | init(file) |
e5a1a0bd | 18 | char* file; |
1ea740e9 SS |
19 | |
20 | CODE: | |
da1039da | 21 | struct loc_ctx* ctx = NULL; |
1ea740e9 | 22 | |
74ad091d | 23 | // Initialise location context |
da1039da | 24 | int err = loc_new(&ctx); |
1ea740e9 | 25 | if (err < 0) |
5242283a | 26 | croak("Could not initialize libloc context: %d\n", err); |
1ea740e9 | 27 | |
74ad091d | 28 | // Open the database file for reading |
1ea740e9 SS |
29 | FILE* f = fopen(file, "r"); |
30 | if (!f) { | |
c820094d MT |
31 | loc_unref(ctx); |
32 | ||
5242283a MT |
33 | croak("Could not open file for reading: %s: %s\n", |
34 | file, strerror(errno)); | |
1ea740e9 SS |
35 | } |
36 | ||
74ad091d | 37 | // Parse the database |
c820094d | 38 | struct loc_database* db = NULL; |
1ea740e9 | 39 | err = loc_database_new(ctx, &db, f); |
46d6c767 MT |
40 | |
41 | // We can close the database file straight away | |
42 | // because loc_database_new creates a copy of the file descriptor | |
43 | fclose(f); | |
44 | ||
1ea740e9 | 45 | if (err) { |
c820094d MT |
46 | loc_unref(ctx); |
47 | ||
5242283a | 48 | croak("Could not read database: %s\n", file); |
1ea740e9 SS |
49 | } |
50 | ||
3bbf013a MT |
51 | // Cleanup |
52 | loc_unref(ctx); | |
53 | ||
54 | RETVAL = db; | |
55 | OUTPUT: | |
56 | RETVAL | |
57 | ||
58 | # | |
59 | # Database functions | |
60 | # | |
61 | bool | |
62 | verify(db, keyfile) | |
63 | struct loc_database* db; | |
64 | char* keyfile; | |
65 | ||
66 | CODE: | |
2061ff77 | 67 | // Try to open the keyfile |
3bbf013a | 68 | FILE* f = fopen(keyfile, "r"); |
2061ff77 | 69 | if (!f) { |
2061ff77 SS |
70 | croak("Could not open keyfile %s: %s\n", |
71 | keyfile, strerror(errno)); | |
72 | } | |
73 | ||
74 | // Verify the database | |
75 | int status = loc_database_verify(db, f); | |
76 | if (status) { | |
3bbf013a | 77 | RETVAL = false; |
2061ff77 SS |
78 | fclose(f); |
79 | ||
80 | croak("Could not verify the database signature\n"); | |
81 | } | |
82 | ||
3bbf013a MT |
83 | // Database was validated successfully |
84 | RETVAL = true; | |
85 | ||
2061ff77 SS |
86 | // Close the keyfile |
87 | fclose(f); | |
1ea740e9 SS |
88 | OUTPUT: |
89 | RETVAL | |
90 | ||
777959b2 MT |
91 | const char* |
92 | get_vendor(db) | |
93 | struct loc_database* db; | |
94 | ||
95 | CODE: | |
96 | // Get vendor | |
97 | RETVAL = loc_database_get_vendor(db); | |
98 | OUTPUT: | |
99 | RETVAL | |
100 | ||
973c5f03 SS |
101 | const char* |
102 | get_description(db) | |
103 | struct loc_database* db; | |
104 | ||
105 | CODE: | |
106 | // Get database description | |
107 | RETVAL = loc_database_get_description(db); | |
108 | OUTPUT: | |
109 | RETVAL | |
110 | ||
733bd087 SS |
111 | const char* |
112 | get_license(db) | |
113 | struct loc_database* db; | |
114 | ||
115 | CODE: | |
116 | // Get database license | |
117 | RETVAL = loc_database_get_license(db); | |
118 | OUTPUT: | |
119 | RETVAL | |
120 | ||
c1590ddd SS |
121 | void |
122 | database_countries(db) | |
123 | struct loc_database* db; | |
124 | ||
125 | PPCODE: | |
126 | // Create Database enumerator | |
127 | struct loc_database_enumerator* enumerator; | |
128 | int err = loc_database_enumerator_new(&enumerator, db, LOC_DB_ENUMERATE_COUNTRIES); | |
129 | ||
130 | if (err) { | |
131 | croak("Could not create a database enumerator\n"); | |
132 | } | |
133 | ||
134 | // Init and enumerate first country. | |
135 | struct loc_country* country; | |
136 | err = loc_database_enumerator_next_country(enumerator, &country); | |
137 | if (err) { | |
138 | croak("Could not enumerate next country\n"); | |
139 | } | |
140 | ||
141 | while (country) { | |
142 | // Extract the country code. | |
143 | const char* ccode = loc_country_get_code(country); | |
144 | ||
145 | // Push country code. | |
146 | XPUSHs(sv_2mortal(newSVpv(ccode, 2))); | |
147 | ||
148 | // Unref country pointer. | |
149 | loc_country_unref(country); | |
150 | ||
151 | // Enumerate next item. | |
152 | err = loc_database_enumerator_next_country(enumerator, &country); | |
153 | if (err) { | |
154 | croak("Could not enumerate next country\n"); | |
155 | } | |
156 | } | |
157 | ||
158 | loc_database_enumerator_unref(enumerator); | |
159 | ||
46fbc975 SS |
160 | # |
161 | # Lookup functions | |
162 | # | |
6aa97cac | 163 | SV* |
70f45781 | 164 | lookup_country_code(db, address) |
e5a1a0bd MT |
165 | struct loc_database* db; |
166 | char* address; | |
1ea740e9 SS |
167 | |
168 | CODE: | |
6aa97cac SS |
169 | RETVAL = &PL_sv_undef; |
170 | ||
74ad091d | 171 | // Lookup network |
1ea740e9 | 172 | struct loc_network *network; |
d3daf87c | 173 | int err = loc_database_lookup_from_string(db, address, &network); |
6aa97cac SS |
174 | if (!err) { |
175 | // Extract the country code | |
176 | const char* country_code = loc_network_get_country_code(network); | |
177 | RETVAL = newSVpv(country_code, strlen(country_code)); | |
1ea740e9 | 178 | |
6aa97cac | 179 | loc_network_unref(network); |
1ea740e9 | 180 | } |
1ea740e9 SS |
181 | OUTPUT: |
182 | RETVAL | |
183 | ||
8d4f5f67 SS |
184 | SV* |
185 | lookup_asn(db, address) | |
186 | struct loc_database* db; | |
187 | char* address; | |
188 | ||
189 | CODE: | |
190 | RETVAL = &PL_sv_undef; | |
191 | ||
192 | // Lookup network | |
193 | struct loc_network *network; | |
194 | int err = loc_database_lookup_from_string(db, address, &network); | |
195 | if (!err) { | |
196 | // Extract the ASN | |
197 | unsigned int as_number = loc_network_get_asn(network); | |
198 | if (as_number > 0) { | |
199 | RETVAL = newSViv(as_number); | |
200 | } | |
201 | ||
202 | loc_network_unref(network); | |
203 | } | |
204 | OUTPUT: | |
205 | RETVAL | |
206 | ||
cd022c5f SS |
207 | # |
208 | # Get functions | |
209 | # | |
210 | SV* | |
211 | get_continent_code(db, ccode) | |
212 | struct loc_database* db; | |
213 | char* ccode; | |
214 | ||
215 | CODE: | |
216 | RETVAL = &PL_sv_undef; | |
217 | ||
218 | // Lookup country code | |
219 | struct loc_country *country; | |
220 | int err = loc_database_get_country(db, &country, ccode); | |
221 | if(!err) { | |
222 | //Extract the continent code for the given country code. | |
223 | const char* continent_code = loc_country_get_continent_code(country); | |
224 | RETVAL = newSVpv(continent_code, strlen(continent_code)); | |
225 | ||
226 | loc_country_unref(country); | |
227 | } | |
228 | ||
229 | OUTPUT: | |
230 | RETVAL | |
231 | ||
1ea740e9 SS |
232 | void |
233 | DESTROY(db) | |
34eed014 | 234 | struct loc_database* db; |
da1039da | 235 | |
1ea740e9 | 236 | CODE: |
74ad091d | 237 | // Close database |
1ea740e9 | 238 | loc_database_unref(db); |