/* * 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("", cnflags, rqflags, tflags, lflags, srch); return sm_test_end(); }