#define	DEFSONLY
#include  "KIP.h"			/* KIP/global */

#ifdef	EMULATE
#include  "EMUdefs.h"	/* KIP/global */
#endif	EMULATE

#include  "db"
#include  "basicdefs.h"

int daemon_flag;			/* indicates if process is a daemon */
#ifdef	EMULATE
/*************************************************************************
	PROCEDURE   warning
	PURPOSE     To relay that somthing unexpected happened.
*************************************************************************/
warning(arglist)
{
	register save_fout ;
	extern fout ;

	save_fout = fout ;
	flush() ;
	fout = 2 ;
	printf("WARNING: (%s) %r\n",gfiden,&arglist) ;
	flush() ;
	fout = save_fout ;
}
#endif	EMULATE

/* This function moves a specified number of bytes.
 *	Inputs:
 *		cnt	- number of bytes to move.
 *		src	- address of source data.
 *		dst	- address of destination buffer.
 *	Outputs:
 *		Address of end of the destination buffer.
 */
move_data(cnt,src,dst)
int cnt ;			/* number of characters to move */
char *src ;			/* address of string to store */
char *dst ;			/* address at which to store string */
{
	while ( cnt-- > 0 )
		*dst++ = *src++ ;
	return(dst) ;
}

seid of_seid ;			/* SEID of open files data file */
long cblock ;

/* This function is the initialization function for processes which
 * utilize the Kernel Interface Package (KIP).  This function must
 * be called as soon as a process is invoked.  It sets up the KIP
 * environment.
 */
KIP_init()
{
	register excep ;
	int dummy ;
	int od ;			/* Fid for o.f. data file */
	long Kmodes ;
	extern dirSTod ;		/* OD for directory sub-type */
#ifdef	DEBUG
	tii_struct file_tii ;
#endif	DEBUG

#ifdef	EMULATE
char buff[512] ;
char *dmyptr ;
int dmyfid ;
#endif	EMULATE

	/* Initialize null structures */
	null_Pblk.location.domain = null_domain ;
	null_Pblk.location.space = null_space ;
	null_Pblk.location.address = 0 ;
	null_Pblk.b_size = 0 ;
	errno = 0 ;

#ifdef	DEBUG
db(("KIP_init: parent_seid: "))
pr_seid(parent_seid) ;
printf("\n") ;
#endif	DEBUG
	/* Change own discretionary access so can receive IPC msgs */

#ifndef	EMULATE
	if ( (od = K_set_da(own_seid,0660)) )
		warning("KIP_init: Can't set own discretionary access\n") ;
#endif	EMULATE

#ifdef	DEBUG
	if ( (od = K_get_object_level(own_seid,&file_tii)) )
	{
		printf("KIP_init: (%s) K_get_object_level for own_seid returned %d\n",gfiden,od) ;
	}
	else
	{
printf("KIP_init: (%s) sec - %dD,integ - %dD,security_compart - %loO,da - %o,priv - %loO\n",gfiden,file_tii.access_level.security_category,file_tii.access_level.integrity_category,file_tii.access_level.security_compart,file_tii.da,file_tii.tii_priv) ;
	}
#endif	DEBUG

	/* Construct 'open files data' file name from PID */
	build_of() ;
	/* Does 'open files data' file exist AND we didn't open the tty? */
	if ( O_F_data[0].ftype || KIP_stat(KIPOF,&of_seid) < 0 )
	{
		/* Assume initial process, clear parent's seid */
		parent_seid = 0L ;
	}
	else
	{
		/* Although 'open files data' file exists, if the terminal was
		   opened initially, assume that the file is old and not ours */
		/* Open 'open files data' file */
db(("KIPinit: call K_open with SEID %d/%d/%d\n",(of_seid.nsp&0377),of_seid.uniq_id0,of_seid.uniq_id1))
		if ( K_open(of_seid,om_read,null_open_descriptor,&od) != XOK )
			die(-1) ;
db(("KIP_init: Kopen returns od %d for open files data file\n",od))
		/* Read 'open files data' from disk */
		inp.location.domain = supervisor_domain ;
		inp.location.space = d_space ;
		inp.location.address = I_O_buff ;
		inp.b_size = blksize(sizeof O_F_data) ;
		if ( (excep = K_device_function(od,READ,cblock,&inp,&null_Pblk,
		0,&IoStatus,&dummy)) == XOK )
		{
			move_data(sizeof O_F_data,I_O_buff,O_F_data) ;
			cblock = inp.b_size/BLOCKSZ ;
			inp.b_size = blksize(sizeof buf_data) ;
			if ( (excep = K_device_function(od,READ,cblock,&inp,
			&null_Pblk,0,&IoStatus,&dummy)) == XOK )
			{
				move_data(sizeof buf_data,I_O_buff,buf_data) ;
				cblock += inp.b_size/BLOCKSZ ;
				inp.b_size = blksize(sizeof tty_data) ;
				if ( (excep = K_device_function(od,READ,cblock,
				&inp,&null_Pblk,0,&IoStatus,&dummy)) == XOK )
					move_data(sizeof tty_data,I_O_buff,
					tty_data) ;
			}
		}
db(("KIP_init: call K_close with %d\n",od))
		K_close(od) ;
		if ( excep != XOK )
		{
db(("KIP_init: ERROR from K_device_function\n"))
			die(-1) ;
		}
		/* Let startup program(s) unlink the Open Files Data files */
/*
		Xunlink(KIPOF) ;
*/

#ifdef	EMULATE
		/* Set up 'sharable segment' files for emulation */
		for ( od = 0 ; od < 15 ; od++ )
			if ( O_F_data[od].ftype == PIPE )
			{
				dmyptr = strcopy("/tmp/",buff) ;
				for ( dmyfid = 1 ; path_seid[dmyfid].Seid ; dmyfid++ ) ;
				if ( UDMstore(dmyfid,buff,null_seid) )
				{
					warning("internal table path_seid full\n") ;
					return(-1) ;
				}
				path_seid[dmyfid].Seid = O_F_data[od].sseid ;
				lzitoa(5,path_seid[dmyfid].Seid.uniq_id1,dmyptr) ;
				strcopy(buff,path_seid[dmyfid].Path) ;
			}
#endif	EMULATE

	}
	/* Set a flag for the directory sub-type od */

#ifdef	EMULATE
if ( dirSTod >= 0 )
#endif	EMULATE

	O_F_data[dirSTod].ftype = -1 ;

#ifdef	DEBUG
print_o_f() ;
#endif	DEBUG

}
/* This function opens the terminal.
 *	Inputs:
 *		od	- address to store open descriptor.
 *	Outputs:
 *		-1	- error.
 *		Open mode:
 *			MREADWRITE.
 *			MWRITE.
 *		open descriptor stored in od in no error.
 */
open_tty(od)
int *od ;
{
	register excep ;

	/* If terminal can't be opened for read/write, try to open it for
	   write only */
	if ( (excep = K_open(term_seid,(om_read|om_write),null_open_descriptor,
	od)) != XOK )
	{

#ifdef	EMULATE
db(("open_tty: K_open returns %d for RW open of term_seid ",excep))
pr_seid(term_seid) ;
printf("\n") ;
#endif	EMULATE

		if ( (excep = K_open(term_seid,om_write,null_open_descriptor,
		od)) != XOK )
		{
	
#ifdef	EMULATE
db(("open_tty: K_open returns %d for W open of term_seid ",excep))
pr_seid(term_seid) ;
printf("\n") ;
#endif	EMULATE
			return(-1) ;
		}
		return(MWRITE) ;
	}
	return(MREADWRITE) ;
}
termInit()
{
	register tIx, Mode ;
	int dummy ;
	long tty_id ;
	open_mode Omode ;
	extern fout ;


#ifndef	EMULATE

#ifdef	DEBUG
dbgmsk |= dbg14 ;
#endif	DEBUG

#endif	EMULATE

	/* Force include of KIP version of putchar() instead of UNIX version */
	putchar(0) ;
	if ( K_get_process_status(null_seid,&Proc_stat_block) != XOK )
		die(-1) ;

	/* Pick up pertinent data from the process status block */
	own_seid = Proc_stat_block.own ;
	parent_seid = Proc_stat_block.parent ;
	own_ruid = Proc_stat_block.owner&0377 ;
	own_rgid = Proc_stat_block.group&0377 ;
	for ( tIx = 0 ; tIx < NOFILE ; tIx++ )
		O_F_data[tIx].ftype = 0 ;
	/* Construct this terminal's seid */
	term_seid.nsp      = terminal_nsp ;
	tty_id = term_seid.uniq_id0 = (Proc_stat_block.family>>8)&0377 ;
	term_seid.uniq_id1 = Proc_stat_block.family&0377 ;

	/*  set the daemon_flag based on the terminal seid:
	 *	if the seid is a console seid (terminal_nsp,0,0), set
	 *	  daemon_flag to 1 indicating that the process is a daemon
	 *	else, process is executed from another terminal and
	 *	  daemon_flag is set to 0
	 */
	if (term_seid.uniq_id0 == 0)
		daemon_flag = 1;
	else
		daemon_flag = 0;

	fin = 0 ;
	fout = 1 ;
	/* If terminal can't be opened, exit */
	if ( (Mode = open_tty(&dummy)) < 0 )
	{
		die(-1) ;
	}
	/* NOTE: MAJOR ASSUMPTION MADE IN KIP INITIALIZATION - FILE DESCRIPTOR
	0 IS ASSUMED TO ALWAYS BE OPEN ONCE A PROCESS FAMILY STARTS UP.  HENCE,
	AN INITIAL OPEN OF THE TTY WHICH YIELDS THE FID 0 IMPLIES AN INITIAL
	PROCESS IN A PROCESS FAMILY */
	/* If od not 0, assume not initial process, close od */
	if ( dummy > 0 )
	{
		K_close(dummy) ;
	}
	/* Assume initial process in this 'process family' */
	else
	{
		/* Initialize this terminal's Open Files Data item */
		if ( init_one(fin,term_seid,TTY,tty_id) )
			die(-1) ;
		O_F_data[fin].fmode = O_F_data[fin].rmode = Mode ;
		/* Output initial message if a daemon */
		if ( daemon_flag )
		{
			printf("%s: owner %d, group %d, own_seid ",gfiden,own_ruid,own_rgid) ;
			pr_seid(own_seid) ;
			printf("\n") ;
		}

		/* Open terminal again for standard output (od = 1) */

#ifdef	EMULATE
for ( tIx = 1 ; tIx < NOFILE ; close(tIx++) ) ;
#endif	EMULATE

		/* If terminal can't be opened, exit */
		if ( (Mode = open_tty(&dummy)) < 0 )
		{
			die(-1) ;
		}
		/* Initialize this terminal's Open Files Data item */
		if ( init_one(dummy,term_seid,TTY,tty_id) )
			die(-1) ;
		O_F_data[dummy].fmode = O_F_data[dummy].rmode = Mode ;
		/* Open terminal again for standard error (od = 2) */
		/* If terminal can't be opened, exit */
		if ( (Mode = open_tty(&dummy)) < 0 )
		{
			die(-1) ;
		}
db(("termInit: K_open returns XOK, 'error' is %d\n",dummy))
		/* Initialize this terminal's Open Files Data item */
		if ( init_one(dummy,term_seid,TTY,tty_id) )
			die(-1) ;
		O_F_data[dummy].fmode = O_F_data[dummy].rmode = Mode ;
	}

#ifdef	EMULATE
	EDI_Init() ;
	KIP_init() ;
#endif	EMULATE

}
