/*
* 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-rcb-dec.c,v 1.6 2005/03/15 19:56:02 ca Exp $")
#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/heap.h"
#include "sm/ctype.h"
#include "sm/test.h"
#include "sm/str.h"
#include "sm/rcb.h"
#include "sm/reccom.h"
#include <stdio.h>
#define SMAXLEN (64 * 1024)
#define PRINTIT(c) (ISPRINT(c) ? (c) : '_')
int
dec_rcb(sm_rcb_P rcb)
{
int r;
uint u;
uint32_t l, rt, v, tl;
uchar *src;
u = 0;
r = sm_rcb_open_dec(rcb);
SM_TEST(r == SM_SUCCESS);
/* Total length of record */
r = sm_rcb_getuint32(rcb, &tl);
SM_TEST(!(sm_is_err(r) || tl > SMAXLEN ||
tl > sm_rcb_getlen(rcb)));
if (sm_is_err(r) || tl > SMAXLEN ||
tl > sm_rcb_getlen(rcb))
{
fprintf(stderr, "tl=%4u, r=0x%x\n", tl, r);
goto error;
}
u += 4;
fprintf(stdout, "tl=%4u\n", tl);
r = sm_rcb_get3uint32(rcb, &l, &rt, &v);
SM_TEST(r == SM_SUCCESS);
if (sm_is_err(r))
goto error;
fprintf(stdout, "rt=%08X, l=%4u, v=%08X\n", rt, l, v);
u += 12;
SM_TEST(!(l != 4 || rt != RT_PROT_VER || v != PROT_VER_RT));
if (l != 4 || rt != RT_PROT_VER || v != PROT_VER_RT)
{
r = sm_error_perm(SM_EM_Q_SC2Q, SM_E_PR_V_MISM);
}
while (!SM_RCB_ISEOB(rcb) && u < tl)
{
r = sm_rcb_get2uint32(rcb, &l, &rt);
SM_TEST(r == SM_SUCCESS);
if (sm_is_err(r))
break;
fprintf(stdout, "%4u: rt=%08X, l=%4u: ", u, rt, l);
u += 8;
while (l > 0)
{
r = sm_rcb_getuint32(rcb, &v);
SM_TEST(r == SM_SUCCESS);
if (sm_is_err(r))
goto error;
fprintf(stdout, "0x%08X ", v);
src = (uchar *) &v;
fprintf(stdout, "%c%c%c%c "
, PRINTIT(src[0])
, PRINTIT(src[1])
, PRINTIT(src[2])
, PRINTIT(src[3]));
u += 4;
SM_TEST(l >= 4);
if (l >= 4)
l -= 4;
else
{
/* COMPLAIN? */
break;
fprintf(stdout, "\n");
goto error;
}
SM_TEST(u <= tl);
if (u > tl)
{
/* COMPLAIN? */
fprintf(stdout, "\nERROR: TL exceeded\n");
goto error;
}
}
fprintf(stdout, "\n");
}
SM_TEST(u == tl && SM_RCB_ISEOB(rcb));
if (u >= tl && !SM_RCB_ISEOB(rcb))
{
fprintf(stdout, "ERROR: u=%u, tl=%u, eob=%d\n", u, tl,
SM_RCB_ISEOB(rcb));
}
error:
return r;
}
int
read_rcb(FILE *fp, sm_rcb_P rcb)
{
int r, i;
uint32_t u;
i = 0;
while (fscanf(fp, "%x", &u) == 1)
{
r = sm_rcb_putuint32(rcb, u);
SM_TEST(r == SM_SUCCESS);
if (SmTestVerbose)
fprintf(stdout, "%4d: %08x ", i, u);
++i;
if (SmTestVerbose && i % 4 == 0)
fprintf(stdout, "\n");
}
if (SmTestVerbose)
fprintf(stdout, "\ngot %d\n", i);
r = sm_rcb_close_enc(rcb);
SM_TEST(r == SM_SUCCESS);
return 0;
}
int
open_rcb(sm_rcb_P *prcb)
{
int r;
sm_rcb_P rcb;
rcb = sm_rcb_new(NULL, SMAXLEN, SMAXLEN);
SM_TEST(rcb != NULL);
if (rcb == NULL)
return -1;
r = sm_rcb_open_enc(rcb, SMAXLEN);
SM_TEST(r == SM_SUCCESS);
*prcb = rcb;
return r;
}
int
main(int argc, char *argv[])
{
int r;
sm_rcb_P rcb;
sm_test_begin(argc, argv, "test rcb decode");
rcb = NULL;
r = open_rcb(&rcb);
if (r != SM_SUCCESS)
return r;
r = read_rcb(stdin, rcb);
if (r != SM_SUCCESS)
return r;
dec_rcb(rcb);
return sm_test_end();
}
syntax highlighted by Code2HTML, v. 0.9.1