/*
 *  General Delivery Agent API Definitions
 *
 *  Last modified: 21 Octrober 1998
 *
 *  $Header:$
 */

#ifndef __DAAPI_H__
	#define __DAAPI_H__


/* Commonly used upper bounds of text strings */

#define LABELSZ       64            /* domain name label maximum size per RFC1034 */
#define DOMAINSZ     256            /* domain name maximum size per RFC1123 */
#define LOCALSZ      256            /* maximum size of local part of an RFC822 mailbox */
#define PATHSZ       256            /* maximum size of a disk file path name */
#define WORDSZ       256            /* maximum length of an RFC-822 word token */
#define PHRASESZ    1024            /* maximum length of an RFC-822 phrase */
#define ROUTESZ     1024            /* maximum length of an RFC-822 route sequence */
#define ENVIDSZ      100            /* maximum length of the ENVID SMTP extension */
#define ORCPTSZ      500            /* maximum length of the ORCPT SMTP extension */



/*----------------------------------------------
 * The following structures are used in the API
 *----------------------------------------------
 */



/*
 *  Linked list of (RFC-822) text lines; each element contains the text of one 
 *  line without the terminating CRLF
 */

typedef struct ll_LineT 
	{
    struct ll_LineT *next;          /* double-linked */
    struct ll_LineT *prev;          /* list pointers */
    char *buffer;                   /* pointer to textual data */
	} ll_Line;

typedef struct 
	{
    ll_Line *first;                 /* double-linked */
    ll_Line *last;                  /* list pointers */
	} ll_Lines;


/*
 *  An RFC821 envelope addresses divided into local part and domain.
 */

struct rfc821_name 
	{
    char *local;                    /* local part (left of @) */
    char *domain;                   /* domain part (right of @) */
    };


/*
 * A (possibly unary) linked list of RFC821 envelope addresses, plus 
 * ESMTP extension data.
 */

struct ll_recipT 
	{
    struct ll_recipT *next;         /* if list of recipient, double-linked */
    struct ll_recipT *prev;         /* list pointers, else unused fields */
    struct rfc821_name name;        /* RFC821 recipient name */
    char *orcpt;                    /* RFC8191 ORCPT option */
    int notify;                     /* RFC1891 NOTIFY option */
    };


/*
 * A linked list of (possibly unary linked-lists) of RFC821 recipients.
 */

struct ll_recips                    /* recipient list */
	{                  
    struct rec *first;              /* pointer to first entry in list */
    struct rec *last;               /* pointer to last entry in list */
    };



/* RFC822 message description (simplified).  The header must be filled-in,
 * but the body may be omitted or present (Sieve standard does not give
 * access to the body, but extensions might.)
 */

struct daa_msg 
	{
    ll_Lines headers;                /* list of raw RFC-822 headers (unfolded) */
    ll_Lines body;                   /* RFC822 message body data */
    };


/* 
 * Per-message delivery context.
 * 
 * msg_size should be as close to accurate as possible, and should represent
 *    the size of the message in canonical form.
 * msg_orig is the RFC 821 originator.
 * msg_recip is either the single current recipient (to whom this copy of this
 *    message is being delivered) -or- the list of all recipients.
 * daa_msg must contain at least the headers of the message, and may also
 *    contain the body; note that headers are one per entry and must be unfolded 
 *    and not contain CRLF; the message body is also a series of lines which do
 *    not contain CRLF.
 */

typedef struct 
	{
    long               msg_size;    /* the size in bytes of the RFC-822 message */
    struct rfc821_name msg_orig;    /* envelope originator */
    struct ll_recipT   msg_recip;   /* message store recipient */
    struct daa_msg     message;     /* RFC822 headers and message body */
    char              *envID;       /* optional RFC1891 envelope identifier */
    int                retExt;      /* optional RFC1891 RET extension */
	} Context;


/* Action */

/*
 * Sieve is called with Action set to DAA_DELIVER, which is the default value.  Sieve may
 * set Action to DAA_DISCARD, or leave it unchanged.  Sieve itself does not use the other
 * values; other plug-ins might.
 */

#define DAA_IM_DELIVER             1   /* Immediately deliver message as-is (skip other plug-ins) */
#define DAA_DELIVER                2   /* (default) Deliver message as-is (no changes) */
#define DAA_DISCARD                3   /* Discard message immediately (skip other plug-ins) */
#define DAA_BAD_MESSAGE            4   /* Request to save as a BAD message and discard delivery copy */


/* RET DSN extension values */

#define DSN_RET_DEFAULT			   0   /* RET extension was not specified */
#define DSN_RET_FULL			   1   /* Return full message in a Delivery Status Notification */
#define DSN_RET_HDRS			   2   /* Only return message headers in a Delivery Status Notification */


/* DSN NOTIFY extension bits */

#define DSN_NOTIFY_NEVER		   1   /* Never send a Delivery Status Notification */
#define DSN_NOTIFY_SUCCESS		   2   /* Send a Delivery Status Notification on successful delivery */
#define DSN_NOTIFY_DELAY		   4   /* Send a Delivery Status Notification on significant delivery delay */
#define DSN_NOTIFY_FAILURE		   8   /* Send a Delivery Status Notification on unsuccessful delivery */



/*------------------------------------------------------------------------------------
 * The following functions are supplied to the DAA plug-in by the calling environment
 *------------------------------------------------------------------------------------
 */


/* Parses a string containing an RFC821 address(es), returning local-part and domain of next address.
 * Address may optionally be preceded by white space or comma.
 *
 * msg is the current context structure; use by this function is optional.
 * s is where to start looking.
 * loc and dom are set to the local-part and domain of address.
 *
 * Returns pointer to just past the end of this address, so can be called in a loop.
 *
 * ==  This function is not currently called by Sieve; but it may do so in the ==
 * ==  future (to check for syntax errors in the forward action, for example). ==
 */
char       *DAA_parse_next_rfc821_address(Context *msg, char *s, char *loc, char *dom);


/* Looks down a chain of header records, returns next occurance of desired header.
 * (Header chains contain one header per entry, unfolded, not including terminating CRLF).
 *
 * msg is the current context structure; use by this function is optional.
 * start points at pointer to first header (e.g., Context->message.headers.first) to be searched;
 *    is set to next header on exit, so can be called in a loop to get all such headers.
 * target contains desired header (not including colon), e.g., "To".
 *
 * Returns pointer to start of header contents (after colon and white space).
 */
char       *DAA_get_next_rfc822_header   (Context *msg, ll_Line **start, char *target);


/* Looks down a chain of header records, finds desired header.
 * (Header chains contain one header per entry, unfolded, not including terminating CRLF).
 *
 * msg is the current context structure; use by this function is optional.
 * start points at first header (e.g., Context->message.headers.first) to be searched.
 * target contains desired header (not including colon), e.g., "To".
 *
 * Returns pointer to start of header contents (after colon and white space).
 */
char       *DAA_get_rfc822_header        (Context *msg, ll_Lines *start, char *target);

#endif /* __DAAPI_H__ */
