]> git.ipfire.org Git - location/libloc.git/blob - src/perl/Location.xs
perl: Verify database when it is being opened
[location/libloc.git] / src / perl / Location.xs
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
9
10 #include <loc/libloc.h>
11 #include <loc/database.h>
12 #include <loc/network.h>
13
14
15 MODULE = Location PACKAGE = Location
16
17 struct loc_database *
18 init(file, keyfile)
19 char* file;
20 char* keyfile;
21
22 CODE:
23 struct loc_ctx* ctx = NULL;
24
25 // Initialise location context
26 int err = loc_new(&ctx);
27 if (err < 0)
28 croak("Could not initialize libloc context: %d\n", err);
29
30 // Open the database file for reading
31 FILE* f = fopen(file, "r");
32 if (!f) {
33 loc_unref(ctx);
34
35 croak("Could not open file for reading: %s: %s\n",
36 file, strerror(errno));
37 }
38
39 // Parse the database
40 struct loc_database* db = NULL;
41 err = loc_database_new(ctx, &db, f);
42
43 // We can close the database file straight away
44 // because loc_database_new creates a copy of the file descriptor
45 fclose(f);
46
47 if (err) {
48 loc_unref(ctx);
49
50 croak("Could not read database: %s\n", file);
51 }
52
53 // Try to open the keyfile
54 f = fopen(keyfile, "r");
55 if (!f) {
56 loc_database_unref(db);
57 loc_unref(ctx);
58
59 croak("Could not open keyfile %s: %s\n",
60 keyfile, strerror(errno));
61 }
62
63 // Verify the database
64 int status = loc_database_verify(db, f);
65 if (status) {
66 loc_database_unref(db);
67 loc_unref(ctx);
68 fclose(f);
69
70 croak("Could not verify the database signature\n");
71 }
72
73 // Close the keyfile
74 fclose(f);
75
76 // Cleanup
77 loc_unref(ctx);
78
79 RETVAL = db;
80 OUTPUT:
81 RETVAL
82
83 #
84 # Database functions
85 #
86 const char*
87 get_vendor(db)
88 struct loc_database* db;
89
90 CODE:
91 // Get vendor
92 RETVAL = loc_database_get_vendor(db);
93 OUTPUT:
94 RETVAL
95
96 const char*
97 get_description(db)
98 struct loc_database* db;
99
100 CODE:
101 // Get database description
102 RETVAL = loc_database_get_description(db);
103 OUTPUT:
104 RETVAL
105
106 const char*
107 get_license(db)
108 struct loc_database* db;
109
110 CODE:
111 // Get database license
112 RETVAL = loc_database_get_license(db);
113 OUTPUT:
114 RETVAL
115
116 #
117 # Lookup functions
118 #
119 SV*
120 lookup_country_code(db, address)
121 struct loc_database* db;
122 char* address;
123
124 CODE:
125 RETVAL = &PL_sv_undef;
126
127 // Lookup network
128 struct loc_network *network;
129 int err = loc_database_lookup_from_string(db, address, &network);
130 if (!err) {
131 // Extract the country code
132 const char* country_code = loc_network_get_country_code(network);
133 RETVAL = newSVpv(country_code, strlen(country_code));
134
135 loc_network_unref(network);
136 }
137 OUTPUT:
138 RETVAL
139
140 SV*
141 lookup_asn(db, address)
142 struct loc_database* db;
143 char* address;
144
145 CODE:
146 RETVAL = &PL_sv_undef;
147
148 // Lookup network
149 struct loc_network *network;
150 int err = loc_database_lookup_from_string(db, address, &network);
151 if (!err) {
152 // Extract the ASN
153 unsigned int as_number = loc_network_get_asn(network);
154 if (as_number > 0) {
155 RETVAL = newSViv(as_number);
156 }
157
158 loc_network_unref(network);
159 }
160 OUTPUT:
161 RETVAL
162
163 void
164 DESTROY(db)
165 struct loc_database* db;
166
167 CODE:
168 // Close database
169 loc_database_unref(db);