Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-08 - 43,50512/locjob.b36
There are no other files named locjob.b36 in the archive.
MODULE LOCJOB=
!Process a job that was requested locally (master mode)
!Environment:	NETSPL/10/20/40/??
BEGIN

!
! Table of Contents
!
FORWARD ROUTINE
LOCJOB,		!Process a locally-requested job
LOCHANDLE,	!Handler for above
REQIT;		!Determine if job should be re-queued

!
! Conditional compilation
!

REQUIRE 'INTR.REQ';
LIBRARY 'DAPLIB';

THIS_IS [LOCJ]	VERSION [1]	EDIT [21]	DATE [14,DEC,79]

![21]	Fix ASCII block mode to PDP-11 (which lies about datatype).
![20]	Fix ASCII Stream
![17]	Separate CONTROL (Get or Put) from first DATA so not make
!	too large a message for RSTS
![16]	Do 'reasonable' defaulting for file mode
![15]	Remove TEQ routine, use more general TREQ to type out Requestorid
![14]	Get CONFIG message before sending USERID Message
![13]	Un-block the CONFIG message in accordance with 5.0 DAP protocol.

!
! Externals
!

EXTERNAL ROUTINE
	FBINI,INTINI,NDBINI,FILOP,LINK,SNDATT,XMTMSG,TABLEL,XOUTPUT,
	PRO_QS,PRO_DS,SNDUID,LOGS,IOICOD,TREQ,DAT_DS,
	XMIT,RECV,RELEASE,FREEFB,QUIT,XBIN,XBOUT,TELLJOB,USRLOG,ACCT,RESETF,
	CHKLIM,GETCFG,DOAA,DOCTL,SNDACC,SNDCTL,UDT,TSIGNL,TSICAN,TERROR;

EXTERNAL
	CFGMSG,CFGLEN,
	RUN: REF PROCESS_BLOCK;	!The currently-running process

BIND	ACCOMP_CMD=PLIT(CHAR8(DAP_ACM,0,ACM_CMD));
LITERAL	ACCOMP_CMD_LEN=3;
BIND	ACCOMP_PURGE=UPLIT(CHAR8(DAP_ACM,0,ACM_PRG));
LITERAL	ACCOMP_PURGE_L=3;

!
! Macros
!

GLOBAL ROUTINE LOCJOB(ARGS)=
!	Main routine to process a locally-generated job
!	Upon completion, the request will have been processed
!	or errors will have been signalled
BEGIN
MAP ARGS: REF VECTOR;	!.ARGS[0] = length of vector + 1
BIND NB=ARGS[1]: REF NDB;	!NDB for transfer (IB & FB set up already)
BIND FB=.N[FB]: FILE_BLOCK;	!File block for file being transferred
!BIND IB=.N[IB]: INT_BLOCK;	!Interrupt block for link
BIND EQ=.NB[NDB$EQ]: QSR_EQ;	!Quasar message that created us

LABEL CMDBLOCK,ACMDISPATCH;

ESTABLISH(LOCHANDLE,.NB);	!Set up condition handler

	BEGIN
	LOCAL TT;
	LOCAL LOCTMO: INT_BLOCK;

	RUN[P$NDB]=.NB;		!Claim the NDB as our own

	!Now change our name to the job name
	IF EQ NEQ 0
	THEN	RUN[P$NAME]=.EQ[QSR$EQ_JOBNAME];

	IF (TT=.NB[NDB$CONTO]) NEQ 0 THEN
		BEGIN
		CLEARV(LOCTMO);
		LOCTMO[INT$STSCODE]=TIMOUT;
		LOCTMO[INT$SIGNAL_ARGS]=1;
		LOCTMO[INT$SEVERITY]=SS$_ERROR;
		TT=TSIGNL(LOCTMO,UDT()+.TT);
				!Set timer so we don't wait forever
		END
	ELSE	TT=-1;
	LINK(.NB);
	IF (TT NEQ -1) THEN TSICAN(.TT);	!Cancel time-out

		BEGIN	!Say we're connected
		MACRO PREFIX='LEC'%;
		CINFO(LCD,'Local system Established Connection');
		END;

	XOUTPUT(.NB);	!Dummy out
	XMTMSG(.NB,CFGMSG,CFGLEN);	!Send a config message
	XOUTPUT(.NB);	![13] The config message is supposed to be alone
			![14] Get CFG before sending USERID
	GETCFG(.NB);	!Get CONFIG from remote system
	SNDUID(.NB);	!Send USERID message
	XOUTPUT(.NB);	!Force it out

	SELECT .N[ACCFUNC] OF SET

	!Now do some defaulting if (as is usually the case)
	!we didn't get any switches from the user telling us
	!what kind of file it was

	[ACC$OPEN,ACC$CREATE,ACC$CMD]:
	%IF FTTOPS10 %THEN
	IF (.N[OSTYPE] NEQ DAP$TOPS10) AND (.N[OSTYPE] NEQ DAP$TOPS20) AND
	(.N[RMC$O_B16P]+.N[RMC$O_B36]+.N[RMC$O_B16I] EQL 0)
	THEN	(EX[N[DATATYPE],DAT$ASC]=1; FB[FILE$MODE]=_IOASC)
	ELSE	(EX[N[DATATYPE],DAT$IMA]=1; FB[FILE$MODE]=_IOIMG);
				!Default to ASCII block mode
				!Unless this is TOPS-10 or TOPS-20
	%FI

	!Open the local file, if there is one

	[ACC$OPEN]:		(N[CTLFUNC]=C$GET; OPEN_W(FB));
	[ACC$CREATE,ACC$CMD]:	(N[CTLFUNC]=C$PUT; OPEN_R(FB));

	!Set up protection where DAP routines will find it.
	[ACC$CREATE,ACC$CMD]:
		BEGIN
		FB[FILE$PROTWLD]=PRO_QS(.EQ[QSR$EQ_RPROT_WO]);
		FB[FILE$PROTOWN]=PRO_QS(.EQ[QSR$EQ_RPROT_OW]);
		FB[FILE$PROTGRP]=PRO_QS(.EQ[QSR$EQ_RPROT_GR]);
		%IF %DECLARED(FILE$PROTSYS)
		%THEN
		FB[FILE$PROTSYS]=PRO_QS(.EQ[QSR$EQ_RPROT_SY]);
		%FI
		END;

	[ACC$OPEN,ACC$CREATE,ACC$RENAME,ACC$CMD]:
		SNDATT(.NB);
	[ALWAYS]:
		BEGIN
		SNDACC(.NB);
		XOUTPUT(.NB);
		END;
	[ACC$OPEN,ACC$CREATE,ACC$CMD]:
		BEGIN
		LOCAL DATATYPE: EX[1];	!Save datatype around DOAA
		DATATYPE=.N[DATATYPE];	!
		DOAA(.NB); !Get returned attributes message if any
		DAT_DS(N[START],(N[DATATYPE]=.DATATYPE));
					!PDP-11's tend to send bogus datatype
					!because they don't care
		CHKLIM(N[START]); !Check if this request is over the limit
				!If we returned, then it was OK
		SNDCTL(N[START],C$CONNECT);
		XOUTPUT(N[START]);
		END;
	[ALWAYS]:
		BEGIN
		SELECT GET_HDR OF SET
		[DAP_ACK]:	;	!Go to it
		[DAP_STS]:	ERROR(RMTERR+(GET_2BYTE));
		[OTHERWISE]:	SEND_STATUS(MAC$SYNC,DAP_ACK);
		TES;
		END;
	[ACC$OPEN,ACC$CREATE,ACC$CMD]:
		BEGIN
		SNDCTL(.NB,.N[CTLFUNC]); !Send control message to do our stuff
		XOUTPUT(.NB);	![17] separate message to not overflow buffer
		TELLJOB(.NB);	!Tell opr if he cares
		END;
	[ACC$OPEN]:
		BEGIN
		RESETF(FB);	!Don't create 0 length file

		!Now reset protection to what user wanted.
		FB[FILE$PROTWLD]=PRO_QS(.EQ[QSR$EQ_RPROT_WO]);
		FB[FILE$PROTOWN]=PRO_QS(.EQ[QSR$EQ_RPROT_OW]);
		FB[FILE$PROTGRP]=PRO_QS(.EQ[QSR$EQ_RPROT_GR]);
		%IF %DECLARED(FILE$PROTSYS)
		%THEN
		FB[FILE$PROTSYS]=PRO_QS(.EQ[QSR$EQ_RPROT_SY]);
		%FI

		OPEN_W(FB);	!Open local file again to get attributes
		RECV(.NB);	!Output CONTROL(GET)
		END;
	[ACC$CREATE,ACC$CMD]:
		XMIT(.NB);

	!The access is complete, close up
	[ALWAYS]:
	ACMDISPATCH:
		BEGIN
		IF .NB[NDB$RMC$O_OPR]		!Tell remote opr?
		 THEN SEND_STATUS(MAC$SUCC+ER$TELLOPR);	!YES

		XMTMSG(.NB,ACCOMP_CMD,ACCOMP_CMD_LEN); !Access complete
		XOUTPUT(.NB);

		SELECT GET_HDR OF SET
		[DAP_ACM]: IF GET_BYTE EQL ACM_RSP THEN LEAVE ACMDISPATCH;
		[DAP_STS]: (ERROR(RMTERR+GET_2BYTE);LEAVE ACMDISPATCH);
		[ALWAYS]: SEND_STATUS(MAC$SYNC,DAP_ACM);
		TES;
		END;!ACMDISPATCH
	[ACC$CREATE,ACC$EXE]:
		BEGIN
		IF .FB[FILE$FB$DLC]	!Should we delete the file?
		 THEN	DELETE(FB)
		 ELSE	CLOSE(FB);	!No just close it
		RELEASE(FB);		!Free channel
		END;
	[ACC$OPEN]:
		BEGIN
		CLOSE(FB);RELEASE(FB);	!Finish up with file
		END;
	TES;

	IF .NB[NDB$LOG_FB] NEQ 0 THEN	!User wants a log file
		USRLOG(.NB,WIN);

		!This provides a convenient way of shutting off accounting
		IFNOTMSG(DEBUG,(ACCT(.NB)));

	TELLJOB(.NB);	!Tell opr maybe about job

		BEGIN		!Tell opr about link maybe
		MACRO PREFIX='LTC'%;
		CINFO(LCD,'Local system Terminated Connection')
		END;

	END;
END;
GLOBAL ROUTINE LOCHANDLE(SIGNAL_ARGS,MECH_ARGS,ENABLE_ARGS)=
!Handler for LOCJOB
!ENABLE_ARGS[1]=NB
BEGIN
MAP SIGNAL_ARGS: REF BLOCK FIELD(SA_FIELDS),
	MECH_ARGS: REF VECTOR,
	ENABLE_ARGS: REF VECTOR;
BIND	!Element(s) of ENABLE_ARGS
	NB=.ENABLE_ARGS[1]: NDB;

!	BIND IB=.N[IB]: INT_BLOCK;

EXTERNAL ROUTINE
FSIGNL,
ERTEXT;
LOCAL	C;	!Temp to save error code
C=.SIGNAL_ARGS[SA$STSCODE];	!Get the error code

SELECT	.C OF SET	!Dispatch on error code
[SS$_UNWIND,FRKEND]:
	BEGIN
	QUIT(.SIGNAL_ARGS[SA$STATUS]);	!Tell the boss WHY DID YOU RESIGN
	END;

[RMTERR TO RMTERR+%O'177777']:	!Got a STATUS message (catch all)
	BEGIN
	XMTMSG(NB,ACCOMP_PURGE,ACCOMP_PURGE_L);
	XOUTPUT(NB);
	END;			!This will fall through to print error msg
[FILUNN,TIMOUT]:
	BEGIN
	DEBUGMSG(MSG('%%');TSTR(ERTEXT(.$CODE));TYPE(CRLF));
	SIGNALW(FRKEND,.C);
	!Removed for some reason? QUIT(.SIGNAL_ARGS[SA$CODE]);
	END;
[IOINT]:	C=IOICOD(.SIGNAL_ARGS[SA$REASON]);	!Convert to our code
[ALWAYS]:
	BEGIN
	EXTERNAL ROUTINE TERROR;
	TERROR(.SIGNAL_ARGS,.ENABLE_ARGS,.MECH_ARGS);
		!Type a standard message
	SELECT .$SEVERITY OF SET
	[SS$_NORMAL,SS$_WARN]:	(RETURN SS$_CONTINUE);	!Ho-hum
	[SS$_SEVEREERROR]: CRASH();			!AAAArrrrgggghhhh
	[SS$_ERROR]:	BEGIN	!Abort this process
			EXTERNAL ROUTINE QUIT;
			IF .RUN[P$SUPERIOR] EQL 0
				THEN CRASH('Error at top level');
			IF (REQIT(.C)) EQL 0 THEN USRLOG(NB,.C);
			SIGNALW(FRKEND,.C);!Invoke all handlers to clean up
!!			!!QUIT(.SIGNAL_ARGS[SA$CODE]); !Abandon ship
!!!!!!!!!!		!!RETURN SS$_CONTINUE
			END;
	TES;
	END;
TES;
END;
GLOBAL ROUTINE REQIT(CODE)=
BEGIN
!Accept an error code and decide whether or not to re-que the job
!Returns 1 if job should be requeued, 0 if not.
!A job will be re-queued on all errors EXCEPT:
!	File or directory not found,
!	Device full or quota exceeded,
!	Protection failure
!	Abort by operator or requestor
!	Non-existant structure or device

!
! Formal Parameters
!

!CODE: error code to check

!
! Returned value
!

!1 if a job getting this error should be re-queued, 0 otherwise

SELECTONE .CODE OF SET
[0,WIN,RERPRV,RERDEV,RERDNF,RERFEX,RERFNF,EXQUOTA,
 RERDFL,DEVFULL,RERFUL,
 FILERR TO FILDTB,FILOPN,OPRABO,USRABO]:
		0;	!Don't re-queue
[OTHERWISE]:	1;	!Do re-queue
TES
END;	!REQIT
END ELUDOM