

/*		Alloc module 0
    "AL0.C"

    This module contains   main, menu drivers, quit, and zabort.
*/
/*
#define		debug0		0
*/
#define		EXTERNal	0

#include	"alloc.dat"
#include	"overlay.h"
#include	"errno.h"
#include	"fcntl.h"

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

date		6 March 1984
person		tpl

ver	0
rev	0
mod	d
patch	20

 mod-patch
----------
    d13		24 February 1984	tpl
	.Putting Compress option in.

    d7		16 February 1984	tpl
	.Split Alloc into Alloc and NetAlloc.

    d4		10 February 1984	tpl
	.Attempt to overlay password provision with 'pswdov' file.

   d1		2 February 1984		tpl
	.Take out and rename menus.

   c18		30 January 1984		tpl
	.RELEASED TO SOFTWARE TEST.

   c14		17 January 1984		tpl
	.Take out "if ( debug_mode )" and replace with
	"#ifdef debug" and "#endif" to save space.


   c5		5 January 1984		tppl
	.Enter multi-volume support.
	.Start using Mike Pompa's Assign routine 'P0Assign'
	for assigning to unit0 of chosen volume.

   c4		4 January 1984		tpl
	.Code working from mod 'c' changes.
	.Also changes made flag working.

  c		3 January 1984		tpl
	.Change constants' names and change to new include file structure.

  b		September 23, 1983	tpl
	.Install new menu structure.

  a		September 23, 1983	tpl
	.Make this module from alloc1/g, alloc2/g, alloc3/f, alloc4/e.

*/
/*=============================================================================
			DEFINES
*/

#define		NULL		0

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

#define		USERnumAdr	0x47
#define		MSTRuserNum	0
#define		ALONEuserNum	0xff

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

#define Is_Master()	(*( (CHAR *)USERnumAdr ) == MSTRuserNum)

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

#define IsStandAlone()	(*( (CHAR *)USERnumAdr ) == ALONEuserNum)

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

#define	DisableIntButton()	DISIB()


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

/*=============================================================================
				MAIN
*/
main(arg_count,arg_vector)
int	arg_count;
CHAR	*arg_vector[];
{
    Show_Version();

/* 0x1000 is size of largest overlay, rounded up to nearest 128 byte boundary.*/
    if( settop( 0x1000 ) == NULL )
    {
	printz("%c\nNot enough memory.\n", BELL);
	zabort();
    }


#ifdef NETALLOC

    if ( !Is_Master() )
    {
	printz("%c\n This is not a master.\n\
NetAlloc can only run on a master.\n\n\n", BELL );
	zabort();
    }

#endif

#ifdef ALLOC

    if ( !IsStandAlone() )
    {
	printz("%c\nYou may not run Alloc booted from the net \
(master or station).\n\
You must be booted from a floppy disk to run Alloc.\n\n\n\n", BELL);
	zabort();
    }

#endif

#ifdef ALLOC
    File_Check();	/* Make sure all needed files are present.	*/
			/* ZABORT's if not. For ALLOC only.		*/
#endif
#ifdef ALLOC
    DisableIntButton();	/* Disable the interrupt button on front panel. */
			/* Can't disable on master since not an interrupt. */
#endif

    Initialize();	/* Must initialize hard disk stuff here,	*/
			/* especially before passwords are read in.	*/
			/* Mainly for hd_xfer.				*/


/* GET PASSWORD */

#ifdef ALLOC

/* For level 1, the manager level.	*/
/* Password zaborts if faliure.		*/
    if ( ovloader( "alloc1", MANAGERlevel ) == -1 )
    {
	overlayErr();
	putz(" alloc1.ovr file.\n");
	zabort();
    }/* if ovloader returns error */

    pwLevel = MANAGERlevel;	/* Set password level variable. */

#endif

#ifdef NETALLOC

    GetPW( OPERATORlevel );		/* Operators level */

    pwLevel = OPERATORlevel;

#endif

/* If more than one volume, ask user which volume to use.	*/

    if ( num_vols_present > 1 )
	Vol_Select();

/* OK, now run the program.	*/

    repchar( LF,10 );
    Show_Version();
    Get_Alloc_Table();

#ifdef ALLOC
    Alloc_Menu();
#endif

#ifdef NETALLOC
    NetAlc_Menu();
#endif

    Quit_Program();
}

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

#ifdef NETALLOC

NetAlc_Menu()
{
  CHAR not_done = TRUE;

    while (not_done)
    {
	
	switch( Do_Menu( &menuNetAlloc, RETNOTOK) )
	{
	    case 'C':
		Clear();
		break;

	    case 'O':
		Ownable();
		break;

	    case 'R':
		Only_Read();
		break;

	    case 'W':
		Write_Read();
		break;

	    case 'Y':
		YouOwnIt();
		break;

	    case 'P':
		Password_Change();
		break;

	    case 'V':
		Vol_Select();
		break;

	    case 'I':
		Info();
		Wait_for_Input();
		break;

	    case 'L':
		List_Table();
		Wait_for_Input();
		break;

	    case 'S':
		Save_Table_to_Control_Area();
		break;

	    case 'Q':
		if ( changes_made )
		{
		   printz("\n You have made changes to the ALLOC Table for\n\
volume %d without saving it to the hard disk.\n\
%c\n Do you still want to QUIT the program? --> ", cur_volume, BELL);

		   if ( Get_Yes_No(RETNOTOK) )	/* if yes we are done.	*/
			not_done = FALSE;
		}
		else	/* Else if no changes made just quit.	*/
		    not_done = FALSE;	/* We are done. */

		break;

	    default:
		break;

	}/*switch*/

	putz("\n\n\n\n\n\n\n");

    }/*while not done*/

    return;

} /* NetAlc_Menu */

#endif

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

#ifdef ALLOC

Alloc_Menu()
{
  CHAR	not_done = TRUE;

    while ( not_done )
    {
	switch( Do_Menu( &menuMain, RETNOTOK ) )
	{
	    case 'A':
		Add();
		break;

	    case 'D':
		Delete();
		break;

	    case 'M':
		Modify();
		break;

	    case 'C':
		Compress();

		break;

	    case 'G':
		Get_Alloc_Table();
		break;

	    case 'S':
		Save_Table_to_Control_Area();
		break;

	    case 'Z':

    printz("%c\n\n    WARNING !!!\nThis will blank your alloc table !!!\n\
This is not permanant unless you do a Save.\n\n\
Are you sure you want to ZERO your alloc table?\n\
       -----> ", BELL);

		if ( Get_Yes_No(RETNOTOK) )
		    Zero_Table();
		break;

	    case 'V':
		Vol_Select();
		break;

	    case 'I':
		Info();
		Wait_for_Input();
		break;

	    case 'L':
		List_Table();
		Wait_for_Input();
		break;

	    case 'Q':
		if ( changes_made )
		{
		   putz("\n You have made changes to the ALLOC Table for\n");
		   printz("volume %d without saving it to the hard disk.\n",
								 cur_volume);
		   printz("%c\n Do you still want to QUIT the program? --> ", BELL);

		   if ( Get_Yes_No(RETNOTOK) )	/* if yes we are done.	*/
			not_done = FALSE;
		}
		else	/* Else if no changes made just quit.	*/
		    not_done = FALSE;	/* We are done. */

		break;

	    default:
		break;

	}/*switch*/

	putz("\n\n\n\n\n\n\n\n");

    }/*while not done*/

    return;

} /* Alloc_Menu */

#endif

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

CHAR
Do_Menu( which_menu, accept_return )
  struct menu	*which_menu;
  int	accept_return;
{
  CHAR	i, user_choice;
  int	num_lines;


    num_lines = which_menu->numLines;
    for ( i=0; i<num_lines; i++)
    {
	if ( (user_choice = upgtstch()) != 0 )	/* then character input */
	    if ( index( which_menu->valid_choices, user_choice) )
		return(user_choice);	/* FOUND VALID ENTRY */
	    else
		ptch( BELL );	/* Entry not in menu so beep, no echo. */
	printz("%s", which_menu->lines[i]);  /* Print out next line of menu. */
    }

    while ( TRUE )
    {
	while ( TRUE )
	{
	    user_choice = upgtch();
	    if ( (user_choice == CR) || (user_choice == LF) )
	    {
		if ( accept_return )
		    return RETURN;
		else
		    ptch( BELL );
	    }
	    else
		break;	/* Not a CR or LF so go on to check if menu choice.  */
	}

	if ( index( which_menu->valid_choices, user_choice ) )
	{
	    ptch( user_choice );	/* echo entry.	*/
	    break;			/* FOUND VALID ENTRY.	*/
	}

	if ((user_choice < SPACE) || (user_choice >= DEL))
	    printz("%c    That", BELL);
	else
	    printz("%c       %c", BELL, user_choice);
	printz(" is not in the menu. Please try again.");
	repchar(BS,46);
	ptch( SPACE );
	ptch( BS );

    } /* while TRUE */

    repchar( SPACE, 47);
    putz("\n");
    return(user_choice);

} /* Do_Menu */

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

Wait_for_Input()
{
    putz("\n\nHit any key to return to menu.\n");
    gtch();

} /* Wait_for_Input */

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

Quit_Program()
{
    printz("\n Leave the program.\n");
    ReInitialize();
    exit( 0 );		/* Exit gracefully. Use mode 0 so we don't kill any
				pending submit file.	*/
}/*Quit_Program*/

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

zabort()
{
    printz("\n\n Aborted.\n");
    ReInitialize();
    exit( 0 );		/* Exit gracefully. Use mode 0 so we don't kill any
				pending submit file.	*/
}/*zabort*/

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

#ifdef ALLOC

overlayErr()
{
	ptch( BELL );
	switch ( errno )
	{
	    case ENOENT:
		putz("\nMissing");
		break;

	    case E_OVSMALL:
	    case E_NOTOVLY:
		putz("\nBad");
		break;

	    case E_NOMEM:
		putz("\nOut of memory for");
		break;

	   default:
		putz("\nError using");
		break;
	}/* switch on errno */

} /* overlayErr */

#endif

/*---------------------------------------------------------------------------*/
/*page*/
#ifdef ALLOC

Compress()
{
  register CHAR i;

    if ( changes_made )
    {
	printz("%c\n\n\
You have made changes to the alloc table without saving the table\n\
to the hard disk. You must either Save your changes or Get the\n\
current table to Compress.\n", BELL);
	Wait_for_Input();
	return;
    }


/*   else go on */

/* Check if any deleted partitions */
    for ( i=0; i<NallocEntries; i++)
	if ( alloc_table[i].name[0] == 'd' )	/* then partition is deleted.*/
	    break;
    if ( i == NallocEntries )	/* then no deleted entries.	*/
    {
	putz("\n\
There are no deleted partitions and thus no area on the disk to reclaim.\n");
	Wait_for_Input();
	return;
    }

/*   Give warnings.	*/

    putz("\n\
To perform this operation efficiently, make sure you have\n\
already deleted all the partitions you want to delete before \n\
compressing.\n\
\n\
    Do you want to continue -->                 (y/n)");

    repchar(BS,21);
    if ( !Get_Yes_No(RETNOTOK) )
	return;

    printz("%c\n\n\
WARNING!!! INTERRUPTING THIS PROCESS ONCE IT HAS STARTED \n\
CAN RESULT IN LOSING ALL THE DATA ON YOUR HARD DISK.\n\
SO BEFORE YOU BEGIN, MAKE A COMPLETE BACKUP OF THE HARD DISK.\n\
\n", BELL);
    putz("\n\
    Do you wish to continue with this option? -->          (y/n)");

    repchar(BS,14);
    if ( !Get_Yes_No(RETNOTOK) )
	return;

   putz("\n\
The compression process may take a long time.\n\
\n\
    Do you want to start this process now? -->           (y/n)");
    repchar(BS,15);
    if ( !Get_Yes_No(RETNOTOK) )
	return;

/* else do the compression by calling the overlay.	*/

    if ( ovloader( "alloc3" ) == -1 )
    {
	overlayErr();
	putz(" alloc3.ovr file.\n");
	zabort();
    }/* if overlay error */


    putz("\nThe Compression process is done.\n");
    Wait_for_Input();
    return;

}/* Compress */

#endif
/*---------------------------------------------------------------------------*/
/*page*/

#ifdef ALLOC

File_Check()
{
/* Check to see if all files needed for ALLOC are present on currently	*/
/*logged in disk or drive A. ZABORT if any are not present.		*/
/* Files are: ALLOC1.OVR, ALLOC2.OVR, ALLOC3.OVR, ALLOC.SYS		*/

  register CHAR	*name, *ptr[4], i;
  int	file_desc;

    ptr[0] = "A:ALLOC.SYS";
    ptr[1] = "A:ALLOC1.OVR";
    ptr[2] = "A:ALLOC2.OVR";
    ptr[3] = "A:ALLOC3.OVR";

    for ( i=0; i<4; i++)
    {
	name = ptr[i]+2;	/* Look on the currently logged in drive. */
	file_desc = open( name, O_RDONLY);
	if (file_desc == -1)	/* Look on the 'A' drive.		  */
	{
	    name = ptr[i];
	    file_desc = open( name, O_RDONLY);
	    if (file_desc == -1)	/* Not found so zabort.	*/
	    {
		printz("\n%c Can not find (open) %s file.\n", BELL, ptr[i]+2);
		zabort();
	    }
	}
	close( file_desc );
    }

} /* File_Check */

#endif
/*---------------------------------------------------------------------------*/



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

