#ifdef USE_SASL_AUTH
#include <sasl.h>
#include <saslutil.h>
#endif
#include <vstream.h>
#include <vstring.h>
#include <argv.h>
#include <deliver_request.h>
#include <pfixtls.h>
typedef struct SMTP_STATE {
VSTREAM *src;
DELIVER_REQUEST *request;
struct SMTP_SESSION *session;
VSTRING *buffer;
VSTRING *scratch;
VSTRING *scratch2;
int status;
int features;
ARGV *history;
int error_mask;
#ifdef USE_SASL_AUTH
char *sasl_mechanism_list;
char *sasl_username;
char *sasl_passwd;
sasl_conn_t *sasl_conn;
VSTRING *sasl_encoded;
VSTRING *sasl_decoded;
sasl_callback_t *sasl_callbacks;
#endif
off_t size_limit;
int space_left;
struct MIME_STATE *mime_state;
int final_server;
int rcpt_left;
int rcpt_drop;
int rcpt_keep;
} SMTP_STATE;
#define SMTP_FEATURE_ESMTP (1<<0)
#define SMTP_FEATURE_8BITMIME (1<<1)
#define SMTP_FEATURE_PIPELINING (1<<2)
#define SMTP_FEATURE_SIZE (1<<3)
#define SMTP_FEATURE_STARTTLS (1<<4)
#define SMTP_FEATURE_AUTH (1<<5)
#define SMTP_FEATURE_MAYBEPIX (1<<6)
#define SMTP_FEATURE_XFORWARD_NAME (1<<7)
#define SMTP_FEATURE_XFORWARD_ADDR (1<<8)
#define SMTP_FEATURE_XFORWARD_PROTO (1<<9)
#define SMTP_FEATURE_XFORWARD_HELO (1<<10)
#define SMTP_MISC_FLAG_LOOP_DETECT (1<<0)
#define SMTP_MISC_FLAG_DEFAULT SMTP_MISC_FLAG_LOOP_DETECT
extern int smtp_errno;
#define SMTP_ERR_NONE 0
#define SMTP_ERR_FAIL 1
#define SMTP_ERR_RETRY 2
#define SMTP_ERR_LOOP 3
extern int smtp_host_lookup_mask;
#define SMTP_HOST_FLAG_DNS (1<<0)
#define SMTP_HOST_FLAG_NATIVE (1<<1)
typedef struct SMTP_SESSION {
VSTREAM *stream;
char *host;
char *addr;
char *namaddr;
int best;
int tls_use_tls;
int tls_enforce_tls;
int tls_enforce_peername;
tls_info_t tls_info;
} SMTP_SESSION;
extern void smtp_tls_list_init(void);
extern SMTP_SESSION *smtp_session_alloc(char *, VSTREAM *, char *, char *);
extern void smtp_session_free(SMTP_SESSION *);
extern int smtp_connect(SMTP_STATE *);
extern int smtp_helo(SMTP_STATE *, int);
extern int smtp_xfer(SMTP_STATE *);
extern void smtp_quit(SMTP_STATE *);
typedef struct SMTP_RESP {
int code;
char *str;
VSTRING *buf;
} SMTP_RESP;
extern void PRINTFLIKE(2, 3) smtp_chat_cmd(SMTP_STATE *, char *,...);
extern SMTP_RESP *smtp_chat_resp(SMTP_STATE *);
extern void smtp_chat_reset(SMTP_STATE *);
extern void smtp_chat_notify(SMTP_STATE *);
#define SMTP_RCPT_STATE_KEEP 1
#define SMTP_RCPT_STATE_DROP 2
#define SMTP_RCPT_INIT(state) do { \
(state)->rcpt_drop = (state)->rcpt_keep = 0; \
(state)->rcpt_left = state->request->rcpt_list.len; \
} while (0)
#define SMTP_RCPT_DROP(state, rcpt) do { \
(rcpt)->status = SMTP_RCPT_STATE_DROP; (state)->rcpt_drop++; \
} while (0)
#define SMTP_RCPT_KEEP(state, rcpt) do { \
(rcpt)->status = SMTP_RCPT_STATE_KEEP; (state)->rcpt_keep++; \
} while (0)
#define SMTP_RCPT_ISMARKED(rcpt) ((rcpt)->status != 0)
#define SMTP_RCPT_LEFT(state) (state)->rcpt_left
extern void smtp_rcpt_cleanup(SMTP_STATE *);
extern void smtp_rcpt_done(SMTP_STATE *, const char *, RECIPIENT *);
extern int PRINTFLIKE(3, 4) smtp_conn_fail(SMTP_STATE *, int, char *,...);
extern int PRINTFLIKE(3, 4) smtp_site_fail(SMTP_STATE *, int, char *,...);
extern int PRINTFLIKE(3, 4) smtp_mesg_fail(SMTP_STATE *, int, char *,...);
extern void PRINTFLIKE(4, 5) smtp_rcpt_fail(SMTP_STATE *, int, RECIPIENT *, char *,...);
extern int smtp_stream_except(SMTP_STATE *, int, char *);
extern const char *smtp_unalias_name(const char *);
extern VSTRING *smtp_unalias_addr(VSTRING *, const char *);
extern SMTP_STATE *smtp_state_alloc(void);
extern void smtp_state_free(SMTP_STATE *);