/* * Copyright (c) 2003-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: t-bdb-0.c,v 1.25 2006/10/05 04:27:38 ca Exp $") #include "sm/error.h" #include "sm/heap.h" #include "sm/memops.h" #include "sm/string.h" #include "sm/sysexits.h" #include "sm/test.h" #include "sm/maps.h" #include "sm/mapc.h" #include "sm/map.h" #include "sm/mapclasses.h" #include "sm/bdb.h" #include "sm/cdb_map.h" #include "sm/io.h" int Verbose = 0; #define MAPC_TYPE "hash" #define MAPC_NAME "bdb0" #define MAPC_FILE "./bdb0.db" #define KEY1 "left1" #define KEY2 "left2" #define KEY3 "left3" #define DATA1 "right1" #define DATA2 "right2" static sm_ret_T init_mapc_test(sm_maps_P *pmaps) { sm_ret_T ret; SM_REQUIRE(pmaps != NULL); ret = sm_maps_init(pmaps); SM_TEST(*pmaps != NULL); if (*pmaps == NULL) return ret; SM_TEST(sm_is_success(ret)); ret = sm_bdb_class_create(*pmaps); SM_TEST(sm_is_success(ret)); #if MTA_USE_TINYCDB ret = sm_cdb_class_create(*pmaps); SM_TEST(sm_is_success(ret)); #endif return ret; } static void testh(const char *mapname, const char *mapfile, const char *maptype) { sm_ret_T ret; sm_maps_P maps; sm_map_P map; sm_cstr_P mtype, mname; sm_str_P lhs, rhs; sm_map_key_T key; sm_map_data_T data; maps = NULL; mtype = mname = NULL; lhs = rhs = NULL; mtype = sm_cstr_scpyn0((const uchar *)maptype, strlen(maptype)); SM_TEST(mtype != NULL); if (mtype == NULL) goto error; mname = sm_cstr_scpyn0((const uchar *)mapname, strlen(mapname)); SM_TEST(mname != NULL); if (mname == NULL) goto error; lhs = sm_str_new(NULL, 256, 1024); SM_TEST(lhs != NULL); if (lhs == NULL) goto error; rhs = sm_str_new(NULL, 256, 1024); SM_TEST(rhs != NULL); if (rhs == NULL) goto error; ret = init_mapc_test(&maps); SM_TEST(sm_is_success(ret)); ret = unlink(mapfile); map = NULL; ret = sm_map_open(maps, mname, mtype, SMAP_MODE_CREATE, mapfile, SMAP_MODE_RDWR, &map, SMPO_END); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) goto error; sm_str_assign(key, NULL, (uchar *)KEY1, strlen(KEY1), strlen(KEY1)); sm_str_assign(data, NULL, (uchar *)DATA1, strlen(DATA1), strlen(DATA1)); ret = sm_map_add(map, &key, &data, SMMAP_AFL_NONE); SM_TEST(sm_is_success(ret)); sm_str_assign(key, NULL, (uchar *)KEY2, strlen(KEY2), strlen(KEY2)); sm_str_assign(data, NULL, (uchar *)DATA2, strlen(DATA2), strlen(DATA2)); ret = sm_map_add(map, &key, &data, SMMAP_AFL_NONE); SM_TEST(sm_is_success(ret)); ret = sm_map_add(map, &key, &data, SMMAP_AFL_NONE); SM_TEST(sm_is_success(ret)); ret = sm_map_close(map, 0); SM_TEST(sm_is_success(ret)); map = NULL; ret = sm_map_open(maps, mname, mtype, 0, mapfile, SMAP_MODE_RDONLY, &map, SMPO_END); SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) goto error; /* perform some operations ... */ sm_str_clr(rhs); sm_str_assign(key, NULL, (uchar *)KEY1, strlen(KEY1), strlen(KEY1)); ret = sm_map_lookup(map, SMMAP_FL_NONE, &key, rhs); SM_TEST(sm_is_success(ret)); sm_str_assign(key, NULL, (uchar *)KEY2, strlen(KEY2), strlen(KEY2)); ret = sm_map_lookup(map, SMMAP_FL_NONE, &key, rhs); SM_TEST(sm_is_success(ret)); sm_str_assign(key, NULL, (uchar *)KEY3, strlen(KEY3), strlen(KEY3)); ret = sm_map_lookup(map, SMMAP_FL_NONE, &key, rhs); SM_TEST(!sm_is_success(ret)); sm_str_clr(lhs); sm_str_clr(rhs); ret = sm_str_scat(lhs, KEY1); SM_TEST(sm_is_success(ret)); ret = sm_map_rewrite(map, SMMAP_FL_NONE, lhs, rhs); SM_TEST(sm_is_success(ret)); SM_TEST(strncmp(DATA1, (char *) sm_str_data(rhs), sm_str_getlen(rhs)) == 0); sm_str_clr(lhs); sm_str_clr(rhs); ret = sm_str_scat(lhs, KEY2); SM_TEST(sm_is_success(ret)); ret = sm_map_rewrite(map, SMMAP_FL_NONE, lhs, rhs); SM_TEST(sm_is_success(ret)); SM_TEST(strncmp(DATA2, (char *) sm_str_data(rhs), sm_str_getlen(rhs)) == 0); ret = sm_map_close(map, 0); SM_TEST(sm_is_success(ret)); ret = sm_maps_term(maps); SM_TEST(sm_is_success(ret)); SM_CSTR_FREE(mtype); SM_CSTR_FREE(mname); SM_STR_FREE(lhs); SM_STR_FREE(rhs); return; error: sm_maps_term(maps); } static void usage(const char *prg) { sm_io_fprintf(smioerr, "usage: %s [options]\n" "-F file name of db file [%s]\n" "-l n list available map classes (n: verbosity)\n" "-n name name of map [%s]\n" "-T type map type [%s]\n" , prg , MAPC_FILE , MAPC_NAME , MAPC_TYPE ); exit(EX_USAGE); } int main(int argc, char *argv[]) { int c, list_mapc; char *mapname, *mapfile, *maptype, *prg; prg = argv[0]; mapname = MAPC_NAME; mapfile = MAPC_FILE; maptype = MAPC_TYPE; list_mapc = -1; #if SM_HEAP_CHECK SmHeapCheck = 0; #endif while ((c = getopt(argc, argv, "F:H:l:n:T:V")) != -1) { switch (c) { case 'F': SM_STRDUP_OPT(mapfile, optarg); break; case 'H': #if SM_HEAP_CHECK SmHeapCheck = atoi(optarg); #endif break; case 'l': list_mapc = (int) strtol(optarg, NULL, 0); break; case 'n': SM_STRDUP_OPT(mapname, optarg); break; case 'T': SM_STRDUP_OPT(maptype, optarg); break; default: usage(prg); /* NOTREACHED */ return EX_USAGE; } } sm_test_begin(argc, argv, "test map 0"); if (list_mapc >= 0) { sm_ret_T ret; sm_maps_P maps; maps = NULL; ret = init_mapc_test(&maps); if (sm_is_err(ret)) exit(EX_SOFTWARE); c = sm_mapc_list(smioout, maps, list_mapc, 0); } else testh(mapname, mapfile, maptype); #if SM_HEAP_CHECK if (SmHeapCheck > 0) sm_heap_report(smioerr, 3); #endif return sm_test_end(); }