/*
 *	Copyright 1990 by Rayan S. Zachariassen, all rights reserved.
 *	This will be free software, but only when it is finished.
 */
/*
 *	A plenty of changes, copyright Matti Aarnio 1990-1995
 */

#ifdef HAVE_CONFIG_H
#include "hostenv.h"
#endif

struct address {
	struct address	*link;		/* next sender / sender for this rcpt */
	char		*channel;
	char		*host;
	char		*user;
	char		*misc;		/* expected to be uid privilege */
	char		**routermxes;	/* [mea] hostpointers from router */
};

#define _DSN_RET_NO		0x001
#define _DSN_RET_YES		0x002
#define _DSN_NOTIFY_SUCCESS	0x004
#define _DSN_NOTIFY_FAILURE	0x008
#define _DSN_NOTIFY_ALWAYS	0x010
#define _DSN_NOTIFY_NEVER	0x020

/* `convertmode' controls the behaviour of the message conversion:
     _CONVERT_NONE (0): send as is
     _CONVERT_QP   (1): Convert 8-bit chars to QUOTED-PRINTABLE
     _CONVERT_8BIT (2): Convert QP-encoded chars to 8-bit
     _CONVERT_UNKNOWN (3): Turn message to charset=UNKNOWN-8BIT, Q-P..
*/
#define _CONVERT_NONE	 0
#define _CONVERT_QP	 1
#define _CONVERT_8BIT	 2
#define _CONVERT_UNKNOWN 3


struct rcpt {
	struct rcpt	*next;
	struct address	*addr;		/* addr.link is the sender address */
	char		*orcpt;		/* DSN ORCPT= string */
	int		dsnflags;	/* DSN  RET=, and NOTIFY= flags */
	char		***newmsgheader; /* message header line pointer ptr
					   that points to an address of
					      ctldesc->msgheaders[index]
					   which then points to a place
					   containing the header itself.
					   Thus enabling rewrite of the
					   header on the transport. */
	char		***newmsgheadercvt; /* the rewrite results */
	long		id;		/* the index of this address */
	long		lockoffset;	/* the index of the address lock */
	int		status;		/* current delivery sysexit code */
	struct ctldesc	*desc;		/* backpointer to descriptor */
	/* XX: something needed for XOR address lists */
};

struct ctldesc {
	char		*msgfile;	/* message file name */
	char		*logident;	/* message id for logging */
	char		*verbose;	/* file for verbose logging */
	char		*envid;		/* DSN ENVID data */
	long		msgbodyoffset;	/* offset of message body in msgfile */
	long		msgsizeestimate; /* Estimate of the msg size */
	int		msgfd;		/* message file I/O descriptor */
	int		ctlfd;		/* control file I/O descriptor */
	int		ctlid;		/* control file id (inode number) */
	char		*ctlmap;	/* control file mmap() block */
	char		*contents;	/* message file data */
	long		contentsize;	/* message file size */
	long		*offset;	/* array of indices into contents */
	struct address	*senders;	/* list of sender addresses */
	struct rcpt	*recipients;	/* list of selected recipients */
	int		rcpnts_total;	/* number of recipients, total */
	int		rcpnts_remaining;/* .. how many yet to deliver */
	int		rcpnts_failed  ;/* .. how many failed ones */
	char		***msgheaders;	/* pointer to all msg headers */
	char		***msgheaderscvt; /* converted headers */
#ifdef	HAVE_MMAP
	char		*let_buffer;	/* MMAP()ed memory area containing */
	char		*let_end;	/* the mail -- and its end..	   */
#endif
};


/* MIME-processing headers -- "Content-Transfer-Encoding:",
			  and "Content-Type:"			*/

struct cte_data {
	char	*encoder;
};

struct ct_data {
	char	*basetype;	/* "text"		*/
	char	*subtype;	/* "plain"		*/
	char	*charset;	/* charset="x-yzzy"	*/
	char	*boundary;	/* boundary="...."	*/
	char	*name;		/* name="..."		*/
	char	**unknown;	/* all unknown parameters */
};


#ifndef __
# ifndef __STDC__
#  define __(x) ()
#  ifdef __GNUC__
#   define const    __const
#   define volatile __volatile
#  else
#   define const
#   define volatile
#  endif
# else
#  define __(x) x
# endif
#endif

/* ctlopen.c: */
extern void            ctlfree __((struct ctldesc *dp, void *anyp));
extern void           *ctlrealloc __((struct ctldesc *dp, void *anyp, size_t size));
extern struct ctldesc *ctlopen __((char *file,char *channel, char *host, int *exitflag, int (*selectaddr)(),int (*matchrouter)()));
extern void            ctlclose __((struct ctldesc *dp));
extern int	       ctlsticky __((char *spec_host,char *addr_host));

/* diagnostic.c: */
extern char           *notaryacct __((int rc, char *okstr));
		/* NOTARY: addres / action / status / diagnostic  */
extern void 	       notaryreport __((const char*,const char*,const char*,const char*));
extern void	       diagnostic __((/* struct rcpt *, int, int, char *,... */));

/* dnsgetrr.c */
extern int	getrr     __((char *, int, int, int));
extern int	getrrtype __((char *, int, int, int));

/* emptyline.c: */
extern int	       emptyline __((char *line, int size));

/* esyslib.c: */
extern int eopen __((char *s, int f, int m));
extern int eread __((int fd, char *buf, int len));
extern int epipe __((int fdarr[2]));
extern int embytes;
extern int emcalls;
extern unsigned emsleeptime;
/* extern univptr_t emalloc __((size_t len));
   extern univptr_t erealloc __((univptr_t buf, size_t len)); */
#ifdef S_IWUSR /* Defined on <sys/stat.h> */
extern int efstat __((int fd, struct stat *stbuf));
extern int estat __((char *path, struct stat *stbuf));
#endif
extern long elseek __((int fd, long pos, int action));
extern int elink __((char *file1, char *file2));
extern int eunlink __((char *file));
extern int eclose __((int fd));
extern int echdir __((char *path));
extern int emkdir __((char *path, int mode));
extern int ermdir __((char *path));
extern int erename __((char *from, char *to));

/* lockaddr.c: */
extern int lockaddr __((int fd, char *map, long offset, char was, char new));

/* markoff.c: */
extern int markoff __((char *filecontents, int bytesleft, long offsets[], char *filename));

/* mimeheaders.c: */
extern int append_header __(());
extern struct cte_data *parse_content_encoding __((char **cte_linep));
extern struct ct_data  *parse_content_type __((char **ct_linep));
extern void output_content_type __((struct rcpt *rp, struct ct_data *ct, char **oldpos));
extern int check_conv_prohibit __((struct rcpt *rp));
extern int cte_check __((struct rcpt *rp));
extern char **has_header __((struct rcpt *rp, char *keystr));
extern void delete_header __((struct rcpt *rp, char **hdrp));
extern int downgrade_charset __((struct rcpt *rp, FILE *verboselog));
extern void downgrade_headers __((struct rcpt *rp, int downgrade, FILE *verboselog));
extern int qp_to_8bit __((struct rcpt *rp));

/* mime2headers.c */
extern int headers_to_mime2 __((struct rcpt *rp, FILE *verboselog));


/* writeheaders.c: */
extern int writeheaders __((struct rcpt *rp, FILE *fp, char *newline, int use_cvt, int maxwidth));

/* buildbndry.c: */
extern char *mydomain __((void));
extern char *buildboundary __((char *what));

extern int getout;
extern RETSIGTYPE wantout __(());
