/*
* Copyright (c) 2002-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: edb.h,v 1.53 2007/06/18 04:42:30 ca Exp $
*/
#ifndef SM_EDB_H
#define SM_EDB_H 1
#include "sm/generic.h"
#include "sm/types.h"
#include "sm/magic.h"
#include "sm/str.h"
#include "sm/time.h"
#include "sm/mta.h"
#include "sm/io.h"
#include "sm/log.h"
#include "sm/rcb.h"
#include "sm/bdb.h"
#include "sm/pthread.h"
#include "sm/actdb.h"
#include "sm/queue.h"
#include "sm/edbdef.h"
#include "sm/edbcnf.h"
#ifndef SM_REQL_FLE
#define SM_REQL_FLE 0
#endif
/* Abstraction layer for deferred envelope database (disk only) */
#if 0
XXX Use same data as AQ?
/*
from db.func.tex:
*/
#endif /* 0 */
/*
** Default and maximum size for an RCB which is used to hold ta/rcpt
** information for transferring AQ data to/from EDB.
** Note: if the default size is rather large, then a lot of space is
** wasted. If it is too small, then it could happen that an
** encoding/decoding fails because it runs out of memory.
** XXX need to gather some statistics (and count some bytes...)
** The last entry is the "minimum" size for a rcpt RCB: about 96 bytes
** default data and up to 256 bytes of address rounded to the next
** multiple of 2.
*/
#define EDB_RC_SZ (8 * 1024)
#define EDB_RC_MAXSZ (64 * 1024)
#define EDB_RC_SMALLSZ 512
typedef struct edb_ctx_S edb_ctx_T, *edb_ctx_P;
typedef struct edb_req_S edb_req_T, *edb_req_P;
#if 0
typedef struct edb_ta_S edb_ta_T, *edb_ta_P;
typedef struct edb_rcpt_S edb_rcpt_T, *edb_rcpt_P;
#endif /* 0 */
/* Berkeley DB cursor */
typedef DBC edb_cursor_T, *edb_cursor_P;
/* Use enum? */
#define EDB_REQ_TA 0x01
#define EDB_REQ_RCPT 0x02
#define EDB_REQ_VRS 0x04
#define EDB_REQ_TA_DEL 0x11
#define EDB_REQ_RCPT_DEL 0x12
/* request flags */
#define EDB_RQF_NONE 0x00u
#define EDB_RQF_SMALL 0x01u /* get a "small" rcb */
#define EDB_RQF_ALLOC 0x02u /* alloc rcb even if there are some in list */
#define EDB_RQF_FREE 0x04u /* free rcb instead of putting it into a list */
#if SM_REQL_FLE
#define EDB_RQF_EMERG 0x08u /* get an "emergency" rcb */
#endif
/*
** struct to store "requests", i.e., a list of changes for DEFEDB.
** These changes will be committed in a single transaction.
** An RCB stores the data for the DB entry, req_id is the key,
** its content depends on the request type: it's either a
** - transaction ID or a
** - recipient ID
*/
struct edb_req_S
{
uint edb_req_type;
smtp_id_T edb_req_id;
sm_rcb_P edb_req_rcb;
SIMPLEQ_ENTRY(edb_req_S) edb_req_link;
};
#define EDBREQL_INIT(edb_req_hd) SIMPLEQ_INIT(edb_req_hd)
#define EDBREQL_FIRST(edb_req_hd) SIMPLEQ_FIRST(edb_req_hd)
#define EDBREQL_END(edb_req_hd) SIMPLEQ_END(edb_req_hd)
#define EDBREQL_EMPTY(edb_req_hd) SIMPLEQ_EMPTY(edb_req_hd)
#define EDBREQL_NEXT(edb_req) SIMPLEQ_NEXT(edb_req, edb_req_link)
#define EDBREQL_PRE(edb_req_hd, edb_req) SIMPLEQ_INSERT_HEAD(edb_req_hd, edb_req, edb_req_link)
#define EDBREQL_APP(edb_req_hd, edb_req) SIMPLEQ_INSERT_TAIL(edb_req_hd, edb_req, edb_req_link)
#define EDBREQL_REMOVE(edb_req_hd) SIMPLEQ_REMOVE_HEAD(edb_req_hd, edb_req_link)
#define SM_IS_EDBREQL(edb_req_hd) SM_ASSERT((edb_req_hd) != NULL)
typedef SIMPLEQ_HEAD(, edb_req_S) edb_req_hd_T, *edb_req_hd_P;
#if 0
/*
** No extra data structures for EDB rcpts/tas, the data is transferred
** using AQ structures to avoid extra copying.
*/
/*
** XXX need:
** delivery agent
** host(list) for connection (pre-MX?)
*/
// struct edb_rcpt_S
// {
// sessta_id_T edbr_ss_ta_id; /* ta id in SMTPS */
// sm_str_P edbr_pa; /* printable addr */
// smtp_status_T edbr_status; /* status */
// uint edbr_flags; /* flags */
// rcpt_idx_T edbr_idx; /* rcpt idx */
// uint edbr_tries; /* deliver attemts */
// uint32_t edbr_srv_ipv4; /* XXX HACK! */
// time_T edbr_st_time; /* start time (rcvd) */
// time_T edbr_last_try;
// time_T edbr_next_try;
//
// /* XXX parameters? */
// };
//
//
// /* transaction context */
// struct edb_ta_S
// {
// sessta_id_T edbta_ta_id; /* ta id in SMTPS */
// sm_str_P edbta_mail_pa; /* printable addr */
// uint edbta_rcpts_tot; /* total number recipients */
// uint edbta_rcpts_left; /* rcpts still to deliver */
// uint edbta_state;
// size_t edbta_msg_size; /* KB */
// cdb_id_P edbta_cdb_id;
//
// /* XXX other times? */
// time_T edbta_st_time; /* start time (received) */
// };
#endif /* 0 */
sm_ret_T edb_open(edb_cnf_P _edb_cnf, const char *_base_path, sm_log_ctx_P _lctx, edb_ctx_P *_edb);
sm_ret_T edb_close(edb_ctx_P _edb);
sm_ret_T edb_rcpt_app(edb_ctx_P _edb_ctx, aq_rcpt_P _aq_rcpt, edb_req_hd_P _edb_req_hd, int _status);
sm_ret_T edb_ta_app(edb_ctx_P _edb_ctx, aq_ta_P _aq_ta, edb_req_hd_P _edb_req_hd, int _status);
sm_ret_T edb_wr_status(edb_ctx_P _edb_ctx, edb_req_hd_P _edb_req_hd);
sm_ret_T edb_rd_req(edb_ctx_P _edb_ctx, edb_req_P _edb_req);
sm_ret_T edb_req_new(edb_ctx_P _edb_ctx, uint32_t _flags, edb_req_P *_pedb_req, bool _lockit);
sm_ret_T edb_req_rel(edb_ctx_P _edb_ctx, edb_req_P _edb_req, uint32_t _flags, thr_lock_T _locktype);
sm_ret_T edb_rcpt_dec(edb_req_P _edb_req, aq_rcpt_P _aq_rcpt);
sm_ret_T edb_ta_dec(edb_req_P _edb_req, aq_ta_P _aq_ta);
sm_ret_T edb_rd_open(edb_ctx_P _edb_ctx, edb_cursor_P *_pedb_cursor);
sm_ret_T edb_rd_close(edb_ctx_P _edb_ctx, edb_cursor_P _edb_cursor);
sm_ret_T edb_rd_next(edb_ctx_P _edb_ctx, edb_cursor_P _edb_cursor, edb_req_P _edb_req);
sm_ret_T edb_get_type(edb_req_P _edb_req);
sm_ret_T edb_ta_rm(edb_ctx_P _edb_ctx, sessta_id_T _ta_id);
sm_ret_T edb_rcpt_rm(edb_ctx_P _edb_ctx, rcpt_id_T _rcpt_id);
sm_ret_T edb_ta_rm_req(edb_ctx_P _edb_ctx, sessta_id_T _ta_id, edb_req_hd_P _edb_req_hd);
sm_ret_T edb_rcpt_rm_req(edb_ctx_P _edb_ctx, rcpt_id_T _rcpt_id, edb_req_hd_P _edb_req_hd);
sm_ret_T edb_req_free(edb_req_P _edb_req);
sm_ret_T edb_reql_free(edb_ctx_P _edb_ctx, edb_req_hd_P _edb_reql);
sm_ret_T edb_reql_init(edb_ctx_P _edb_ctx, edb_req_hd_P _edb_reql, thr_lock_T _locktype);
sm_ret_T edb_chkpt(edb_ctx_P _edb_ctx);
sm_ret_T edb_status(edb_ctx_P _edb_ctx, sm_file_T *_fp);
#endif /* SM_EDB_H */
syntax highlighted by Code2HTML, v. 0.9.1