/* * Copyright (c) 2004 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-map-reopen-0.c,v 1.13 2005/09/26 23:32:18 ca Exp $") #include "sm/error.h" #include "sm/heap.h" #include "sm/memops.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/io.h" int Verbose = 0; /* caller must have created MAPC_FILE: use before reopen() and MAPC_FILER: use after reopen() the data in those files must be MAPC_FILE: left1:right1 left2:right2 MAPC_FILER: left1:reopen1 left2:reopen2 MAPC_FILEB is used as "backup" filename for MAPC_FILE, i.e., the latter will be rename()d to the former. */ #define MAPC_TYPE "hash" #define MAPC_NAME "bdbr0" #define MAPC_FILE "./bdbr0.db" #define MAPC_FILER "./bdbrr0.db" #define MAPC_FILEB "./bdbrb0.db" #define MAPC_FILEF "./bdbrf0.db" #define KEY1 "left1" #define KEY2 "left2" #define KEY3 "left3" #define DATA1 "right1" #define DATA2 "right2" #define DATAR1 "reopen1" #define DATAR2 "reopen2" static void testh(bool fail) { 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; int i; maps = NULL; mtype = mname = NULL; lhs = rhs = NULL; ret = sm_maps_init(&maps); SM_TEST(maps != NULL); if (maps == NULL) return; SM_TEST(sm_is_success(ret)); mtype = sm_cstr_scpyn0((const uchar *)MAPC_TYPE, strlen(MAPC_TYPE)); SM_TEST(mtype != NULL); if (mtype == NULL) goto error; mname = sm_cstr_scpyn0((const uchar *)MAPC_NAME, strlen(MAPC_NAME)); 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 = sm_bdb_class_create(maps); SM_TEST(sm_is_success(ret)); map = NULL; ret = sm_map_open(maps, mname, mtype, 0, MAPC_FILE, SMAP_MODE_RDWR, &map, SMPO_END); SM_CSTR_FREE(mtype); SM_CSTR_FREE(mname); 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); /* wait for a char on stdin */ /* i = sm_io_getc(smioin); */ i = rename(MAPC_FILE, MAPC_FILEB); SM_TEST(i == 0); if (fail) { /* shouldn't exist anymore */ (void) unlink(MAPC_FILE); } else { i = rename(MAPC_FILER, MAPC_FILE); SM_TEST(i == 0); } ret = sm_map_reopen(map, 0, SMPO_END); if (fail) { SM_TEST(sm_is_err(ret)); if (!sm_is_err(ret)) goto error; 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_err(ret)); i = rename(MAPC_FILER, MAPC_FILE); SM_TEST(i == 0); ret = sm_map_reopen(map, 0, SMPO_END); } SM_TEST(sm_is_success(ret)); if (!sm_is_success(ret)) goto error; /* perform some operations ... */ 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(DATAR1, (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(DATAR2, (char *) sm_str_data(rhs), sm_str_getlen(rhs)) == 0); sm_str_clr(lhs); sm_str_clr(rhs); ret = sm_str_scat(lhs, KEY3); SM_TEST(sm_is_success(ret)); ret = sm_map_lookup(map, SMMAP_FL_NONE, lhs, rhs); SM_TEST(sm_is_err(ret)); ret = sm_map_close(map, 0); SM_TEST(sm_is_success(ret)); ret = sm_maps_term(maps); SM_TEST(sm_is_success(ret)); SM_STR_FREE(lhs); SM_STR_FREE(rhs); return; error: sm_maps_term(maps); } int main(int argc, char *argv[]) { int c; bool fail; fail = false; while ((c = getopt(argc, argv, "f")) != -1) { switch (c) { case 'f': fail = true; break; default: return 1; } } sm_test_begin(argc, argv, "test map reopen 0"); testh(fail); return sm_test_end(); }