/*
 *  Copyright (c) 2003, Sun Microsystems, Inc.  All rights reserved.
 */

#if !defined(__MTA_SDK__)
#define __MTA_SDK__

#pragma ident "@(#)$Id: mtasdk.h,v 1.49.8.1 2004/06/11 06:01:00 dnewman Exp $"

#ifdef __cplusplus
extern "C" {
#endif

#include <stdarg.h>    /* va_list         */
#include <time.h>      /* time_t          */
#include "mtasdkhdr.h" /* HL_ definitions */

/* **********************************************************************
 *
 *  Opaque contexts
 *
 */

#if !defined(__MTA_SDK_NQ__)
#define __MTA_SDK_NQ__
/*
 *  Enqueue context
 *    Created by   mtaEnqueueStart()
 *    Destroyed by mtaEnqueueFinish()
 */
typedef void mta_nq_t;
#endif

#if !defined(__MTA_SDK_DQ__)
/*
 *  Dequeue context
 *    Created by   mtaDequeueStart()
 *    Destroyed by mtaDequeueFinish(), mtaDequeueStart()
 */
typedef void mta_dq_t;     /* Dequeue context */
#endif

#if !defined(__MTA_SDK_OPT__)
#define __MTA_SDK_OPT__
/*
 *  Option context
 *    Created by   mtaOptionStart(), mtaDecodeMessageInfoParams()
 *    Destroyed by mtaOptionFinish()
 */
typedef void mta_opt_t;
#endif

#if !defined(__MTA_SDK_ADR__)
#define __MTA_SDK_ADR__
/*
 *  Address parsing context
 *    Created by   mtaAddressParse()
 *    Destroyed by mtaAddressFinish()
 */
typedef void mta_adr_t;
#endif

#if !defined(__MTA_SDK_DECODE__)
/*
 *  Message decode context
 *    Created by   mtaDecodeMessage()
 *    Destroyed by mtaDecodeMessage()
 */
typedef void mta_decode_t;
#endif


/* **********************************************************************
 *
 *  String length constants
 *
 */
#define ALFA_SIZE     256  /* Basic MTA string size in bytes            */
#define BIGALFA_SIZE 1024  /* Another basic MTA string size in bytes    */
#define CHANLENGTH     32  /* Maximum length in bytes of a channel name */


/* **********************************************************************
 *
 *  Item list structure
 *
 */
#define MTA_ITEM_LIST_VERSION_0  0
#define MTA_ITEM_LIST_VERSION    ( MTA_ITEM_LIST_VERSION_0 )

typedef struct {
     int         item_code;          /* Item code (e.g., MTA_ORCPT_TO)    */
     void       *item_address;       /* Pointer to item value             */
     size_t      item_length;        /* Length in bytes of the item value */
     int         item_status;        /* Return status code (e.g., MTA_OK) */
     const char *item_smessage;      /* Return status message             */
} mta_item_list_t;


/* **********************************************************************
 *
 *  Item codes
 *
 */
#define MTA_END_LIST                    0
#define MTA_ABORT                       1 
#define MTA_ADR_NOSORT                  2 
#define MTA_ADR_NOSTATUS                3 
#define MTA_ADR_SORT                    4 
#define MTA_ADR_STATUS                  5 
#define MTA_ALIAS_EXPAND                6 
#define MTA_ALIAS_NOEXPAND              7 
#define MTA_BCC                         8 
#define MTA_BLANK                       9 
#define MTA_CC                         10
#define MTA_CDISPOSITION               11
#define MTA_CDISPOSITION_NONE          12
#define MTA_CFILENAME                  13 
#define MTA_CFILENAME_NONE             14 
#define MTA_CHANNEL                    15 
#define MTA_CTYPE                      16 
#define MTA_DEBUG_DECODE               17 
#define MTA_DEBUG_DEQUEUE              18
#define MTA_DEBUG_ENQUEUE              19
#define MTA_DEBUG_MM                   20
#define MTA_DEBUG_OS                   21
#define MTA_DEBUG_SDK                  22
#define MTA_DECODE_CCHARSET            23
#define MTA_DECODE_CDESCR              24
#define MTA_DECODE_CDISP               25
#define MTA_DECODE_CDISP_PARAMS        26
#define MTA_DECODE_CLANG               27
#define MTA_DECODE_CSUBTYPE            28
#define MTA_DECODE_CTRANS_ENCODING     29
#define MTA_DECODE_CTYPE               30
#define MTA_DECODE_CTYPE_PARAMS        31
#define MTA_DECODE_DTYPE               32
#define MTA_DECODE_EHEADER             33
#define MTA_DECODE_LEVELS_MAX          34
#define MTA_DECODE_OHEADER             35
#define MTA_DECODE_PARTS_MAX           36
#define MTA_DECODE_PART_NUMBER         37
#define MTA_DECODE_PHEADER             38
#define MTA_DECODE_SECURITY            39
#define MTA_DECODE_THURMAN             40
#define MTA_DELIVERY_FLAGS             41
#define MTA_DELIVERY_FLAGS_ABS         42
#define MTA_DELIVER_BY                 43
#define MTA_DISP                       44
#define MTA_DOMAIN                     45
#define MTA_DQ_CONTEXT                 46
#define MTA_ENC_7BIT                   47
#define MTA_ENC_8BIT                   48
#define MTA_ENC_BASE32                 49
#define MTA_ENC_BASE64                 50
#define MTA_ENC_BASE85                 51
#define MTA_ENC_BINARY                 52
#define MTA_ENC_BINHEX                 53
#define MTA_ENC_BTOA                   54
#define MTA_ENC_COMPRESSED_BASE64      55
#define MTA_ENC_COMPRESSED_BINARY      56
#define MTA_ENC_COMPRESSED_UUENCODE    57
#define MTA_ENC_HEXADECIMAL            58
#define MTA_ENC_NONE                   59
#define MTA_ENC_PATHWORKS              60
#define MTA_ENC_QUOTED_PRINTABLE       61
#define MTA_ENC_UNKNOWN                62
#define MTA_ENC_UUENCODE               63
#define MTA_ENV_FROM                   64
#define MTA_ENV_ID                     65
#define MTA_ENV_TO                     66
#define MTA_EXPAND_LIMIT               67
#define MTA_EXTRA_HEADER_LINE          68
#define MTA_FRAGMENT_BLOCKS            69
#define MTA_FRAGMENT_LINES             70
#define MTA_FROM                       71
#define MTA_HDRMSG_FILE                72
#define MTA_HDRMSG_PROC                73
#define MTA_HDR_ADRS                   74
#define MTA_HDR_BCC                    75
#define MTA_HDR_CC                     76
#define MTA_HDR_FILE                   77
#define MTA_HDR_FROM                   78
#define MTA_HDR_NOADRS                 79
#define MTA_HDR_NORESENT               80
#define MTA_HDR_PROC                   81
#define MTA_HDR_RESENT                 82
#define MTA_HDR_TO                     83
#define MTA_IGNORE_ERRORS              84
#define MTA_INTERACTIVE                85
#define MTA_IRCPT_TO                   86
#define MTA_ITEM_LIST                  87
#define MTA_JBC_MAX_ATTEMPTS           88
#define MTA_JBC_RETRY_INTERVAL         89
#define MTA_JBC_TIMEOUT                90
#define MTA_MAX_TO                     91
#define MTA_MODE_BINARY                92
#define MTA_MODE_TEXT                  93
#define MTA_MSG_FILE                   94
#define MTA_MSG_ID                     95
#define MTA_MSG_PROC                   96
#define MTA_NOBLANK                    97
#define MTA_NOIGNORE_ERRORS            98
#define MTA_NOTIFY_FLAGS               99
#define MTA_ORCPT_TO                  100
#define MTA_PRIV_DISABLE_PROC         101
#define MTA_PRIV_ENABLE_PROC          102
#define MTA_REASON                    103
#define MTA_SUBADDRESS                104
#define MTA_SUBJECT                   105
#define MTA_TERM_CR                   106
#define MTA_TERM_CRLF                 107
#define MTA_TERM_LF                   108
#define MTA_TERM_LFCR                 109
#define MTA_TERM_NONE                 110
#define MTA_THREAD_ID                 111
#define MTA_THREAD_MAX_MESSAGES       112
#define MTA_THREAD_MAX_THREADS        113
#define MTA_THREAD_STACK_SIZE         114
#define MTA_THREAD_WAIT_TIMEOUT       115
#define MTA_TO                        116
#define MTA_USER                      117


/* **********************************************************************
 *
 *  Callable send mtaSend()
 *
 */
extern int mtaSend(mta_item_list_t *item_list);
extern void mtaSendDispose(mta_item_list_t *item_list);


/* **********************************************************************
 *
 *  Logging and debugging
 *
 */
extern int  mtaDebug(int item_code, ...);
extern void mtaLog(const char *fmt, ...);
extern void mtaLogv(const char *fmt, va_list ap);
extern const char *mtaStrError(int err, int item_code, ...);

/* **********************************************************************
 *
 *  Error handling
 *
 */
#define MTA_OK            0  /* Successful operation; call succeeded */
#define MTA_ACCESS        1  /* Authorization failure                */
#define MTA_AGAIN         2  /* Temporary failure; try again later   */
#define MTA_BADARGS       3  /* Bad or corrupt call arguments        */
#define MTA_EOF           4  /* End of file or end of data reached   */
#define MTA_FCREATE       5  /* Unable to create a message file      */
#define MTA_FIO           6  /* File read/write error                */
#define MTA_FOPEN         7  /* Unable to open the message file      */
#define MTA_NETWORK       8  /* Network I/O error                    */
#define MTA_NO            9  /* Operation failed; permanent error    */
#define MTA_NOMEM        10  /* Insufficient virtual memory          */
#define MTA_NOOP         11  /* Operation completed vaccuously       */
#define MTA_NOSUCHCHAN   12  /* No such channel defined              */
#define MTA_NOSUCHHOST   13  /* No such host or domain               */
#define MTA_NOSUCHITEM   14  /* No such item code                    */
#define MTA_ORDER        15  /* Subroutine called out of sequence    */
#define MTA_SIZE         16  /* Site configured size limits exceeded */
#define MTA_STRTRU       17  /* String too long; truncated to fit    */
#define MTA_STRTRUERR    18  /* String too long; operation failed    */
#define MTA_THREAD       19  /* Threading error                      */
#define MTA_TIMEDOUT     20  /* Operation timed out                  */
#define MTA_ERR_LAST     20  /* Used for range checking              */

extern int mtaErrno(void);

#define mta_errno (mtaErrno())


/* **********************************************************************
 *
 *  Initialization / deinitialization routines
 *
 */
extern int mtaInit(int item_code, ...);
extern void mtaDone(void);
extern void mtaAccountingLogClose(void);  /* Unrelated to mtaLog(), mtaLogv() */


/* **********************************************************************
 *
 *  Message enqueue routines (i.e., message submission)
 *
 */

/*
 *  Notification flags
 */
#define MTA_NOTIFY_CONTENT_FULL     0x00000001 /* DSNs have full msg content */
#define MTA_NOTIFY_CONTENT_HEADER   0x00000002 /* DSNs have msg header only  */
#define MTA_NOTIFY_CONTENT_NONE     0x00000004 /* DSNs have no msg content   */
#define MTA_NOTIFY_DELAY            0x00000008 /* Issue delay DSNs           */
#define MTA_NOTIFY_FAILURE          0x00000010 /* Issue failure DSNs (NDNs)  */
#define MTA_NOTIFY_SUCCESS          0x00000020 /* Issue success DSNs         */

#define MTA_NOTIFY_DEFAULT ( MTA_NOTIFY_DELAY | \
			     MTA_NOTIFY_FAILURE | \
			     MTA_NOTIFY_CONTENT_FULL )

extern int mtaEnqueueStart(mta_nq_t **nq, const char *env_from,
  size_t env_from_len, int item_code, ...);
extern int mtaEnqueueInfo(mta_nq_t *nq, int item_code, ...);
extern int mtaEnqueueTo(mta_nq_t *nq, const char *to_adr, size_t to_adr_len,
  int item_code, ...);
extern int mtaEnqueueWrite(mta_nq_t *nq, const char *str1, size_t len1,
  const char *str2, ...);
extern int mtaEnqueueWriteLine(mta_nq_t *nq, const char *str1, size_t len1,
  const char *str2, ...);
extern int mtaEnqueueFinish(mta_nq_t *nq, int item_code, ...);

extern int mtaEnqueueCopyMessage(mta_nq_t *dst, mta_dq_t *src, int rewind);
extern const char *mtaEnqueueError(mta_nq_t *nq, const char **err,
  size_t *err_len, int item_code, ...);


/* **********************************************************************
 *
 *  Message dequeue routines [see also mtaEnqueueCopyMessage()]
 *
 */

/*
 *  Per-recipient message delivery dispositions
 */
#define MTA_DISP_FIRST            0  /* Used internally as a range check   */
#define MTA_DISP_DEFERRED         0  /* Delivery failed; try again later   */
#define MTA_DISP_DELIVERED        1  /* Message successfully delivered     */
#define MTA_DISP_FAILED           2  /* Delivery failed; return to sender  */
#define MTA_DISP_RELAYED          3  /* Message relayed; no "relay" DSN    */
#define MTA_DISP_RELAYED_FOREIGN  4  /* Message relayed; issue "relay" DSN */
#define MTA_DISP_RETURN           5  /* Return message as undeliverable    */
#define MTA_DISP_TIMEDOUT         6  /* Return message as timed out        */
#define MTA_DISP_LAST             6  /* Used internally as a range check   */

#if !defined(__MTA_SDK_DQ__)
#define __MTA_SDK_DQ__
typedef int mta_dq_process_message_t(void **ctx2, void *ctx1, mta_dq_t *dq,
  const char *env_from, size_t env_from_len);
typedef void mta_dq_process_done_t(void *ctx2, void *ctx1);
#endif

extern int mtaDequeueStart(void *ctx1,
  mta_dq_process_message_t *process_message,
  mta_dq_process_done_t *process_done, int item_code, ...);
extern int mtaDequeueInfo(mta_dq_t *dq, int item_code, ...);
extern int mtaDequeueRecipientNext(mta_dq_t *dq, const char **env_to,
  size_t *env_to_len, int item_code, ...);
extern int mtaDequeueLineNext(mta_dq_t *dq, const char **line, size_t *len);
extern int mtaDequeueRecipientDisposition(mta_dq_t *dq, const char *env_to,
  size_t env_to_len, size_t disposition, int item_code, ...);
extern int mtaDequeueMessageFinish(mta_dq_t *dq, int item_code, ...);

extern int mtaDequeueRewind(mta_dq_t *dq);
extern int mtaDequeueThreadId(mta_dq_t *dq);


/* **********************************************************************
 *
 *  Channel option routines
 *
 */
extern int mtaOptionStart(mta_opt_t **opt, const char *path, size_t len,
  int item_code, ...);
extern int mtaOptionInt(mta_opt_t *opt, const char *name, size_t len,
  int *val);
extern int mtaOptionFloat(mta_opt_t *opt, const char *name, size_t len,
  double *val);
extern int mtaOptionString(mta_opt_t *opt, const char *name, size_t len,
  char *val, size_t *val_len, size_t val_len_max);
extern void mtaOptionFinish(mta_opt_t *opt);


/* **********************************************************************
 *
 *  Address parsing
 *
 */

/*
 *  Address elements
 */
#define MTA_ADDR_PHRASE  0x00000001  /* RFC 822 "phrase" element   */
#define MTA_ADDR_ROUTE   0x00000002  /* RFC 822 "route" element    */
#define MTA_ADDR_LOCAL   0x00000004  /* RFC 822 "local-part" elem  */
#define MTA_ADDR_DOMAIN  0x00000008  /* RFC 822 "domain" element   */

#define MTA_ADDR_FULL ( MTA_ADDR_PHRASE | MTA_ADDR_ROUTE | \
                        MTA_ADDR_LOCAL | MTA_ADDR_DOMAIN )
#define MTA_ADDR_DEFAULT ( MTA_ADDR_FULL )
#define MTA_ADDR_SPEC ( MTA_ADDR_LOCAL | MTA_ADDR_DOMAIN )

extern int mtaAddressParse(mta_adr_t **adr_ctx, size_t *address_count,
  const char *address_list, size_t address_list_len, int item_code, ...);
extern int mtaAddressGetN(mta_adr_t *adr_ctx, size_t address_index,
  const char **address, size_t *address_len, int elements);
extern void mtaAddressFinish(mta_adr_t *adr_ctx);


/* **********************************************************************
 *
 *  Message parsing
 *
 */

/*
 *  Flags for mtaDecodeMessage()
 */
#define MTA_DECODE_DQ    1  /* Use a dequeue context for input message       */
#define MTA_DECODE_NQ    2  /* Use an enqueue context for output message     */
#define MTA_DECODE_PROC  3  /* Use the supplied routine for input or output  */

/*
 *  Flags supplied by mtaDecodeMessage() to call back routines
 */
#define MTA_DATA_NONE    0  /* No data supplied in this call                  */
#define MTA_DATA_HEADER  1  /* Data is from the outer header or a part header */
#define MTA_DATA_TEXT    2  /* Data is from the content of a text / * or      */
                            /*   message / * part                             */
#define MTA_DATA_BINARY  3  /* Data is from a non-text message part (i.e., a  */
                            /*   part which is not text / *, not message / *) */

#if !defined(__MTA_SDK_DECODE__)
#define __MTA_SDK_DECODE__
typedef int mta_decode_read_t(void *ctx, const char **line, size_t *line_len);
typedef int mta_decode_inspect_t(void *ctx, mta_decode_t *dctx, int data_type,
  const char *data, size_t data_len);
typedef int mta_decode_write_t(void *ctx, mta_decode_t *dctx, const char *line,
  size_t line_len);
#endif

extern int mtaDecodeMessage(void *ctx, int input_type, void *input,
  int output_type, void *output, mta_decode_inspect_t *inspect_proc,
  int item_code, ...);
extern int mtaDecodeMessagePartDelete(mta_decode_t *dctx, int item_code, ...);
extern int mtaDecodeMessagePartCopy(mta_decode_t *dctx, int item_code, ...);
extern int mtaDecodeMessageInfoInt(mta_decode_t *dctx, int item_code);
extern mta_opt_t *mtaDecodeMessageInfoParams(mta_decode_t *dctx, int item_code,
  mta_opt_t **params);
extern const char *mtaDecodeMessageInfoString(mta_decode_t *dctx, int item_code,
  const char **str, size_t *len);


/* **********************************************************************
 *
 *  Channel/host routines
 *
 */
extern const char *mtaChannelGetName(char *channel, size_t *channel_len,
  size_t channel_len_max);
extern const char *mtaAddressToChannel(char *channel, size_t *channel_len,
  size_t channel_len_max, const char *address, size_t address_len,
  int address_type, int item_code, ...);
extern const char *mtaChannelToHost(const char **host, size_t *host_len,
  int item_code, ...);


/* **********************************************************************
 *
 *  Item list routines
 *  These routines are largely intended for use from languages for which
 *  there is no easy way to handle C/C++ variable length argument lists.
 *  In those cases, build an item list and then make the call
 *
 *     mta_item_list_t *item_list = NULL;
 *
 *     ...
 *     item_list = NULL;
 *     item_list = mtaItemListInt(item_list, <item_code-1>, <value-1>);
 *     item_list = mtaItemListInt(item_list, <item_code-2>, <value-2>);
 *     ...
 *     item_list = mtaItemListInt(item_list, <item_code-n>, <value-n>);
 *     ...
 *     result = mtaWhatever(arg1, arg2, arg3, MTA_ITEM_LIST, item_list, 0);
 *     ...
 *     mtaItemListDispose(item_list);
 */
extern mta_item_list_t *mtaItemListInt(mta_item_list_t *items, int item_code,
  size_t value);
extern mta_item_list_t *mtaItemListStr(mta_item_list_t *items, int item_code,
  const char *str, size_t len);
extern void mtaItemListDispose(mta_item_list_t *items);


/* **********************************************************************
 *
 *  Miscellaneous functions with string-valued responses
 *
 */
extern const char *mtaDateTime(char *date, size_t *date_len,
  size_t date_len_max, time_t tm);
extern const char *mtaPostmasterAddress(const char **address,
  size_t *address_len, int item_code, ...);
extern const char *mtaUniqueString(char *buf, size_t *len, size_t max_len);


/* **********************************************************************
 *
 *  Miscellaneous functions with numeric-valued responses
 *
 */
extern size_t mtaBlockSize(void);
extern size_t mtaStackSize(void);
extern int    mtaVersionMajor(void);
extern int    mtaVersionMinor(void);
extern int    mtaVersionRevision(void);

#ifdef __cplusplus
}
#endif

#endif
