/*
 * 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: qmgr.h,v 1.36 2007/03/26 02:41:27 ca Exp $
 */

#ifndef QMGR_H
#define QMGR_H 1

#include "sm/generic.h"
#include "sm/error.h"
#include "sm/io.h"
#include "sm/mta.h"
#include "sm/evthr.h"
#include "sm/rcb.h"
#include "sm/rcbl.h"
#include "sm/rcbcomm.h"
#include "sm/qmgr.h"
#include "sm/actdb.h"
#include "sm/cdb.h"
#include "sm/edb.h"
#include "sm/ibdb.h"
#include "sm/dadbstr.h"
#include "sm/sm-conf.h"


/*
**  Question: other resource problems, e.g., disk full?
*/

#define QM_DA_STAT_FATAL(rv)					\
	(sm_error_value(rv) == ENOMEM ||			\
	 sm_error_value(rv) == SM_E_UNEXPECTED ||		\
	 sm_error_value(rv) == SM_E_RANGE ||			\
	 sm_error_value(rv) == SM_E_2BIG ||			\
	 sm_error_value(rv) == SM_E_FULL ||			\
	 sm_error_value(rv) == SM_E_OVFLW_SC ||			\
	 sm_error_value(rv) == SM_E_OVFLW_NS ||			\
	 SM_IS_BDB_ERR(rv) ||	/* any BDB error? */		\
	 sm_error_module(rv) == SM_EM_IO /* any I/O error? */	\
	)

/* prototypes */
sm_ret_T qmgr_init0(qmgr_ctx_P _qmgr_ctx);
sm_ret_T qmgr_init1(qmgr_ctx_P _qmgr_ctx);
sm_ret_T qmgr_rdcf(qmgr_ctx_P _qmgr_ctx, int _argc, char *_argv[]);
sm_ret_T qm_read_cnf(qmgr_ctx_P _qmgr_ctx, const char *_fn, sm_conf_T **_psmc);

sm_ret_T qmgr_start(qmgr_ctx_P _qmgr_ctx);
sm_ret_T qmgr_stop(qmgr_ctx_P _qmgr_ctx);

sm_ret_T qm_gen_li(sm_evthr_task_P _tsk);

/* QMGR and SMTPS */
sm_ret_T qmgr_smtps(sm_evthr_task_P _tsk);
sm_ret_T qm_fr_ss(sm_evthr_task_P _tsk);
sm_ret_T qm_to_ss(sm_evthr_task_P _tsk);
sm_ret_T qss_ctx_new(qmgr_ctx_P _qmgr_ctx, qss_ctx_P *_pqss_ctx);
sm_ret_T qss_ctx_free(qss_ctx_P _qss_ctx);
sm_ret_T qss_ctx_close(qss_ctx_P _qss_ctx);

sm_ret_T qss_control(qss_ctx_P _qss_ctx, int _direction, uint _use, uint _resource, thr_lock_T _locktype);
sm_ret_T qss_unthrottle(qss_ctx_P _qss_ctx);
sm_ret_T qss_wakeup(qmgr_ctx_P _qmgr_ctx, thr_lock_T _locktype);
sm_ret_T qm_ss_wakeup(sm_evthr_task_P _tsk);

/* create replies for requests from SMTPS */
sm_ret_T qm_2ss_nseid(qss_ctx_P _ssctx, sm_rcbe_P _rcbe, uchar *_sessid, int _status);
sm_ret_T qm_2ss_ctaid(qss_ctx_P _ssctx, qss_ta_P _ta, sm_rcbe_P _rcbe, int _status);

/* check whether to accept "command" from SMTPS */
sm_ret_T qm_ss_nseid(qss_ctx_P _ssctx, qss_sess_P sess);
sm_ret_T qm_ss_1taid(qss_ctx_P _qss_ctx, qss_ta_P _qss_ta);
sm_ret_T qm_ss_rcptid(qss_ctx_P _qss_ctx, qss_ta_P _qss_ta, sm_evthr_task_P _tsk, qss_rcpt_P _rcpt);
sm_ret_T qm_ss_ctaid(qss_ctx_P _ssctx, qss_ta_P _ta);
sm_ret_T qm_ss_schedctaid(qmgr_ctx_P _qmgr_ctx, qss_ta_P _ta);
sm_ret_T qm_ss_dtaid(qss_ctx_P _ssctx, qss_ta_P _ta, uint _rmflags);
sm_ret_T qm_ss_rcptdel(qss_ctx_P _qss_ctx, qss_ta_P _qss_ta, sm_str_P _rcpt_pa, rcpt_idx_T _rcpt_idx);

/* flags for qss_rcpt_free() etc */
#define QSS_RMFIQDB		0x01	/* remove from IQDB */
#define QSS_DECR_RCPTS_TOT	0x02	/* decrement qssta_rcpts_tot */
#define QSS_IQDB_NOLOCK		0x04	/* do not lock IQDB */

sm_ret_T qss_mail_new(qss_ta_P _ta);
sm_ret_T qss_mail_free(qss_ta_P _ta);
sm_ret_T qss_rcpts_new(qss_ta_P _ta, sm_str_P *_prcpt_pa,
			rcpt_idx_T _rcpt_idx, qss_rcpt_P *_prcpt);
sm_ret_T qss_rcpt_free(qss_ta_P _ta, qss_rcpt_P _addr, uint _rmflags);
sm_ret_T qss_rcpts_free(qss_ta_P _ta, uint _rmflags, rcpt_idx_T *_prcpt_idx_high);
sm_ret_T qss_ta_abort(qss_ta_P _ta);
sm_ret_T qss_ta_free(qss_ta_P _ta, bool _unlock, uint _flag, uint _rmflags);
sm_ret_T qss_ta_new(qss_ta_P *_ta, qss_ctx_P _ssctx, sm_rpool_P rpool_);
sm_ret_T qss_sess_free(qss_sess_P _sess);
sm_ret_T qss_sess_new(qss_sess_P *_sess, sm_rpool_P _rpool);


/* resource control */
sm_ret_T qm_resource(qmgr_ctx_P _qmgr_ctx, int _direction, uint _use, uint _resource);
sm_ret_T qm_comp_resource(qmgr_ctx_P _qmgr_ctx, thr_lock_T _locktype);

sm_ret_T qm_rsr_problem(qmgr_ctx_P _qmgr_ctx, uint _resource, thr_lock_T _locktype);

/* SMTPC */
sm_ret_T qmgr_smtpc(sm_evthr_task_P _tsk);
sm_ret_T qm_fr_sc(sm_evthr_task_P _tsk);
sm_ret_T qm_to_sc(sm_evthr_task_P _tsk);
sm_ret_T qsc_ctx_new(qmgr_ctx_P _qmgr_ctx, uint8_t _idx, qsc_ctx_P *_pqsc);
sm_ret_T qsc_ctx_free(qsc_ctx_P _qsc);
sm_ret_T qsc_ctx_close(qsc_ctx_P _qsc_ctx);


/* AR */
sm_ret_T qmgr_ar(sm_evthr_task_P _tsk);
sm_ret_T qm_fr_ar(sm_evthr_task_P _tsk);
sm_ret_T qm_to_ar(sm_evthr_task_P _tsk);
sm_ret_T qar_ctx_new(qmgr_ctx_P _qmgr_ctx, qar_ctx_P *_par_ctx);
sm_ret_T qar_ctx_free(qar_ctx_P _ar_ctx);

sm_ret_T qm_ar_actsched(qmgr_ctx_P _qmgr_ctx, aq_rcpt_P _aq_rcpt, bool *_pnotify_sched);

uint	 qm_delay_next_try(qmgr_ctx_P _qmgr_ctx, aq_rcpt_P _aq_rcpt);

sm_ret_T qda_upd_iqdb(qmgr_ctx_P _qmgr_ctx, uint _iqdb_rcpts_done, sessta_id_T _ss_ta_id, cdb_id_P _cdb_id, ibdb_req_hd_P _ibdb_req_hd);

sm_ret_T qda_upd_ta_rcpt_stat(qmgr_ctx_P _qmgr_ctx
			, sessta_id_T _da_ta_id
			, sm_ret_T _status
			, uint _err_st
			, dadb_ctx_P dadb_ctx
			, dadb_entry_P _dadb_entry
			, aq_ta_P _aq_ta
			, aq_rcpt_P _aq_rcpt
			, edb_req_hd_P _edb_req_hd
			, ibdb_req_hd_P ibdb_req_hd
			, sm_str_P errmsg
			, int *pdelay_next_try
			);

sm_ret_T q_upd_rcpt_stat(qmgr_ctx_P _qmgr_ctx
			, sessta_id_T _ss_ta_id
			, sm_ret_T _status
			, uint _err_st
			, aq_ta_P _aq_ta
			, aq_rcpt_P _aq_rcpt
			, edb_req_hd_P _edb_req_hd
			, ibdb_req_hd_P _ibdb_req_hd
			, sm_str_P _errmsg
			, uint *_piqdb_rcpts_done
			, int *_pdelay_next_try
			);

sm_ret_T qda_dadb_close(qmgr_ctx_P _qmgr_ctx, sessta_id_T _da_ta_id, dadb_ctx_P _dadb_ctx, dadb_entry_P _dadb_entry, sm_ret_T _status, sm_ret_T *_pflags);

sm_ret_T qm_bounce_add(qmgr_ctx_P _qmgr_ctx, aq_ta_P _aq_ta, aq_rcpt_P _aq_rcpt, sm_str_P _errmsg, aq_rcpt_P *_paq_rcpt_dsn);

/* cleanup functions */
sm_ret_T qcleanup_ctx_free(qcleanup_ctx_P _qcleanup_ctx);
sm_ret_T qcleanup_ctx_new(qmgr_ctx_P _qmgr_ctx, qcleanup_ctx_P *_pqcleanup_ctx);
sm_ret_T qmgr_cleanup(sm_evthr_task_P _tsk);
sm_ret_T qmgr_set_cleanup(qcleanup_ctx_P _qcleanup_ctx, time_T _when, uint _which, bool _changewakeup);

/* control socket */
sm_ret_T qm_ctl_li(sm_evthr_task_P _tsk);
sm_ret_T qm_info(qmgr_ctx_P _qmgr_ctx, sm_file_T *_fp);

sm_ret_T qm_reopen_maps(qmgr_ctx_P _qmgr_ctx);

/* callback for IQDB operations */
void	*qm_iqdb_create(const char *, uint, void *, void *, uint);

/* EDBR */
sm_ret_T qm_get_edb_entries(qmgr_ctx_P _qmgr_ctx, int *_pnext_try);
sm_ret_T qm_edb_scan(qmgr_ctx_P _qmgr_ctx);

sm_ret_T qmgr_ibdb_commit(sm_evthr_task_P _tsk);
sm_ret_T qmgr_sched(sm_evthr_task_P _tsk);

sm_ret_T qm_rcbe_new(qmgr_ctx_P qmgr_ctx, sm_rcbe_P *_prcbe, int _minsz);
sm_ret_T qm_rcbcom_prerep(qmgr_ctx_P qmgr_ctx, rcbcom_ctx_P _rcbcom_ctx, sm_evthr_task_P _tsk, sm_rcbe_P *_prcbe);
sm_ret_T qm_rcbe_put(qmgr_ctx_P _qmgr_ctx, sm_rcbe_P _rcbe);

#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
sm_ret_T chkaq_ta(qmgr_ctx_P _qmgr_ctx, aq_ta_P _aq_ta);
#endif

#endif /* QMGR_H */


syntax highlighted by Code2HTML, v. 0.9.1