1 #line 982 "../../src/builtin/snarf.m4"
2 /* -*- buffer-read-only: t -*- vi: set ro:
3 THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT.
4 */
5 #line 982
6 #ifdef HAVE_CONFIG_H
7 #line 982
8 # include <config.h>
9 #line 982
10 #endif
11 #line 982
12 #include <sys/types.h>
13 #line 982
14
15 #line 982
16 #include "mailfromd.h"
17 #line 982
18 #include "prog.h"
19 #line 982
20 #include "builtin.h"
21 #line 982
22
23 #line 982
24
25 #line 1022 "../../src/builtin/snarf.m4"
26
27 /* End of snarf.m4 */
28 #line 1 "dns.bi"
29 /* This file is part of Mailfromd. -*- c -*-
30 Copyright (C) 2006-2021 Sergey Poznyakoff
31
32 This program is free software; you can redistribute it and/or modify
33 it under the terms of the GNU General Public License as published by
34 the Free Software Foundation; either version 3, or (at your option)
35 any later version.
36
37 This program is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
41
42 You should have received a copy of the GNU General Public License
43 along with this program. If not, see <http://www.gnu.org/licenses/>. */
44
45
46
47 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #include <netdb.h>
50 #include <arpa/inet.h>
51 #include <limits.h>
52 #include "srvcfg.h"
53 #include "global.h"
54
55 void
56 #line 27
bi_primitive_hostname(eval_environ_t env)57 bi_primitive_hostname(eval_environ_t env)
58 #line 27
59
60 #line 27
61
62 #line 27 "dns.bi"
63 {
64 #line 27
65
66 #line 27
67
68 #line 27
69
70 #line 27
71 char * MFL_DATASEG string;
72 #line 27
73
74 #line 27
75 get_string_arg(env, 0, &string);
76 #line 27
77
78 #line 27
79
80 #line 27
81 adjust_stack(env, 1);
82 #line 27
83
84 #line 27
85
86 #line 27
87 if (builtin_module_trace(BUILTIN_IDX_dns))
88 #line 27
89 prog_trace(env, "primitive_hostname %s",string);;
90 #line 27
91
92 {
93 char *hbuf;
94 mf_status stat;
95
96 stat = resolve_ipstr(string, &hbuf);
97 if (!(stat == mf_success))
98 #line 33
99 (
100 #line 33
101 env_throw_bi(env, mf_status_to_exception(stat), "primitive_hostname", _("cannot resolve IP %s"),string)
102 #line 33
103 )
104 #line 36
105 ;
106
107 pushs(env, hbuf);
108 free(hbuf);
109 }
110
111 #line 41
112 env_function_cleanup_flush(env, NULL);
113 #line 41
114 return;
115 #line 41
116 }
117
118 void
119 #line 43
bi_primitive_resolve(eval_environ_t env)120 bi_primitive_resolve(eval_environ_t env)
121 #line 43
122
123 #line 43
124
125 #line 43 "dns.bi"
126 {
127 #line 43
128
129 #line 43
130
131 #line 43
132 long __bi_argcnt;
133 #line 43
134 char * MFL_DATASEG string;
135 #line 43
136 char * MFL_DATASEG domain;
137 #line 43
138
139 #line 43
140 get_string_arg(env, 1, &string);
141 #line 43
142 get_string_arg(env, 2, &domain);
143 #line 43
144
145 #line 43
146 get_numeric_arg(env, 0, &__bi_argcnt);
147 #line 43
148 adjust_stack(env, __bi_argcnt + 1);
149 #line 43
150
151 #line 43
152
153 #line 43
154 if (builtin_module_trace(BUILTIN_IDX_dns))
155 #line 43
156 prog_trace(env, "primitive_resolve %s %s",string, ((__bi_argcnt > 1) ? domain : ""));;
157 #line 43
158
159 {
160 char *ipstr;
161 mf_status stat;
162
163 if (((__bi_argcnt > 1) ? domain : "")[0]) {
164 stat = resolve_ipstr_domain(string, domain, &ipstr);
165 if (!(stat == mf_success))
166 #line 50
167 (
168 #line 50
169 env_throw_bi(env, mf_status_to_exception(stat), "primitive_resolve", _("cannot resolve %s.%s"),string,domain)
170 #line 50
171 )
172 #line 52
173 ;
174 } else {
175 stat = resolve_hostname(string, &ipstr);
176 if (!(stat == mf_success))
177 #line 55
178 (
179 #line 55
180 env_throw_bi(env, mf_status_to_exception(stat), "primitive_resolve", _("cannot resolve %s"),string)
181 #line 55
182 )
183 #line 57
184 ;
185 }
186 pushs(env, ipstr);
187 free(ipstr);
188 }
189
190 #line 62
191 env_function_cleanup_flush(env, NULL);
192 #line 62
193 return;
194 #line 62
195 }
196
197 void
198 #line 64
bi_primitive_hasmx(eval_environ_t env)199 bi_primitive_hasmx(eval_environ_t env)
200 #line 64
201
202 #line 64
203
204 #line 64 "dns.bi"
205 {
206 #line 64
207
208 #line 64
209
210 #line 64
211
212 #line 64
213 char * string;
214 #line 64
215
216 #line 64
217 get_string_arg(env, 0, &string);
218 #line 64
219
220 #line 64
221
222 #line 64
223 adjust_stack(env, 1);
224 #line 64
225
226 #line 64
227
228 #line 64
229 if (builtin_module_trace(BUILTIN_IDX_dns))
230 #line 64
231 prog_trace(env, "primitive_hasmx %s",string);;
232 #line 64
233
234 {
235 struct dns_reply repl;
236 mf_status mxstat;
237
238 mxstat = dns_to_mf_status(mx_lookup(string, 0, &repl));
239
240 if (!(mxstat == mf_success || mxstat == mf_not_found))
241 #line 71
242 (
243 #line 71
244 env_throw_bi(env, mf_status_to_exception(mxstat), "primitive_hasmx", _("cannot get MX records for %s"),string)
245 #line 71
246 )
247 #line 74
248 ;
249 dns_reply_free(&repl);
250 if (mxstat == mf_success) {
251
252 #line 77
253 do {
254 #line 77
255 push(env, (STKVAL)(mft_number)(1));
256 #line 77
257 goto endlab;
258 #line 77
259 } while (0);
260 }
261
262 #line 79
263 do {
264 #line 79
265 push(env, (STKVAL)(mft_number)(0));
266 #line 79
267 goto endlab;
268 #line 79
269 } while (0);
270 }
271 endlab:
272 #line 81
273 env_function_cleanup_flush(env, NULL);
274 #line 81
275 return;
276 #line 81
277 }
278
279 static dns_status
resolve_host(const char * string,struct dns_reply * reply)280 resolve_host(const char *string, struct dns_reply *reply)
281 {
282 struct in_addr addr;
283
284 if (inet_aton(string, &addr)) {
285 dns_reply_init(reply, dns_reply_ip, 1);
286 reply->data.ip[0] = addr.s_addr;
287 return dns_success;
288 }
289 return a_lookup(string, reply);
290 }
291
292 static int
dns_replies_intersect(struct dns_reply const * a,struct dns_reply const * b)293 dns_replies_intersect(struct dns_reply const *a, struct dns_reply const *b)
294 {
295 int i, j;
296
297 if (a->type == b->type && a->type == dns_reply_ip) {
298 for (i = 0; i < a->count; i++)
299 for (j = 0; j < b->count; j++)
300 if (a->data.ip[i] == b->data.ip[j])
301 return 1;
302 }
303 return 0;
304 }
305
306 void
307 #line 110
bi_primitive_ismx(eval_environ_t env)308 bi_primitive_ismx(eval_environ_t env)
309 #line 110
310
311 #line 110
312
313 #line 110 "dns.bi"
314 {
315 #line 110
316
317 #line 110
318
319 #line 110
320
321 #line 110
322 char * domain;
323 #line 110
324 char * ipstr;
325 #line 110
326
327 #line 110
328 get_string_arg(env, 0, &domain);
329 #line 110
330 get_string_arg(env, 1, &ipstr);
331 #line 110
332
333 #line 110
334
335 #line 110
336 adjust_stack(env, 2);
337 #line 110
338
339 #line 110
340
341 #line 110
342 if (builtin_module_trace(BUILTIN_IDX_dns))
343 #line 110
344 prog_trace(env, "primitive_ismx %s %s",domain, ipstr);;
345 #line 110
346
347 {
348 struct dns_reply areply, mxreply;
349 dns_status status;
350 int rc = 0;
351
352 status = resolve_host(ipstr, &areply);
353 if (!(status == dns_success))
354 #line 117
355 (
356 #line 117
357 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(status)), "primitive_ismx", _("cannot resolve host name %s"),ipstr)
358 #line 117
359 )
360 #line 119
361 ;
362 status = mx_lookup(domain, 1, &mxreply);
363 if (status != dns_success) {
364 dns_reply_free(&areply);
365 (
366 #line 123
367 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(status)), "primitive_ismx", _("cannot get MXs for %s"),domain)
368 #line 123
369 );
370 #line 125
371 }
372 rc = dns_replies_intersect(&areply, &mxreply);
373 dns_reply_free(&areply);
374 dns_reply_free(&mxreply);
375
376 #line 129
377 do {
378 #line 129
379 push(env, (STKVAL)(mft_number)(rc));
380 #line 129
381 goto endlab;
382 #line 129
383 } while (0);
384 }
385 endlab:
386 #line 131
387 env_function_cleanup_flush(env, NULL);
388 #line 131
389 return;
390 #line 131
391 }
392
393 void
394 #line 133
bi_relayed(eval_environ_t env)395 bi_relayed(eval_environ_t env)
396 #line 133
397
398 #line 133
399
400 #line 133 "dns.bi"
401 {
402 #line 133
403
404 #line 133
405
406 #line 133
407
408 #line 133
409 char * s;
410 #line 133
411
412 #line 133
413 get_string_arg(env, 0, &s);
414 #line 133
415
416 #line 133
417
418 #line 133
419 adjust_stack(env, 1);
420 #line 133
421
422 #line 133
423
424 #line 133
425 if (builtin_module_trace(BUILTIN_IDX_dns))
426 #line 133
427 prog_trace(env, "relayed %s",s);;
428 #line 133
429
430 {
431
432 #line 135
433 do {
434 #line 135
435 push(env, (STKVAL)(mft_number)(relayed_domain_p(s)));
436 #line 135
437 goto endlab;
438 #line 135
439 } while (0);
440 }
441 endlab:
442 #line 137
443 env_function_cleanup_flush(env, NULL);
444 #line 137
445 return;
446 #line 137
447 }
448
449 void
450 #line 139
bi_ptr_validate(eval_environ_t env)451 bi_ptr_validate(eval_environ_t env)
452 #line 139
453
454 #line 139
455
456 #line 139 "dns.bi"
457 {
458 #line 139
459
460 #line 139
461
462 #line 139
463
464 #line 139
465 char * s;
466 #line 139
467
468 #line 139
469 get_string_arg(env, 0, &s);
470 #line 139
471
472 #line 139
473
474 #line 139
475 adjust_stack(env, 1);
476 #line 139
477
478 #line 139
479
480 #line 139
481 if (builtin_module_trace(BUILTIN_IDX_dns))
482 #line 139
483 prog_trace(env, "ptr_validate %s",s);;
484 #line 139
485
486 {
487 int rc, res;
488 switch (rc = ptr_validate(s, NULL)) {
489 case dns_success:
490 res = 1;
491 break;
492 case dns_not_found:
493 res = 0;
494 break;
495 default:
496 (
497 #line 150
498 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(rc)), "ptr_validate", _("failed to get PTR record for %s"),s)
499 #line 150
500 );
501 #line 152
502 }
503
504 #line 153
505 do {
506 #line 153
507 push(env, (STKVAL)(mft_number)(res));
508 #line 153
509 goto endlab;
510 #line 153
511 } while (0);
512 }
513 endlab:
514 #line 155
515 env_function_cleanup_flush(env, NULL);
516 #line 155
517 return;
518 #line 155
519 }
520
521 void
522 #line 157
bi_primitive_hasns(eval_environ_t env)523 bi_primitive_hasns(eval_environ_t env)
524 #line 157
525
526 #line 157
527
528 #line 157 "dns.bi"
529 {
530 #line 157
531
532 #line 157
533
534 #line 157
535
536 #line 157
537 char * dom;
538 #line 157
539
540 #line 157
541 get_string_arg(env, 0, &dom);
542 #line 157
543
544 #line 157
545
546 #line 157
547 adjust_stack(env, 1);
548 #line 157
549
550 #line 157
551
552 #line 157
553 if (builtin_module_trace(BUILTIN_IDX_dns))
554 #line 157
555 prog_trace(env, "primitive_hasns %s",dom);;
556 #line 157
557
558 {
559 struct dns_reply repl;
560 mf_status stat = dns_to_mf_status(ns_lookup(dom, 0, &repl));
561 if (!(stat == mf_success || stat == mf_not_found))
562 #line 161
563 (
564 #line 161
565 env_throw_bi(env, mf_status_to_exception(stat), "primitive_hasns", _("cannot get NS records for %s"),dom)
566 #line 161
567 )
568 #line 164
569 ;
570 dns_reply_free(&repl);
571 if (stat == mf_success) {
572
573 #line 167
574 do {
575 #line 167
576 push(env, (STKVAL)(mft_number)(1));
577 #line 167
578 goto endlab;
579 #line 167
580 } while (0);
581 }
582
583 #line 169
584 do {
585 #line 169
586 push(env, (STKVAL)(mft_number)(0));
587 #line 169
588 goto endlab;
589 #line 169
590 } while (0);
591 }
592 endlab:
593 #line 171
594 env_function_cleanup_flush(env, NULL);
595 #line 171
596 return;
597 #line 171
598 }
599
600 static int
cmp_ip(void const * a,void const * b)601 cmp_ip(void const *a, void const *b)
602 {
603 GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T const *)a);
604 GACOPYZ_UINT32_T ipb = ntohl(*(GACOPYZ_UINT32_T const *)b);
605 if (ipa < ipb)
606 return -1;
607 if (ipa > ipb)
608 return 1;
609 return 0;
610 }
611
612 static int
cmp_str(void const * a,void const * b)613 cmp_str(void const *a, void const *b)
614 {
615 char * const *stra = a;
616 char * const *strb = b;
617 return strcmp(*stra, *strb);
618 }
619
620 static int
cmp_hostname(const void * a,const void * b)621 cmp_hostname(const void *a, const void *b)
622 {
623 return strcasecmp(*(const char**) a, *(const char**) b);
624 }
625
626 typedef long DNS_REPLY_COUNT;
627 #define DNS_REPLY_MAX LONG_MAX
628
629 struct dns_reply_storage {
630 DNS_REPLY_COUNT reply_count;
631 size_t reply_max;
632 struct dns_reply *reply_tab;
633 };
634
635 static inline int
dns_reply_entry_unused(struct dns_reply_storage * rs,DNS_REPLY_COUNT n)636 dns_reply_entry_unused(struct dns_reply_storage *rs, DNS_REPLY_COUNT n)
637 {
638 return n == -1 || rs->reply_tab[n].type == -1;
639 }
640
641 static inline void
dns_reply_entry_release(struct dns_reply_storage * rs,DNS_REPLY_COUNT n)642 dns_reply_entry_release(struct dns_reply_storage *rs, DNS_REPLY_COUNT n)
643 {
644 rs->reply_tab[n].type = -1;
645 }
646
647 static inline struct dns_reply *
dns_reply_entry_locate(struct dns_reply_storage * rs,DNS_REPLY_COUNT n)648 dns_reply_entry_locate(struct dns_reply_storage *rs, DNS_REPLY_COUNT n)
649 {
650 if (n < 0 || n >= rs->reply_count || dns_reply_entry_unused(rs, n))
651 return NULL;
652 return &rs->reply_tab[n];
653 }
654
655 static void *
dns_reply_storage_alloc(void)656 dns_reply_storage_alloc(void)
657 {
658 struct dns_reply_storage *rs = mu_alloc(sizeof(*rs));
659 rs->reply_count = 0;
660 rs->reply_max = 0;
661 rs->reply_tab = NULL;
662 return rs;
663 }
664
665 static void
dns_reply_storage_destroy(void * data)666 dns_reply_storage_destroy(void *data)
667 {
668 struct dns_reply_storage *rs = data;
669 DNS_REPLY_COUNT i;
670
671 for (i = 0; i < rs->reply_count; i++) {
672 if (!dns_reply_entry_unused(rs, i)) {
673 dns_reply_free(&rs->reply_tab[i]);
674 dns_reply_entry_release(rs, i);
675 }
676 }
677 free(rs->reply_tab);
678 free(rs);
679 }
680
681
682 #line 254
683
684 #line 254
685 static int DNS_id;
686 #line 254 "dns.bi"
687
688
689 static inline DNS_REPLY_COUNT
dns_reply_entry_alloc(struct dns_reply_storage * rs,struct dns_reply ** return_reply)690 dns_reply_entry_alloc(struct dns_reply_storage *rs,
691 struct dns_reply **return_reply)
692 {
693 DNS_REPLY_COUNT i;
694
695 for (i = 0; i < rs->reply_count; i++) {
696 if (dns_reply_entry_unused(rs, i)) {
697 *return_reply = &rs->reply_tab[i];
698 return i;
699 }
700 }
701 if (rs->reply_count == DNS_REPLY_MAX)
702 return -1;
703 if (rs->reply_count == rs->reply_max) {
704 size_t n = rs->reply_max;
705 rs->reply_tab = mu_2nrealloc(rs->reply_tab, &rs->reply_max,
706 sizeof(rs->reply_tab[0]));
707 for (; n < rs->reply_max; n++)
708 dns_reply_entry_release(rs, n);
709 }
710 *return_reply = &rs->reply_tab[rs->reply_count];
711 return rs->reply_count++;
712 }
713
714 void
715 #line 281
bi_dns_reply_release(eval_environ_t env)716 bi_dns_reply_release(eval_environ_t env)
717 #line 281
718
719 #line 281
720
721 #line 281 "dns.bi"
722 {
723 #line 281
724
725 #line 281
726
727 #line 281
728
729 #line 281
730 long n;
731 #line 281
732
733 #line 281
734 get_numeric_arg(env, 0, &n);
735 #line 281
736
737 #line 281
738
739 #line 281
740 adjust_stack(env, 1);
741 #line 281
742
743 #line 281
744
745 #line 281
746 if (builtin_module_trace(BUILTIN_IDX_dns))
747 #line 281
748 prog_trace(env, "dns_reply_release %lu",n);;
749 #line 281
750
751 {
752 struct dns_reply_storage *repl = env_get_builtin_priv(env,DNS_id);
753 if (!dns_reply_entry_unused(repl, n)) {
754 dns_reply_free(&repl->reply_tab[n]);
755 dns_reply_entry_release(repl, n);
756 }
757 }
758
759 #line 289
760 env_function_cleanup_flush(env, NULL);
761 #line 289
762 return;
763 #line 289
764 }
765
766 void
767 #line 291
bi_dns_reply_count(eval_environ_t env)768 bi_dns_reply_count(eval_environ_t env)
769 #line 291
770
771 #line 291
772
773 #line 291 "dns.bi"
774 {
775 #line 291
776
777 #line 291
778
779 #line 291
780
781 #line 291
782 long n;
783 #line 291
784
785 #line 291
786 get_numeric_arg(env, 0, &n);
787 #line 291
788
789 #line 291
790
791 #line 291
792 adjust_stack(env, 1);
793 #line 291
794
795 #line 291
796
797 #line 291
798 if (builtin_module_trace(BUILTIN_IDX_dns))
799 #line 291
800 prog_trace(env, "dns_reply_count %lu",n);;
801 #line 291
802
803 {
804 struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
805 struct dns_reply *reply;
806
807 if (n == -1)
808
809 #line 297
810 do {
811 #line 297
812 push(env, (STKVAL)(mft_number)(0));
813 #line 297
814 goto endlab;
815 #line 297
816 } while (0);
817 if (n < 0)
818 (
819 #line 299
820 env_throw_bi(env, mfe_failure, "dns_reply_count", _("invalid DNS reply number: %ld"),n)
821 #line 299
822 );
823 #line 301
824 reply = dns_reply_entry_locate(rs, n);
825 if (!reply)
826 (
827 #line 303
828 env_throw_bi(env, mfe_failure, "dns_reply_count", _("no such reply: %ld"),n)
829 #line 303
830 );
831 #line 305
832
833 #line 305
834 do {
835 #line 305
836 push(env, (STKVAL)(mft_number)(reply->count));
837 #line 305
838 goto endlab;
839 #line 305
840 } while (0);
841 }
842 endlab:
843 #line 307
844 env_function_cleanup_flush(env, NULL);
845 #line 307
846 return;
847 #line 307
848 }
849
850 void
851 #line 309
bi_dns_reply_string(eval_environ_t env)852 bi_dns_reply_string(eval_environ_t env)
853 #line 309
854
855 #line 309
856
857 #line 309 "dns.bi"
858 {
859 #line 309
860
861 #line 309
862
863 #line 309
864
865 #line 309
866 long n;
867 #line 309
868 long i;
869 #line 309
870
871 #line 309
872 get_numeric_arg(env, 0, &n);
873 #line 309
874 get_numeric_arg(env, 1, &i);
875 #line 309
876
877 #line 309
878
879 #line 309
880 adjust_stack(env, 2);
881 #line 309
882
883 #line 309
884
885 #line 309
886 if (builtin_module_trace(BUILTIN_IDX_dns))
887 #line 309
888 prog_trace(env, "dns_reply_string %lu %lu",n, i);;
889 #line 309
890
891 {
892 struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
893 struct dns_reply *reply = dns_reply_entry_locate(rs, n);
894 if (!reply)
895 (
896 #line 314
897 env_throw_bi(env, mfe_failure, "dns_reply_string", _("no such reply: %ld"),n)
898 #line 314
899 );
900 #line 316
901 if (i < 0 || i >= reply->count)
902 (
903 #line 317
904 env_throw_bi(env, mfe_range, "dns_reply_string", _("index out of range: %ld"),i)
905 #line 317
906 );
907 #line 319
908 if (reply->type == dns_reply_ip) {
909 struct in_addr addr;
910 addr.s_addr = reply->data.ip[i];
911
912 #line 322
913 do {
914 #line 322
915 pushs(env, inet_ntoa(addr));
916 #line 322
917 goto endlab;
918 #line 322
919 } while (0);
920 }
921
922 #line 324
923 do {
924 #line 324
925 pushs(env, reply->data.str[i]);
926 #line 324
927 goto endlab;
928 #line 324
929 } while (0);
930 }
931 endlab:
932 #line 326
933 env_function_cleanup_flush(env, NULL);
934 #line 326
935 return;
936 #line 326
937 }
938
939 void
940 #line 328
bi_dns_reply_ip(eval_environ_t env)941 bi_dns_reply_ip(eval_environ_t env)
942 #line 328
943
944 #line 328
945
946 #line 328 "dns.bi"
947 {
948 #line 328
949
950 #line 328
951
952 #line 328
953
954 #line 328
955 long n;
956 #line 328
957 long i;
958 #line 328
959
960 #line 328
961 get_numeric_arg(env, 0, &n);
962 #line 328
963 get_numeric_arg(env, 1, &i);
964 #line 328
965
966 #line 328
967
968 #line 328
969 adjust_stack(env, 2);
970 #line 328
971
972 #line 328
973
974 #line 328
975 if (builtin_module_trace(BUILTIN_IDX_dns))
976 #line 328
977 prog_trace(env, "dns_reply_ip %lu %lu",n, i);;
978 #line 328
979
980 {
981 struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
982 struct dns_reply *reply = dns_reply_entry_locate(rs, n);
983 if (!reply)
984 (
985 #line 333
986 env_throw_bi(env, mfe_failure, "dns_reply_ip", _("no such reply: %ld"),n)
987 #line 333
988 );
989 #line 335
990 if (i < 0 || i >= reply->count)
991 (
992 #line 336
993 env_throw_bi(env, mfe_range, "dns_reply_ip", _("index out of range: %ld"),i)
994 #line 336
995 );
996 #line 338
997 if (reply->type == dns_reply_str) {
998 (
999 #line 339
1000 env_throw_bi(env, mfe_failure, "dns_reply_ip", _("can't use dns_reply_ip on string replies"))
1001 #line 339
1002 );
1003 #line 341
1004 }
1005
1006 #line 342
1007 do {
1008 #line 342
1009 pushs(env, reply->data.str[i]);
1010 #line 342
1011 goto endlab;
1012 #line 342
1013 } while (0);
1014 }
1015 endlab:
1016 #line 344
1017 env_function_cleanup_flush(env, NULL);
1018 #line 344
1019 return;
1020 #line 344
1021 }
1022
1023 enum {
1024 DNS_TYPE_A = 1,
1025 DNS_TYPE_NS = 2,
1026 DNS_TYPE_PTR = 12,
1027 DNS_TYPE_MX = 15,
1028 DNS_TYPE_TXT = 16,
1029 };
1030
1031 static char *dns_type_name[] = {
1032 [DNS_TYPE_A] = "a",
1033 [DNS_TYPE_NS] = "ns",
1034 [DNS_TYPE_PTR] = "ptr",
1035 [DNS_TYPE_MX] = "mx",
1036 [DNS_TYPE_TXT] = "txt"
1037 };
1038
1039 void
1040 #line 362
bi_dns_query(eval_environ_t env)1041 bi_dns_query(eval_environ_t env)
1042 #line 362
1043
1044 #line 362
1045
1046 #line 362 "dns.bi"
1047 {
1048 #line 362
1049
1050 #line 362
1051
1052 #line 362
1053 long __bi_argcnt;
1054 #line 362
1055 long type;
1056 #line 362
1057 char * domain;
1058 #line 362
1059 long sort;
1060 #line 362
1061 long resolve;
1062 #line 362
1063
1064 #line 362
1065 get_numeric_arg(env, 1, &type);
1066 #line 362
1067 get_string_arg(env, 2, &domain);
1068 #line 362
1069 get_numeric_arg(env, 3, &sort);
1070 #line 362
1071 get_numeric_arg(env, 4, &resolve);
1072 #line 362
1073
1074 #line 362
1075 get_numeric_arg(env, 0, &__bi_argcnt);
1076 #line 362
1077 adjust_stack(env, __bi_argcnt + 1);
1078 #line 362
1079
1080 #line 362
1081
1082 #line 362
1083 if (builtin_module_trace(BUILTIN_IDX_dns))
1084 #line 362
1085 prog_trace(env, "dns_query %lu %s %lu %lu",type, domain, ((__bi_argcnt > 2) ? sort : 0), ((__bi_argcnt > 3) ? resolve : 0));;
1086
1087 {
1088 struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
1089 dns_status dnsstat;
1090 mf_status stat;
1091 DNS_REPLY_COUNT ret;
1092 struct dns_reply *reply;
1093 int (*cmpfun)(const void *, const void *) = NULL;
1094 struct in_addr addr;
1095
1096 ret = dns_reply_entry_alloc(rs, &reply);
1097 if (!(ret >= 0))
1098 #line 374
1099 (
1100 #line 374
1101 env_throw_bi(env, mfe_failure, "dns_query", _("DNS reply table full"))
1102 #line 374
1103 )
1104 #line 376
1105 ;
1106
1107 switch (type) {
1108 case DNS_TYPE_PTR:
1109 if (!(inet_aton(domain, &addr)))
1110 #line 380
1111 (
1112 #line 380
1113 env_throw_bi(env, mfe_invip, "dns_query", _("invalid IP: %s"),domain)
1114 #line 380
1115 )
1116 #line 382
1117 ;
1118 dnsstat = ptr_lookup(addr, reply);
1119 cmpfun = cmp_hostname;
1120 break;
1121
1122 case DNS_TYPE_A:
1123 dnsstat = resolve_host(domain, reply);
1124 break;
1125
1126 case DNS_TYPE_TXT:
1127 dnsstat = txt_lookup(domain, reply);
1128 break;
1129
1130 case DNS_TYPE_MX:
1131 dnsstat = mx_lookup(domain, ((__bi_argcnt > 3) ? resolve : 0), reply);
1132 break;
1133
1134 case DNS_TYPE_NS:
1135 dnsstat = ns_lookup(domain, ((__bi_argcnt > 3) ? resolve : 0), reply);
1136 break;
1137
1138 default:
1139 dns_reply_entry_release(rs, ret);
1140 (
1141 #line 405
1142 env_throw_bi(env, mfe_failure, "dns_query", _("unsupported type: %ld"),type)
1143 #line 405
1144 );
1145 #line 407
1146 }
1147
1148 stat = dns_to_mf_status(dnsstat);
1149
1150 if (!mf_resolved(stat)) {
1151 dns_reply_entry_release(rs, ret);
1152 (
1153 #line 413
1154 env_throw_bi(env, mf_status_to_exception(stat), "dns_query", _("cannot get %s records for %s"),dns_type_name[type],domain)
1155 #line 413
1156 );
1157 #line 416
1158 }
1159 if (stat == mf_not_found) {
1160 dns_reply_entry_release(rs, ret);
1161
1162 #line 419
1163 do {
1164 #line 419
1165 push(env, (STKVAL)(mft_number)(-1));
1166 #line 419
1167 goto endlab;
1168 #line 419
1169 } while (0);
1170 }
1171 if (sort) {
1172 size_t entry_size;
1173
1174 if (!cmpfun) {
1175 if (reply->type == dns_reply_str) {
1176 cmpfun = cmp_str;
1177 } else {
1178 cmpfun = cmp_ip;
1179 }
1180 }
1181 if (reply->type == dns_reply_str) {
1182 entry_size = sizeof(reply->data.str[0]);
1183 } else {
1184 entry_size = sizeof(reply->data.ip[0]);
1185 }
1186
1187 qsort(reply->data.ptr, reply->count, entry_size, cmpfun);
1188 }
1189
1190 #line 439
1191 do {
1192 #line 439
1193 push(env, (STKVAL)(mft_number)(ret));
1194 #line 439
1195 goto endlab;
1196 #line 439
1197 } while (0);
1198 }
1199 endlab:
1200 #line 441
1201 env_function_cleanup_flush(env, NULL);
1202 #line 441
1203 return;
1204 #line 441
1205 }
1206 #line 982 "../../src/builtin/snarf.m4"
1207
1208 #line 982
1209
1210 #line 982
1211
1212 #line 982
1213 void
1214 #line 982
dns_init_builtin(void)1215 dns_init_builtin(void)
1216 #line 982
1217 {
1218 #line 982
1219
1220 #line 982
1221 #line 27 "dns.bi"
1222 va_builtin_install_ex("primitive_hostname", bi_primitive_hostname, 0, dtype_string, 1, 0, 0|0, dtype_string);
1223 #line 43 "dns.bi"
1224 va_builtin_install_ex("primitive_resolve", bi_primitive_resolve, 0, dtype_string, 2, 1, 0|0, dtype_string, dtype_string);
1225 #line 64 "dns.bi"
1226 va_builtin_install_ex("primitive_hasmx", bi_primitive_hasmx, 0, dtype_number, 1, 0, 0|0, dtype_string);
1227 #line 110 "dns.bi"
1228 va_builtin_install_ex("primitive_ismx", bi_primitive_ismx, 0, dtype_number, 2, 0, 0|0, dtype_string, dtype_string);
1229 #line 133 "dns.bi"
1230 va_builtin_install_ex("relayed", bi_relayed, 0, dtype_number, 1, 0, 0|0, dtype_string);
1231 #line 139 "dns.bi"
1232 va_builtin_install_ex("ptr_validate", bi_ptr_validate, 0, dtype_number, 1, 0, 0|0, dtype_string);
1233 #line 157 "dns.bi"
1234 va_builtin_install_ex("primitive_hasns", bi_primitive_hasns, 0, dtype_number, 1, 0, 0|0, dtype_string);
1235 #line 254 "dns.bi"
1236 DNS_id = builtin_priv_register(dns_reply_storage_alloc, dns_reply_storage_destroy,
1237 #line 254
1238 NULL);
1239 #line 281 "dns.bi"
1240 va_builtin_install_ex("dns_reply_release", bi_dns_reply_release, 0, dtype_unspecified, 1, 0, 0|0, dtype_number);
1241 #line 291 "dns.bi"
1242 va_builtin_install_ex("dns_reply_count", bi_dns_reply_count, 0, dtype_number, 1, 0, 0|0, dtype_number);
1243 #line 309 "dns.bi"
1244 va_builtin_install_ex("dns_reply_string", bi_dns_reply_string, 0, dtype_string, 2, 0, 0|0, dtype_number, dtype_number);
1245 #line 328 "dns.bi"
1246 va_builtin_install_ex("dns_reply_ip", bi_dns_reply_ip, 0, dtype_string, 2, 0, 0|0, dtype_number, dtype_number);
1247 #line 362 "dns.bi"
1248 va_builtin_install_ex("dns_query", bi_dns_query, 0, dtype_number, 4, 2, 0|0, dtype_number, dtype_string, dtype_number, dtype_number);
1249
1250 #line 982 "../../src/builtin/snarf.m4"
1251
1252 #line 982
1253 }
1254 #line 982 "../../src/builtin/snarf.m4"
1255
1256