#line 945 "../../src/builtin/snarf.m4" /* -*- buffer-read-only: t -*- vi: set ro: THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT. */ #line 945 #ifdef HAVE_CONFIG_H #line 945 # include <config.h> #line 945 #endif #line 945 #include <sys/types.h> #line 945 #line 945 #include "mailfromd.h" #line 945 #include "prog.h" #line 945 #include "builtin.h" #line 945 #line 945 #line 985 "../../src/builtin/snarf.m4" /* End of snarf.m4 */ #line 1 "dns.bi" /* This file is part of Mailfromd. -*- c -*- Copyright (C) 2006-2020 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include "srvcfg.h" #include "global.h" void #line 26 bi_primitive_hostname(eval_environ_t env) #line 26 #line 26 #line 26 "dns.bi" { #line 26 #line 26 #line 26 #line 26 char * MFL_DATASEG string; #line 26 #line 26 get_string_arg(env, 0, &string); #line 26 #line 26 #line 26 adjust_stack(env, 1); #line 26 #line 26 #line 26 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 26 prog_trace(env, "primitive_hostname %s",string);; #line 26 { char *hbuf; mf_status stat; stat = resolve_ipstr(string, &hbuf); if (!(stat == mf_success)) #line 32 ( #line 32 env_throw_bi(env, mf_status_to_exception(stat), "primitive_hostname", _("cannot resolve IP %s"),string) #line 32 ) #line 35 ; pushs(env, hbuf); free(hbuf); } #line 40 env_function_cleanup_flush(env, NULL); #line 40 return; #line 40 } void #line 42 bi_primitive_resolve(eval_environ_t env) #line 42 #line 42 #line 42 "dns.bi" { #line 42 #line 42 #line 42 long __bi_argcnt; #line 42 char * MFL_DATASEG string; #line 42 char * MFL_DATASEG domain; #line 42 #line 42 get_string_arg(env, 1, &string); #line 42 get_string_arg(env, 2, &domain); #line 42 #line 42 get_numeric_arg(env, 0, &__bi_argcnt); #line 42 adjust_stack(env, __bi_argcnt + 1); #line 42 #line 42 #line 42 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 42 prog_trace(env, "primitive_resolve %s %s",string, ((__bi_argcnt > 1) ? domain : ""));; #line 42 { char *ipstr; mf_status stat; if (((__bi_argcnt > 1) ? domain : "")[0]) { stat = resolve_ipstr_domain(string, domain, &ipstr); if (!(stat == mf_success)) #line 49 ( #line 49 env_throw_bi(env, mf_status_to_exception(stat), "primitive_resolve", _("cannot resolve %s.%s"),string,domain) #line 49 ) #line 51 ; } else { stat = resolve_hostname(string, &ipstr); if (!(stat == mf_success)) #line 54 ( #line 54 env_throw_bi(env, mf_status_to_exception(stat), "primitive_resolve", _("cannot resolve %s"),string) #line 54 ) #line 56 ; } pushs(env, ipstr); free(ipstr); } #line 61 env_function_cleanup_flush(env, NULL); #line 61 return; #line 61 } static int ipaddr_cmp(const void *a, const void *b) { GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T*)a); GACOPYZ_UINT32_T ipb = ntohl(*(GACOPYZ_UINT32_T*)b); if (ipa < ipb) return -1; if (ipa > ipb) return 1; return 0; } void #line 75 bi_dns_getaddr(eval_environ_t env) #line 75 #line 75 #line 75 "dns.bi" { #line 75 #line 75 #line 75 #line 75 char * MFL_DATASEG string; #line 75 #line 75 get_string_arg(env, 0, &string); #line 75 #line 75 #line 75 adjust_stack(env, 1); #line 75 #line 75 #line 75 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 75 prog_trace(env, "dns_getaddr %s",string);; #line 75 { size_t i; dns_status dnstat; struct dns_reply r; dnstat = a_lookup(string, &r); switch (dnstat) { case dns_success: { heap_obstack_begin(env); qsort(r.data.ip, r.count, sizeof r.data.ip[0], ipaddr_cmp); for (i = 0; i < r.count; i++) { struct in_addr addr; char *q; addr.s_addr = r.data.ip[i]; q = inet_ntoa(addr); if (i > 0) do { char __c = ' '; heap_obstack_grow(env, &__c, 1); } while(0); #line 94 do { #line 94 char *__s = q; #line 94 heap_obstack_grow(env, __s, strlen(__s)); #line 94 } while (0); } dns_reply_free(&r); do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0); #line 98 do { #line 98 push(env, (STKVAL) (heap_obstack_finish(env))); #line 98 goto endlab; #line 98 } while (0); } case dns_not_found: #line 101 do { #line 101 pushs(env, ""); #line 101 goto endlab; #line 101 } while (0); default: ( #line 103 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(dnstat)), "dns_getaddr", _("failed to get A record for %s"),string) #line 103 ); #line 105 } } endlab: #line 107 env_function_cleanup_flush(env, NULL); #line 107 return; #line 107 } static int hostname_cmp(const void *a, const void *b) { return strcmp(*(const char**) a, *(const char**) b); } void #line 115 bi_dns_getname(eval_environ_t env) #line 115 #line 115 #line 115 "dns.bi" { #line 115 #line 115 #line 115 #line 115 char * MFL_DATASEG ipstr; #line 115 #line 115 get_string_arg(env, 0, &ipstr); #line 115 #line 115 #line 115 adjust_stack(env, 1); #line 115 #line 115 #line 115 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 115 prog_trace(env, "dns_getname %s",ipstr);; #line 115 { dns_status dnstat; struct in_addr addr; struct dns_reply r; if (!(inet_aton(ipstr, &addr))) #line 121 ( #line 121 env_throw_bi(env, mfe_invip, "dns_getname", _("invalid IP: %s"),ipstr) #line 121 ) #line 123 ; dnstat = ptr_lookup(addr, &r); switch (dnstat) { case dns_success: { size_t i; qsort(r.data.str, r.count, sizeof r.data.str[0], hostname_cmp); heap_obstack_begin(env); for (i = 0; i < r.count; i++) { if (i > 0) do { char __c = ' '; heap_obstack_grow(env, &__c, 1); } while(0); #line 136 do { #line 136 char *__s = (char*)r.data.str[i]; #line 136 heap_obstack_grow(env, __s, strlen(__s)); #line 136 } while (0); } do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0); dns_reply_free(&r); #line 141 do { #line 141 push(env, (STKVAL) (heap_obstack_finish(env))); #line 141 goto endlab; #line 141 } while (0); } case dns_not_found: #line 144 do { #line 144 pushs(env, ""); #line 144 goto endlab; #line 144 } while (0); default: ( #line 146 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(dnstat)), "dns_getname", _("failed to get PTR record for %s"),ipstr) #line 146 ); #line 148 } } endlab: #line 150 env_function_cleanup_flush(env, NULL); #line 150 return; #line 150 } void #line 152 bi_primitive_hasmx(eval_environ_t env) #line 152 #line 152 #line 152 "dns.bi" { #line 152 #line 152 #line 152 #line 152 char * string; #line 152 #line 152 get_string_arg(env, 0, &string); #line 152 #line 152 #line 152 adjust_stack(env, 1); #line 152 #line 152 #line 152 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 152 prog_trace(env, "primitive_hasmx %s",string);; #line 152 { struct dns_reply repl; mf_status mxstat; mxstat = dns_to_mf_status(mx_lookup(string, 0, &repl)); if (!(mxstat == mf_success || mxstat == mf_not_found)) #line 159 ( #line 159 env_throw_bi(env, mf_status_to_exception(mxstat), "primitive_hasmx", _("cannot get MX records for %s"),string) #line 159 ) #line 162 ; dns_reply_free(&repl); if (mxstat == mf_success) { #line 165 do { #line 165 push(env, (STKVAL)(mft_number)(1)); #line 165 goto endlab; #line 165 } while (0); } #line 167 do { #line 167 push(env, (STKVAL)(mft_number)(0)); #line 167 goto endlab; #line 167 } while (0); } endlab: #line 169 env_function_cleanup_flush(env, NULL); #line 169 return; #line 169 } void #line 171 bi_getmx(eval_environ_t env) #line 171 #line 171 #line 171 "dns.bi" { #line 171 #line 171 #line 171 long __bi_argcnt; #line 171 char * MFL_DATASEG domain; #line 171 long resolve; #line 171 #line 171 get_string_arg(env, 1, &domain); #line 171 get_numeric_arg(env, 2, &resolve); #line 171 #line 171 get_numeric_arg(env, 0, &__bi_argcnt); #line 171 adjust_stack(env, __bi_argcnt + 1); #line 171 #line 171 #line 171 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 171 prog_trace(env, "getmx %s %lu",domain, ((__bi_argcnt > 1) ? resolve : 0));; #line 171 { mf_status mxstat; struct dns_reply reply; int i; mxstat = dns_to_mf_status(mx_lookup(domain, ((__bi_argcnt > 1) ? resolve : 0), &reply)); if (!mf_resolved(mxstat)) { ( #line 180 env_throw_bi(env, mf_status_to_exception(mxstat), "getmx", _("cannot get MX records for %s"),domain) #line 180 ); #line 182 } if (mxstat == mf_not_found) { #line 184 do { #line 184 pushs(env, ""); #line 184 goto endlab; #line 184 } while (0); } else if (reply.type == dns_reply_ip) { heap_obstack_begin(env); for (i = 0; i < reply.count; i++) { struct in_addr s; s.s_addr = reply.data.ip[i]; if (i > 0) do { char __c = ' '; heap_obstack_grow(env, &__c, 1); } while(0); #line 192 do { #line 192 char *__s = inet_ntoa(s); #line 192 heap_obstack_grow(env, __s, strlen(__s)); #line 192 } while (0); } } else { heap_obstack_begin(env); for (i = 0; i < reply.count; i++) { if (i > 0) do { char __c = ' '; heap_obstack_grow(env, &__c, 1); } while(0); #line 199 do { #line 199 char *__s = reply.data.str[i]; #line 199 heap_obstack_grow(env, __s, strlen(__s)); #line 199 } while (0); } } do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0); dns_reply_free(&reply); #line 204 do { #line 204 push(env, (STKVAL) (heap_obstack_finish(env))); #line 204 goto endlab; #line 204 } while (0); } endlab: #line 206 env_function_cleanup_flush(env, NULL); #line 206 return; #line 206 } static dns_status resolve_host(const char *string, struct dns_reply *reply) { struct in_addr addr; if (inet_aton(string, &addr)) { dns_reply_init(reply, dns_reply_ip, 1); reply->data.ip[0] = addr.s_addr; return dns_success; } return a_lookup(string, reply); } static int dns_replies_intersect(struct dns_reply const *a, struct dns_reply const *b) { int i, j; if (a->type == b->type && a->type == dns_reply_ip) { for (i = 0; i < a->count; i++) for (j = 0; j < b->count; j++) if (a->data.ip[i] == b->data.ip[j]) return 1; } return 0; } void #line 235 bi_primitive_ismx(eval_environ_t env) #line 235 #line 235 #line 235 "dns.bi" { #line 235 #line 235 #line 235 #line 235 char * domain; #line 235 char * ipstr; #line 235 #line 235 get_string_arg(env, 0, &domain); #line 235 get_string_arg(env, 1, &ipstr); #line 235 #line 235 #line 235 adjust_stack(env, 2); #line 235 #line 235 #line 235 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 235 prog_trace(env, "primitive_ismx %s %s",domain, ipstr);; #line 235 { struct dns_reply areply, mxreply; dns_status status; int rc = 0; status = resolve_host(ipstr, &areply); if (!(status == dns_success)) #line 242 ( #line 242 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(status)), "primitive_ismx", _("cannot resolve host name %s"),ipstr) #line 242 ) #line 244 ; status = mx_lookup(domain, 1, &mxreply); if (status != dns_success) { dns_reply_free(&areply); ( #line 248 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(status)), "primitive_ismx", _("cannot get MXs for %s"),domain) #line 248 ); #line 250 } rc = dns_replies_intersect(&areply, &mxreply); dns_reply_free(&areply); dns_reply_free(&mxreply); #line 254 do { #line 254 push(env, (STKVAL)(mft_number)(rc)); #line 254 goto endlab; #line 254 } while (0); } endlab: #line 256 env_function_cleanup_flush(env, NULL); #line 256 return; #line 256 } void #line 258 bi_relayed(eval_environ_t env) #line 258 #line 258 #line 258 "dns.bi" { #line 258 #line 258 #line 258 #line 258 char * s; #line 258 #line 258 get_string_arg(env, 0, &s); #line 258 #line 258 #line 258 adjust_stack(env, 1); #line 258 #line 258 #line 258 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 258 prog_trace(env, "relayed %s",s);; #line 258 { #line 260 do { #line 260 push(env, (STKVAL)(mft_number)(relayed_domain_p(s))); #line 260 goto endlab; #line 260 } while (0); } endlab: #line 262 env_function_cleanup_flush(env, NULL); #line 262 return; #line 262 } void #line 264 bi_ptr_validate(eval_environ_t env) #line 264 #line 264 #line 264 "dns.bi" { #line 264 #line 264 #line 264 #line 264 char * s; #line 264 #line 264 get_string_arg(env, 0, &s); #line 264 #line 264 #line 264 adjust_stack(env, 1); #line 264 #line 264 #line 264 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 264 prog_trace(env, "ptr_validate %s",s);; #line 264 { int rc, res; switch (rc = ptr_validate(s, NULL)) { case dns_success: res = 1; break; case dns_not_found: res = 0; break; default: ( #line 275 env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(rc)), "ptr_validate", _("failed to get PTR record for %s"),s) #line 275 ); #line 277 } #line 278 do { #line 278 push(env, (STKVAL)(mft_number)(res)); #line 278 goto endlab; #line 278 } while (0); } endlab: #line 280 env_function_cleanup_flush(env, NULL); #line 280 return; #line 280 } void #line 282 bi_primitive_hasns(eval_environ_t env) #line 282 #line 282 #line 282 "dns.bi" { #line 282 #line 282 #line 282 #line 282 char * dom; #line 282 #line 282 get_string_arg(env, 0, &dom); #line 282 #line 282 #line 282 adjust_stack(env, 1); #line 282 #line 282 #line 282 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 282 prog_trace(env, "primitive_hasns %s",dom);; #line 282 { struct dns_reply repl; mf_status stat = dns_to_mf_status(ns_lookup(dom, 0, &repl)); if (!(stat == mf_success || stat == mf_not_found)) #line 286 ( #line 286 env_throw_bi(env, mf_status_to_exception(stat), "primitive_hasns", _("cannot get NS records for %s"),dom) #line 286 ) #line 289 ; dns_reply_free(&repl); if (stat == mf_success) { #line 292 do { #line 292 push(env, (STKVAL)(mft_number)(1)); #line 292 goto endlab; #line 292 } while (0); } #line 294 do { #line 294 push(env, (STKVAL)(mft_number)(0)); #line 294 goto endlab; #line 294 } while (0); } endlab: #line 296 env_function_cleanup_flush(env, NULL); #line 296 return; #line 296 } static int cmp_ip(void const *a, void const *b) { GACOPYZ_UINT32_T ipa = *(GACOPYZ_UINT32_T const *)a; GACOPYZ_UINT32_T ipb = *(GACOPYZ_UINT32_T const *)b; if (ipa < ipb) return -1; if (ipa > ipb) return 1; return 0; } static int cmp_str(void const *a, void const *b) { char * const *stra = a; char * const *strb = b; return strcmp(*stra, *strb); } void #line 318 bi_getns(eval_environ_t env) #line 318 #line 318 #line 318 "dns.bi" { #line 318 #line 318 #line 318 long __bi_argcnt; #line 318 char * MFL_DATASEG domain; #line 318 long resolve; #line 318 long sort; #line 318 #line 318 get_string_arg(env, 1, &domain); #line 318 get_numeric_arg(env, 2, &resolve); #line 318 get_numeric_arg(env, 3, &sort); #line 318 #line 318 get_numeric_arg(env, 0, &__bi_argcnt); #line 318 adjust_stack(env, __bi_argcnt + 1); #line 318 #line 318 #line 318 if (builtin_module_trace(BUILTIN_IDX_dns)) #line 318 prog_trace(env, "getns %s %lu %lu",domain, ((__bi_argcnt > 1) ? resolve : 0), ((__bi_argcnt > 2) ? sort : 0));; #line 318 { mf_status stat; struct dns_reply reply; int i; stat = dns_to_mf_status(ns_lookup(domain, ((__bi_argcnt > 1) ? resolve : 0), &reply)); if (!mf_resolved(stat)) { ( #line 327 env_throw_bi(env, mf_status_to_exception(stat), "getns", _("cannot get MX records for %s"),domain) #line 327 ); #line 329 } if (stat == mf_not_found) { #line 331 do { #line 331 pushs(env, ""); #line 331 goto endlab; #line 331 } while (0); } heap_obstack_begin(env); if (reply.type == dns_reply_ip) { if (sort) qsort(reply.data.ip, reply.count, sizeof(reply.data.ip[0]), cmp_ip); for (i = 0; i < reply.count; i++) { struct in_addr s; s.s_addr = reply.data.ip[i]; if (i > 0) do { char __c = ' '; heap_obstack_grow(env, &__c, 1); } while(0); #line 346 do { #line 346 char *__s = inet_ntoa(s); #line 346 heap_obstack_grow(env, __s, strlen(__s)); #line 346 } while (0); } } else { if (sort) qsort(reply.data.str, reply.count, sizeof(reply.data.str[0]), cmp_str); for (i = 0; i < reply.count; i++) { if (i > 0) do { char __c = ' '; heap_obstack_grow(env, &__c, 1); } while(0); #line 357 do { #line 357 char *__s = reply.data.str[i]; #line 357 heap_obstack_grow(env, __s, strlen(__s)); #line 357 } while (0); } } do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0); dns_reply_free(&reply); #line 362 do { #line 362 push(env, (STKVAL) (heap_obstack_finish(env))); #line 362 goto endlab; #line 362 } while (0); } endlab: #line 364 env_function_cleanup_flush(env, NULL); #line 364 return; #line 364 } #line 945 "../../src/builtin/snarf.m4" #line 945 #line 945 #line 945 void #line 945 dns_init_builtin(void) #line 945 { #line 945 #line 945 #line 26 "dns.bi" va_builtin_install_ex("primitive_hostname", bi_primitive_hostname, 0, dtype_string, 1, 0, 0|0, dtype_string); #line 42 "dns.bi" va_builtin_install_ex("primitive_resolve", bi_primitive_resolve, 0, dtype_string, 2, 1, 0|0, dtype_string, dtype_string); #line 75 "dns.bi" va_builtin_install_ex("dns_getaddr", bi_dns_getaddr, 0, dtype_string, 1, 0, 0|0, dtype_string); #line 115 "dns.bi" va_builtin_install_ex("dns_getname", bi_dns_getname, 0, dtype_string, 1, 0, 0|0, dtype_string); #line 152 "dns.bi" va_builtin_install_ex("primitive_hasmx", bi_primitive_hasmx, 0, dtype_number, 1, 0, 0|0, dtype_string); #line 171 "dns.bi" va_builtin_install_ex("getmx", bi_getmx, 0, dtype_string, 2, 1, 0|0, dtype_string, dtype_number); #line 235 "dns.bi" va_builtin_install_ex("primitive_ismx", bi_primitive_ismx, 0, dtype_number, 2, 0, 0|0, dtype_string, dtype_string); #line 258 "dns.bi" va_builtin_install_ex("relayed", bi_relayed, 0, dtype_number, 1, 0, 0|0, dtype_string); #line 264 "dns.bi" va_builtin_install_ex("ptr_validate", bi_ptr_validate, 0, dtype_number, 1, 0, 0|0, dtype_string); #line 282 "dns.bi" va_builtin_install_ex("primitive_hasns", bi_primitive_hasns, 0, dtype_number, 1, 0, 0|0, dtype_string); #line 318 "dns.bi" va_builtin_install_ex("getns", bi_getns, 0, dtype_string, 3, 2, 0|0, dtype_string, dtype_number, dtype_number); #line 945 "../../src/builtin/snarf.m4" #line 945 } #line 945 "../../src/builtin/snarf.m4"