/*
#ident	"@(#)smail/src:RELEASE-3_2_0_121:addr.h,v 1.30 2005/07/25 05:10:08 woods Exp"
 */

/*
 *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
 *    Copyright (C) 1992  Ronald S. Karr
 *
 * See the file COPYING, distributed with smail, for restriction
 * and warranty information.
 */

/*
 * addr.h:
 *	interface file for routines in addr.c
 */

/* types used in addr.h */
/*
 * addr - Everything needed to understand an address is stored in
 *	  here somewhere.
 *
 * XXX except we should also keep the parse_address() result (the address form)
 * in here somewhere, and similarly have a global struct addr *sender_addr for
 * the parsed sender address too.
 *
 * XXX we should also store a whole struct addr for the owner address, so that
 * we only have to parse it once when it is first verified.
 */
struct addr {
    struct addr *succ;		/* next addr in queue */
    unsigned long int flags;	/* miscellaneous flags */
    int parseflags;		/* parse flags for parse_address() */
    struct addr *parent;	/* addr from which this one is derived */
    struct addr *true_addr;	/* point to addr which had an error */
    char *in_addr;		/* reconstituted address from header or args */
#if 0
    int form;			/* parse_address() result */
#endif
    char *target;		/* generally the target domain name */
    char *remainder;		/* generally the local mailbox name */
    char *rem_prefix;		/* prefix stripped from remainder */
    char *rem_suffix;		/* suffix stripped from remainder */
    char *work_addr;		/* working area */
    int match_count;		/* chars of target matched by router */
    char *local_name;           /* domain matched as local */
    char *owner;                /* address owner (fwdfile/aliasfile) */
#if 0
    struct addr *owner_addr;	/* parsed owner address */
#endif
    char *route;		/* the route to the target */
    struct router *router;	/* router used for route and next_host */
    struct director *director;	/* director which matched address */
    char *next_host;		/* next-hop host to receive message */
    char *next_addr;		/* address to give next-hop host */
    struct transport *transport; /* transport to use for remote delivery */
    char *home;			/* home directory associated with login */
    uid_t uid;			/* user for pipes/files perms or BOGUS_USER */
    gid_t gid;			/* gid for pipes/files perms or BOGUS_GROUP */
    struct error *error;	/* error message associated */
    struct transport_hints *tphint_list; /* transport hints from the router */
};

/* structure for errors stored in the addr structure */
struct error {
    unsigned long int info;		/* info associated with error */
    char *message;			/* error message */
};

/*
 * The identify_addr structure is used to uniquely identify specific addr
 * structures produced by resolve_addr_list().  The in_addr value in an addr
 * structure is insufficient, by itself, to identify an addr structure, when
 * that address has been derived from any other address.  It is, however,
 * sufficient to give the (top) parent address as well, if one exists.
 */
struct identify_addr {
    struct identify_addr *succ;		/* this will be a linked list */
    char *address;			/* the address of interest */
    char *parent;			/* the (top) parent of that address */
};

/*
 * The defer_addr structure is used to form a list of previously defer'd
 * addresses.  This list is formed from the per-message logfile data, and
 * is used to filter out redundant deferal messages.
 */
struct defer_addr {
    struct defer_addr *succ;		/* this will be a linked list */
    unsigned long int error;		/* error number */
    char *message;			/* deferal message */
    char *address;			/* address defered */
    char *parent;			/* (top) parent of defered address */
};

/*
 * The transport_hints structure can be used to pass additional
 * routing information between a router and a transport.  It is
 * organized as a linked list of tagged values, where the tags
 * describe the type of hint.  The bind router, for example, passes an
 * "mx" type transport hint for each possible SMTP mail exchanger to
 * the tcpsmtp transport.
 */
struct transport_hints {
	struct transport_hints * succ;	/* pointer to next hint */
	char * hint_name;		/* type of information */
	char * private;			/* pointer to information */
};

/*
 * bits used in (struct addr).flag
 */
/* note: sadly traditional C doesn't have a "UL" integer modifier */
#define ADDR_CAUTION	((unsigned long int) 0x00000010) /* be cautious of this address */
#define ADDR_UNSECURE	((unsigned long int) 0x00000200) /* address from an unsecure source */
#define ADDR_PUTDOT	((unsigned long int) 0x00000400) /* dot removed from end of target */
#define ADDR_MOVEDOT	((unsigned long int) 0x00000800) /* end dot moved to front of target */
#define ADDR_ERROR	((unsigned long int) 0x00001000) /* error in resolving address */
#define ADDR_FINISHED	((unsigned long int) 0x00002000) /* address fully resolved */
#define ADDR_FULLMATCH	((unsigned long int) 0x00004000) /* router fully matched target */
#define ADDR_DONTHASH	((unsigned long int) 0x00008000) /* addr states should not be hashed */
#define ADDR_SMARTUSER	((unsigned long int) 0x00010000) /* smart user director already used */
#define ADDR_SMARTHOST	((unsigned long int) 0x00020000) /* smart host router already used */
#define ADDR_NOTUSER	((unsigned long int) 0x00040000) /* address is not a local user */
#define ADDR_ISUSER	((unsigned long int) 0x00080000) /* address is a local user */
#define ADDR_FWDTYPE	((unsigned long int) 0x00100000) /* director used was forwarding type */
#define ADDR_ALIASTYPE	((unsigned long int) 0x00200000) /* director used was aliasing type */
#define ADDR_LISTTYPE	((unsigned long int) 0x00400000) /* director was mailinglist type */
#define ADDR_SHADOW	((unsigned long int) 0x00800000) /* using shadow transport */
#define ADDR_PARTLOCAL	((unsigned long int) 0x01000000) /* partially matched local host */
#define ADDR_RETRY_FILE	((unsigned long int) 0x02000000) /* on failure, touch retry file */
#define ADDR_VRFY_ONLY	((unsigned long int) 0x04000000) /* don't do any transforms in directors */
#define ADDR_FORM_MASK	((unsigned long int) 0x0000000f) /* form from parse_address */

/*
 * NOTE:
 *
 *	Routers can set ADDR_SMARTHOST if routers using the smarthost driver
 *	should not be used.  For example, if the local host is a gateway for a
 *	domain and a hostname within that domain cannot be resolved, then the
 *	router can set ADDR_SMARTHOST to prevent an incorrect usage of a
 *	smarthost router.
 *
 *	Directors can set ADDR_SMARTUSER in a similar manner to prevent any
 *	other director using the smartuser driver from matching an address
 *	derived by that director.  For example directors that need to verify
 *	owner addresses will not want any smartuser director to match those
 *	addresses since that would cause directing recursion loops by
 *	effectively allowing all owner addresses to exist, e.g. ones such as
 *	owner-owner-xxxx or xxxx-request-request.  All directors using the
 *	smartuser driver also implicitly set this flag on all addresses they
 *	rewrite to prevent subsequent directors which also use the smartuser
 *	driver from also trying to match the new target address.
 *
 * The ADDR_PARTLOCAL should also be set for partial matches to the local
 * host.  If ADDR_PARTLOCAL is set for an address and ADDR_FULLMATCH
 * is not set, the target is not considered to be resolved.
 */

/* bits stored in error.info */
/* note: sadly traditional C doesn't have a "UL" integer modifier */
#define ERR_MASK	((unsigned long int) 0x0000ffff) /* mask for the error number */
#define ERR_NSENDER	((unsigned long int) 0x00010000) /* notify sender of message */
#define ERR_NPOSTMAST	((unsigned long int) 0x00020000) /* notify postmaster */
#define ERR_NSOWNER	((unsigned long int) 0x00040000) /* notify address owner or sender */
#define ERR_NPOWNER	((unsigned long int) 0x00080000) /* notify owner or postmaster */
#define ERR_CONFERR	((unsigned long int) 0x00100000) /* configuration error encountered */
#define ERR_DONTLOG	((unsigned long int) 0x00200000) /* don't log this error */

/*
 * return values from parse_address() -- the address form
 *
 * XXX should be an enum to help catch missing case clauses and other misuses
 */
/*	FAIL		(-1)               syntax or other error */
#define PARSE_ERROR	0		/* error in parsing (normally only set
					 * in addr flags if preparse_address()
					 * fails */
#define RFC_ROUTE	1		/* route part of a route-addr */
#define RFC_ENDROUTE	2		/* last component of a route */
#define MAILBOX		3		/* standard user@foo mailbox */
#define UUCP_ROUTE	4		/* uucp !-route */
#define PCT_MAILBOX	5		/* non-standard user%foo mailbox */
#define LOCAL		6		/* local address */
#define BERKENET	7		/* berkenet host:user form */
#define DECNET		8		/* decnet host::user form */

/* flag values for the parse_address flagp argument */
#define FOUND_MAILBOX	0x0001		/* found user@host address form */

/* external functions defined in addr.c */
extern char *preparse_address __P((char *, char **));
extern char *preparse_address_1 __P((char *, char **, char **));
extern int parse_address __P((char *, char **, char **, int *));
extern char *address_token __P((char *));
extern char *back_address_token __P((char *, char *));
extern int mixed_address __P((char *));
extern char *build_uucp_route __P((char *, char **, int));
extern char *build_partial_uucp_route __P((char *, char **, int));
extern void strip_rfc822_comments __P((char *));
extern void strip_rfc822_whitespace __P((char *));
extern int rfc2822_is_dot_string __P((char *));
extern int rfc2822_is_quoted_string __P((char *));
extern int rfc1035_is_valid_domainname __P((char *, int, char **));
extern struct addr *alloc_addr __P((void));
extern void free_addr __P((struct addr *));
extern void free_addr_list __P((struct addr *));
extern void insert_addr_list __P((struct addr *, struct addr **, struct error *));
extern struct addr *remove_addr __P((struct addr *, char *, char *));
extern struct addr *keep_matching_addrs __P((struct addr *, char *));
extern struct addr *addr_sort __P((struct addr *, int));
extern struct error *note_error __P((unsigned long int, char *));
extern void free_error __P((struct error *));
#ifndef NDEBUG
extern void dump_addr_list __P((struct addr *));
extern void dump_addr __P((struct addr *, char *));
#endif

/* 
 * Local Variables:
 * c-file-style: "smail"
 * End:
 */
