/*	Alloc module 7.				#7
    "al7.c"

    This module contains support for Partition manipulation routines,
	Add, Delete, Modify.
*/
/*
#define		debug7		FALSE
*/

#define		EXTERNal	0

#include	"alloc.dat"

/*=============================================================================
			HISTORY

date		24 February 1984
person		tpl

ver	0
rev	0
mod	a
patch	3

 ver-rev
"""""""""
   0-0


     mod-patch
    -----------
	a0		2 February 1984		tpl
		.Make from al3.c.

*/

/*page*/
/*=============================================================================
			ROUTINES
*/

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
Get_Size()
{
  register CHAR		size;
  register CHAR		bad_size = TRUE;

    while (bad_size)
    {
	size = Read_Size();

#ifdef debug7
    printz("..Get_Size    size: %d  space_allocated: %d  total: %d\n",
			size, space_allocated[cur_volume],
			hd_types[ type_index[cur_volume] ].size_in_Kbytes);
#endif
	if ( (space_allocated[cur_volume] + (256 * power2(size)) )
		> hd_types[ type_index[cur_volume] ].size_in_Kbytes )

	    printz("%cThere is not enough free space for that size partition.\n",BELL);
	else
	{
	    if ( Find_Size_Partition( size ) == 0 )
	    {
		printz("%cYou must Compress to Add that size partition.\n",BELL);
		printz("Do you want to continue Adding :              (yes/no)");
		repchar(BS,21);
		if ( !Get_Yes_No(RETNOTOK) )
		    return(0);
	    }
	    else
		bad_size = FALSE;

	}/*else*/

    }/*while bad_size*/

    return(size);

}/*Get_Size*/

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
Ask_if_Partition_OK(ptr_partition)

  struct a_entry	*ptr_partition;
{
    Show_Header_of_Table();
    Show_Partition(ptr_partition);
    printz("\nIs this correct ...>                 (yes/no)");
    repchar(BS,24);
    return(Get_Yes_No(RETNOTOK));	/* Return TRUE for Yes, FALSE for No.	*/

} /* Ask_if_Partition_OK */

/*---------------------------------------------------------------------------*/
/*page*/

Reset_Partition(ptr_partition)
  struct a_entry	*ptr_partition;  
{

    ptr_partition->size = 0;
    clear( ptr_partition->name, Lname, SPACE);
    clear( ptr_partition->password, Lpassword, SPACE);
    ptr_partition->control = 0;

} /* Reset_Partition */

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
First_Free_Partition()
{
  register CHAR		i;

    for ( i=0; (i<NallocEntries) && (alloc_table[i].size != 0); i++)
	;
    if (i == NallocEntries)
	return (0);
    else
	return(i);

} /* First_Free_Partition*/

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
Read_Size()
{
  CHAR	choice[ LpartSize + 1 ];
  register CHAR		size,i,length;

    while ( TRUE )
    {
    printz("Size             :                (256K, 512K, 1M, 2M, 4M, 8M)");
	repchar(BS,43);
	while ( (length = Tintostring( choice, LpartSize, FALSE )) == 0 )
	    ptch( BELL );

	strUpper(choice);
	for ( i=0; i<NpartSizes; i++)
	    if (strcmp(choice, size_table[i]) == 0)
	    {
		putz("\n");
		return(i+1);
	    }
	ptch(BELL);
	repchar(BS,length);	 /* Backspace over bad partition.	 */
	repchar(SPACE,length+8); /* Overwrite partition with spaces. */
	printz("%4s ",choice);
	printz("is not a valid partition size.    \n");
			
    } /* while true */

} /* Read_Size */

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
Read_Op_Sys(accept_return)
  CHAR	accept_return;		/* TRUE if RET is ok as a response.	*/
{
  CHAR	choice[ LosName + 1 ];
  register CHAR		i,length;

    while ( TRUE )
    {
	printz("Operating System :                (MSDOS, CPM)");
	repchar(BS,27);
	while( (length = Tintostring( choice, LosName, FALSE)) == 0 )
	    if ( accept_return )
		return(RETURN);
	    else
		ptch( BELL );

	strUpper(choice);

	for ( i=0; i<Nos; i++)
	    if (strcmp(choice, os_table[i]) == 0)
	    {
		putz("\n");
		switch(i)
		{
		    case 0:
			return(CPM);
		    case 1:
			return(MSDOS);
		}
	    }/*if match*/
	ptch(BELL);
	repchar(SPACE,16-length);
	putz("That is not a valid operating system.\n");
			
    } /* while true */

} /* Read_Op_Sys */

/*---------------------------------------------------------------------------*/
/*page*/

Read_Protection_Type(accept_return, control)
  CHAR	accept_return;		/* TRUE if RET is ok as a response.	*/
  CHAR	control;		/* control byte to tell if MSDOS or not.*/
{
  CHAR	choice[ LprotectName + 1 ];	/* +1 for '\0' */
  register CHAR		i, length, question;
  CHAR	no_share = FALSE;

    while ( TRUE )
    {
	question = TRUE;
	while (question)
	{
	    printz("Protection Mode  :                (O, RO, ");
	    if ( (control & OSMASK) == CPM )
	    {
		putz("S, RW, ?)");
		repchar(BS,32);
	    }
	    else
	    {
		putz("RW, ?)");
		repchar(BS,29);
	    }

	    while( ( length = Tintostring( choice, LprotectName, FALSE)) == 0 )
		if ( accept_return )
		    return(RETURN);
		else
		    ptch( BELL );

	    if (choice[0] == '?')
	    {
		putz("\n  O = Ownable\n RO = Read Only\n");
		if ( (control & OSMASK) == CPM )
		    putz("  S = Shared\n");
		putz(" RW = Read Write\n");
	    }
	    else
		question = FALSE;
	}

	strUpper(choice);

	for ( i=0; i<Nprotect; i++)
	    if (strcmp(choice, protct_types[i]) == 0)
	    {
		putz("\n");
		switch(i)
		{
		    case 0:
			printz("%c\n\
    WARNING\n\
Read/Write partitions are dangerous and warrant special consideration.\n\
Consult your manual for information and explanation.\n\n", BELL);

			return(READWRITE);
		    case 1:
			return(READONLY);
		    case 2:
			return(OWNABLE);
		    case 3:
			if ( (control & OSMASK) == MSDOS )
			    no_share = TRUE;
			else
			    return(SHARED);
		}/*switch*/

	    }/*if match*/

	ptch(BELL);
	if ( no_share )
	{
	    putz("    You may not have a shared MSDOS partition.\n");
	    no_share = FALSE;
	}
	else
	{
	    printz("\n    %5s ",choice);
	    putz("is not a valid protection mode.\n");
	}
	
    } /* while true */

} /* Read_Protection_Type */

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
GetPartName()
{
  register CHAR		i, length = 0;
  CHAR	partName[Lname+1];

    while (TRUE)
    {
	clear( partName, Lname, SPACE);

	printz("\nWhich partition :                     (Press RETURN to go back to menu)" );
	repchar(BS,53);
	length = Tintostring( partName, Lname, TRUE );
	if (length == 0)
	    return(0);
	partName[length] = SPACE;	/* Cancel null so compare works. */
	partName[Lname] = '\0';		/* Put this here for strUpper.	 */
	strUpper(partName);

	i = 1;				/* Don't check unit 0. */
	while ( ( alloc_table[i].size != 0) && (i<NallocEntries) )
	{
	    if (strncmp( partName, alloc_table[i].name, Lname) == 0)
		return(i);
	    i++;
	}
	printz("%c  That is not a valid partition name.\n",BELL);

    }/*while TRUE*/

}/*GetPartName*/

/*---------------------------------------------------------------------------*/
/*page*/

Is_Duplicate_Name(name)
  CHAR	*name;
{
  register CHAR	i = 1;			/* Don't check system partition. */
  register CHAR	match = FALSE;

    while ( (alloc_table[i].size != 0) && (!match) && (i<NallocEntries) )
    {
	if (strncmp( name, alloc_table[i].name, Lname) == 0)
	    match = TRUE;
	i++;
    }

    return(match);

}/*Is_Duplicate_Name*/

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
Get_Yes_No(accept_return)
  int	accept_return;	/* Is "RET" a valid response besides yes or no. */
{
  CHAR	response[ Lyn + 1 ];	/* Can hold "yes\0".	*/
  register CHAR	length, i;

    while(TRUE)
    {
	length = Tintostring( response, Lyn, FALSE);
	if ( (length == 0) && (accept_return) )
	    return(RETURN);
	strUpper(response);
	for ( i=0; i<Nyn; i++ )
	if ( strcmp( response, yes_no_responses[i] ) == 0 )
	{
	    putz("\n");
	    if (i < 2)
		return(TRUE);  /* Yes entry. */
	    else
		return(FALSE); /* No entry.  */
	}
	ptch(BELL);
	repchar(BS,length);

    } /* while true */

} /* Get_Yes_No */

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
Find_Size_Partition(size)
  int	size;
{
  register CHAR		i = 0;

#ifdef debug7
	printz("..Find_Size_Partition\n");
#endif

/* First look for a deleted entry of the correct size. */

    while ( (alloc_table[i].size != 0) && (i<NallocEntries) )
    {
	if ( ( alloc_table[i].size == size)
		&& ( alloc_table[i].name[0] == 'd' )  )
	    return(i);
	i++;
    }
/* Deleted entry not found, give first free table entry if enough space.     */

#ifdef debug7
	printz("find first free table entry.\n");
#endif
    if ( hd_types[ type_index[cur_volume] ].size_in_Kbytes
		- space_partitioned[cur_volume] >= (size * 256) )
	return( First_Free_Partition() );
    else
	return(0);

}/*Find_Size_Partition*/

/*---------------------------------------------------------------------------*/
/*page*/

int
power2(exponent)
  int exponent;
{
  register CHAR		i;
  int	power = 1;

    for ( i=0; i<exponent-1; i++)
	power *= 2;
    return( power );

}/*power2*/

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
*Read_Name( length, ret_ok_flag )
  CHAR	*length;
  int	ret_ok_flag;
{
  register CHAR		duplicate;

    *length = 0;
    duplicate = TRUE;
    while ( (*length == 0) || (duplicate == TRUE) )
    {
	clear( input_buff, Lname, SPACE);
	printz("Name             :                (8 characters max)");
	repchar(BS,33);
	*length = Tintostring( input_buff, Lname, FALSE);
	if (*length == 0)
	{
	    if ( ret_ok_flag == RETNOTOK )
		printz("%c        You must enter a name.        \n",BELL);
	    else
		return( input_buff );
	}
	else
	{
	    if ( input_buff[0] == SPACE )
	    {
		printz("%c        The first character cannot be a space.\n",BELL);
		*length = 0;	/* flag bad entry. */
	    }
	    else
	    {
		strUpper(input_buff);
		input_buff[*length] = SPACE;

		if ( duplicate = Is_Duplicate_Name(input_buff) )
		    printz("%c        That partition name already exists\n",BELL);
	    }/*else*/

	}/*else*/

    } /* while bad entry for name */

    return( input_buff );

} /* Read_Name */

/*---------------------------------------------------------------------------*/
/*page*/

CHAR
*ReadPassword( length )
  CHAR	*length;
{
  register CHAR		bad_password = TRUE;

    while ( bad_password )
    {
	clear( input_buff, Lpassword, SPACE);
	printz("Password         :                (6 characters max)");
	repchar(BS,33);
	*length = Tintostring( input_buff, Lpassword, FALSE);
	if ( (input_buff[0] == SPACE) && (*length != 0) )
	    printz("%c        The first character cannot be a space.\n",BELL);
	else
	    bad_password = FALSE;

    } /* while bad entry for name */

    input_buff[ *length ] = SPACE;	/* Allows string compares to work. */

    return( input_buff );	/* return address of input string. */

} /* ReadPassword */

/*---------------------------------------------------------------------------*/
/*page*/

GetPassword( partition )
  CHAR	partition;
{
  CHAR *input_string;
  register CHAR		i, length;

    for ( i=0; i<3; i++ )
    {
	putz("\nWhat is the current password?\n");
	input_string = ReadPassword( &length );
	if ( strncmp( alloc_table[ partition ].password, input_string,
							Lpassword ) == 0 )
	    return;
	putz("\nThat is not the old password.\n");
    }

    printz("%c\n\n  I assume you do not know the password. Good-bye.\n", BELL);
    zabort();

} /* GetPassword */

/*---------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
