/*
 * Copyright (c) 2002-2006 Sendmail, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: dnsmgr.c,v 1.25 2007/01/13 21:26:31 ca Exp $")
#include "sm/ctype.h"
#include "sm/dns.h"
#include "sm/dns-int.h"
#include "sm/dnstsk.h"
#include "dns.h"

/*
**  DNS_MGR_CTX_DEL -- delete a DNS task
**
**	Parameters:
**		dns_mgr_ctx -- DNS manager context
**
**	Return value:
**		usual sm_error code
*/

sm_ret_T
dns_mgr_ctx_del(dns_mgr_ctx_P dns_mgr_ctx)
{
	uint u;

	if (NULL == dns_mgr_ctx)
		return SM_SUCCESS;
	for (u = 0; u < dns_mgr_ctx->dnsmgr_ntsks; u++) {
		if (dns_mgr_ctx->dnsmgr_tskstatus[u] >= DNSTSK_ST_INIT)
			dns_tsk_del(dns_mgr_ctx->dnsmgr_dnstsks[u]);
	}

#if MTA_USE_PTHREADS
	(void) pthread_mutex_destroy(&dns_mgr_ctx->dnsmgr_mutex);
#endif
	bht_destroy(dns_mgr_ctx->dnsmgr_req_ht, dns_req_del, NULL);
	sm_free_size(dns_mgr_ctx, sizeof(*dns_mgr_ctx));
	return SM_SUCCESS;
}

/*
**  DNS_MGR_CTX_NEW -- make a DNS manager context
**
**	Parameters:
**		flags -- flags
**		timeout -- query timeout
**		htsize -- size of hash table (0: use default)
**		htlimit -- maximum size of hash table (0: use default)
**		pdns_mgr_ctx -- (pointer to) DNS manager context (output)
**
**	Return value:
**		usual sm_error code
*/

sm_ret_T
dns_mgr_ctx_new(uint flags, uint timeout, uint htsize, uint htlimit, dns_mgr_ctx_P *pdns_mgr_ctx)
{
	sm_ret_T ret;
#if MTA_USE_PTHREADS
	int r;
	uint u;
#endif /* MTA_USE_PTHREADS */
	dns_mgr_ctx_P dns_mgr_ctx;

	SM_REQUIRE(pdns_mgr_ctx != NULL);

	dns_mgr_ctx = (dns_mgr_ctx_P) sm_zalloc(sizeof(*dns_mgr_ctx));
	if (NULL == dns_mgr_ctx)
		return sm_error_temp(SM_EM_DNS, ENOMEM);
	dns_mgr_ctx->dnsmgr_flags = flags;
	dns_mgr_ctx->dnsmgr_timeout = timeout;
	if (0 == htsize)
		htsize = DNS_HT_SIZE;
	if (0 == htlimit)
		htlimit = DNS_HT_MAX;
	dns_mgr_ctx->dnsmgr_req_ht = bht_new(htsize, htlimit);
	if (NULL == dns_mgr_ctx->dnsmgr_req_ht) {
		ret = sm_error_temp(SM_EM_DNS, ENOMEM);
		goto error;
	}

	DNSIRQL_INIT(dns_mgr_ctx);
	DNSWRQL_INIT(dns_mgr_ctx);
	dns_mgr_ctx->dnsmgr_ntsks = 0;
#if MTA_USE_PTHREADS
	for (u = 0; u < SM_DNS_MAX_TSKS; u++) {
		dns_mgr_ctx->dnsmgr_tsk[u] = NULL;
		dns_mgr_ctx->dnsmgr_tskstatus[u] = DNSTSK_ST_NONE;
	}
	dns_mgr_ctx->dnsmgr_ctsk = 0;
	r = pthread_mutex_init(&dns_mgr_ctx->dnsmgr_mutex, SM_PTHREAD_MUTEXATTR);
	if (r != 0) {
		ret = sm_error_perm(SM_EM_DNS, r);
		goto err1;
	}
#endif /* MTA_USE_PTHREADS */
	*pdns_mgr_ctx = dns_mgr_ctx;
	return SM_SUCCESS;

#if MTA_USE_PTHREADS
  err1:
	bht_destroy(dns_mgr_ctx->dnsmgr_req_ht, NULL, NULL);
#endif /* MTA_USE_PTHREADS */
  error:
	if (dns_mgr_ctx != NULL)
		sm_free_size(dns_mgr_ctx, sizeof(*dns_mgr_ctx));
	return ret;
}

/*
**  DNS_MGR_SET_TIMEOUT -- set DNS timeout
**
**	Parameters:
**		dns_mgr_ctx -- DNS manager context
**		timeout -- query timeout
**
**	Return value:
**		usual sm_error code
*/

sm_ret_T
dns_mgr_set_timeout(dns_mgr_ctx_P dns_mgr_ctx, uint timeout)
{
	SM_REQUIRE(dns_mgr_ctx != NULL);
	if (timeout <= 1)
		return sm_error_perm(SM_EM_DNS, EINVAL);
	dns_mgr_ctx->dnsmgr_timeout = timeout;
	return SM_SUCCESS;
}


syntax highlighted by Code2HTML, v. 0.9.1