/*
 *	Copyright 1988 by Rayan S. Zachariassen, all rights reserved.
 *	This will be free software, but only when it is finished.
 */

#include "hostenv.h"
#include "malloc.h"
#include "splay.h"

#ifndef	USE_SYSLOG
#define	syslog	(void)
#endif


struct config_entry {
	struct config_entry *next;
	char	*channel;	/* channel part of pattern */
	char	*host;		/* host part of pattern */
	u_int	interval;	/* how often to start up these things */
	u_int	expiry;		/* bounce the message after this long in q's */
	char	*expiryform;	/* use this form as the error message */
	int	uid;		/* what uid to run the transport agent under */
	int	gid;		/* what gid to run the transport agent under */
	char	*command;	/* the command to run */
	short	bychannel;	/* indicates $channel occurs in command */
	short	byhost;		/* indicates $host occurs in command */
	int	flags;		/* miscellaneous flags */
	int	maxkids;	/* run command only if # TA's running < this */
	int	maxkidChannel;	/* run only if # TA's running channel < this */
	int	maxkidHost;	/* run only if # TA's running host < this */
	int	skew;		/* retry skew parameter */
	int	mark;		/* non-0 if we started a TA the last time */
	int	pending;	/* non-0 if TA fork would go over limits */
	char	**argv;		/* execv parameters for the command */
	int	nretries;	/* number of retry factors known */
	int	*retries;	/* list of nretries retry factors */
};

#define FF_GANGSCHEDULE	01	/* synchronize scheduling of all address groups
				   for the same channel/host destination */

#define	MAXHOSTSPERCHANNEL	500 /* only check the first N hosts listed */

#define	L_CTLFILE	0
#define L_HOST		1
#define L_CHANNEL	2
#define SIZE_L		3

extern struct sptree *spt_mesh[SIZE_L];

#define	V_NONE		0
#define	V_ALL		1
#define	V_SELECT	2

struct ctlfile {
	int	fd;		/* a file descriptor pointing at the file */
	FILE	*vfp;		/* a FILE * for verbose logging for mail -v */
	int	uid;		/* the owner of the control file (== msg file)*/
	time_t	ctime;		/* when this file was created (more or less) */
	int	haderror;	/* some errors/diagnostics need processing */
	struct vertex	*head;		/* head of the list of groups */
	int	nlines;		/* number of lines/entries in the file */
	char	*contents;	/* the control file as copied into memory */
	char	*logident;	/* identification for log entries */
	char	*erroraddr;	/* error address(es) */
	ino_t	id;		/* identification # (inode# of control file) */
	char	*mid;		/* msg identification (name of message file) */
	int	mark;		/* flag used by selector() to pass filenames */
	long	offset[1];	/* array of nlines byte offsets into the file */
};

struct web {
	char		*name;	/* name of the L_? thingy */
	int		kids;	/* how many transport agents running for me */
	struct vertex	*link;	/* points at group of addresses */
	struct vertex	*lastlink;	/* for efficiency */
	struct vertex	*fifohead;	/* fifo of pending vertices */
	struct vertex	*fifotail;
};

struct procinfo {
	int	pid;
	struct web *ch;
	struct web *ho;
	struct vertex *vertices;
	char	*carryover;
};

/* Stores the offset indices of all addresses that have same channel and host */

struct vertex {		
	struct ctlfile	*cfp;		/* control file containing this group */
	struct web	*orig[SIZE_L];	/* original names (channel,host,etc) */
	struct vertex	*next[SIZE_L];	/* next group with same L_? */
	struct vertex	*prev[SIZE_L];	/* previous group with same L_? */
	struct vertex	*nextmark;	/* next in list of marked vertices */
	struct vertex	*nextitem;	/* next in list of scheduled vertices */
	struct vertex	*previtem;	/* prev in list of scheduled vertices */
	char		*message;	/* some text associated with node */
	struct config_entry ce;		/* consed scheduler config file entry */
	struct procinfo *proc;		/* current TA process description */
	int		attempts;	/* count of number of TA invocations */
	int		retryindex;	/* cur index into ce->retries array */
	time_t		wakeup;		/* time to wake up and run this */
	int		ngroup;		/* number of addresses in group */
	int		index[1];	/* index of cfp->offset for group */
};

extern char		*strcpy(), *strncpy(), *strcat();

