Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/remjob.b36
There are no other files named remjob.b36 in the archive.
MODULE REMJOB=
!Process a request from a remote system
!A process running REMJOB is created by FAL when a request is received
BEGIN
!
! Table of Contents
!
FORWARD ROUTINE
REMJOB,			!Process 1 or more remote jobs
REMJ1,			!Process a remote job
REMHANDLE,		!Condition handler for REMJOB
REMJ1HANDLE;		!Handler for REMJ1

!
! REQUIRE & LIBRARY files
!
REQUIRE 'INTR.REQ';
LIBRARY 'DAPLIB';

THIS_IS [REMJ]	VERSION[1]	EDIT[17]	DATE [14,AUG,79]
!
! Revision history
!
%(
[17]	Type out Requestor-ID in WHAT command
[16]	Fill in (and check) other NODTBL parameters,
	fill in "??????" for nodeid of unknown or anonymous node.
[15]	Make REMJOB observe LIMIT for node
[14]	Revamp REMHANDLE. make it check correct interrupt bits, make it use
	fields for SIGNAL_ARGS.
[13]	Fix error messages and /OPR
[12]	Make /OPR & /DELETE work right
[11]	Fix handling of random aborts
[10]	Prevent recursive timeout loop
)%
!
! Externals
!
EXTERNAL ROUTINE
XBIN,	!Read a character off the network
XINPUT,	!Get a packet off the network
UNWIND,	!Throw away a few routine calls in case of an error
TERROR,	!Type an error message
XOUTPUT,!Shove our output out the network
GETCFG,	!Get config message
DOUID,	!Do USERID message
DOAA,	!Process Attributes & Access messages
DOCTL,	!Process Control message
CHKLIM,	!Check size of file against limit in NODTBL
FREEFB,	!Free a fileblock & all decendants
LOGS,	!Write string to log file
TELLJOB,!Tell opr what we're up to if he wants to know
FUNPARSE,!Convert a fileblock into a filespec
TREQ,	!Type out Requestor-ID for WHAT command
WRSIXA,	!Convert sixbit to ASCII
MOVEAZ,	!Copy ASCIZ string
TELLOPR,!Type out on OPR: terminal
DAPCODE,!Get DAP error code from system error code
QUIT,	!Tell our superior of our demise
NODNDB,	!Fill in stuff from NODTBL & check if request allowed
XMTMSG;	!Transmit a message

EXTERNAL
RUN: REF PROCESS_BLOCK,	!P.B of current process
CFGMSG,	!Canned CONFIG message to send out
CFGLEN;	!Length of aforementioned CONFIG message

!
! Macros
!
MACRO CLOSE_LINK(CODE)=
	BEGIN
	INFORM(CODE);	!Signal that the link went away
	SIGNALW(FRKEND);!& we will too
	QUIT(CODE)
	END%;

!
! Routines
!
GLOBAL ROUTINE REMJOB(ARGS)=
!	Main routine to process a remote job
!Parameter:
!ARGS:	A vector containing the following
!ARGS[0]:	1	# of elements following
!ARGS[1]:	NB - A Node Data Block as defined in TBL.REQ
!	     for the link that has been established
!Side Effects:
!1 or more remote requests will have been processed, logged, and accounted
BEGIN
MAP ARGS: REF VECTOR;
BIND NB=ARGS[1]: REF NDB;
BIND IB=.NB[FILE$IB]: INT_BLOCK;

EXTERNAL ROUTINE XBIN,XBOUT;

!First establish a condition handler
LOCAL	
	LEN,		!DAP message length
	FLAGS,		!DAP message flags
	T;		!Temp
ESTABLISH(REMHANDLE,.NB);	!This must immediately follow the last declaration

RUN[P$NDB]=.NB;		!Display this NDB in WHAT command
IB[INT$PROCESS]=.RUN;	!We now own these interrupts
XOUTPUT(.NB);		![4] Shove out any partial messages & do 'dummy out'
WHILE 1 DO		!While we don't get a device offline interrupt anyway
	BEGIN
	IF .NB[NDB$NSPMLENGTH] EQL 0 THEN XINPUT(.NB); !Wait for a message
	REMJ1(.NB)	!Do the request
	END; !While 1...
END;	!End of REMJOB

ROUTINE REMJ1(NB)=
!Process a single remote request, then return
!Parameter: NB: NDB for request
BEGIN
MAP NB: REF NDB;

ESTABLISH(REMJ1HANDLE,.NB);

DO () WHILE GETCFG(.NB) NEQ DAP_CFG; !Receive & save info from config message
XMTMSG(.NB,CFGMSG,CFGLEN);	!Send one back
XOUTPUT(.NB);	!Force it out
DOUID(.NB);		!Process USERID message
RUN[P$DISPLAY]=TREQ;	!Type out requestor ID as part of WHAT cmd

!Now that we know the identity of the remote system, tell the opr
	BEGIN
	MACRO PREFIX='CON'%;
	CINFO(RCD,' Remote system Established Connection')
	END;

DOAA(.NB);		!Get Attributes & access
!The Attributes & Access messages have been received & responded to
!The file to be accessed is open

!Now check the length of the file against the limit
NODNDB(.NB);		!Fill in NDB stuff from NODTBL
CHKLIM(.NB);		!Will signal NODLIM if not OK

DOCTL(.NB);		!Get a control messages & do as he says
!When this returns, we are finished.

%(	!See if we are supposed to dispose of the file
	BEGIN
	BIND FB=.N[FB]: FILE_BLOCK;	!File being accessed
	BIND FOP=NB[NDB$FOP]: EX;	!FOP field
	IF .FOP[FB$DLC]
	THEN	DELETE(FB)	!Delete on close
	ELSE	CLOSE(FB);	!Just close it
	END;
MOVED TO DAP (Release has aready been done by this point) )%

!Special hack for image mode all the time
%IF (%VARIANT AND 8) NEQ 0	!Eat trailing nulls
 %THEN	BEGIN
	WHILE (.NB[NDB$NSPMLENGTH] GTR 0)
	 DO	BEGIN
		IF CH$RCHAR(.NB[FILE$I_PTR]) NEQ 0 THEN EXITLOOP;
		XBIN(.NB);	!Eat the null
		END;
	END;
 %FI;

END;	!REMJ1

ROUTINE REMHANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
BEGIN
MAP SIGNAL_ARGS: REF BLOCK FIELD(SA_FIELDS),
    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
BIND	!Elements of ENABLE_ARGS
	NB=ENABLE_ARGS[1]: REF NDB;
BIND FB=.NB[NDB$FB]: FILE_BLOCK;

EXTERNAL ROUTINE
	FSIGNL,	!Force a signal to another process
	ERTEXT;	!Get text of error message
EXTERNAL RUN: REF PROCESS_BLOCK;

LABEL CHECK_STATUS;
LOCAL
	C,	!Code
	S;	!Severity


!	!ESTABLISH(REMHANDLE,.ENABLE_ARGS[1])

CHECK_STATUS:
	BEGIN
	S=.SIGNAL_ARGS[SA$SEVERITY];
	SELECT (C=.SIGNAL_ARGS[SA$STSCODE]) OF SET
		!Fill in conditions here
		[SS$_UNWIND,FRKEND]:
			BEGIN
			RETURN SS$_CONTINUE;
			END;

		[ENDFILE]:
			BEGIN
			IF .NB EQL .SIGNAL_ARGS[SA$FB]	!Link went away
			 THEN	BEGIN		!But no transfer in progress
				CLOSE_LINK(RMTDIS); !or REMJ1H would get this
				END;
			END;
		[IOINT]:	!Software interrupt of an unexpected kind
			BEGIN
			IF .SIGNAL_ARGS[SA$FILBLK] EQL .NB THEN !Data link condition
			    BEGIN
			    IF .SIGNAL_ARGS[SA$IN_DONE]
			     AND (NOT .SIGNAL_ARGS[SA$IN_ERROR])
			    THEN BEGIN	!Unexpected DAP message
				LOCAL MTYPE;	!Will hold message type
				SELECTONE GET_HDR OF SET
				[DAP_STS]: SIGNALE(RMTERR+GET_2BYTE);
				[DAP_ACM]: SELECTONE GET_BYTE OF SET
				    [ACM_CMD,ACM_PRG]:
					BEGIN
					TELLJOB(.NB);
					END;
				    [OTHERWISE]:
					SEND_STATUS(MAC$SYNC,DAP_ACM);
				    TES;
				[OTHERWISE]: SEND_STATUS(MAC$SYNC,.MTYPE);
				TES;
				RETURN SS$_CONTINUE	!Win if we got here
				END

			    ELSE	!Link went away
				BEGIN
				CLOSE_LINK(RMTDIS);
				END
			    END

			ELSE		!Real I/O condition
			    BEGIN
			    IF .SIGNAL_ARGS[SA$IN_ERROR]
			     THEN (SEND_STATUS(MAC$TRANS,ER$RER));
			    IF .SIGNAL_ARGS[SA$OUT_ERROR]
			     THEN (SEND_STATUS(MAC$TRANS,ER$WER));
			    IF .SIGNAL_ARGS[SA$EOF]
			     THEN (SEND_STATUS(MAC$TRANS,ER$EOF));
			    IF .SIGNAL_ARGS[SA$FULL]
			     THEN (SEND_STATUS(MAC$TRANS,ER$FUL));
			    IF .SIGNAL_ARGS[SA$QUOTA_EX]
			     THEN (SEND_STATUS(MAC$TRANS,ER$QEX));
			    END;
			LEAVE CHECK_STATUS;
			END;
		[INERROR,OUTERROR,IOERROR]:
			BEGIN
			IF .NB EQL .SIGNAL_ARGS[SA$FB] THEN
				BEGIN
				CLOSE_LINK(RMTDIS);
				END;
			END;
		[RMTERR TO RMTERR+%O'177777']:
				BEGIN
				WHILE .NB[NDB$MLENGTH] GTR 0 DO XBIN(.NB);
				END;	!Eat rest of message if nobody else does
		[RMTERR+MAC$SUCC+ER$TELLOPR]: !Wake up the operator
				BEGIN	!'cause other end said /OPERATOR
				UNDECLARE %QUOTE PREFIX;
				MACRO PREFIX='OPR'%;
				LOCAL STR: VECTOR[CH$ALLOCATION(200)];
				LOCAL PTR;
				PTR=CH$PTR(STR);
				CH$WCHAR_A(%C'"',PTR);
				PTR=FUNPARSE(FB,.PTR);	!Fill in filename
				MOVEAZ(%REF(CH$PTR(
				 SELECTONE .NB[NDB$ACCFUNC] OF SET
					[ACC$CREATE]:UPLIT(%ASCIZ
						'" received from  "');
					[ACC$OPEN]:UPLIT(%ASCIZ
						'" sent to "');
					[ACC$RENAME]:UPLIT(%ASCIZ
						'" renamed by "');
					[ACC$ERASE]:UPLIT(%ASCIZ
						'" deleted by "');
					TES)),PTR);
				WRSIXA(.NB[NDB$NODEID],PTR);
				CH$WCHAR_A(%C'"',PTR);
				CH$WCHAR_A(0,PTR);	!Make ASCIZ
				INFO_NCRLF('');TSTR(STR);TYPE(']',CRLF);
				TELLOPR(UPLIT(%ASCIZ%STRING(
				 CRLF,'** NETSPL ** ')));
				TELLOPR(STR);
				TELLOPR(UPLIT(%ASCIZ%STRING(CRLF)));
				RETURN SS$_CONTINUE;
				END;
		[OPRABO]:	BEGIN
				MACRO PREFIX='ABO'%;
				SEND_STATUS(MAC$TRANS,ER$ABO);
				INFO('Request aborted by operator');
				SIGNALW(FRKEND);
				QUIT(OPRABO);
				END;
		[RMTDIS]:	!Remote system closed link
			BEGIN
			MACRO PREFIX='CON'%;
			CINFO(RCD,'Remote system terminated connection');
			QUIT(.C);
			END;
		[RMTABO]:	!Link closed during transfer
			BEGIN
				BEGIN
				MACRO PREFIX='RSA'%;
				CERR(RJERR,'Remote system aborted transfer');
				END;

				BEGIN
				MACRO PREFIX='CON'%;
				CWRN(RCD,'Remote system terminated connection');
				END;
			QUIT(.C);
			END;

		[TIMOUT]:
			BEGIN	!Prevent timeout on "timeout" status msg.
			IF .NB[NDB$TIMEDOUT] THEN
				BEGIN
				UNDECLARE %QUOTE PREFIX;
				MACRO PREFIX='XTM'%;
				IFMSG(RJERR,(ERR('Timeout period exhausted')));
				QUIT(TIMOUT);
				END;
			NB[NDB$TIMEDOUT]=1;
			END;
		[RMTERR TO RMTERR+%O'177777']:
			LEAVE CHECK_STATUS;	!Don't send status message back!
		[ALWAYS]:
			BEGIN
			SEND_STATUS(DAPCODE(.C),0);	!Tell other system
			TYPE(CRLF);		!Start on a new line
			END;
		TES;
	END;	!CHECK_STATUS


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

SELECT .S OF SET	!Check severity
[SS$_NORMAL,SS$_WARN]:
		BEGIN
		RETURN SS$_CONTINUE
		END;
[SS$_SEVEREERROR]:
		BEGIN
		CRASH();
		END;
[SS$_ERROR]:
		BEGIN
		UNWIND(.MECH_ARGS[MA_DEPTH]);
		END;
TES
END;	!REMHANDLE
ROUTINE REMJ1HANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
!Handler for REMJ1
BEGIN

UNDECLARE %QUOTE PREFIX;

MAP	SIGNAL_ARGS:	REF BLOCK FIELD(SA_FIELDS),
	MECH_ARGS:	REF VECTOR,
	ENABLE_ARGS:	REF VECTOR;

SELECT .$CODE OF SET
[INERROR,OUTERROR,ENDFILE]:
	BEGIN	!This is really a network error
	IF .SIGNAL_ARGS[SA$FB] EQL .ENABLE_ARGS[1]
	 THEN (SIGNALE(RMTABO);SIGNALE(RMTDIS);QUIT(RMTDIS))
	END;
[IOINT]:
	BEGIN
	IF (.SIGNAL_ARGS[SA$FILBLK] EQL .ENABLE_ARGS[1])
	 THEN	BEGIN
		IF (.SIGNAL_ARGS[SA$IN_ERROR] OR .SIGNAL_ARGS[SA$OUT_ERROR])
		 THEN (SIGNALE(RMTABO);SIGNALE(RMTDIS);QUIT(RMTDIS))
		END;
	END;
[ALWAYS]: RETURN SS$_RESIGNAL;
TES;
END;
END ELUDOM