#include <sys/time.h>
#include <vstring.h>
#include <vstream.h>
#include <argv.h>
#include <nvtable.h>
#include <maps.h>
#include <tok822.h>
#include <been_here.h>
#include <mail_stream.h>
#include <mail_conf.h>
#include <mime_state.h>
#include <string_list.h>
#include <cleanup_user.h>
#include <header_body_checks.h>
#include <dsn_mask.h>
#include <milter.h>
typedef struct CLEANUP_STATE {
VSTRING *attr_buf;
VSTRING *temp1;
VSTRING *temp2;
VSTRING *stripped_buf;
VSTREAM *src;
VSTREAM *dst;
MAIL_STREAM *handle;
char *queue_name;
char *queue_id;
struct timeval arrival_time;
char *fullname;
char *sender;
char *recip;
char *orig_rcpt;
char *return_receipt;
char *errors_to;
int flags;
int qmgr_opts;
int errs;
int err_mask;
int headers_seen;
int hop_count;
char *resent;
BH_TABLE *dups;
void (*action) (struct CLEANUP_STATE *, int, const char *, ssize_t);
off_t data_offset;
off_t body_offset;
off_t xtra_offset;
off_t cont_length;
off_t sender_pt_offset;
off_t sender_pt_target;
off_t append_rcpt_pt_offset;
off_t append_rcpt_pt_target;
off_t append_hdr_pt_offset;
off_t append_hdr_pt_target;
off_t append_meta_pt_offset;
off_t append_meta_pt_target;
ssize_t rcpt_count;
char *reason;
char *smtp_reply;
NVTABLE *attr;
MIME_STATE *mime_state;
int mime_errs;
char *hdr_rewrite_context;
char *filter;
char *redirect;
char *dsn_envid;
int dsn_ret;
int dsn_notify;
char *dsn_orcpt;
char *verp_delims;
#ifdef DELAY_ACTION
int defer_delay;
#endif
MILTERS *milters;
const char *client_name;
const char *reverse_name;
const char *client_addr;
int client_af;
const char *client_port;
VSTRING *milter_ext_from;
VSTRING *milter_ext_rcpt;
VSTRING *milter_err_text;
HBC_CHECKS *milter_hbc_checks;
VSTRING *milter_hbc_reply;
struct CLEANUP_REGION *free_regions;
struct CLEANUP_REGION *body_regions;
struct CLEANUP_REGION *curr_body_region;
} CLEANUP_STATE;
#define CLEANUP_FLAG_INRCPT (1<<16)
#define CLEANUP_FLAG_WARN_SEEN (1<<17)
#define CLEANUP_FLAG_END_SEEN (1<<18)
extern MAPS *cleanup_comm_canon_maps;
extern MAPS *cleanup_send_canon_maps;
extern MAPS *cleanup_rcpt_canon_maps;
extern int cleanup_comm_canon_flags;
extern int cleanup_send_canon_flags;
extern int cleanup_rcpt_canon_flags;
extern MAPS *cleanup_header_checks;
extern MAPS *cleanup_mimehdr_checks;
extern MAPS *cleanup_nesthdr_checks;
extern MAPS *cleanup_body_checks;
extern MAPS *cleanup_virt_alias_maps;
extern ARGV *cleanup_masq_domains;
extern STRING_LIST *cleanup_masq_exceptions;
extern int cleanup_masq_flags;
extern MAPS *cleanup_send_bcc_maps;
extern MAPS *cleanup_rcpt_bcc_maps;
extern VSTRING *cleanup_reject_chars;
extern VSTRING *cleanup_strip_chars;
extern MILTERS *cleanup_milters;
#define CLEANUP_CANON_FLAG_ENV_FROM (1<<0)
#define CLEANUP_CANON_FLAG_ENV_RCPT (1<<1)
#define CLEANUP_CANON_FLAG_HDR_FROM (1<<2)
#define CLEANUP_CANON_FLAG_HDR_RCPT (1<<3)
#define CLEANUP_MASQ_FLAG_ENV_FROM (1<<0)
#define CLEANUP_MASQ_FLAG_ENV_RCPT (1<<1)
#define CLEANUP_MASQ_FLAG_HDR_FROM (1<<2)
#define CLEANUP_MASQ_FLAG_HDR_RCPT (1<<3)
extern int cleanup_ext_prop_mask;
extern char *cleanup_path;
extern VSTRING *cleanup_trace_path;
extern VSTRING *cleanup_bounce_path;
extern CLEANUP_STATE *cleanup_state_alloc(VSTREAM *);
extern void cleanup_state_free(CLEANUP_STATE *);
extern CLEANUP_STATE *cleanup_open(VSTREAM *);
extern void cleanup_control(CLEANUP_STATE *, int);
extern int cleanup_flush(CLEANUP_STATE *);
extern void cleanup_free(CLEANUP_STATE *);
extern void cleanup_all(void);
extern void cleanup_sig(int);
extern void cleanup_pre_jail(char *, char **);
extern void cleanup_post_jail(char *, char **);
extern CONFIG_INT_TABLE cleanup_int_table[];
extern CONFIG_BOOL_TABLE cleanup_bool_table[];
extern CONFIG_STR_TABLE cleanup_str_table[];
extern CONFIG_TIME_TABLE cleanup_time_table[];
#define CLEANUP_RECORD(s, t, b, l) ((s)->action((s), (t), (b), (l)))
extern void cleanup_out(CLEANUP_STATE *, int, const char *, ssize_t);
extern void cleanup_out_string(CLEANUP_STATE *, int, const char *);
extern void PRINTFLIKE(3, 4) cleanup_out_format(CLEANUP_STATE *, int, const char *,...);
extern void cleanup_out_header(CLEANUP_STATE *, VSTRING *);
#define CLEANUP_OUT_BUF(s, t, b) \
cleanup_out((s), (t), vstring_str((b)), VSTRING_LEN((b)))
#define CLEANUP_OUT_OK(s) \
(!((s)->errs & (s)->err_mask) && !((s)->flags & CLEANUP_FLAG_DISCARD))
extern void cleanup_envelope(CLEANUP_STATE *, int, const char *, ssize_t);
extern void cleanup_message(CLEANUP_STATE *, int, const char *, ssize_t);
extern void cleanup_extracted(CLEANUP_STATE *, int, const char *, ssize_t);
extern void cleanup_final(CLEANUP_STATE *);
extern int cleanup_rewrite_external(const char *, VSTRING *, const char *);
extern int cleanup_rewrite_internal(const char *, VSTRING *, const char *);
extern int cleanup_rewrite_tree(const char *, TOK822 *);
extern int cleanup_map11_external(CLEANUP_STATE *, VSTRING *, MAPS *, int);
extern int cleanup_map11_internal(CLEANUP_STATE *, VSTRING *, MAPS *, int);
extern int cleanup_map11_tree(CLEANUP_STATE *, TOK822 *, MAPS *, int);
ARGV *cleanup_map1n_internal(CLEANUP_STATE *, const char *, MAPS *, int);
extern int cleanup_masquerade_external(CLEANUP_STATE *, VSTRING *, ARGV *);
extern int cleanup_masquerade_internal(CLEANUP_STATE *, VSTRING *, ARGV *);
extern int cleanup_masquerade_tree(CLEANUP_STATE *, TOK822 *, ARGV *);
extern void cleanup_out_recipient(CLEANUP_STATE *, const char *, int, const char *, const char *);
extern void cleanup_addr_sender(CLEANUP_STATE *, const char *);
extern void cleanup_addr_recipient(CLEANUP_STATE *, const char *);
extern void cleanup_addr_bcc_dsn(CLEANUP_STATE *, const char *, const char *, int);
#define NO_DSN_ORCPT ((char *) 0)
#define NO_DSN_NOTIFY DSN_NOTIFY_NEVER
#define DEF_DSN_NOTIFY (0)
#define cleanup_addr_bcc(state, addr) \
cleanup_addr_bcc_dsn((state), (addr), NO_DSN_ORCPT, NO_DSN_NOTIFY)
extern int cleanup_bounce(CLEANUP_STATE *);
#define CLEANUP_MSG_STATS(stats, state) \
MSG_STATS_INIT1(stats, incoming_arrival, state->arrival_time)
extern void cleanup_milter_receive(CLEANUP_STATE *, int);
extern void cleanup_milter_inspect(CLEANUP_STATE *, MILTERS *);
extern void cleanup_milter_emul_mail(CLEANUP_STATE *, MILTERS *, const char *);
extern void cleanup_milter_emul_rcpt(CLEANUP_STATE *, MILTERS *, const char *);
extern void cleanup_milter_emul_data(CLEANUP_STATE *, MILTERS *);
#define CLEANUP_MILTER_OK(s) \
(((s)->flags & CLEANUP_FLAG_MILTER) != 0 \
&& (s)->errs == 0 && ((s)->flags & CLEANUP_FLAG_DISCARD) == 0)
typedef struct CLEANUP_REGION {
off_t start;
off_t len;
off_t write_offs;
struct CLEANUP_REGION *next;
} CLEANUP_REGION;
extern void cleanup_region_init(CLEANUP_STATE *);
extern CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *, ssize_t);
extern void cleanup_region_close(CLEANUP_STATE *, CLEANUP_REGION *);
extern CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *, CLEANUP_REGION *);
extern void cleanup_region_done(CLEANUP_STATE *);
extern int cleanup_body_edit_start(CLEANUP_STATE *);
extern int cleanup_body_edit_write(CLEANUP_STATE *, int, VSTRING *);
extern int cleanup_body_edit_finish(CLEANUP_STATE *);
extern void cleanup_body_edit_free(CLEANUP_STATE *);