/*
 * Copyright (c) 2004, 2005 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.
 *
 * $Id: t-ringinschk.h,v 1.2 2005/04/14 17:08:56 ca Exp $
 */

static int Verbose = 0;

#define AQR_SS2R(aq_rcpt)	(&((aq_rcpt)->aqr_ss_link))
#define AQR_R2SS(ring)	SM_RING_EMBED((ring), aq_rcpt_T, aqr_ss_link)
#define AQR_SS_INIT(aq_rcpt)	SM_RING_INIT(AQR_SS2R(aq_rcpt))
#define AQR_SS_APP(aq_rcpt, aq_rcpt_nxt)	SM_RING_APPEND(AQR_SS2R(aq_rcpt), AQR_SS2R(aq_rcpt_nxt))
#define AQR_SS_PRE(aq_rcpt, aq_rcpt_nxt)	SM_RING_PREPEND(AQR_SS2R(aq_rcpt), AQR_SS2R(aq_rcpt_nxt))
#define AQR_SS_SUCC(aq_rcpt)	AQR_R2SS(sm_ring_succ(AQR_SS2R(aq_rcpt)))
#define AQR_SS_PRED(aq_rcpt)	AQR_R2SS(sm_ring_pred(AQR_SS2R(aq_rcpt)))
#define AQR_SS_DELENTRY(aq_rcpt)	sm_ring_delentry(AQR_SS2R(aq_rcpt))


/* function/macro to compare two ring elements */
#define RING_CMP(el1, el2)	\
	sm_str_casecmp(AQR_R2SS(el1)->aqr_domain, AQR_R2SS(el2)->aqr_domain)

#define SMT_NOCHECKS	0x01
#define SMT_APPEND	0x02

#define SM_AQ_RCPTS	256
#define RCPT_MAX_LEN	256

#define SM_TEST_ERR(ret)	do {	\
	SM_TEST(!sm_is_err(ret));	\
	if (sm_is_err(ret))		\
		goto error;		\
	} while (0)

#define DIR(d)	((d > 0) ? 1 : ((d < 0) ? (-1) : 0))

static sm_ret_T
aqr_test1(aq_rcpt_P aq_rcpt, uint n)
{
	uint i;
	int direction;
	aq_rcpt_P aq_rcpt_nxt, aq_rcpt_prev, aq_rcpt_f;

	if (Verbose > 0)
		sm_io_fprintf(smioerr, "\naq_rcpt=%p, domain=%S\n",
			aq_rcpt, aq_rcpt->aqr_domain);

	if (Verbose > 0)
		sm_io_fprintf(smioerr, "LIST:  0: aq_rcpt=%p, domain=%S\n",
			aq_rcpt, aq_rcpt->aqr_domain);
	for (aq_rcpt_prev = aq_rcpt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt), i = 1;
	     aq_rcpt_nxt != aq_rcpt;
	     aq_rcpt_prev = aq_rcpt_nxt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_nxt), i++)
	{
		direction = sm_str_casecmp(aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt->aqr_domain);
		direction = DIR(direction);
		if (Verbose > 0)
			sm_io_fprintf(smioerr,
				"LIST: %2d: aq_rcpt=%p, domain=%S, dir=%d\n",
				i, aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain,
				direction);
	}

	aq_rcpt_f = NULL;
	for (aq_rcpt_prev = aq_rcpt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt), i = 0;
	     aq_rcpt_nxt != aq_rcpt;
	     aq_rcpt_prev = aq_rcpt_nxt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_nxt), i++)
	{
		direction = sm_str_casecmp(aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt->aqr_domain);
		direction = DIR(direction);
		if (Verbose > 0)
			sm_io_fprintf(smioerr,
				"%2d/0: aq_rcpt=%p, domain=%S, dir=%d\n",
				i, aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
				direction);
		if (direction > 0)
		{
			if (Verbose > 0)
				sm_io_fprintf(smioerr,
					"BREAK: %p, %S, nxt=%p, %S, dir=%d\n",
					aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain,
					direction);
			aq_rcpt_f = aq_rcpt_nxt;
			break;
		}
	}

	if (aq_rcpt_f != NULL)
	{
		for (aq_rcpt_prev = aq_rcpt_f,
			aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_f), i = 0;
		     aq_rcpt_nxt != aq_rcpt_f;
		     aq_rcpt_prev = aq_rcpt_nxt,
			aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_nxt), i++)
		{
			direction = sm_str_casecmp(aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt->aqr_domain);
			direction = DIR(direction);
			if (Verbose > 0)
				sm_io_fprintf(smioerr,
					"%2d: aq_rcpt=%p, domain=%S, dir=%d\n",
					i, aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
					direction);
			SM_TEST(direction <= 0);
			if (direction > 0 && Verbose > 0)
				sm_io_fprintf(smioerr,
					"ERROR: %p, %S, nxt=%p, %S, dir=%d\n",
					aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain,
					direction);
		}
	}


	SM_TEST(i == n);
	if (i != n && Verbose > 0)
		sm_io_fprintf(smioerr, "i=%2d, n=%2d\n", i, n);
	if (Verbose > 0)
		sm_io_fprintf(smioerr, "%2d: aq_rcpt=%p, domain=%S [LAST]\n",
			i, aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain);
	sm_io_flush(smioerr);
	return SM_SUCCESS;
}

static sm_ret_T
aqr_tests(aq_rcpt_P aq_rcpt, int n)
{
	int direction, i;
	aq_rcpt_P aq_rcpt_nxt, aq_rcpt_prev, aq_rcpt_f;

	if (Verbose > 0)
		sm_io_fprintf(smioerr, "\naq_rcpt=%p, domain=%S\n",
			aq_rcpt, aq_rcpt->aqr_domain);

	if (Verbose > 0)
		sm_io_fprintf(smioerr, "LIST:  0: aq_rcpt=%p, domain=%S\n",
			aq_rcpt, aq_rcpt->aqr_domain);
	for (aq_rcpt_prev = aq_rcpt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt), i = 1;
	     aq_rcpt_nxt != aq_rcpt;
	     aq_rcpt_prev = aq_rcpt_nxt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_nxt), i++)
	{
		direction = sm_str_casecmp(aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt->aqr_domain);
		direction = DIR(direction);
		if (Verbose > 0)
			sm_io_fprintf(smioerr,
				"LIST: %2d: aq_rcpt=%p, domain=%S, dir=%d\n",
				i, aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain,
				direction);
	}

	aq_rcpt_f = NULL;
	for (aq_rcpt_prev = aq_rcpt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt), i = 0;
	     aq_rcpt_nxt != aq_rcpt;
	     aq_rcpt_prev = aq_rcpt_nxt, aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_nxt), i++)
	{
		direction = sm_str_casecmp(aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt->aqr_domain);
		direction = DIR(direction);
		if (Verbose > 0)
			sm_io_fprintf(smioerr,
				"%2d/0: aq_rcpt=%p, domain=%S, dir=%d\n",
				i, aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
				direction);
		if (direction > 0)
		{
			if (Verbose > 0)
				sm_io_fprintf(smioerr,
					"BREAK: %p, %S, nxt=%p, %S, dir=%d\n",
					aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain,
					direction);
			aq_rcpt_f = aq_rcpt_nxt;
			break;
		}
	}

	if (aq_rcpt_f != NULL)
	{
		for (aq_rcpt_prev = aq_rcpt_f,
			aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_f), i = 0;
		     aq_rcpt_nxt != aq_rcpt_f;
		     aq_rcpt_prev = aq_rcpt_nxt,
			aq_rcpt_nxt = AQR_SS_SUCC(aq_rcpt_nxt), i++)
		{
			direction = sm_str_casecmp(aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt->aqr_domain);
			direction = DIR(direction);
			if (Verbose > 0)
				sm_io_fprintf(smioerr,
					"%2d: aq_rcpt=%p, domain=%S, dir=%d\n",
					i, aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
					direction);
			SM_TEST(direction <= 0);
			if (direction > 0 && Verbose > 0)
				sm_io_fprintf(smioerr,
					"ERROR: %p, %S, nxt=%p, %S, dir=%d\n",
					aq_rcpt_prev, aq_rcpt_prev->aqr_domain,
					aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain,
					direction);
		}
	}


	SM_TEST(i == n);
	if (i != n && Verbose > 0)
		sm_io_fprintf(smioerr, "i=%2d, n=%2d\n", i, n);
	if (Verbose > 0)
		sm_io_fprintf(smioerr, "%2d: aq_rcpt=%p, domain=%S [LAST]\n",
			i, aq_rcpt_nxt, aq_rcpt_nxt->aqr_domain);
	sm_io_flush(smioerr);
	return SM_SUCCESS;
}



syntax highlighted by Code2HTML, v. 0.9.1