/*
 * Copyright (c) 2005, 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: greyprint.c,v 1.7 2006/11/30 04:32:59 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/net.h"
#include "sm/time.h"
#include "sm/sysexits.h"
#include "sm/greyctl.h"
#include "sm/bdb.h"
#if MTA_USE_PTHREADS
#include "sm/pthread.h"
#endif
#include "greyctl.h"

static int Verbose = 0;
#define MAX_BUF_LEN_TIME	32

static sm_ret_T
grey_display0(DB *db, sm_file_T *fp)
{
	sm_ret_T ret;
	DBC *dbcp;
	DBT db_data, db_key;
	greyentry_T ge;

	ret = db->cursor(db, NULL, &dbcp, 0);
	if (ret != 0)
		return ret;
	do
	{
		sm_memzero(&db_key, sizeof(db_key));
		sm_memzero(&db_data, sizeof(db_data));
		db_data.flags = DB_DBT_USERMEM;
		db_data.data = ≥
		db_data.ulen = sizeof(ge);

		ret = dbcp->c_get(dbcp, &db_key, &db_data, DB_NEXT);
		if (ret != 0)
			break;
		if (Verbose == 0)
		{
			sm_io_fprintf(fp,
				"addr=%16A, time=%7ld, expire=%7ld, type=%s\n",
				(ipv4_T) ge.ge_key,
				(long) ge.ge_time,
				(long) ge.ge_expire,
				ge.ge_type == GREY_TYPE_GREY ? "grey" :
				ge.ge_type == GREY_TYPE_WHITE ? "white"
				: "oops");
		}
#if HAVE_STRFTIME
		if (Verbose >= 1)
		{
			char b_time[MAX_BUF_LEN_TIME], e_time[MAX_BUF_LEN_TIME];

			strftime(b_time, sizeof(b_time), "%Y-%m-%d/%H:%M:%S",
				localtime(&(ge.ge_time)));
			strftime(e_time, sizeof(e_time), "%Y-%m-%d/%H:%M:%S",
				localtime(&(ge.ge_expire)));
			sm_io_fprintf(fp,
				"addr=%16A, time=%s, expire=%s, type=%s\n",
				(ipv4_T) ge.ge_key, b_time, e_time,
				ge.ge_type == GREY_TYPE_GREY ? "grey" :
				ge.ge_type == GREY_TYPE_WHITE ? "white"
				: "oops");
		}
#endif
	} while (ret == 0);
	ret = dbcp->c_close(dbcp);
	return ret;
}

static sm_ret_T
grey_print(const char *db_name)
{
	sm_ret_T ret;
	DB *db;
#define dbenv	NULL

	/* open primary */
	ret = db_create(&db, dbenv, 0);
	if (ret != 0)
		return ret;
	ret = db->open(db, NULL, db_name, NULL, DB_BTREE, DB_RDONLY, 0600);
	if (ret != 0)
		return ret;

	grey_display0(db, smioout);
	sm_io_putc(smioout, '\n');
	sm_io_flush(smioout);
	ret = db->close(db, 0);
	return ret;
}

/*
**  USAGE -- Show usage
**
**	Parameters:
**		prg -- program name
**
**	Returns:
**		none
*/

static void
usage(const char *prg)
{
	fprintf(stderr, "%s: usage: %s [options] grey.db\n"
		"options:\n"
		"-V       increase verbosity\n"
		, prg, prg);
}

int
main(int argc, char *argv[])
{
	int c, r;
	char *db_name;
#define DB_NAME "grey_grey_m.db"

	db_name = DB_NAME;
	while ((c = getopt(argc, argv, "V")) != -1)
	{
		switch (c)
		{
		  case 'V':
			++Verbose;
			break;
		  default:
			usage(argv[0]);
			return EX_USAGE;
		}
	}
	argc -= optind;
	argv += optind;

	r = 0;	/* shut up bogus gcc complaint */
	if (argc == 0)
		r = grey_print(db_name);
	else
	{
		for (c = 0; c < argc; c++)
			r = grey_print(argv[c]);
	}
	return r;
}


syntax highlighted by Code2HTML, v. 0.9.1