#line 982 "../../src/builtin/snarf.m4"
/* -*- buffer-read-only: t -*- vi: set ro:
   THIS FILE IS GENERATED AUTOMATICALLY.  PLEASE DO NOT EDIT.
*/
#line 982
#ifdef HAVE_CONFIG_H
#line 982
# include <config.h>
#line 982
#endif
#line 982
#include <sys/types.h>
#line 982

#line 982
#include "mailfromd.h"
#line 982
#include "prog.h"
#line 982
#include "builtin.h"
#line 982

#line 982

#line 1022 "../../src/builtin/snarf.m4"

/* End of snarf.m4 */
#line 1 "dns.bi"
/* This file is part of Mailfromd.             -*- c -*-
   Copyright (C) 2006-2022 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 <limits.h>
#include "srvcfg.h"
#include "global.h"

void
#line 27
bi_primitive_hostname(eval_environ_t env)
#line 27

#line 27

#line 27 "dns.bi"
{
#line 27
	
#line 27

#line 27

#line 27
char * MFL_DATASEG string;
#line 27
        
#line 27
get_string_arg(env, 0, &string);
#line 27
        
#line 27

#line 27
        adjust_stack(env, 1);
#line 27

#line 27

#line 27
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 27
		prog_trace(env, "primitive_hostname %s",string);;
#line 27

{
	char *hbuf;
	mf_status stat;

	stat = resolve_ipstr(string, &hbuf);
		if (!(stat == mf_success))
#line 33
		(
#line 33
	env_throw_bi(env, mf_status_to_exception(stat), "primitive_hostname", _("cannot resolve IP %s"),string)
#line 33
)
#line 36
;
	
	pushs(env, hbuf);
	free(hbuf);
}

#line 41
        env_function_cleanup_flush(env, NULL);
#line 41
	return;
#line 41
}

void
#line 43
bi_primitive_resolve(eval_environ_t env)
#line 43

#line 43

#line 43 "dns.bi"
{
#line 43
	
#line 43

#line 43
long __bi_argcnt;
#line 43
char * MFL_DATASEG string;
#line 43
        char * MFL_DATASEG domain;
#line 43
        
#line 43
get_string_arg(env, 1, &string);
#line 43
        get_string_arg(env, 2, &domain);
#line 43
        
#line 43
get_numeric_arg(env, 0, &__bi_argcnt);
#line 43
        adjust_stack(env, __bi_argcnt + 1);
#line 43

#line 43

#line 43
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 43
		prog_trace(env, "primitive_resolve %s %s",string, ((__bi_argcnt > 1) ? domain : ""));;
#line 43

{
	char *ipstr;
	mf_status stat;
	
	if (((__bi_argcnt > 1) ? domain : "")[0]) {
		stat = resolve_ipstr_domain(string, domain, &ipstr);
			if (!(stat == mf_success))
#line 50
		(
#line 50
	env_throw_bi(env, mf_status_to_exception(stat), "primitive_resolve", _("cannot resolve %s.%s"),string,domain)
#line 50
)
#line 52
;
	} else {
		stat = resolve_hostname(string, &ipstr);
			if (!(stat == mf_success))
#line 55
		(
#line 55
	env_throw_bi(env, mf_status_to_exception(stat), "primitive_resolve", _("cannot resolve %s"),string)
#line 55
)
#line 57
;
	}
	pushs(env, ipstr);
	free(ipstr);
}

#line 62
        env_function_cleanup_flush(env, NULL);
#line 62
	return;
#line 62
}

void
#line 64
bi_primitive_hasmx(eval_environ_t env)
#line 64

#line 64

#line 64 "dns.bi"
{
#line 64
	
#line 64

#line 64

#line 64
char *  string;
#line 64
        
#line 64
get_string_arg(env, 0, &string);
#line 64
        
#line 64

#line 64
        adjust_stack(env, 1);
#line 64

#line 64

#line 64
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 64
		prog_trace(env, "primitive_hasmx %s",string);;
#line 64

{
	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 71
		(
#line 71
	env_throw_bi(env, mf_status_to_exception(mxstat), "primitive_hasmx", _("cannot get MX records for %s"),string)
#line 71
)
#line 74
;
	dns_reply_free(&repl);
	if (mxstat == mf_success) {
		
#line 77
do {
#line 77
  push(env, (STKVAL)(mft_number)(1));
#line 77
  goto endlab;
#line 77
} while (0);
	}
	
#line 79
do {
#line 79
  push(env, (STKVAL)(mft_number)(0));
#line 79
  goto endlab;
#line 79
} while (0);
}
endlab:
#line 81
        env_function_cleanup_flush(env, NULL);
#line 81
	return;
#line 81
}

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 110
bi_primitive_ismx(eval_environ_t env)
#line 110

#line 110

#line 110 "dns.bi"
{
#line 110
	
#line 110

#line 110

#line 110
char *  domain;
#line 110
        char *  ipstr;
#line 110
        
#line 110
get_string_arg(env, 0, &domain);
#line 110
        get_string_arg(env, 1, &ipstr);
#line 110
        
#line 110

#line 110
        adjust_stack(env, 2);
#line 110

#line 110

#line 110
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 110
		prog_trace(env, "primitive_ismx %s %s",domain, ipstr);;
#line 110

{
	struct dns_reply areply, mxreply;
	dns_status status;
	int rc = 0;

	status = resolve_host(ipstr, &areply);
		if (!(status == dns_success))
#line 117
		(
#line 117
	env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(status)), "primitive_ismx", _("cannot resolve host name %s"),ipstr)
#line 117
)
#line 119
;
	status = mx_lookup(domain, 1, &mxreply);
	if (status != dns_success) {
		dns_reply_free(&areply);
		(
#line 123
	env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(status)), "primitive_ismx", _("cannot get MXs for %s"),domain)
#line 123
);
#line 125
	}
	rc = dns_replies_intersect(&areply, &mxreply);
	dns_reply_free(&areply);
	dns_reply_free(&mxreply);
	
#line 129
do {
#line 129
  push(env, (STKVAL)(mft_number)(rc));
#line 129
  goto endlab;
#line 129
} while (0);
}
endlab:
#line 131
        env_function_cleanup_flush(env, NULL);
#line 131
	return;
#line 131
}

void
#line 133
bi_relayed(eval_environ_t env)
#line 133

#line 133

#line 133 "dns.bi"
{
#line 133
	
#line 133

#line 133

#line 133
char *  s;
#line 133
        
#line 133
get_string_arg(env, 0, &s);
#line 133
        
#line 133

#line 133
        adjust_stack(env, 1);
#line 133

#line 133

#line 133
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 133
		prog_trace(env, "relayed %s",s);;
#line 133

{
	
#line 135
do {
#line 135
  push(env, (STKVAL)(mft_number)(relayed_domain_p(s)));
#line 135
  goto endlab;
#line 135
} while (0);
}
endlab:
#line 137
        env_function_cleanup_flush(env, NULL);
#line 137
	return;
#line 137
}

void
#line 139
bi_ptr_validate(eval_environ_t env)
#line 139

#line 139

#line 139 "dns.bi"
{
#line 139
	
#line 139

#line 139

#line 139
char *  s;
#line 139
        
#line 139
get_string_arg(env, 0, &s);
#line 139
        
#line 139

#line 139
        adjust_stack(env, 1);
#line 139

#line 139

#line 139
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 139
		prog_trace(env, "ptr_validate %s",s);;
#line 139

{
	int rc, res;
	switch (rc = ptr_validate(s, NULL)) {
	case dns_success:
		res = 1;
		break;
	case dns_not_found:
		res = 0;
		break;
	default:
		(
#line 150
	env_throw_bi(env, mf_status_to_exception(dns_to_mf_status(rc)), "ptr_validate", _("failed to get PTR record for %s"),s)
#line 150
);
#line 152
	}
	
#line 153
do {
#line 153
  push(env, (STKVAL)(mft_number)(res));
#line 153
  goto endlab;
#line 153
} while (0);
}
endlab:
#line 155
        env_function_cleanup_flush(env, NULL);
#line 155
	return;
#line 155
}

void
#line 157
bi_primitive_hasns(eval_environ_t env)
#line 157

#line 157

#line 157 "dns.bi"
{
#line 157
	
#line 157

#line 157

#line 157
char *  dom;
#line 157
        
#line 157
get_string_arg(env, 0, &dom);
#line 157
        
#line 157

#line 157
        adjust_stack(env, 1);
#line 157

#line 157

#line 157
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 157
		prog_trace(env, "primitive_hasns %s",dom);;
#line 157

{
	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 161
		(
#line 161
	env_throw_bi(env, mf_status_to_exception(stat), "primitive_hasns", _("cannot get NS records for %s"),dom)
#line 161
)
#line 164
;
	dns_reply_free(&repl);
	if (stat == mf_success) {
		
#line 167
do {
#line 167
  push(env, (STKVAL)(mft_number)(1));
#line 167
  goto endlab;
#line 167
} while (0);
	}
	
#line 169
do {
#line 169
  push(env, (STKVAL)(mft_number)(0));
#line 169
  goto endlab;
#line 169
} while (0);
}
endlab:
#line 171
        env_function_cleanup_flush(env, NULL);
#line 171
	return;
#line 171
}

static int
cmp_ip(void const *a, void const *b)
{
	GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T const *)a);
	GACOPYZ_UINT32_T ipb = ntohl(*(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);
}

static int
cmp_hostname(const void *a, const void *b)
{
	return strcasecmp(*(const char**) a, *(const char**) b);
}

typedef long DNS_REPLY_COUNT;
#define DNS_REPLY_MAX LONG_MAX

struct dns_reply_storage {
	DNS_REPLY_COUNT reply_count;
	size_t reply_max;
	struct dns_reply *reply_tab;
};

static inline int
dns_reply_entry_unused(struct dns_reply_storage *rs, DNS_REPLY_COUNT n)
{
	return n == -1 || rs->reply_tab[n].type == -1;
}

static inline void
dns_reply_entry_release(struct dns_reply_storage *rs, DNS_REPLY_COUNT n)
{
	rs->reply_tab[n].type = -1;
}

static inline struct dns_reply *
dns_reply_entry_locate(struct dns_reply_storage *rs, DNS_REPLY_COUNT n)
{
	if (n < 0 || n >= rs->reply_count || dns_reply_entry_unused(rs, n))
		return NULL;
	return &rs->reply_tab[n];
}

static void *
dns_reply_storage_alloc(void)
{
	struct dns_reply_storage *rs = mu_alloc(sizeof(*rs));
	rs->reply_count = 0;
	rs->reply_max = 0;
	rs->reply_tab = NULL;
	return rs;
}

static void
dns_reply_storage_destroy(void *data)
{
	struct dns_reply_storage *rs = data;
	DNS_REPLY_COUNT i;

	for (i = 0; i < rs->reply_count; i++) {
		if (!dns_reply_entry_unused(rs, i)) {
			dns_reply_free(&rs->reply_tab[i]);
			dns_reply_entry_release(rs, i);
		}
	}
	free(rs->reply_tab);
	free(rs);
}


#line 254

#line 254
static int DNS_id;
#line 254 "dns.bi"


static inline DNS_REPLY_COUNT
dns_reply_entry_alloc(struct dns_reply_storage *rs,
		      struct dns_reply **return_reply)
{
	DNS_REPLY_COUNT i;
	
	for (i = 0; i < rs->reply_count; i++) {
		if (dns_reply_entry_unused(rs, i)) {
			*return_reply = &rs->reply_tab[i];
			return i;
		}
	}
	if (rs->reply_count == DNS_REPLY_MAX)
		return -1;
	if (rs->reply_count == rs->reply_max) {
		size_t n = rs->reply_max;
		rs->reply_tab = mu_2nrealloc(rs->reply_tab, &rs->reply_max,
					     sizeof(rs->reply_tab[0]));
		for (; n < rs->reply_max; n++)
			dns_reply_entry_release(rs, n);
	}
	*return_reply = &rs->reply_tab[rs->reply_count];
	return rs->reply_count++;
}

void
#line 281
bi_dns_reply_release(eval_environ_t env)
#line 281

#line 281

#line 281 "dns.bi"
{
#line 281
	
#line 281

#line 281

#line 281
long  n;
#line 281
        
#line 281
get_numeric_arg(env, 0, &n);
#line 281
        
#line 281

#line 281
        adjust_stack(env, 1);
#line 281

#line 281

#line 281
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 281
		prog_trace(env, "dns_reply_release %lu",n);;
#line 281

{
	struct dns_reply_storage *repl = env_get_builtin_priv(env,DNS_id);
	if (!dns_reply_entry_unused(repl, n)) {
		dns_reply_free(&repl->reply_tab[n]);
		dns_reply_entry_release(repl, n);
	}
}

#line 289
        env_function_cleanup_flush(env, NULL);
#line 289
	return;
#line 289
}

void
#line 291
bi_dns_reply_count(eval_environ_t env)
#line 291

#line 291

#line 291 "dns.bi"
{
#line 291
	
#line 291

#line 291

#line 291
long  n;
#line 291
        
#line 291
get_numeric_arg(env, 0, &n);
#line 291
        
#line 291

#line 291
        adjust_stack(env, 1);
#line 291

#line 291

#line 291
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 291
		prog_trace(env, "dns_reply_count %lu",n);;
#line 291

{
	struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
	struct dns_reply *reply;
	
	if (n == -1)
		
#line 297
do {
#line 297
  push(env, (STKVAL)(mft_number)(0));
#line 297
  goto endlab;
#line 297
} while (0);
	if (n < 0)
		(
#line 299
	env_throw_bi(env, mfe_failure, "dns_reply_count", _("invalid DNS reply number: %ld"),n)
#line 299
);
#line 301
	reply = dns_reply_entry_locate(rs, n);
	if (!reply)
		(
#line 303
	env_throw_bi(env, mfe_failure, "dns_reply_count", _("no such reply: %ld"),n)
#line 303
);
#line 305
	
#line 305
do {
#line 305
  push(env, (STKVAL)(mft_number)(reply->count));
#line 305
  goto endlab;
#line 305
} while (0);
}
endlab:
#line 307
        env_function_cleanup_flush(env, NULL);
#line 307
	return;
#line 307
}

void
#line 309
bi_dns_reply_string(eval_environ_t env)
#line 309

#line 309

#line 309 "dns.bi"
{
#line 309
	
#line 309

#line 309

#line 309
long  n;
#line 309
        long  i;
#line 309
        
#line 309
get_numeric_arg(env, 0, &n);
#line 309
        get_numeric_arg(env, 1, &i);
#line 309
        
#line 309

#line 309
        adjust_stack(env, 2);
#line 309

#line 309

#line 309
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 309
		prog_trace(env, "dns_reply_string %lu %lu",n, i);;
#line 309

{
	struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
	struct dns_reply *reply = dns_reply_entry_locate(rs, n);
	if (!reply)
		(
#line 314
	env_throw_bi(env, mfe_failure, "dns_reply_string", _("no such reply: %ld"),n)
#line 314
);
#line 316
	if (i < 0 || i >= reply->count)
		(
#line 317
	env_throw_bi(env, mfe_range, "dns_reply_string", _("index out of range: %ld"),i)
#line 317
);
#line 319
	if (reply->type == dns_reply_ip) {
		struct in_addr addr;
		addr.s_addr = reply->data.ip[i];
		
#line 322
do {
#line 322
  pushs(env, inet_ntoa(addr));
#line 322
  goto endlab;
#line 322
} while (0);
	}
	
#line 324
do {
#line 324
  pushs(env, reply->data.str[i]);
#line 324
  goto endlab;
#line 324
} while (0);
}
endlab:
#line 326
        env_function_cleanup_flush(env, NULL);
#line 326
	return;
#line 326
}

void
#line 328
bi_dns_reply_ip(eval_environ_t env)
#line 328

#line 328

#line 328 "dns.bi"
{
#line 328
	
#line 328

#line 328

#line 328
long  n;
#line 328
        long  i;
#line 328
        
#line 328
get_numeric_arg(env, 0, &n);
#line 328
        get_numeric_arg(env, 1, &i);
#line 328
        
#line 328

#line 328
        adjust_stack(env, 2);
#line 328

#line 328

#line 328
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 328
		prog_trace(env, "dns_reply_ip %lu %lu",n, i);;
#line 328

{
	struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
	struct dns_reply *reply = dns_reply_entry_locate(rs, n);
	if (!reply)
		(
#line 333
	env_throw_bi(env, mfe_failure, "dns_reply_ip", _("no such reply: %ld"),n)
#line 333
);
#line 335
	if (i < 0 || i >= reply->count)
		(
#line 336
	env_throw_bi(env, mfe_range, "dns_reply_ip", _("index out of range: %ld"),i)
#line 336
);
#line 338
	if (reply->type == dns_reply_str) {
		(
#line 339
	env_throw_bi(env, mfe_failure, "dns_reply_ip", _("can't use dns_reply_ip on string replies"))
#line 339
);
#line 341
	}
	
#line 342
do {
#line 342
  pushs(env, reply->data.str[i]);
#line 342
  goto endlab;
#line 342
} while (0);
}
endlab:
#line 344
        env_function_cleanup_flush(env, NULL);
#line 344
	return;
#line 344
}

enum {
	DNS_TYPE_A = 1,
	DNS_TYPE_NS = 2,
	DNS_TYPE_PTR = 12,	
	DNS_TYPE_MX = 15,
	DNS_TYPE_TXT = 16,
};

static char *dns_type_name[] = {
	[DNS_TYPE_A] = "a",
	[DNS_TYPE_NS] = "ns",
	[DNS_TYPE_PTR] = "ptr",	
	[DNS_TYPE_MX] = "mx",
	[DNS_TYPE_TXT] = "txt"
};

void
#line 362
bi_dns_query(eval_environ_t env)
#line 362

#line 362

#line 362 "dns.bi"
{
#line 362
	
#line 362

#line 362
long __bi_argcnt;
#line 362
long  type;
#line 362
        char *  domain;
#line 362
        long  sort;
#line 362
        long  resolve;
#line 362
        
#line 362
get_numeric_arg(env, 1, &type);
#line 362
        get_string_arg(env, 2, &domain);
#line 362
        get_numeric_arg(env, 3, &sort);
#line 362
        get_numeric_arg(env, 4, &resolve);
#line 362
        
#line 362
get_numeric_arg(env, 0, &__bi_argcnt);
#line 362
        adjust_stack(env, __bi_argcnt + 1);
#line 362

#line 362

#line 362
	if (builtin_module_trace(BUILTIN_IDX_dns))
#line 362
		prog_trace(env, "dns_query %lu %s %lu %lu",type, domain, ((__bi_argcnt > 2) ? sort : 0), ((__bi_argcnt > 3) ? resolve : 0));;

{
	struct dns_reply_storage *rs = env_get_builtin_priv(env,DNS_id);
	dns_status dnsstat;
	mf_status stat;
	DNS_REPLY_COUNT ret;
	struct dns_reply *reply;
	int (*cmpfun)(const void *, const void *) = NULL;
	struct in_addr addr;
	
	ret = dns_reply_entry_alloc(rs, &reply);
		if (!(ret >= 0))
#line 374
		(
#line 374
	env_throw_bi(env, mfe_failure, "dns_query", _("DNS reply table full"))
#line 374
)
#line 376
;
	
	switch (type) {
	case DNS_TYPE_PTR:
			if (!(inet_aton(domain, &addr)))
#line 380
		(
#line 380
	env_throw_bi(env, mfe_invip, "dns_query", _("invalid IP: %s"),domain)
#line 380
)
#line 382
;
		dnsstat = ptr_lookup(addr, reply);
		cmpfun = cmp_hostname;
		break;
		
	case DNS_TYPE_A:
		dnsstat = resolve_host(domain, reply);
		break;
		
	case DNS_TYPE_TXT:
		dnsstat = txt_lookup(domain, reply);
		break;
		
	case DNS_TYPE_MX:
		dnsstat = mx_lookup(domain, ((__bi_argcnt > 3) ? resolve : 0), reply);
		break;
		
	case DNS_TYPE_NS:
		dnsstat = ns_lookup(domain, ((__bi_argcnt > 3) ? resolve : 0), reply);
		break;

	default:
		dns_reply_entry_release(rs, ret);		
		(
#line 405
	env_throw_bi(env, mfe_failure, "dns_query", _("unsupported type: %ld"),type)
#line 405
);
#line 407
	}
	
	stat = dns_to_mf_status(dnsstat);

	if (!mf_resolved(stat)) {
		dns_reply_entry_release(rs, ret);
		(
#line 413
	env_throw_bi(env, mf_status_to_exception(stat), "dns_query", _("cannot get %s records for %s"),dns_type_name[type],domain)
#line 413
);
#line 416
	}
	if (stat == mf_not_found) {
		dns_reply_entry_release(rs, ret);
		
#line 419
do {
#line 419
  push(env, (STKVAL)(mft_number)(-1));
#line 419
  goto endlab;
#line 419
} while (0);
	}
	if (sort) {
		size_t entry_size;
		
		if (!cmpfun) {
			if (reply->type == dns_reply_str) {
				cmpfun = cmp_str;
			} else {
				cmpfun = cmp_ip;
			}
		}
		if (reply->type == dns_reply_str) {
			entry_size = sizeof(reply->data.str[0]);
		} else {
			entry_size = sizeof(reply->data.ip[0]);
		}
		
		qsort(reply->data.ptr, reply->count, entry_size, cmpfun);
	}
	
#line 439
do {
#line 439
  push(env, (STKVAL)(mft_number)(ret));
#line 439
  goto endlab;
#line 439
} while (0);
}
endlab:
#line 441
        env_function_cleanup_flush(env, NULL);
#line 441
	return;
#line 441
}
#line 982 "../../src/builtin/snarf.m4"

#line 982

#line 982

#line 982
void
#line 982
dns_init_builtin(void)
#line 982
{
#line 982
	
#line 982
	#line 27 "dns.bi"
va_builtin_install_ex("primitive_hostname", bi_primitive_hostname, 0, dtype_string, 1, 0, 0|0, dtype_string);
#line 43 "dns.bi"
va_builtin_install_ex("primitive_resolve", bi_primitive_resolve, 0, dtype_string, 2, 1, 0|0, dtype_string, dtype_string);
#line 64 "dns.bi"
va_builtin_install_ex("primitive_hasmx", bi_primitive_hasmx, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 110 "dns.bi"
va_builtin_install_ex("primitive_ismx", bi_primitive_ismx, 0, dtype_number, 2, 0, 0|0, dtype_string, dtype_string);
#line 133 "dns.bi"
va_builtin_install_ex("relayed", bi_relayed, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 139 "dns.bi"
va_builtin_install_ex("ptr_validate", bi_ptr_validate, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 157 "dns.bi"
va_builtin_install_ex("primitive_hasns", bi_primitive_hasns, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 254 "dns.bi"
DNS_id = builtin_priv_register(dns_reply_storage_alloc, dns_reply_storage_destroy,
#line 254
NULL);
#line 281 "dns.bi"
va_builtin_install_ex("dns_reply_release", bi_dns_reply_release, 0, dtype_unspecified, 1, 0, 0|0, dtype_number);
#line 291 "dns.bi"
va_builtin_install_ex("dns_reply_count", bi_dns_reply_count, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 309 "dns.bi"
va_builtin_install_ex("dns_reply_string", bi_dns_reply_string, 0, dtype_string, 2, 0, 0|0, dtype_number, dtype_number);
#line 328 "dns.bi"
va_builtin_install_ex("dns_reply_ip", bi_dns_reply_ip, 0, dtype_string, 2, 0, 0|0, dtype_number, dtype_number);
#line 362 "dns.bi"
va_builtin_install_ex("dns_query", bi_dns_query, 0, dtype_number, 4, 2, 0|0, dtype_number, dtype_string, dtype_number, dtype_number);

#line 982 "../../src/builtin/snarf.m4"
	
#line 982
}
#line 982 "../../src/builtin/snarf.m4"

