/*
* 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.
*/
#include "sm/generic.h"
SM_IDSTR(id, "@(#)$Id: t-adbr-1.c,v 1.8 2006/10/21 05:02:41 ca Exp $")
#include "sm/debug.h"
#include "sm/heap.h"
#include "sm/sysexits.h"
#include "sm/test.h"
#include "sm/io.h"
#include "sm/rfc2821.h"
#include "sm/actdb-int.h"
#define QMGR_DEBUG_DEFINE 1
#include "sm/qmgrdbg.h"
static int Verbose = 0;
#if SM_HEAP_CHECK
# include "sm/io.h"
extern SM_DEBUG_T SmHeapCheck;
# define HEAP_CHECK (SmHeapCheck > 0)
#else
# define HEAP_CHECK 0
#endif
#define SM_AQ_RCPTS 256
#define RCPT_MAX_LEN 256
static char *list[] = {
"<_@Sendmail.ORG>",
"<_@sendmailx.org>",
"<_@sendmail.com>",
"<_@Sendmail.ORG>",
"<_@sendmail.com>",
"<_@Sendmail.COM>",
"<_@Sendmail.COM>",
"<_@sendmail.com>",
"<_@sendmail.com>",
"<_@sendmail.com>",
"<_@sendmail.com>",
"<_@sendmail.com>",
"<_@sendmail.com>",
"<_@sendmail.org>",
"<_@csuchico.edu>",
"<_@niu.edu>",
"<_@uni-kiel.de>",
"<_@informatik.uni-kiel.de>",
"<_@vt.edu>",
"<_@andrew.cmu.edu>",
"<_@onet.pl>",
"<_@Sendmail.ORG>",
"<_@debian.org>",
"<_@nmt.edu>",
"<_@uwaterloo.ca>",
"<_@yale.edu>",
"<_@uni-erlangen.de>",
"<_@yahoo.com>",
"<_@earthlink.net>",
"<_@hotmail.com>",
"<_@hp.com>",
"<_@polytechnique.fr>",
"<_@gmail.com>",
NULL
};
static sm_ret_T
aqr_test1(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);
#define DIR(d) ((d > 0) ? 1 : ((d < 0) ? (-1) : 0))
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_test0(void)
{
sm_ret_T ret;
int i;
sm_str_P str;
aq_rcpt_P aq_rcpt_a[SM_AQ_RCPTS];
aq_rcpt_P aq_rcpt, aq_rcpt_prev;
aq_rcpt_prev = NULL;
srand(time(0));
for (i = 0; i < SM_AQ_RCPTS; i++)
{
if (list[i] == NULL)
break;
ret = aq_rcpt_new(&(aq_rcpt_a[i]));
SM_TEST_ERR(ret);
aq_rcpt = aq_rcpt_a[i];
sm_snprintf(aq_rcpt->aqr_ss_ta_id,
sizeof(aq_rcpt->aqr_ss_ta_id), SMTPS_STID_FORMAT,
(ulonglong_T) i, i);
str = sm_str_scpy0(NULL, list[i], strlen(list[i]) + 2);
if (aq_rcpt->aqr_pa != NULL)
sm_str_free(aq_rcpt->aqr_pa);
aq_rcpt->aqr_pa = str;
str = NULL;
/* get domain part */
ret = aq_rcpt_set_domain(aq_rcpt, NULL);
SM_TEST_ERR(ret);
AQR_DA_INIT(aq_rcpt);
ret = aq_rcpt_ss_insert(aq_rcpt_prev, aq_rcpt);
SM_TEST_ERR(ret);
aq_rcpt_prev = aq_rcpt;
ret = aqr_test1(aq_rcpt_a[0], i);
}
ret = aqr_test1(aq_rcpt_a[0], i - 1);
return ret;
error:
return ret;
}
static void
usage(const char *prg)
{
sm_io_fprintf(smioerr, "usage: %s [options]\n", prg);
sm_io_fprintf(smioerr, "Test AQ recipient sorting (domains are hardcoded)\n");
sm_io_fprintf(smioerr, "options:\n");
sm_io_fprintf(smioerr, "-V increase verbosity\n");
exit(0);
}
int
main(int argc, char **argv)
{
int c;
sm_ret_T r;
#if SM_HEAP_CHECK
SmHeapCheck = 0;
#endif
while ((c = getopt(argc, argv, "H:V")) != -1)
{
switch (c)
{
#if SM_HEAP_CHECK
case 'H':
SmHeapCheck = atoi(optarg);
break;
#endif
case 'V':
++Verbose;
break;
default:
usage(argv[0]);
return EX_USAGE;
}
}
sm_test_begin(argc, argv, "test adbr 0");
r = aqr_test0();
#if SM_HEAP_CHECK
if (HEAP_CHECK)
{
sm_io_fprintf(smioout, "heap should be empty except for makebuf:\n");
sm_heap_report(smioout, 3);
}
#endif /* SM_HEAP_CHECK */
return sm_test_end();
}
syntax highlighted by Code2HTML, v. 0.9.1