"Fossies" - the Fresh Open Source Software Archive 
Member "libspf2-1.2.10/perl/SPF_XS.xs" (28 Jan 2012, 10515 Bytes) of package /linux/privat/libspf2-1.2.10.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 #include <EXTERN.h>
2 #include <perl.h>
3 #include <XSUB.h>
4
5 // XXX Need to fix ns_type in spf_dns.h first.
6 // #include <arpa/nameser.h>
7
8 #include "../src/include/spf_server.h"
9 #include "../src/include/spf_request.h"
10 #include "../src/include/spf_response.h"
11 #include "../src/include/spf_dns_zone.h"
12 #include "../src/include/spf_internal.h"
13
14 typedef SPF_server_t *Mail__SPF_XS__Server;
15 typedef SPF_record_t *Mail__SPF_XS__Record;
16 typedef SPF_request_t *Mail__SPF_XS__Request;
17 typedef SPF_response_t *Mail__SPF_XS__Response;
18 typedef SPF_dns_server_t *Mail__SPF_XS__Resolver;
19
20 #define EXPORT_INTEGER(x) do { \
21 newCONSTSUB(stash, #x, newSViv(x)); \
22 av_push(export, newSVpv(#x, strlen(#x))); \
23 } while(0)
24
25 #define EXPORT_BIVALUE(x, p) do { \
26 SV *sv = newSViv(x); \
27 sv_setpv(sv, p); \
28 SvIOK_on(sv); \
29 newCONSTSUB(stash, #x, sv); \
30 av_push(export, newSVpv(#x, strlen(#x))); \
31 } while(0)
32 #define EXPORT_ERRCODE(x) EXPORT_BIVALUE(x, SPF_strerror(x))
33
34 MODULE = Mail::SPF_XS PACKAGE = Mail::SPF_XS
35
36 PROTOTYPES: ENABLE
37
38 BOOT:
39 {
40 HV *stash;
41 AV *export;
42
43 stash = gv_stashpv("Mail::SPF_XS", TRUE);
44 export = get_av("Mail::SPF_XS::EXPORT_OK", TRUE);
45
46 EXPORT_INTEGER(SPF_DNS_RESOLV);
47 EXPORT_INTEGER(SPF_DNS_CACHE);
48 EXPORT_INTEGER(SPF_DNS_ZONE);
49
50 EXPORT_ERRCODE(SPF_E_SUCCESS);
51 EXPORT_ERRCODE(SPF_E_NO_MEMORY);
52 EXPORT_ERRCODE(SPF_E_NOT_SPF);
53 EXPORT_ERRCODE(SPF_E_SYNTAX);
54 EXPORT_ERRCODE(SPF_E_MOD_W_PREF);
55 EXPORT_ERRCODE(SPF_E_INVALID_CHAR);
56 EXPORT_ERRCODE(SPF_E_UNKNOWN_MECH);
57 EXPORT_ERRCODE(SPF_E_INVALID_OPT);
58 EXPORT_ERRCODE(SPF_E_INVALID_CIDR);
59 EXPORT_ERRCODE(SPF_E_MISSING_OPT);
60 EXPORT_ERRCODE(SPF_E_INTERNAL_ERROR);
61 EXPORT_ERRCODE(SPF_E_INVALID_ESC);
62 EXPORT_ERRCODE(SPF_E_INVALID_VAR);
63 EXPORT_ERRCODE(SPF_E_BIG_SUBDOM);
64 EXPORT_ERRCODE(SPF_E_INVALID_DELIM);
65 EXPORT_ERRCODE(SPF_E_BIG_STRING);
66 EXPORT_ERRCODE(SPF_E_BIG_MECH);
67 EXPORT_ERRCODE(SPF_E_BIG_MOD);
68 EXPORT_ERRCODE(SPF_E_BIG_DNS);
69 EXPORT_ERRCODE(SPF_E_INVALID_IP4);
70 EXPORT_ERRCODE(SPF_E_INVALID_IP6);
71 EXPORT_ERRCODE(SPF_E_INVALID_PREFIX);
72 EXPORT_ERRCODE(SPF_E_RESULT_UNKNOWN);
73 EXPORT_ERRCODE(SPF_E_UNINIT_VAR);
74 EXPORT_ERRCODE(SPF_E_MOD_NOT_FOUND);
75 EXPORT_ERRCODE(SPF_E_NOT_CONFIG);
76 EXPORT_ERRCODE(SPF_E_DNS_ERROR);
77 EXPORT_ERRCODE(SPF_E_BAD_HOST_IP);
78 EXPORT_ERRCODE(SPF_E_BAD_HOST_TLD);
79 EXPORT_ERRCODE(SPF_E_MECH_AFTER_ALL);
80 EXPORT_ERRCODE(SPF_E_INCLUDE_RETURNED_NONE);
81 EXPORT_ERRCODE(SPF_E_RECURSIVE);
82
83 EXPORT_INTEGER(SPF_RESULT_INVALID);
84 EXPORT_INTEGER(SPF_RESULT_NEUTRAL);
85 EXPORT_INTEGER(SPF_RESULT_PASS);
86 EXPORT_INTEGER(SPF_RESULT_FAIL);
87 EXPORT_INTEGER(SPF_RESULT_SOFTFAIL);
88
89 EXPORT_INTEGER(SPF_RESULT_NONE);
90 EXPORT_INTEGER(SPF_RESULT_TEMPERROR);
91 EXPORT_INTEGER(SPF_RESULT_PERMERROR);
92
93 // stash = gv_stashpv("Mail::SPF_XS::Resolver", TRUE);
94 // export = get_av("Mail::SPF_XS::Resolver::EXPORT_OK", TRUE);
95
96 EXPORT_INTEGER(ns_t_a);
97 EXPORT_INTEGER(ns_t_any);
98 EXPORT_INTEGER(ns_t_mx);
99 EXPORT_INTEGER(ns_t_ns);
100 EXPORT_INTEGER(ns_t_ptr);
101 // EXPORT_INTEGER(ns_t_soa);
102 EXPORT_INTEGER(ns_t_txt);
103
104 EXPORT_INTEGER(NETDB_SUCCESS);
105 EXPORT_INTEGER(TRY_AGAIN);
106 }
107
108 MODULE = Mail::SPF_XS PACKAGE = Mail::SPF_XS::Server
109
110 Mail::SPF_XS::Server
111 new(class, args)
112 SV *class
113 HV *args
114 PREINIT:
115 SPF_server_t *spf_server;
116 SV **svp;
117 SPF_server_dnstype_t dnstype;
118 int debug;
119 CODE:
120 (void)class;
121 svp = hv_fetch(args, "dnstype", 7, FALSE);
122 if (svp) {
123 if (SvIOK(*svp))
124 dnstype = SvIV(*svp);
125 else
126 croak("dnstype must be an integer");
127 }
128 else {
129 dnstype = SPF_DNS_RESOLV;
130 }
131 svp = hv_fetch(args, "debug", 5, FALSE);
132 if (svp && SvIOK(*svp))
133 debug = SvIV(*svp);
134 else
135 debug = 0;
136 spf_server = SPF_server_new(dnstype, debug);
137 RETVAL = spf_server;
138 OUTPUT:
139 RETVAL
140
141 void
142 DESTROY(server)
143 Mail::SPF_XS::Server server
144 CODE:
145 SPF_server_free(server);
146
147 Mail::SPF_XS::Resolver
148 resolver(server)
149 Mail::SPF_XS::Server server
150 CODE:
151 RETVAL = server->resolver;
152 OUTPUT:
153 RETVAL
154
155 char *
156 expand(server, text)
157 Mail::SPF_XS::Server server
158 const char * text
159 PREINIT:
160 SPF_response_t *response = NULL;
161 SPF_request_t *request;
162 SPF_macro_t *macro;
163 SPF_errcode_t err;
164 char *buf = NULL;
165 size_t buflen = 0;
166 CODE:
167 response = SPF_response_new(NULL);
168 err = SPF_record_compile_macro(server, response, ¯o, text);
169 if (err != SPF_E_SUCCESS) {
170 SPF_response_free(response);
171 if (macro)
172 SPF_macro_free(macro);
173 croak("Failed to compile macro: err = %s", SPF_strerror(err));
174 }
175 request = SPF_request_new(server);
176 /* Deliberately very long, for testing. */
177 SPF_request_set_env_from(request,
178 "env-from-local-part@env-from-domain-part.com");
179 err = SPF_record_expand_data(server, request, response,
180 SPF_macro_data(macro), SPF_macro_data_len(macro),
181 &buf, &buflen);
182 if (err != SPF_E_SUCCESS) {
183 SPF_response_free(response);
184 if (macro)
185 SPF_macro_free(macro);
186 croak("Failed to expand macro: err = %s", SPF_strerror(err));
187 }
188 SPF_response_free(response);
189 SPF_request_free(request);
190 if (macro)
191 SPF_macro_free(macro);
192 RETVAL = buf;
193 OUTPUT:
194 RETVAL
195
196 Mail::SPF_XS::Record
197 compile(server, text)
198 Mail::SPF_XS::Server server
199 const char * text
200 PREINIT:
201 SPF_record_t *record = NULL;
202 SPF_response_t *response = NULL;
203 SPF_errcode_t err;
204 CODE:
205 response = SPF_response_new(NULL);
206 err = SPF_record_compile(server, response, &record, text);
207 if (err != SPF_E_SUCCESS) {
208 SPF_response_free(response);
209 croak("Failed to compile record: err = %s", SPF_strerror(err));
210 }
211 SPF_response_free(response);
212 RETVAL = record;
213 OUTPUT:
214 RETVAL
215
216 Mail::SPF_XS::Response
217 process(server, request)
218 Mail::SPF_XS::Server server
219 Mail::SPF_XS::Request request
220 PREINIT:
221 SPF_response_t *response = NULL;
222 CODE:
223 request->spf_server = server;
224 SPF_request_query_mailfrom(request, &response);
225 RETVAL = response;
226 OUTPUT:
227 RETVAL
228
229 MODULE = Mail::SPF_XS PACKAGE = Mail::SPF_XS::Record
230
231 char *
232 modifier(record, name)
233 Mail::SPF_XS::Record record
234 const char * name
235 PREINIT:
236 SPF_request_t *request;
237 SPF_response_t *response;
238 SPF_errcode_t err;
239 char *buf = NULL;
240 size_t buflen = 0;
241 CODE:
242 request = SPF_request_new(NULL);
243 response = SPF_response_new(NULL);
244 err = SPF_record_find_mod_value(record->spf_server,
245 request, response, record, name,
246 &buf, &buflen);
247 if (err != SPF_E_SUCCESS) {
248 SPF_request_free(request);
249 SPF_response_free(response);
250 croak("Failed to find or expand modifier \"%s\": err = %s", name, SPF_strerror(err));
251 }
252 SPF_request_free(request);
253 SPF_response_free(response);
254 RETVAL = buf;
255 OUTPUT:
256 RETVAL
257
258 char *
259 string(record)
260 Mail::SPF_XS::Record record
261 PREINIT:
262 char *buf = NULL;
263 size_t buflen = 0;
264 SPF_errcode_t err;
265 CODE:
266 err = SPF_record_stringify(record, &buf, &buflen);
267 if (err != SPF_E_SUCCESS)
268 croak("Failed to stringify record: err = %s", SPF_strerror(err));
269 RETVAL = buf;
270 OUTPUT:
271 RETVAL
272
273 void
274 DESTROY(record)
275 Mail::SPF_XS::Record record
276 CODE:
277 SPF_record_free(record);
278
279 MODULE = Mail::SPF_XS PACKAGE = Mail::SPF_XS::Request
280
281 Mail::SPF_XS::Request
282 new(class, args)
283 SV *class
284 HV *args
285 PREINIT:
286 SV **svp;
287 SPF_request_t *spf_request;
288 CODE:
289 (void)class;
290 spf_request = SPF_request_new(NULL);
291 svp = hv_fetch(args, "ip_address", 10, FALSE);
292 if (!svp || !SvPOK(*svp))
293 croak("new() requires ip_address => $address");
294 if (SPF_request_set_ipv4_str(spf_request, SvPV_nolen(*svp)) != SPF_E_SUCCESS)
295 if (SPF_request_set_ipv6_str(spf_request, SvPV_nolen(*svp)) != SPF_E_SUCCESS)
296 croak("Failed to set client address: Not a valid ipv4 or ipv6");
297 svp = hv_fetch(args, "identity", 8, FALSE);
298 if (!svp || !SvPOK(*svp))
299 croak("new() requires identity => $identity");
300 if (SPF_request_set_env_from(spf_request, SvPV_nolen(*svp)) != 0)
301 croak("Failed to set env_from identity");
302 // ...
303 RETVAL = spf_request;
304 OUTPUT:
305 RETVAL
306
307 void
308 DESTROY(request)
309 Mail::SPF_XS::Request request
310 CODE:
311 SPF_request_free(request);
312
313 SV *
314 string(request)
315 Mail::SPF_XS::Request request
316 PREINIT:
317 char buf[INET_ADDRSTRLEN];
318 CODE:
319 if (request == NULL) {
320 RETVAL = newSVpvf("(null)");
321 }
322 else {
323 memset(buf, 0, sizeof(buf));
324 if (request->client_ver == AF_INET) {
325 inet_ntop(AF_INET, &(request->ipv4), buf, sizeof(buf));
326 }
327 else if (request->client_ver == AF_INET6) {
328 inet_ntop(AF_INET6, &(request->ipv6), buf, sizeof(buf));
329 }
330 else {
331 snprintf(buf, sizeof(buf), "Unknown family %d",
332 request->client_ver);
333 }
334 RETVAL = newSVpvf("ip=%s, identity=%s",
335 buf,
336 request->env_from);
337 }
338 OUTPUT:
339 RETVAL
340
341 MODULE = Mail::SPF_XS PACKAGE = Mail::SPF_XS::Response
342
343 void
344 DESTROY(response)
345 Mail::SPF_XS::Response response
346 CODE:
347 SPF_response_free(response);
348
349 const char *
350 code(response)
351 Mail::SPF_XS::Response response
352 CODE:
353 RETVAL = SPF_strresult(SPF_response_result(response));
354 OUTPUT:
355 RETVAL
356
357 const char *
358 reason(response)
359 Mail::SPF_XS::Response response
360 CODE:
361 RETVAL = SPF_strreason(SPF_response_reason(response));
362 OUTPUT:
363 RETVAL
364
365 const char *
366 error(response)
367 Mail::SPF_XS::Response response
368 CODE:
369 RETVAL = SPF_strerror(SPF_response_errcode(response));
370 OUTPUT:
371 RETVAL
372
373 const char *
374 explanation(response)
375 Mail::SPF_XS::Response response
376 CODE:
377 RETVAL = SPF_response_get_explanation(response);
378 // RETVAL = response->smtp_comment;
379 OUTPUT:
380 RETVAL
381
382 SV *
383 string(response)
384 Mail::SPF_XS::Response response
385 PREINIT:
386 const char *exp;
387 int i;
388 CODE:
389 if (response == NULL) {
390 RETVAL = newSVpvf("(null)");
391 }
392 else {
393 exp = SPF_response_get_explanation(response);
394 RETVAL = newSVpvf("result=%s, reason=\"%s\", error=%s, explanation=\"%s\"",
395 SPF_strresult(SPF_response_result(response)),
396 SPF_strreason(SPF_response_reason(response)),
397 SPF_strerror(SPF_response_errcode(response)),
398 exp ? exp : "(null)");
399 if (response->errors_length) {
400 sv_catpv(RETVAL, ", errors={");
401 for (i = 0; i < response->errors_length; i++) {
402 sv_catpvf(RETVAL, " (%d)%s",
403 response->errors[i].code,
404 response->errors[i].message);
405 }
406 sv_catpv(RETVAL, " }");
407 }
408 }
409 OUTPUT:
410 RETVAL
411
412 MODULE = Mail::SPF_XS PACKAGE = Mail::SPF_XS::Resolver
413
414 int
415 add(resolver, domain, rr_type, herrno, data)
416 Mail::SPF_XS::Resolver resolver
417 const char *domain
418 int rr_type
419 int herrno
420 const char *data
421 CODE:
422 /* XXX Ensure it's a zone resolver. */
423 RETVAL = SPF_dns_zone_add_str(resolver, domain, rr_type, herrno, data);
424 OUTPUT:
425 RETVAL
426