/*
* 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_RCSID("@(#)$Id: t-rcpts-0.c,v 1.33 2006/11/09 01:53:49 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/heap.h"
#include "sm/test.h"
#include "sm/maps.h"
#include "sm/map.h"
#include "sm/mapclasses.h"
#include "sm/hostname.h"
#include "sm/bhtable.h"
#include "sm/io.h"
#include "sm/smardef.h"
#include "smar.h"
#include "t-init.h"
#define SMAR_LOG_DEFINES 1
#include "log.h"
/*
** Test program for alias expansion.
** This program is directly linked against the smar functions that
** perform alias expansion, it does not communicate with an smar daemon.
** This is done to allow for direct testing of one component instead
** of the significantly more complicated part of communicating with
** an smar daemon (which is done by other test programs).
*/
static int Verbose = 0;
int Loglevel = 0;
static bool List;
static bool ShowFlags = true;
#define TRS_FL_NORECERR 0x0001 /* ignore recursion error */
/*
** PRINT_RCPT_CB -- Callback for bht_walk: print some smar_rcpt data.
**
** Parameters:
** entry -- bht entry
** ctx -- ignored
**
** Returns:
** usual sm_error code
*/
/* ARGSUSED1 */
static sm_ret_T
print_rcpt_cb(bht_entry_P entry, void *ctx)
{
smar_rcpt_P smar_rcpt;
(void) ctx;
SM_TEST(entry != NULL);
if (entry == NULL)
return -1;
smar_rcpt = entry->bhe_value;
SM_TEST(smar_rcpt != NULL);
if (smar_rcpt == NULL)
return -1;
sm_io_fprintf(smioout, "address: %16S ", smar_rcpt->arr_pa);
if (Verbose > 2)
{
sm_io_fprintf(smioout, "idx: %u, ", smar_rcpt->arr_idx);
sm_io_fprintf(smioout, "owner: %u, ", smar_rcpt->arr_owner_idx);
}
if (ShowFlags)
sm_io_fprintf(smioout, "flags: %x\n", smar_rcpt->arr_flags);
else
sm_io_fprintf(smioout, "\n");
return SM_SUCCESS;
}
/*
** PRINT_RCPT_L -- print some smar_rcpt data.
**
** Parameters:
** entry -- bht entry
**
** Returns:
** usual sm_error code
*/
static sm_ret_T
print_rcpt_l(smar_rcpts_P smar_rcpts)
{
smar_rcpt_P smar_rcpt;
uint n;
SM_TEST(smar_rcpts->arrs_lst_n <= smar_rcpts->arrs_ht_n);
for (smar_rcpt = RCPTS_FIRST(smar_rcpts), n = 0;
smar_rcpt != RCPTS_END(smar_rcpts);
smar_rcpt = RCPTS_NEXT(smar_rcpt), ++n)
{
sm_io_fprintf(smioout, "address: %16S ",
smar_rcpt->arr_pa);
if (Verbose > 2)
{
sm_io_fprintf(smioout, "idx: %u, ",
smar_rcpt->arr_idx);
sm_io_fprintf(smioout, "owner: %u, ",
smar_rcpt->arr_owner_idx);
}
if (ShowFlags)
sm_io_fprintf(smioout, "flags: %x\n",
smar_rcpt->arr_flags);
else
sm_io_fprintf(smioout, "\n");
}
SM_TEST(smar_rcpts->arrs_lst_n == n);
return SM_SUCCESS;
}
/*
** PRINT_OWNER_L -- print some smar_rcpt data.
**
** Parameters:
** entry -- bht entry
**
** Returns:
** usual sm_error code
*/
static sm_ret_T
print_owner_l(smar_rcpts_P smar_rcpts)
{
smar_rcpt_P smar_rcpt;
uint n;
if (Verbose > 2)
sm_io_fprintf(smioout, "\nOwner-List:\n");
for (smar_rcpt = OWNER_FIRST(smar_rcpts), n = 0;
smar_rcpt != OWNER_END(smar_rcpts);
smar_rcpt = OWNER_NEXT(smar_rcpt), ++n)
{
#if 0
sm_io_fprintf(smioout, "orig_pa: %16S ", smar_rcpt->arr_pa);
#endif
sm_io_fprintf(smioout, "owner: %16S ", smar_rcpt->arr_owner_pa);
if (Verbose > 2)
{
sm_io_fprintf(smioout, "idx: %u, ",
smar_rcpt->arr_idx);
sm_io_fprintf(smioout, "owner: %u, ",
smar_rcpt->arr_owner_idx);
}
if (ShowFlags)
sm_io_fprintf(smioout, "flags: %x\n",
smar_rcpt->arr_flags);
else
sm_io_fprintf(smioout, "\n");
}
return SM_SUCCESS;
}
/*
** T_RCPTS_0_INIT -- Initialize smar_ctx
** See smar_init(), this is the part of it that is necessary for
** looking up aliases.
**
** Parameters:
** smar_ctx -- SMAR context
**
** Returns:
** usual sm_error code
*/
static sm_ret_T
t_rcpts_0_init(smar_ctx_P smar_ctx)
{
return t_smar_0_init(smar_ctx, TSMARI_FL_MT|TSMARI_FL_ALIAS);
}
/*
** T_RCPTS_0_FREE -- Free data in smar_ctx
**
** Parameters:
** smar_ctx -- SMAR context
**
** Returns:
** usual sm_error code
*/
static void
t_rcpts_0_free(smar_ctx_P smar_ctx)
{
if (smar_ctx->smar_mt_map != NULL)
{
(void) sm_map_close(smar_ctx->smar_mt_map, 0);
smar_ctx->smar_mt_map = NULL;
}
if (smar_ctx->smar_aliases != NULL)
{
(void) sm_map_close(smar_ctx->smar_aliases, 0);
smar_ctx->smar_aliases = NULL;
}
if (smar_ctx->smar_maps != NULL)
{
(void) sm_maps_term(smar_ctx->smar_maps);
smar_ctx->smar_maps = NULL;
}
}
/*
** T_RCPTS_0 -- Perform alias expansion
**
** Parameters:
** addr -- (printable) address to expand.
**
** Returns:
** none.
*/
static void
t_rcpts_0(char *addr, uint32_t cnflags, uint32_t rqflags, uint tflags, uint lflags, sm_str_P srch)
{
sm_ret_T ret;
sm_str_P str;
smar_rcpts_P smar_rcpts;
smar_rcpt_P smar_rcpt;
smar_ctx_T smar_ctx;
ret = t_rcpts_0_init(&smar_ctx);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
return;
smar_ctx.smar_cnf.smar_cnf_alias_fl = cnflags;
smar_ctx.smar_alias_lfl = SMMAP_LFL_ALIAS;
ret = smar_init_map_lfl(&smar_ctx, smar_ctx.smar_cnf.smar_cnf_alias_fl,
&smar_ctx.smar_alias_lfl);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
return;
ret = smar_rcpt_new(&smar_rcpt);
SM_TEST(ret == SM_SUCCESS);
str = sm_str_new(NULL, MAXADDRLEN, MAXADDRLEN + 2);
SM_TEST(str != NULL);
if (str == NULL)
return;
ret = sm_str_scopy(str, addr);
SM_TEST(ret == SM_SUCCESS);
smar_rcpt->arr_pa = str;
smar_rcpt->arr_timeout = 1;
smar_rcpt->arr_rqflags = rqflags;
sm_snprintf(smar_rcpt->arr_id, sizeof(smar_rcpt->arr_id),
SMTP_RCPTID_FORMAT, "S00000000404763B601", (rcpt_idx_T)9876);
ret = smar_rcpts_new(&smar_ctx, NULL, &smar_rcpts);
SM_TEST(ret == SM_SUCCESS);
smar_rcpts->arrs_flags = lflags;
smar_rcpts->arrs_pa = srch;
ret = smar_rcpt_expand(smar_rcpts, smar_rcpt, 0, 0, 0);
SM_TEST(ret == SM_SUCCESS);
if (ret == SM_SUCCESS)
{
if (SMARRS_IS_FLAG(smar_rcpts, SMARRS_FL_COMP))
{
if (Verbose > 1)
sm_io_fprintf(smioout, "flags=%#x\n",
smar_rcpts->arrs_flags);
else
sm_io_fprintf(smioout, "found=%d\n",
SMARRS_IS_FLAG(smar_rcpts,
SMARRS_FL_FOUND));
}
else if (List)
{
ret = smar_rcpts_t2l(smar_rcpts);
SM_TEST(ret == SM_SUCCESS);
ret = print_rcpt_l(smar_rcpts);
SM_TEST(ret == SM_SUCCESS);
ret = print_owner_l(smar_rcpts);
SM_TEST(ret == SM_SUCCESS);
#if 0
ret = smar_rcpt_free(smar_rcpt, NULL);
SM_TEST(ret == SM_SUCCESS);
#endif
smar_rcpt = NULL;
}
else
{
bht_walk(smar_rcpts->arrs_rcpts, print_rcpt_cb, NULL);
}
sm_io_flush(smioout);
}
else if (Verbose > 0)
sm_io_fprintf(smioerr, "smar_rcpt_expand=%#X\n", ret);
ret = smar_rcpts_free(smar_rcpts);
SM_TEST(ret == SM_SUCCESS);
t_rcpts_0_free(&smar_ctx);
}
/*
** USAGE -- usage message
**
** Parameters:
** prg -- program name
**
** Returns:
** none
*/
static void
usage(const char *prg)
{
sm_io_fprintf(smioerr, "usage: %s [options] addresses...\n"
"-e does address (-S) exist in list?\n"
"-F do not show flags\n"
"-f flags set test flags\n"
"-L alias expansion for local addresses including domain\n"
"-l list\n"
"-o perform owner- expansion\n"
"-r alias expansion for all addresses\n"
"-S addr specify address (e.g., to find in list)\n"
"-V increase verbosity\n"
, prg
);
return;
}
int
main(int argc, char *argv[])
{
int c, i;
uint32_t cnflags, rqflags;
uint tflags, lflags;
sm_str_P srch;
List = false;
rqflags = SMARRQ_FL_ALIAS;
cnflags = SMARCNF_FL_MAP_LP;
tflags = 0;
lflags = 0;
srch = NULL;
while ((c = getopt(argc, argv, "d:eFf:LlorS:s:V")) != -1)
{
switch (c)
{
case 'd':
#if SMAR_DEBUG
smar_debug = (uint) strtoul(optarg, NULL, 0);
#endif
break;
case 'e':
lflags = SMARRS_FL_NOREC|SMARRS_FL_NOADD|SMARRS_FL_COMP;
break;
case 'F':
ShowFlags = false;
break;
case 'f':
tflags = (uint) strtoul(optarg, NULL, 0);
break;
case 'l':
List = true;
break;
case 'L':
cnflags = SMARCNF_FL_MAP_LD;
break;
case 'o':
rqflags |= SMARRQ_FL_OWNER;
break;
case 'r':
cnflags = SMARCNF_FL_MAP_ALL;
break;
case 'S':
srch = sm_str_scpy(NULL, optarg, 256);
break;
case 's':
lflags = (uint) strtoul(optarg, NULL, 0);
break;
case 'V':
++Verbose;
break;
default:
usage(argv[0]);
return 1;
}
}
sm_test_begin(argc, argv, "test rcpts 0");
argc -= optind;
argv += optind;
if (argc > 0)
{
for (i = 0; i < argc; i++)
t_rcpts_0(argv[i], cnflags, rqflags, tflags, lflags,
srch);
}
else
t_rcpts_0("<a@b.c>", cnflags, rqflags, tflags, lflags, srch);
return sm_test_end();
}
syntax highlighted by Code2HTML, v. 0.9.1