/*	Convergent Technologies - System V - Sep 1984	*/
/*	"@(#)spawn.h	1.1"	*/

/*
 *	common definitions for the spawn code
 */
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/param.h>

key_t	ftok();

#define APNUM	syslocal(4)	/* my AP number */
#define APNUMT	syslocal(5)	/* total number of APs */
#define EQ(s1, s2) (strcmp(s1, s2) == 0)
#define	MAGICMODE 06000
#define	MSZ(msg) (sizeof(msg) - sizeof(long))
#define MTYP(mypid, childpid) ((mypid << 16) | childpid)
#define	PIDTOAP(pid)	(((pid - 1) * APNUMT) / MAXPID)
#define RETURNERR(x) {errno = x; return(-1);}
#define	SPAWNPATH	"/usr/bin/spawn"

/*
 *	idinfo	is info currently replicated for security between
 *	tmpfile & msg sent to spawnsrv
 */
struct	idinfo {
	int	i_spid;	/* spawner's pid */
	int	i_uid;	/* real uid */
	int	i_euid;	/* effective uid */
	int	i_gid;	/* real gid */
	int	i_egid;	/* effective gid */
};

struct	t_file {
	struct idinfo t_id;	
	int	t_umask;	/* old umask */
	char	t_sig[NSIG];	/* old signals */
	char	t_path[128];	/* cwd path */
	char	t_name[128];	/* cmd name */
	int	t_argc;		/* arg count */
	int	t_envc;		/* env var count */
	/*
	 *	followed by the t_argc argument variables &
	 *	t_env environment variables
	 */
};

/*
 *	spawnvp/spwait communicate to spawnsrv via S5 messages,
 *	using following message structure:
 *	msgs1:	request server to spawn
 *	msgr1:	reply to msgs1
 *	msgs2:	request server to do spwait
 *	msgr2:	reply to spwait request
 */

struct	msgs1 {			/* spawnvp ==> spawnsrv */
	long	m_type;		/* 1 <= mtype <= APNUMT+1 = apnum+1 where
				msg directed; spawnsrv will read using APNUM+1 :
				note magic use of msgtyp=0 makes us add 1 */
	int	m_stype;		/* subtype = M_SPAWN */
	struct idinfo m_id;		/* ID info (unsafe) */
	char	m_tfile[L_tmpnam];	/* name of corresp temp file */
};

#define	M_SPAWN	0
#define M_WAIT	1

struct	msgr1 {			/* spawnsrv ==> spawnvp */
	long	m_type;		/* = mypid << 16 | 0 */
	int	m_cpid;		/* "child" pid or -1 */
	int	m_errno;	/* errno, if any */
};

struct	msgs2 {			/* spwait ==> spawnsrv */
	long	m_type;		/* 1 <= m_type <= APNUMT+1: number +1 of AP */
	int	m_stype;	/* subtype = M_WAIT */
	int	m_cpid;		/* "child" pid or 0 (meaning any child) */
	int	m_spid;		/* my pid */
};

struct msgr2 {			/* spawnsrv ==> spwait */
	long	m_type;		/* = mypid << 16|m_cpid (as given) */
	int	m_cpid;		/* "child" pid or -1 */
				/* if prev msg used cpid =0, this has the one
				 * found, OR
				 * -1: other AP had none for me
				 * 0: other AP has some, but not dead
				 */
	int	m_status;	/* status, as in wait(2) */
};
