/*
 * Copyright (c) 2003-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: errlog.c,v 1.9 2006/10/05 04:27:37 ca Exp $")

#include <stdarg.h>
#include "sm/io.h"
#include <stdlib.h>
#include "sm/string.h"
#include <unistd.h>
#include <errno.h>
#include "sm/log.h"
#include "sm/errlog.h"
#if MTA_USE_STATETHREADS
#include "statethreads/st.h"
#endif /* MTA_USE_STATETHREADS */

#define snprintf sm_snprintf
#define vsnprintf sm_vsnprintf

/*
**  Simple error reporting functions.
**  Suggested in W. Richard Stevens' "Advanced Programming in UNIX
**  Environment".
*/

#define SM_LOG_MAXLINE (8 * 1024)	/* max line length */

#if 0
///*
// * Return a pointer to a string containing current time.
// * Warning: uses (local) static variable for result!
// */
//
//static char *
//errlog_tstamp(void)
//{
//	static char str[32];
//	static time_t lastt = 0;
//#if MTA_USE_PTHREADS
//	struct tm tm;
//#endif /* MTA_USE_PTHREADS */
//	struct tm *tmp;
//	time_t currt;
//
//	/* XXX statethreads specific... generic solution? */
//#if MTA_USE_STATETHREADS
//	currt = st_time();
//#else /* MTA_USE_STATETHREADS */
//	OOPS...
//#endif /* MTA_USE_STATETHREADS */
//	if (currt == lastt)
//		return str;
//		/* XXX protect access? */
//#if MTA_USE_PTHREADS
//	tmp = localtime_r(&currt, &tm);
//#else /* MTA_USE_PTHREADS */
//	tmp = localtime(&currt);
//#endif /* MTA_USE_PTHREADS */
//	snprintf(str, sizeof(str), "[%d-%02d-%02d/%02d:%02d:%02d] ",
//		1900 + tmp->tm_year,	/* HACK */
//		tmp->tm_mon + 1,
//		tmp->tm_mday,
//		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
//	lastt = currt;
//	return str;
//}
#endif /* 0 */

/*
**  Print a message and return to caller.
**  Caller specifies "errnoflag".
*/

static void
errlog_doit(sm_log_ctx_P lctx, bool errnoflag, const char *fmt, va_list ap)
{
	int errno_save;
#if 0
	int n;
	char buf[SM_LOG_MAXLINE];
#endif /* 0 */

	errno_save = errno;	/* value caller might want printed */

#if 0
//	/* prepend a message with time stamp */
//	strlcpy(buf, errlog_tstamp(), sizeof(buf));
//	n = strlen(buf);
//	vsnprintf(buf + n, sizeof(buf) - n, fmt, ap);
//	n = strlen(buf);
//
//	/* XXX ignored for now... */
//	if (errnoflag)
//		snprintf(buf + n, sizeof(buf) - n, ": %s",
//			strerror(errno_save));
#endif /* 0 */

#define LCAT	NULL
#define LMOD	NULL

	sm_log_vwrite(lctx,
		LCAT,	/* XXX */
		LMOD,	/* XXX */
		SM_LOG_ERR,	/* XXX */
		0,	/* XXX */
		fmt, ap);

	errno = errno_save;
}

/*
**  Nonfatal error related to a system call.
**  Print a message and return.
*/

void
errlog_sys_report(sm_log_ctx_P lctx, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	errlog_doit(lctx, true, fmt, ap);
	va_end(ap);
}

/*
**  Fatal error related to a system call.
**  Print a message and terminate.
*/

void
errlog_sys_quit(sm_log_ctx_P lctx, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	errlog_doit(lctx, true, fmt, ap);
	va_end(ap);
	exit(1);
}

/*
**  Fatal error related to a system call.
**  Print a message, dump core, and terminate.
*/

void
errlog_sys_dump(sm_log_ctx_P lctx, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	errlog_doit(lctx, true, fmt, ap);
	va_end(ap);
	abort();		/* dump core and terminate */
	/* NOTREACHED */
	exit(1);		/* shouldn't get here */
}

/*
**  Nonfatal error unrelated to a system call.
**  Print a message and return.
*/

void
errlog_report(sm_log_ctx_P lctx, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	errlog_doit(lctx, false, fmt, ap);
	va_end(ap);
}

/*
**  Fatal error unrelated to a system call.
**  Print a message and terminate.
*/

void
errlog_quit(sm_log_ctx_P lctx, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	errlog_doit(lctx, false, fmt, ap);
	va_end(ap);
	exit(1);
}


syntax highlighted by Code2HTML, v. 0.9.1