/*
* Copyright (c) 2002-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-idb-1.c,v 1.31 2007/06/18 04:42:31 ca Exp $")
#include "sm/io.h"
#include "sm/mta.h"
#include "sm/cstr.h"
#include "sm/cdb.h"
#include "sm/ibdb.h"
#include "sm/qmgr.h"
#include "sm/memops.h"
#include "sm/test.h"
#include "sm/sysexits.h"
#define FNAME "ibd"
#define IBDBSIZE (8 * 1024)
#define INIT_SEQ 1
static int init_seq = INIT_SEQ;
static int debug = 0;
/*
** ToDo:
** - more consistency checks for read data.
** - cleanup files.
*/
/*
** TESTIDB -- write INCEDB records
**
** Parameters:
** base_dir -- name of base directory (can be NULL)
** iter -- number of iterations (transactions)
** maxs -- maximum size of an INCEDB file
**
** Returns:
** usual sm_error code.
*/
static int
testidb(const char *base_dir, int iter, int maxs)
{
int i, j, nrcpts;
sm_ret_T ret;
ibdb_ctx_P ibdb_ctx;
ibdb_ta_P ta;
ibdb_rcpt_P rcpt;
sessta_id_T id;
sessta_id_T da_id;
char cdb[32];
id_count_T id_count;
ibdb_req_hd_T ibdb_req_hd, ibdb_req_hd_c;
id_count = time(NULLT);
ret = ibdb_open(base_dir, FNAME, SM_IO_WRONLY, init_seq, maxs,
IBDB_OFL_WRITE, NULLPTR, &ibdb_ctx);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
return ret;
rcpt = NULL;
ta = (ibdb_ta_P) sm_zalloc(sizeof(*ta));
SM_TEST(ta != NULL);
if (ta == NULL)
goto end;
ta->ibt_ta_id = id;
ta->ibt_mail_pa = sm_str_new(NULL, 256, 256);
SM_TEST(ta->ibt_mail_pa != NULL);
if (ta->ibt_mail_pa == NULL)
goto end;
rcpt = (ibdb_rcpt_P) sm_zalloc(sizeof(*rcpt));
SM_TEST(rcpt != NULL);
if (rcpt == NULL)
goto end;
rcpt->ibr_ta_id = id;
rcpt->ibr_pa = sm_str_new(NULL, 256, 256);
SM_TEST(rcpt->ibr_pa != NULL);
if (rcpt->ibr_pa == NULL)
goto end;
for (i = 0; i < iter; i++)
{
id_count++;
IBDBREQL_INIT(&(ibdb_req_hd));
sm_snprintf(id, SMTP_STID_SIZE, SMTPS_STID_FORMAT, id_count, 2);
sm_str_clr(ta->ibt_mail_pa);
ret = sm_strprintf(ta->ibt_mail_pa, "sender-%d@some.domain", i);
ret = sm_snprintf(cdb, sizeof(cdb), "cdb%010d", i);
ta->ibt_cdb_id = sm_cstr_scpyn((const uchar *) cdb, strlen(cdb));
SM_TEST(ta->ibt_cdb_id != NULL);
if (ta->ibt_cdb_id == NULL)
goto end;
nrcpts = ta->ibt_nrcpts = (i % 5) + 1;
sm_snprintf(da_id, SMTP_STID_SIZE, SMTPC_STID_FORMAT,
4, (uint) id_count, 3);
for (j = 0; j < nrcpts; j++)
{
sm_str_clr(rcpt->ibr_pa);
ret = sm_strprintf(rcpt->ibr_pa,
"rcpt-%d-%d@other.Rcpt", i, j);
rcpt->ibr_idx = (rcpt_idx_T) j;
if (debug > 2)
{
sm_io_fprintf(smioout, "ADD RCPT: ");
sm_io_fprintf(smioout, "ta_id=%s, ", rcpt->ibr_ta_id);
sm_io_fprintf(smioout, "rcpt_pa=%s, ", sm_str_data(rcpt->ibr_pa));
sm_io_fprintf(smioout, "rcpt_idx=%d, ", rcpt->ibr_idx);
sm_io_fprintf(smioout, "\n");
sm_io_flush(smioout);
}
ret = ibdb_rcpt_app(ibdb_ctx, rcpt, &ibdb_req_hd,
IBDB_RCPT_NEW);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
}
ret = ibdb_ta_app(ibdb_ctx, ta, &ibdb_req_hd, IBDB_TA_NEW);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
ret = ibdb_wr_status(ibdb_ctx, &ibdb_req_hd);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
/* list to cancel */
IBDBREQL_INIT(&(ibdb_req_hd_c));
sm_str_clr(rcpt->ibr_pa);
ret = sm_strprintf(rcpt->ibr_pa,
"rcpt-%d-%d@Cancel.Rcpt", i, nrcpts);
rcpt->ibr_idx = (rcpt_idx_T) nrcpts;
ret = ibdb_rcpt_app(ibdb_ctx, rcpt, &ibdb_req_hd_c, IBDB_RCPT_NEW);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
sm_str_clr(ta->ibt_mail_pa);
ret = sm_strprintf(ta->ibt_mail_pa, "sender-%d@cancel.domain", i);
ret = ibdb_ta_app(ibdb_ctx, ta, &ibdb_req_hd_c, IBDB_TA_NEW);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
ret = ibdb_req_cancel(ibdb_ctx, &ibdb_req_hd_c);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
ret = ibdb_wr_status(ibdb_ctx, &ibdb_req_hd_c);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
for (j = 0; j < nrcpts; j++)
{
sm_str_clr(rcpt->ibr_pa);
ret = sm_strprintf(rcpt->ibr_pa,
"rcpt-%d-%d@other.Rcpt", i, j);
rcpt->ibr_idx = (rcpt_idx_T) j;
if (debug > 2)
{
sm_io_fprintf(smioout, "REM RCPT: ");
sm_io_fprintf(smioout, "ta_id=%s, ", rcpt->ibr_ta_id);
sm_io_fprintf(smioout, "rcpt_pa=%s, ", sm_str_data(rcpt->ibr_pa));
sm_io_fprintf(smioout, "rcpt_idx=%d, ", rcpt->ibr_idx);
sm_io_fprintf(smioout, "\n");
sm_io_flush(smioout);
}
ret = ibdb_rcpt_status(ibdb_ctx, rcpt, IBDB_RCPT_DONE,
IBDB_FL_NOROLL, THR_LOCK_UNLOCK);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
goto end;
}
sm_str_clr(ta->ibt_mail_pa);
ret = sm_strprintf(ta->ibt_mail_pa, "sender-%d@some.domain", i);
ret = ibdb_ta_status(ibdb_ctx, ta, IBDB_TA_DONE, IBDB_FL_NONE,
0, THR_LOCK_UNLOCK);
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
break;
sm_cstr_free(ta->ibt_cdb_id);
}
end:
if (ta != NULL)
{
SM_STR_FREE(ta->ibt_mail_pa);
sm_free(ta);
}
if (rcpt != NULL)
{
SM_STR_FREE(rcpt->ibr_pa);
sm_free(rcpt);
}
ret = ibdb_close(ibdb_ctx);
SM_TEST(ret == SM_SUCCESS);
sm_io_flush(smioout);
return ret;
}
/*
** TESTIDBR -- read INCEDB records
**
** Parameters:
** base_dir -- name of base directory (can be NULL)
** iter -- number of iterations (transactions)
** maxs -- maximum size of an INCEDB file
**
** Returns:
** usual sm_error code.
*/
static sm_ret_T
testidbr(const char *base_dir, int iter, int maxs)
{
int i, j, nrcpts, status;
ibdbr_ctx_P ibdbrc;
ibdb_ta_P ta;
ibdb_rcpt_P rcpt;
ibdb_hdrmod_P ibdb_hdrmod;
sessta_id_T id;
id_count_T id_count;
sm_str_P str;
sm_ret_T ret;
ret = ibdbr_open(base_dir, FNAME, SM_IO_RDONLY, init_seq, maxs,
IBDB_OFL_WRITE, &ibdbrc);
if (sm_is_err(ret) && sm_error_value(ret) == ENOENT)
return SM_SUCCESS;
SM_TEST(ret == SM_SUCCESS);
if (ret != SM_SUCCESS)
return ret;
str = NULL;
rcpt = NULL;
ta = (ibdb_ta_P) sm_zalloc(sizeof(*ta));
SM_TEST(ta != NULL);
if (ta == NULL)
goto end;
ta->ibt_ta_id = id;
ta->ibt_mail_pa = sm_str_new(NULL, 256, 256);
SM_TEST(ta->ibt_mail_pa != NULL);
if (ta->ibt_mail_pa == NULL)
goto end;
ibdb_hdrmod = (ibdb_hdrmod_P) sm_zalloc(sizeof(*ibdb_hdrmod));
SM_TEST(ibdb_hdrmod != NULL);
if (ibdb_hdrmod == NULL)
goto end;
rcpt = (ibdb_rcpt_P) sm_zalloc(sizeof(*rcpt));
SM_TEST(rcpt != NULL);
if (rcpt == NULL)
goto end;
rcpt->ibr_ta_id = id;
rcpt->ibr_pa = sm_str_new(NULL, 256, 256);
SM_TEST(rcpt->ibr_pa != NULL);
if (rcpt->ibr_pa == NULL)
goto end;
str = sm_str_new(NULL, 256, 256);
SM_TEST(str != NULL);
if (str == NULL)
goto end;
id_count = 0;
for (i = 0; i < iter; i++)
{
id_count++;
nrcpts = (i % 5) + 1;
for (j = 0; j < nrcpts; j++)
{
sm_str_clr(str);
ret = sm_strprintf(str,
"rcpt-%d-%d@other.Rcpt", i, j);
ret = ibdbr_get(ibdbrc, rcpt, ta, ibdb_hdrmod, &status);
SM_TEST(ret == RT_IBDB_RCPT);
if (sm_is_err(ret))
goto end;
SM_TEST(sm_memeq(sm_str_getdata(str),
sm_str_getdata(rcpt->ibr_pa),
sm_str_getlen(rcpt->ibr_pa)));
SM_TEST(rcpt->ibr_idx == (rcpt_idx_T) j);
}
ret = ibdbr_get(ibdbrc, rcpt, ta, ibdb_hdrmod, &status);
SM_TEST(ret == RT_IBDB_TA);
if (sm_is_err(ret) || ret != RT_IBDB_TA)
break;
SM_CSTR_FREE(ta->ibt_cdb_id);
for (j = 0; j < nrcpts; j++)
{
sm_str_clr(str);
ret = sm_strprintf(str,
"rcpt-%d-%d@other.Rcpt", i, j);
ret = ibdbr_get(ibdbrc, rcpt, ta, ibdb_hdrmod
, &status);
SM_TEST(ret == RT_IBDB_RCPT);
if (sm_is_err(ret))
goto end;
SM_TEST(sm_memeq(sm_str_getdata(str),
sm_str_getdata(rcpt->ibr_pa),
sm_str_getlen(rcpt->ibr_pa)));
}
ret = ibdbr_get(ibdbrc, rcpt, ta, ibdb_hdrmod, &status);
SM_TEST(ret == RT_IBDB_TA);
if (sm_is_err(ret) || ret != RT_IBDB_TA)
break;
SM_CSTR_FREE(ta->ibt_cdb_id);
}
end:
if (ta != NULL)
{
SM_STR_FREE(ta->ibt_mail_pa);
sm_free(ta);
}
if (rcpt != NULL)
{
SM_STR_FREE(rcpt->ibr_pa);
sm_free(rcpt);
}
SM_STR_FREE(str);
ret = ibdbr_close(ibdbrc);
SM_TEST(ret == SM_SUCCESS);
return ret;
}
int
main(int argc, char *argv[])
{
int iter, c, maxs;
sm_ret_T ret;
bool readonly;
char *base_dir;
base_dir = NULL;
iter = 100;
maxs = IBDBSIZE;
readonly = false;
while ((c = getopt(argc, argv, "b:d:i:m:Hr")) != -1)
{
switch (c)
{
case 'b':
base_dir = strdup(optarg);
if (NULL == base_dir)
return EX_OSERR;
break;
case 'd':
debug = strtol(optarg, NULL, 0);
break;
#if SM_HEAP_CHECK
case 'H':
SmHeapCheck = atoi(optarg);
break;
#endif /* SM_HEAP_CHECK */
case 'i':
iter = strtol(optarg, NULL, 0);
break;
case 'm':
maxs = strtol(optarg, NULL, 0);
break;
case 'r':
readonly = true;
break;
#if 0
default:
usage(argv[0]);
return(1);
#endif /* 0 */
}
}
sm_test_begin(argc, argv, "test idb-1");
if (readonly)
ret = SM_SUCCESS;
else
ret = testidb(base_dir, iter, maxs);
if (ret == SM_SUCCESS)
ret = testidbr(base_dir, iter, maxs);
return sm_test_end();
}
syntax highlighted by Code2HTML, v. 0.9.1