#
/*
*	SCCS File Type - 
*
* 	What identification string
*/
static char *_S_getacclevc =  "@(#)getacclev.c	1.9";
#include "KERcalls.h"
#include "NKSRdefs.h"
#include "NKedit.h"
#include "KSOSpaths.h"

/*****************************************************************************

PURPOSE
		Getaccesslev calls three routines to store
		access level data in the received pointer.

CALLS           getseccat, getintcat, getcompart

*****************************************************************************/
getaccesslev(levl)
access_level_type *levl;
{

	getseccat(&levl->security_category);
	getintcat(&levl->integrity_category);
	getcompart(&levl->security_compart);
}

/*****************************************************************************

PURPOSE
		Getseccat prompts the user for security category
		information to be stored in the passed pointer location.

CALLED BY       getaccesslev

CALLS           prtcategory, catmatch,
		printf, scaner

*****************************************************************************/
getseccat(seccat)
register char    *seccat;
{
	char    category[LINELENGTH];   /* group input  */
	int     beg = 0;                /* begining location in seclist */
	int     end = NUMSECCAT;        /* ending location in seclist */


	printf("\nSECURITY CATEGORY\n");

	while(FOREVER)
	{
		printf("\nEnter desired SECURITY category: ");
		scaner(category);

		if(category[0] == ENDSTRING)
			prtcategory(&beg,&end);       /* Carriage return */

		else if(strlen(category) > SHORT)
			printf("Category name too long.\n\n");

		else if((*seccat = catmatch(category,&beg,&end)) != CATERROR)
			break;
		else
			prtcategory(&beg,&end);
	}
	return;
}


/*****************************************************************************

PURPOSE
		Getintcat prompts the user for integrity category
		information to be stored in the passed pointer location.

CALLED BY       getaccesslev

CALLS           prtcategory, catmatch,
		printf, scaner

*****************************************************************************/
getintcat(intcat)
char    *intcat;
{
	char    category[LINELENGTH];   /* group input  */
	int     beg = NUMSECCAT;        /* begining location in seclist */
	int     end = NUMCAT;           /* ending location in seclist */

	printf("\nINTEGRITY CATEGORY\n");

	while(FOREVER)
	{
		printf("\nEnter desired INTEGRITY category: ");
		scaner(category);

		if(category[0] == ENDSTRING)
			prtcategory(&beg,&end);  /* Carriage return */

		else if(strlen(category) > SHORT)
			printf("Category name too long.\n\n");

		else if((*intcat = catmatch(category,&beg,&end)) != CATERROR)
		{
			*intcat -= NUMSECCAT;
			break; 
		}
		else
			prtcategory(&beg,&end);
	}
	return;
}

/*
 * prtcategory print list of valid categories
 * called by getseccat, getintcat
 * calls printf
 */
prtcategory(begnum,endnum)
int     *begnum; /* begining location in security map */
int     *endnum; /* ending location in security map */
{
	extern  secarray seclist[];
	register int     secnum;
	register int     i;

	for (secnum = *begnum; secnum < *endnum; secnum++)
		if (seclist[secnum].activ == ACTIVE)
		{
			printf ("%-12s        ",seclist[secnum].shortname);
		}
	return;
}

/*
 * catmatch check if group input is a valid category
 * called by getseccat, getintcat
 * calls printf, scaner, toupper
 */
catmatch(category,begnum,endnum)
register char    category[];
int     *begnum,*endnum;
{
	extern  secarray seclist[];
	register int     secnum;        /* index into security map */
	char    catchar;                /* low bits of secmap index */
	char    nc;                     /* char of category named */
	int     i;                      /* index through category */

	for (secnum = *begnum; secnum < *endnum; secnum++)
	{
		/* convert any lowercase char to uppercase */
		for (i = 0; (i <= SHORT) && ((nc = category[i]) != ENDSTRING); i++)
			if (nc >= 'a' && nc <= 'z')
				category[i] -= CASEDIFF;


		if(strlcmp(category,seclist[secnum].shortname,SHORT) == EQUAL)
		{
			catchar = secnum & LOWMODE;
			return(catchar);
		}
	}
	printf("Invalid category.\n\n");
	return(CATERROR);
}

/*****************************************************************************

PURPOSE
		Getcompart prompts the user for security compartments
		information to be stored in the passed pointer location.

CALLED BY       getaccesslev

CALLS           getdec, printcompart,
		printf

*****************************************************************************/
getcompart(compartment)
int     compartment[2];
{
	extern  secarray seclist[];
	char    c;              /* non digit input set by getdec*/
	int     anumber;        /* set on if a number is found */
	int     compnum;        /* user input number set by getdec */

	while(FOREVER)
	{
		printf("\n\nThe valid security compartments are\n");
		compartment[0] = ~0;
		compartment[1] = ~0;
		printcompart(compartment);
		compartment[0] = 0;
		compartment[1] = 0;

		printf("\nEnter numbers of desired security compartments\n");
		printf("separated by spaces (carriage return for NULL):\n");

		/* continue reading compartments until carriage return */
		while(c != NEWLINE)
		{
			/* read standard in for compartment or carriage return */
			do
				anumber = getdec(&compnum,&c);
			while
				((anumber != FOUND) && (c != NEWLINE));

			/* compartment number found */
			if(anumber == FOUND)
				if((compnum<0) || (compnum>31) ||
				(seclist[compnum+NUMCAT].activ != ACTIVE))
					printf("\n%d is an invalid security compartment.\n",compnum);
				else
				{
					if (compnum < 16)
						compartment[0] |= 1<<compnum;
					else
						compartment[1] |= 1<<(compnum-16);
				}

		}
		printf("\nYou have selected the following compartments:\n");
		printcompart(compartment);

		printf("Are these correct (y or n): ");
		if (yesorno() == NO)
		{
			printf("Please reenter.\n");
			c = BLANK;
		}
		else
			return;
	}
}
/* print level structure */
prtlevel(level)
access_level_type *level;
{
	extern 	secarray seclist[];	/* security map */
	int	indx;			/* index into security map */

	printf ("        security category: %s\n",seclist[indx = level->security_category].shortname);
	printf ("        integrity category: %s\n",seclist[NUMSECCAT + (indx = level->integrity_category)].shortname);
	printf ("        security compartments:");
	printcompart(&level->security_compart);
	printf ("\n");
	return;
}
/*
 * printcompart prints the flagged compartments in the passed long
 * called by getcomp
 * calls printf
 */
printcompart(comp)
int  *comp;
{
	int     compartment[2];
	extern  secarray seclist[];
	int     any = OFF;
	register int     mask;  /* mask integer */
	register int     j; /* index through secMap */
	register int     order; /* designates which integer of compartment */

	compartment[0] = *comp;
	compartment[1] = *(comp+1);
	printf("\n");

	for (mask = 1, j = COMPLOW, order = 0; j < COMPHIGH; mask <<= 1, j++)
	{
		/* reset for second compartment integer */
		if (j == HALFWAY)
		{
			order = 1;
			mask = 1;
		}

		if ((compartment[order] & mask) && (seclist[j].activ == ACTIVE))
		{
			printf ("        %-12s",seclist[j].shortname);
			printf(" %d\n",j-NUMCAT);
			any = ON;
		}
	}
	if (any == OFF)
		printf("        NULL\n");
}
/*
 * makes security map list from the security_map
 */
mkseclist()
{
	extern  secarray seclist[];
	char    secbuff[SMRECLEN];              /* security map buffer */
	extern  int     F1;                     /* file descriptors */
	register int     lindex = 0;            /* local index */

	/* open security map for reading */
	if ((F1 = N_open(secmapPath, READ)) == -1)
	{
		printf ("can't open security map data base\n");
		K_release_process (null_seid);
	}

	/* create secMap */
	while (N_read(F1,secbuff,SECMAPLEN) > 0)
	{
		strcopy(&seclist[lindex].shortname,secbuff,SHORT);
		seclist[lindex++].activ = secbuff[ACTPLACE];
	}

	N_close(F1);
}
