/*
 * Copyright (c) 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-extracthdr.c,v 1.10 2006/07/16 02:07:40 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/sm_extracthdr.h"
#include "sm/io.h"
#include "sm/sysexits.h"
#include "sm/test.h"

static int Verbose = 0;

static int
testextracthdr(sm_file_T *fp, size_t chunksize)
{
	sm_ret_T ret;
	bool newchunk;
	sm_xhdr_ctx_P sm_xhdr_ctx;
	size_t len, off, thislen;
	uchar *chunk;
	char mail1[] = "From: someone@some.com\r\nTo: luser@victim.com\r\nSUBJECT: M$\r\nsucks\r\nMIME-Version: 1.0\r\nContent-Type: multipart/alternative; boundary=\"abcdef\"\r\n\r\noh really?\r\n";

	off = 0;
	ret = sm_xhdr_init(SM_XHDR_FL_SKIP_FIRST_BLANK, &sm_xhdr_ctx);
	SM_TEST(sm_is_success(ret));
	chunk = (uchar *) mail1;
	len = thislen = strlen((char *)chunk);
	newchunk = true;
	if (fp != NULL)
	{
		ret = sm_refill(fp);
		if (sm_is_err(ret))
			return ret;
		chunk = f_p(*fp);
		len = thislen = f_r(*fp);
	}

	if (chunksize > 0 && thislen > chunksize)
		thislen = chunksize;
	do {
		ret = sm_xhdr(chunk + off, thislen, newchunk, sm_xhdr_ctx);
		newchunk = false;
		if (ret == SM_XHDR_GOT1 || ret == SM_XHDR_GOTA ||
		    ret == SM_XHDR_GOTL)
		{
			sm_io_fprintf(smioout, "name: %#S\n",
				sm_xhdr_ctx->sm_xhdr_name);
			sm_io_fprintf(smioout, "value: %#S\n",
				sm_xhdr_ctx->sm_xhdr_value);
		}
		if (ret == SM_XHDR_CONT && thislen + off < len)
		{
			newchunk = true;
			off += thislen;
			if (off + thislen > len)
				thislen = len - off;
		}
		else if (ret == SM_XHDR_CONT && fp != NULL)
		{
			newchunk = true;
			ret = sm_refill(fp);
			if (sm_is_err(ret))
				return ret;
			chunk = f_p(*fp);
			len = thislen = f_r(*fp);
			if (chunksize > 0 && thislen > chunksize)
				thislen = chunksize;
		}
	} while (!sm_is_err(ret) && ret != SM_XHDR_EOHDR
		 && ret != SM_XHDR_GOTL);
	if (Verbose > 0 && sm_is_err(ret))
		sm_io_fprintf(smioout, "ret=%r, error=%m\n", ret, ret);
	sm_io_flush(smioout);
	ret = sm_xhdr_end(sm_xhdr_ctx);
	SM_TEST(sm_is_success(ret));
	return 0;
}

static void
usage(const char *prg)
{
	sm_io_fprintf(smioerr,
		"%s: usage: %s [options] [mail]\n"
		"options:\n"
		"-s n     set chunksize to n\n"
		"-V       increase verbosity\n"
		, prg, prg
		);
	exit(EX_USAGE);
}

int
main(int argc, char **argv)
{
	int c;
	size_t chunksize;
	char *prg;
	sm_file_T *fp;

	chunksize = 0;
	prg = argv[0];
	while ((c = getopt(argc, argv, "s:V")) != -1)
	{
		switch (c)
		{
		  case 's':
			chunksize = strtoul(optarg, NULL, 0);
			break;
		  case 'V':
			++Verbose;
			break;
		  default:
			usage(prg);
			break;
		}
	}
	sm_test_begin(argc, argv, "test extracthdr");
	argc -= optind;
	argv += optind;

	if (argc > 0)
	{
		for (c = 0; c < argc; c++)
		{
			sm_ret_T ret;

			ret = sm_io_open(SmStStdio, argv[c], SM_IO_RDONLY, &fp,
					SM_IO_WHAT_END);
			SM_TEST(ret == SM_SUCCESS);
			SM_TEST(fp != NULL);
			if (fp != NULL)
				(void) testextracthdr(fp, chunksize);
			ret = sm_io_close(fp, SM_IO_CF_NONE);
		}
	}
	else
		(void) testextracthdr((sm_file_T *)0, chunksize);

	return sm_test_end();
}


syntax highlighted by Code2HTML, v. 0.9.1