Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/main.b36
There are no other files named main.b36 in the archive.
MODULE MAIN=
!The buck starts here
BEGIN
!
! Table of Contents
!
FORWARD ROUTINE
	MAIN,
	SAYCMD,	!Type out "(Processing commands)"
	NETCMD,	!Process string as NETSPL commands
	NETCMHANDLE, !Condition handler for NETCMD
	HANDLE;	!Condition handler for MAIN

!
! LIBRARY & REQUIRE files
!
REQUIRE 'INTR.REQ';
LIBRARY 'NODTBL';	!Need NODTBL defs too

!
THIS_IS[MAIN] VERSION [1] EDIT [7] DATE [19,DEC,79]
![7]	Set DSKFUL ERROR, since PAUSE stops us dead!

!
!
! Builtin
!
BUILTIN MACHSKIP,MACHOP;
!
!External routines
!
EXTERNAL ROUTINE
	GETTAB,
	FAL,
	SPL,
	MOVEAZ,
	GETVRS,
	TERROR,
	SCALLI,
	CLKCHK,
	FSTACK,
	QUEFLS,
	STOP,
	ATTACH_TTY,
	DOCMDS,	!Process commands
	IRESTART,	!Code for if somebody trys to restart us
	QUIT,
!	FSIGNL,
	UNWIND,
	TTYINI,
	ERTEXT,
	TTYIN;

!
!External data
!
EXTERNAL
	HIMSG: QSR$HI,
	MJOBS,		!Total # of simultaneous jobs allowed
	MAXDRQ,		!Max # of data requests we can set
	MLEVEL: BLOCK FIELD(MLEVEL_FIELDS),	!Message level
	COMTAB,		!Table of operator commands
	TTYBLK: FILE_BLOCK, !File block for TTY
	TTYINTBLK: INT_BLOCK, !Interrupt block for TTY
	DETINTBLK: INT_BLOCK, !Interrupt for DETACH & ATTACH interrupts
	QSRSTINT: INT_BLOCK, !Interrupt block for status change to QUASAR
	TERMINAL,	!Designator for terminal
	PRIOUT,		!Designator for primary output device
	RUN:REF PROCESS_BLOCK;

!
!Literals
!

LITERAL	INITIAL_NXFERS=1;	!MJOB starts out as this value
LITERAL CNDVN=XWD(%O'71',%O'11');	!GETTAB for Monitor version #
LITERAL	DSKFUL_ERROR=XWD(%O'21',1);	!DSKFUL PAUSE blows us away!
LITERAL INITIAL_MAXDRQ=14;	!Initial value of MAXDRQ

!
!Macros
!
MACRO PREFIX='CMD'%;	!For MSG macro
MACRO SETUUO(ARG)=SCALLI(%O'75',ARG) %;
MACRO SETUWP(ARG)=SCALLI(%O'36',ARG) %;

MACRO MERGE(DEV,FILE,EXT,PPN)=
	BEGIN
	EXTERNAL ROUTINE GETSEG;
	GETSEG(UPLIT(%SIXBIT%STRING(DEV),
		     %SIXBIT%STRING(FILE),0,0,0,0))
	END%;

!
! Global Data
!
GLOBAL	MONVER;			!Monitor version we are using

!
!Routines
!

GLOBAL ROUTINE MAIN=
	BEGIN
	REGISTER T;
	GLOBAL CMDPBLOCK: PROCESS_BLOCK;
	GLOBAL CMDTMO: INT_BLOCK;
	OWN LINE: VECTOR[CH$ALLOCATION(81)], PTR: INITIAL(CH$PTR(LINE));

	ESTABLISH(HANDLE);	!Condition handler

	(EXTERNAL INTENC;INTENC=1);	!Save interrupts 'till not busy
	MONVER=((GETTAB(CNDVN)^-18) AND %O'77777');
	!Get the current monitor version

	MAXDRQ=(IF .MONVER GEQ %O'70000' THEN INITIAL_MAXDRQ ELSE 1);
	!Never more than 1 drq for 6.03 or 6.03A

	SETUUO(DSKFUL_ERROR);	![7] DSKFUL PAUSE blows us away!

	MLEVEL[MLEVEL$ALL]=-1;	!Set the message level to ALL

	RUN=CMDPBLOCK;		!We are the current process
	CMDPBLOCK[P$STK]=FSTACK();	!The current stack is ours
	CMDPBLOCK[P$FREE]=CMDPBLOCK[P$STKL]=0;	!Never free anything
	CMDPBLOCK[P$NAME]=%SIXBIT'CMD';
	CMDPBLOCK[P$INFERIORS]=CMDPBLOCK[P$LINK]=0; !No inferiors or peers
	CMDPBLOCK[P$SUPERIOR]=0;	!There is no superior
	CMDPBLOCK[P$DISPLAY]=SAYCMD;	!Say what CMD process is doing
	T=INTVEC;	!Start of 4 word blocks
	CALLI(T,%O'135');	!PIINI.
	TTYINI();		!Initialize TTY interrupts
	MERGE('SYS','NODTBL');		!Get the node table
	WHILE SETUWP(0) EQL 0 DO		!Write-enable the high segment
		BEGIN
		MSG('?',CRLF,'No write access to SYS:NODTBL.EXE');
		STOP()
		END;

	!Now flush the IPCF queue
	QUEFLS();

	!Now initialize MJOB
	MJOBS=(HIMSG[QSR$HI_MJOB]=INITIAL_NXFERS);
	!Now initialize the QUASAR status change interrupt block
	QSRSTINT[INT$SIGNAL_ARGS]=1;
	QSRSTINT[INT$STSCODE]=QSRSTC;
	QSRSTINT[INT$SEVERITY]=SS$_NORMAL;
	QSRSTINT[INT$NEXT]=0;

	!Now identify ourself
		BEGIN
		LOCAL PTR, STR: VECTOR[CH$ALLOCATION(132)];
		EXTERNAL ROUTINE MOVEAZ,GETVRS;

		PTR=CH$PTR(STR);
		MOVEAZ(%REF(CH$PTR(UPLIT(%ASCIZ
		 '[NETRUN  NETSPL version '))),PTR);
		PTR=CH$PLUS(.PTR,GETVRS(.PTR,35));	!Get our version number
		MOVEAZ(%REF(CH$PTR(UPLIT(%ASCIZ%STRING(
		 ' running]',CRLF)))),PTR);
		TSTR(STR);
		END;

	IRESTART();		!Handle restarts

	!Initialization is now complete

	!Command loop
	WHILE 1 DO
		BEGIN
		LOCAL TI;	!Index of timeout request
!!!		TYPE('NETSPL>'); !Prompt
		CLEARV(CMDTMO);	!Zero out interrupt block
				!No condition to signal, just wake up
		TTYIN(.PTR,80);		!Get a line of input
		NETCMD(.PTR);		!Process as commands
		END;
END;
ROUTINE SAYCMD=
!Type out info about CMD process for WHAT command
!i.e. "  ---  (Processing commands)"

!
! Formal Parameters
!

!None

!
! Implicit inputs
!

!None

!
! Returned value
!

!None

!
! Implicit outputs
!

!None

BEGIN
TYPE('  ---	(Processing commands)');
END;	!SAYCMD
GLOBAL ROUTINE NETCMD(PTR)=
!Process a string as NETSPL commands
!PTR: Byte pointer (if .PTR<LH> NEQ {0,-1}) or address of string (otherwise)
BEGIN
EXTERNAL ROUTINE ERTEXT;
EXTERNAL ROUTINE DOCMDS;
LITERAL DELIMITERS=%C';'+%O'7600';	!Accept ";" & the usual line delimiters
LOCAL R;

ESTABLISH(NETCMHANDLE,.PTR);		!Set up condition handler

SELECTONE .PTR<LH> OF SET
[0,%O'777777']: PTR=CH$PTR(.PTR);	!Set up byte pointer
[OTHERWISE]:	;
TES;

IF (R=DOCMDS(COMTAB,PTR,DELIMITERS,%REF(0))) GTR 1^16
	THEN (TSTR(ERTEXT(.R));TYPE(CRLF));
	!Process commands & type error msg if needed
END;	!NETCMD

ROUTINE NETCMHANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
!Condition handler for NETCMD (command processing routine)
BEGIN
MAP SIGNAL_ARGS: REF VECTOR,
    MECH_ARGS: REF VECTOR,
    ENABLE_ARGS: REF VECTOR;
	!These are all argument lists of the form:
	!length,arg1,arg2,arg3,arg4,... (words)
	!length does not include the length word itself
EXTERNAL ROUTINE
FSIGNL,	!Force a signal to another process
UNWIND, !Crawl back up the stack
ERTEXT;	!Get text of error message
LOCAL
	C,	!Code
	S;	!Severity

S=.(SIGNAL_ARGS[SA_CODE])<SEVERITY>;
SELECT (C=.(SIGNAL_ARGS[SA_CODE])<STSCODE>) OF SET
	!Fill in conditions here
[FILERR TO FILOPN,CMDERR TO CMDERR+%O'77',FPAERR TO FPAERR+%O'17']:
	BEGIN
	EXTERNAL ROUTINE TERROR;

	TERROR(.SIGNAL_ARGS,.ENABLE_ARGS,.MECH_ARGS);

	SELECT .S OF SET	!Check severity
	[SS$_WARN,SS$_NORMAL]:
			BEGIN
			RETURN SS$_CONTINUE
			END;
	[SS$_SEVEREERROR]:
			BEGIN
			CRASH(CRLF);
			END;
	[SS$_ERROR]:
			BEGIN
			UNWIND(.MECH_ARGS[MA_DEPTH]+1); !Unwind thru establisher
			END;
	TES
	END;
[OTHERWISE]: RETURN SS$_RESIGNAL;	!Pass the buck
TES;
END;	!NETCMHANDLE
ROUTINE HANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
!Condition handler for MAIN
	BEGIN
	MAP SIGNAL_ARGS: REF VECTOR,
	    MECH_ARGS: REF VECTOR,
	    ENABLE_ARGS: REF VECTOR;
		!These are all argument lists of the form:
		!length,arg1,arg2,arg3,arg4,... (words)
		!length does not include the length word itself
	EXTERNAL ROUTINE
	FSIGNL,	!Force a signal to another process
	ERTEXT;	!Get text of error message

	EXTERNAL RUN: REF PROCESS_BLOCK;
	LOCAL
		C,	!Code
		S;	!Severity

	S=.(SIGNAL_ARGS[SA_CODE])<SEVERITY>;
	SELECT (C=.(SIGNAL_ARGS[SA_CODE])<STSCODE>) OF SET
		!Fill in conditions here

		[INFQIT]:	!One of our inferiors just died
			BEGIN
			BIND RFORK=.SIGNAL_ARGS[2]: PROCESS_BLOCK;
			EXTERNAL ROUTINE REMINF;
			BIND RFORK_NAME=.RFORK[P$NAME];	!Save process name
			BIND REASON=.(SIGNAL_ARGS[3])<STSCODE>; !and error code
			REMINF(RFORK); !Out of linked lists, etc.
			!Note that we cannot access RFORK or SIGNAL_ARGS now
			SELECTONE REASON OF SET
			[OPRABO,QSRNRN]:;
			[OTHERWISE]:
				BEGIN	!Try to restart it
				UNDECLARE %QUOTE PREFIX;
				OWN MAXRESTART: INITIAL(100);
				SELECT RFORK_NAME OF SET
				[PNAME(FAL)]:
					BEGIN
					OWN FALCR: INITIAL(0);
					IF (FALCR=.FALCR+1) GTR .MAXRESTART
					 THEN	BEGIN
						MACRO PREFIX='FCH'%;
						WRN('FAL crash rate too high')
						END
					 ELSE	BEGIN
						MACRO PREFIX='FRS'%;
						INFO('Restarting FAL');
						FORK(FAL);
						END;
					END;
				[PNAME(SPL)]:
					BEGIN
					OWN SPLCR: INITIAL(0);
					IF (SPLCR=.SPLCR+1) GTR .MAXRESTART
					THEN	BEGIN
						MACRO PREFIX='SCH'%;
						WRN('SPL crash rate to high');
						END
					 ELSE	BEGIN
						MACRO PREFIX='SRS'%;
						INFO('Restarting SPL');
						FORK(SPL);
						END;
					END;
				TES;
				END;
			TES;
			RETURN SS$_CONTINUE	!On our way
			END;
		[FRKEND]:
			RETURN SS$_CONTINUE;
		[REATTA]:
			BEGIN	!We got attached or detached
			LOCAL TTY;	!TTY # of new TTY
			IF (TTY=.SIGNAL_ARGS[SA_STATUS]) EQL _PCDAT_DETACH
			THEN	BEGIN
				TERMINAL=0;
				END
			ELSE	BEGIN
				UNDECLARE %QUOTE PREFIX;
				MACRO PREFIX='ATT'%;	!For MSG Macro
				IF .TTY EQL 0 THEN RETURN SS$_CONTINUE;
				!Ignore spurious interrupts!!!
				PRIOUT=TERMINAL=(.TTY<0,9> + TTYDESIG);
				!Set up terminal designator for new TTY
				NOINTS	((
					ATTACH_TTY(.TERMINAL);
					MSG('[','','NETSPL re-attached to TTY');
					TNUM(.TERMINAL<0,9>,8);
					TYPE(']',CRLF);
					TTYINI();
					))
				END;
			RETURN SS$_CONTINUE;
			END;
		[OTHERWISE]:
			BEGIN
			EXTERNAL ROUTINE TERROR;

			TERROR(.SIGNAL_ARGS,.MECH_ARGS,.ENABLE_ARGS);

			SELECT .S OF SET	!Check severity
			[SS$_NORMAL,SS$_WARN]:	BEGIN
						RETURN SS$_CONTINUE
						END;
			[SS$_SEVEREERROR]:	CRASH();
			[SS$_ERROR]:	BEGIN
					LOCAL PQUIT: VECTOR[4];
					IF .RUN[P$SUPERIOR] EQL 0
						THEN CRASH(' at top level');
						!Boy, are we in trouble!
					QUIT(.SIGNAL_ARGS[SA_CODE]);
					END;
			TES
			END;
	TES
	END;	!HANDLE

END ELUDOM