/*
 * 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.
 *
 *	$Id: qmgrdbg.h,v 1.22 2007/03/26 03:21:33 ca Exp $
 */

#ifndef SM_QMGRDBG_H
#define SM_QMGRDBG_H 1

#include "sm/generic.h"
#include "sm/qmgrcto.h"

#if QMGR_DEBUG
# include "sm/io.h"

# define QMGR_DEBUG_CATS	32	/* maximum number of debug categories */

/* synchronize this with qmgr/log.h: QM_LMOD_ */
# define QDC_GENERIC	0	/* default if nothing else is specified */
# define QDC_INIT	1
# define QDC_START	2
# define QDC_STOP	3
# define QDC_S2Q	4	/* SMTPS to QMGR */
# define QDC_Q2S	5	/* QMGR to SMTPS */
# define QDC_C2Q	6	/* SMTPC to QMGR */
# define QDC_Q2C	7	/* QMGR to SMTPC */
# define QDC_A2Q	8	/* SMAR to QMGR */
# define QDC_Q2A	9	/* QMGR to SMAR */
# define QDC_SCHED	10
# define QDC_UPDRCPT	11
# define QDC_BOUNCE	12
# define QDC_CLEANUP	13
# define QDC_RSRC	14
# define QDC_EDBR	15
# define QDC_EDBS	16
# define QDC_EDBC	17
# define QDC_IQDB	18
# define QDC_IBDB	19
# define QDC_CTL2Q	20	/* CTL to QMGR */
# define QDC_WKSCHED	21	/* wakeup scheduler */
# define QDC_IBDBR	22
# define QDC_OCC	23
/* # define QDC_DADB	24 */

# define QDC_C2Q_TM	24	/* SMTPC to QMGR: timing */
# define QDC_S2Q_TM	25	/* SMTPS to QMGR: timing */
# define QDC_Q2C_TM	26	/* QMGR to SMTPC: timing */

/* check whether last number is too big */
# if QDC_Q2C_TM >= QMGR_DEBUG_CATS
 ERROR: QDC_Q2C_TM >= QMGR_DEBUG_CATS_
# endif

# if QMGR_DEBUG_DEFINE
uint qm_debug[QMGR_DEBUG_CATS];
# else
extern uint qm_debug[QMGR_DEBUG_CATS];
# endif

# define QM_DEBFP	smioerr
# define QM_LEV_DPRINTF(lev, x)	do			\
	{						\
		if ((lev) < qm_debug[0])		\
			sm_io_fprintf x;		\
	} while (0)

# define QM_LEV_DPRINTFC(cat, lev, x)	do		\
	{						\
		if ((lev) < qm_debug[cat])		\
			sm_io_fprintf x;		\
	} while (0)

/* This is ugly since it references QM_DEBFP */
# define QM_LEV_DPRINTT(lev, x, tv)	do		\
	{						\
		if ((lev) <= qm_debug[0])		\
		{					\
			sm_io_fprintf(QM_DEBFP, "%ld.%06ld: ", (tv).tv_sec, (tv).tv_usec);	\
			sm_io_fprintf x;		\
		}					\
	} while (0)

# define QM_LEV_DPRINTTC(cat, lev, x, tv)	do {	\
		if ((lev) <= qm_debug[cat])		\
		{					\
			sm_io_fprintf(QM_DEBFP, "%ld.%06ld: ", (tv).tv_sec, (tv).tv_usec);	\
			sm_io_fprintf x;		\
		}					\
	} while (0)


# define QM_DPRINTF(x)	sm_io_fprintf x
#else /* QMGR_DEBUG */
# define QM_DPRINTF(x)
# define QM_LEV_DPRINTF(lev, x)
# define QM_LEV_DPRINTT(lev, x, tv)
# define QM_LEV_DPRINTFC(cat, lev, x)
# define QM_LEV_DPRINTTC(cat, lev, x, tv)
#endif /* QMGR_DEBUG */

#if QM_TIMING
# if HAVE_GETHRTIME
#  define QM_HRT_DPRINTF(cat, lev, x)	do {	\
		if (qm_debug[cat] > (lev)) {		\
		hrtime_t hrt;				\
		hrt = gethrtime();			\
		sm_io_fprintf(QM_DEBFP, "r=%lld: ", hrt);	\
		sm_io_fprintf x;			\
		}					\
	} while (0)
# endif

# if HAVE_GETHRVTIME
#  define QM_HRVT_DPRINTF(cat, lev, x)	do {	\
		if (qm_debug[cat] > (lev)) {		\
		hrtime_t hrt;				\
		hrt = gethrvtime();			\
		sm_io_fprintf(QM_DEBFP, "v=%lld: ", hrt);	\
		sm_io_fprintf x;			\
		}					\
	} while (0)
# endif

# if HAVE_GETHRVTIME && HAVE_GETHRTIME
#  define QM_HRBT_DPRINTF(cat, lev, x)	do {	\
		if (qm_debug[cat] > (lev)) {		\
		hrtime_t hrvt, hrt;			\
		hrt = gethrtime();			\
		hrvt = gethrvtime();			\
		sm_io_fprintf(QM_DEBFP, "r=%lld, v=%lld: ", hrt, hrvt);	\
		sm_io_fprintf x;			\
		}					\
	} while (0)
# elif HAVE_CLOCK_GETTIME
#  define QM_HRBT_DPRINTF(cat, lev, x)	do {	\
		if (qm_debug[cat] > (lev)) {		\
		struct timespec tsr, tsv;		\
		int r;					\
		r = clock_gettime(CLOCK_MONOTONIC, &tsr);	\
		if (r != 0) timespecclear(&tsr);	\
		r = clock_gettime(CLOCK_PROF, &tsv);	\
		if (r != 0) timespecclear(&tsv);	\
		sm_io_fprintf(QM_DEBFP, "r=%d.%09ld, v=%d.%09ld: ", tsr.tv_sec, tsr.tv_nsec, tsv.tv_sec, tsv.tv_nsec);			\
		sm_io_fprintf x;			\
		}					\
	} while (0)
# endif
#endif /* QM_TIMING */

#ifndef	QM_HRT_DPRINTF
# define QM_HRT_DPRINTF(cat, lev, x)
#endif

#ifndef	QM_HRVT_DPRINTF
# define QM_HRVT_DPRINTF(cat, lev, x)
#endif

#ifndef	QM_HRBT_DPRINTF
# define QM_HRBT_DPRINTF(cat, lev, x)
#endif

#if QMGR_DEBUG > 1
void	 aq_rcpt_print(aq_rcpt_P _aq_rcpt);
void	 aq_ta_print(aq_ta_P _aq_ta);
#endif

#if QMGR_DEBUG > 2
# define CDB_PRT(cdb_id, ss_ta_id, where) \
	sm_io_fprintf(smioerr, "where=%s, ref=%u, ss_ta=%s, cdb_id=%C\n", where, cdb_id != NULL ? cdb_id->sm_cstr_refcnt : UINT_MAX, ss_ta_id, cdb_id)
#else /* QMGR_DEBUG */
# define CDB_PRT(cdb_id, ss_ta_id, where) 
#endif /* QMGR_DEBUG */

#endif /* SM_QMGRDBG_H */


syntax highlighted by Code2HTML, v. 0.9.1