Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93d-bb - 7,6/ap015/senvax.x15
There are 6 other files named senvax.x15 in the archive. Click here to see a list.
	TITLE SENVAX	KL TO VAX sender
	TWOSEG
	RELOC	400000

	SEARCH	MACSYM,MSUNV

	EXTERN	ER%PRC,MX$VAL,MXERRS,UF%CLO,UF%OPE,UF%REA,UF%WRI,UM%GET,UM%REL
	EXTERN	UMP%GE,UMP%RE,UN%ABO,UN%ACC,UN%CLO,UN%OPE,UN%REA,UN%STA,UN%WRI
	EXTERN	GETSUB,NW$ERR,S2$ERR,NMLDIE

;AC Definitions

	T0==0			;SCRATCH REGISTERS
	T1==1
	T2==2
	T3==3
	T4==4
	T5==5
	FLGWRD==5		;CR AND LF FLAGS FOR SENDING MAIL FILE
	T6==6
	T7==7
	T10==10
	WRKREQ==11		;WORK REQUEST POINTER
	MSGBLK==12		;MESSAGE BLOCK POINTER
;AC 13 AND 15 RESERVED FOR BLISS
	T14==14			;ANOTHER SCRATCH REGISTER
	VARPTR==16		;POINTS TO VARIABLES AND POINTERS BUFFER
	P==17			;STACK

;INFORMATION BLOCK OFFSETS

	CNNBLK==0		;CONNECT BLOCK ADDRESS
	TOLIST==1		;TO: LIST BUFFER POINTER
	SNDSTR==2		;SENDER STRING POINTER
	WRKBUF==3		;WORKING BUFFER ADDRESS
	TOHOLD==4		;RECIPIENTS FIT INTO TO: LIST BUFFER
	FALSND==5		;ALL RECIPIENTS O.K.ED BY VAX
	MAIPTR==6		;POINTS TO MAIL FILE SPEC
	SCRAT1==7		;SCRATCH WORDS
	SCRAT2==10		
	SCRAT3==11		
	SCRAT4==12
	NUMSUC==13		;NUMBER OF SUCCESSFUL SENDS
	SNDERR==14		;SENDER STRING POINTER (7 BIT)
	FILNB==15		;FILE NUMBER OF MAIL FILE
	DATLNK==16		;SENVAX'S DATA LINK
	BUFPTR==17		;POINTER TO REPLIES FROM THE VAX
	RCPT==20		;NUMBER OF RECIPIENTS
	FSRCPT==21		;ADDRESS OF FIRST RECIPIENT BLOCK IN THIS PASS
	FSTPSS==22		;FIRST PASS FLAG
	DSTNDE==23		;DESTINATION NODE NAME
	NUMVAR==25		;INFORMATION BLOCK SIZE

;DEFINITIONS

	$DONE==2		;ALL RECIPIENTS RECEIVED MAIL
	$DEFER==3		;A NETWORK PROBLEM OCCURRED
	$REJECT==5		;ONE OR MORE RECIPIENTS DID NOT RECEIVE MAIL
	CBKSIZ==^D64		;CONNECTION BLOCK SIZE
	VAXOBJ==^D27		;VAX OBJECT TYPE
	SUCBIT==2000		;SUCCESS BIT FROM VAX REPLY
	FAIBIT==1B31		;FAILURE BIT FROM VAX REPLY
	CRFLG==1B34		;CARRIAGE RETURN WAS SEEN IN MAIL FILE LINE
	LFFLG==1B35		;LINE FEED WAS SEEN IN MAIL FILE LINE
	DELVER==1B0		;ADDRESSEE RECEIVED MAIL
	REJECT==1B1		;ADDRESSEE DID NOT RECEIVE MAIL
	MAXSND==^D100		;MAXIMUM NUMBER OF ADDRESSEES ALLOWED
	.CR==15			;CARRIAGE RETURN
	.LF==12			;LINE FEED
	QUOTE==42		;ASCII QUOTE VALUE

;SEVERITY CODES

	$ERR==4
	$INFO==3

;ERROR CODES

	UF$FCF==8		;MAIL FILE CLOSE ERROR
	UF$FRF==9		;MAIL FILE READ ERROR
	UF$FOF==^D11		;MAIL FILE OPEN ERROR

;FACILITY CODES

	$PROTO==1		;PROTOCOL ERROR
	$MESSA==2		;INFORMATIVE MESSAGE

;ERRORS REPORTED BY VMS MAIL-11

	LOGLNK==125001,,760000	;Error creating logical link
	.DCX11==13
	SALL

	RELOC	0		;DATA AREA (LOWSEG)

;THE ARGUMENT BLOCK PASSED TO ROUTINE ER%PRC (NETERR:)

ERRBLK:	EXP	6			;SIZE OF THE BLOCK
	EXP	FLD(1,1B3)!FLD($PROTO,37777B17)!FLD(1,1B18)!FLD(NW$ERR,37777B32)!FLD($ERR,7B35)
	EXP	0,0			;NO  OPTIONAL DATA
	EXP	2			;NUMBER OF WORDS THAT FOLLOW
	EXP	0			;NODE NAME POINTER
	EXP	0			;NETWORK ERROR POINTER

;THE ARGUMENT BLOCK PASSED TO ROUTINE ER%PRC (FILERR:)
FILBLK:	EXP	5			;SIZE OF THE ARGUMENT BLOCK
	EXP	0,0,0			;FLAG, ID AND OPTIONAL DATA WORDS
	EXP	1			;NUMBER OF FOLLOWING WORDS
	EXP	0			;POINTER TO MAIL FILE SPEC

;THE ARGUMENT BLOCK PASSED TO ROUTINE ER%PRC (ADRERR:)
ADRBLK:	EXP	5			;SIZE OF THE ARGUMENT BLOCK
	EXP	FLD(1,1B3)!FLD($MESSA,37777B17)!FLD(1,1B18)!FLD(S2$ERR,37777B32)!FLD($ERR,7B35)
	EXP	0,0			;NO OPTIONAL DATA
	EXP	1			;NUMBER OF WORDS THAT FOLLOW
	EXP	0			;USER NAME POINTER

	RELOC	400000			;BACK TO THE HISEG
;SAVE REGISTERS ACCORDING TO BLISS CONVENTION

SENVAX::MOVE	T5,P		;SAVE ORIGINAL STACK TO PICK UP ARGUMENTS LATER
	PUSH	P,T0		;SAVE THE REGISTERS PRESERVED BY BLISS
	PUSH	P,T6
	PUSH	P,T7
	PUSH	P,T10
	PUSH	P,WRKREQ
	PUSH	P,MSGBLK
	PUSH	P,T14
	PUSH	P,VARPTR

	MOVE	WRKREQ,-2(T5)	;WORK REQUEST ADDRESS
	MOVE	MSGBLK,-1(T5)	;MESSAGE BLOCK ADDRESS

	PUSH	P,13		;SAVE A BLISS LINKAGE REGISTER

;ALLOCATE BUFFER SPACES

	CALL	GETBUF

;MAKE THE CONNECTION

	SETZM	RCPT(VARPTR)	;NO RECIPIENTS YET
	SETZM	FALSND(VARPTR)	;NO REJECTED RECIPIENTS YET
	SETZM	FSTPSS(VARPTR)	;STILL ON FIRST PASS
MKECON:	CALL	CONECT
	JRST	RELBUF		;AN ERROR OCCURRED

;SEND THE SENDER'S NAME TO THE VAX

	CALL	SENSEN
	JRST	[ CALL ABTLNK     ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  JRST RELBUF]	  ;RELEASE THE BUFFERS

;SEND THE ADDRESSEES TO THE VAX

	CALL	ADRSEN
	JRST	[ CALL ABTLNK	  ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  CALL ZREJEC	  ;ZERO OUT ANY REJECTED ADDRESSEESS
		  JRST RELBUF ]   ;RELEASE THE BUFFERS

;SEND THE TO: LIST

	CALL	TOSEND
	JRST	[ CALL ABTLNK     ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  CALL ZREJEC	  ;ZERO OUT ANY REJECTED ADDRESSEESS
		  JRST RELBUF]	  ;RELEASE THE BUFFERS

;SEND THE SUBJ: LINE

	CALL	SUBSEN
	JRST	[ CALL ABTLNK     ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  CALL ZREJEC	  ;ZERO OUT ANY REJECTED ADDRESSEESS
		  JRST RELBUF]	  ;RELEASE THE BUFFERS


;OPEN THE MAIL FILE

	CALL	MAIOPN
	JRST	[ CALL ABTLNK     ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  CALL ZREJEC	  ;ZERO OUT ANY REJECTED ADDRESSEESS
		  JRST RELBUF]	  ;RELEASE THE BUFFERS

;TRANSFER THE MAIL FILE AND THEN CLOSE IT

	CALL	MAISEN
	JRST	[ CALL ABTLNK     ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  CALL ZREJEC	  ;ZERO OUT ANY REJECTED ADDRESSEESS
		  JRST RELBUF]	  ;RELEASE THE BUFFERS

;GET SUCCESS/FAILURE MESSAGES FOR EACH RECIPIENT FROM THE VAX

	CALL	SFMSG
	JRST	[ CALL ABTLNK     ;A NETWORK ERROR OCCURRED, ABORT THE LINK
		  CALL ZREJEC	  ;ZERO OUT ANY REJECTED ADDRESSEESS
		  JRST RELBUF]	  ;RELEASE THE BUFFERS

;CLOSE THE LINK

	SKIPE	RCPT(VARPTR)	;ANY MORE RECIPIENTS?
	JRST	[ CALL CSLINK	  ;YES, 
		  SETOM FSTPSS(VARPTR) ;NO LONGER THE FIRST PASS
		  JRST	MKECON ]  ;BEGIN A NEW SESSION
	CALL	CLOLIN		;NO, TERMINATE THIS SESSION
	MOVEI	T1,$DONE	;ASSUME ALL RECIPIENTS RECEIVED MAIL
	SKIPE	FALSND(VARPTR)	;DID THEY REALLY?
	MOVEI	T1,$REJECT	;NO, SO INDICATE SO
	MOVEM	T1,5(WRKREQ)	;STORE IN THE WORK REQUEST BLOCK

;RELEASE THE BUFFERS AND RETURN

RELBUF:	CALL	BUFREL		;RETURN THE BUFFERS
	MOVE	T1,5(WRKREQ)	;PICK UP STATUS FOR MX

	POP	P,13		;RESTORE REGISITERS FOR BLISS	
	POP	P,VARPTR
	POP	P,T14
	POP	P,MSGBLK
	POP	P,WRKREQ
	POP	P,10
	POP	P,T7
	POP	P,T6
	POP	P,T0

	RET			;AND RETURN TO THE CALLING ROUTINE

SUBTTL GETBUF	GET BUFFERS

;GET SPACE FOR LIST OF ADDRESSES AND POINTERS

GETBUF:	PUSH	P,[NUMVAR]	;GET SPACE FOR THE ADDRESS LIST
	CALL	UM%GET		;DO IT
	ADJSP	P,-1		;RESET THE STACK
	JUMPLE	T1,BUFERR	;AN ERROR OCCURRED
	MOVE	VARPTR,T1	;SAVE THE ADDRESS OF THE LIST

;GET SPACE FOR THE CONNECT BLOCK

	PUSH	P,[CBKSIZ]	;SIZE OF THE CONNECTION BLOCK
	CALL	UM%GET		;GET THE SPACE
	ADJSP	P,-1		;ADJUST THE POINTER
	JUMPLE	T1,BUFERR	;ERROR, HALT
	MOVEM	T1,CNNBLK(VARPTR) ;SAVE THE ADDRESS FOR LATER


;ALLOCATE SPACE FOR THE TO: LIST

	PUSH	P,[^D70]	;BUFFER SIZE
	CALL	UM%GET		;GET THE SPACE
	ADJSP	P,-1		;ADJUST THE POINTER
	JUMPLE	T1,BUFERR	;AN ERROR OCCURRED, HALT
	HRLI	T1,(POINT 8)	;MAKE INTO A POINTER
	MOVEM	T1,TOLIST(VARPTR) ;SAVE FOR LATER

;ALLOCATE SPACE FOR THE FROM STRING (8 BIT BYTE POINTER)

	PUSH	P,[^D70]		;AMOUNT OF SPACE NEEDED
	CALL	UM%GET			;GET THE SPACE
	ADJSP	P,-1			;RESET THE STACK
	JUMPLE	T1,BUFERR		;AN ERROR OCCURRED
	HRLI	T1,(POINT 8)		;MAKE A POINTER
	MOVEM	T1,SNDSTR(VARPTR)	;SAVE FOR LATER

;ALLOCATE SPACE FOR THE FROM STRING (7 BIT BYTE POINTER)

	PUSH	P,[^D70]		;AMOUNT OF SPACE NEEDED
	CALL	UM%GET			;GET THE SPACE
	ADJSP	P,-1			;RESET THE STACK
	JUMPLE	T1,BUFERR		;AN ERROR OCCURRED
	HRLI	T1,(POINT 7)		;MAKE A POINTER
	MOVEM	T1,SNDERR(VARPTR)	;SAVE FOR LATER

;ALLOCATE SPACE FOR A WORKING BUFFER

	PUSH	P,[^D100]		;THE NUMBER OF WORDS TO GET
	CALL	UM%GET			;GET THEM
	ADJSP	P,-1			;RESET THE STACK
	JUMPLE	T1,BUFERR		;AN ERROR OCCURRED, HALT
	MOVEM	T1,WRKBUF(VARPTR)	;SAVE FOR LATER
	HRLI	T1,(POINT 8)		;MAKE INTO A POINTER
	MOVEM	T1,BUFPTR(VARPTR)	;FOR VAX REPLIES
	RET				;RETURN

BUFERR:	PUSH	P,[POINT 7,[ASCIZ /No memory at BUFERR:(SENVAX)/]]
	PUSHJ	P,NMLDIE		;NO MEMORY AVAILABLE, HALT

SUBTTL	CONECT	MAKE THE CONNECTION

;CONSTRUCT THE CONNECT BLOCK

CONECT:	MOVE	T7,CNNBLK(VARPTR)	;GET ADDRESS OF THE DATA BLOCK
	HRR	T1,4(WRKREQ)		;DESTINATION NODE ADDRESS
	HRLI	T1,(POINT 8)		;MAKE INTO A POINTER
	MOVEM	T1,0(T7)		;NODE NAME POINTER
	IBP	T1			;SKIP TWO NULLS
	IBP	T1
	ILDB	T2,T1			;GET LENGTH
	MOVEM	T2,1(T7)		;NODE NAME LENGTH
	MOVEI	T2,DSTNDE(VARPTR)	;ADDRESS TO STORE ASCIZ NODE NAME
	HRLI	T2,(POINT 7)		;MAKE INTO A POINTER
NDECHR:	ILDB	T3,T1			;GET NEXT 8 BIT BYTE NODE NAME CHR
	IDPB	T3,T2			;PLACE IN 7 BIT BYTE BUFFER
	CAIE	T3,0			;FINISHED?
	JRST	NDECHR			;NO, GET THE NEXT CHARACTER
	MOVEI	T1,VAXOBJ		;OBJECT TYPE
	MOVEM	T1,2(T7)		;PLACE IN THE CONNECT BLOCK

	SETZM	3(T7)			;THE REST WILL BE ZEROED
	HRLI	T1,3(T7)		;PREPARE FOR THE BLT
	HRRI	T1,4(T7)
	BLT	T1,CBKSIZ-1(T7)		;ZERO THE REST OF THE BLOCK

;OPEN THE CONNECTION

	PUSH	P,[2]			;CONNECT TYPE 2, SOURCE
	PUSH	P,T7			;LINK CONNECT BLOCK ADDRESS
	PUSH	P,[0]			;NO RESPONSE MESSAGE
	PUSH	P,[0]			;ZERO RESPONSE MESSAGE LENGTH
	PUSH	P,[0]			;NO ERROR CODE
	CALL	UN%OPEN			;OPEN AND BLOCK FOR INITIATION
	ADJSP	P,-5			;RESET THE STACK
	SKIPG	T1			;OBTAINED THE DATA LINK NUMBER?
	JRST	CONERR			;RETURN, A NETWORK ERROR OCCURRED
	MOVEM	T1,DATLNK(VARPTR)	;SAVE THE DATA LINK NUMBER FOR LATER

;WAIT FOR THE SLAVE'S CONFIRMATION/REJECTION
REPEAT 0,<
	PUSH	P,DATLNK(VARPTR)	;LINK IDENTIFIER
	PUSH	P,[^D4]			;NUMBER OF BYTES IN THE BUFFER
	PUSH	P,BUFPTR(VARPTR)	;POINTER TO THE BUFFER
	CALL	UN%REA			;CHECK FOR CONFIRMATION
	ADJSP	P,-3			;ADJUST THE STACK
	JUMPLE	T1,CONERR		;RETURN, A NETWORK ERROR OCCURRED

	HRRZ	T2,BUFPTR(VARPTR)	;ADDRESS OF THE SUCCESS/FAIL MESSAGE
	MOVE	T2,0(T2)		;PICK UP THE STATUS WORD
	TLNE	T2,SUCBIT		;CONFIRMATION?
>
	RETSKP				;YES RETURN TRUE

CONERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred while opening the link/]]
	PUSH	P,T1			;PASS THE REASON FOR ERROR
	CALL	NETERR			;INFORM MX OF THE ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;ASSUME NO ONE RECEIVED MAIL
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEESS RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;PLACE IN THE WORK REQUEST BLOCK
	RET				;RETURN FALSE

SUBTTL SENSEN		SEND THE SENDER STRING

;SENDER'S NAME IN MESSAGE BLOCK IS IN THE FORM  NAME@NODE. TRANSLATE THIS
;TO NAME

SENSEN:	SETZ	T6,			;NUMBER OF CHARACTERS IN NAME SO FAR
	HRR	T4,1(MSGBLK)		;PICK UP ADDRESS OF SENDER STRING
	HRLI	T4,(POINT 7)		;MAKE INTO A POINTER
	MOVE	T2,SNDSTR(VARPTR)	;8 BIT BYTE POINTER TO STORE NAME IN
	SETZ	T3,			;NO QUOTES FOUND YET

FINDNM:	ILDB	T1,T4			;GET THE FIRST NAME CHARACTER
	CAIN	T1," "			;A BLANK?
	JRST	FINDNM			;YES, IGNORE LEADING BLANKS
	CAIN	T1,QUOTE		;FIRST CHARACTER A QUOTE?
	CALL	SKPQTS			;Ignore the quoted string...
	SKIPA
FINDN2:	ILDB	T1,T4			;GET THE NEXT CHARACTER
	CAIN	T1,"@"			;END OF THE NAME FOUND?
	JRST	MKEASZ			;YES, MAKE ASCIZ AND SEND OFF TO VAX
	CAIN	T1,0			;END OF THE NAME FOUND?
	JRST	SNDNAM			;YES, SEND OFF THE NAME TO THE VAX
	CALL	CHNUPC			;CHANGE ANY L.C. TO U.C.
	IDPB	T1,T2			;STORE IN TEMPORARY BUFFER
	AOS	T6			;INCREMENT THE CHARACTER COUNT
	JRST	FINDN2			;GET THE NEXT CHARACTER

;SKPQTS: Ignore the quoted string...

;**;[303] ADD 1 LINE AT SKPQTS+2
SKPQTS:	IDPB	T1,T2			;STORE THE CHARACTER IN THE TEMP BUFFER
	ILDB	T1,T4			;GET THE NEXT CHARACTER
	AOS	T6			;[303] INCREMENT THE CHARACTER COUNT
	CAIE	T1,QUOTE		;IS IT A QUOTE?
	JRST	SKPQTS			;NO, KEEP LOOKING
	IDPB	T1,T2			;STORE THE CHARACTER IN THE TEMP BUFFER
	RET				;ALL DONE, RETURN

;SEND OFF THE SENDER STRING TO THE VAX

MKEASZ:	SETZ	T1,			;ADD ASCIZ TERMINATION CHARACTER
SNDNAM:	IDPB	T1,T2			;PLACE IN THE BUFFER
	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T6			;LENGTH OF STRING
	MOVE	T2,SNDSTR(VARPTR)	;POINTER TO STRING
	PUSH	P,T2			;PASS AS AN ARGUMENT
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	JUMPLE	T1,SENERR		;NETWORK ERROR
	RETSKP				;RETURN SUCCESS

SENERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred while sending the sender's name/]]
	PUSH	P,T1			;PASS THE REASON FOR THE ERROR
	CALL	NETERR			;INFORM MX OF THE ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;STORE IN THE WORK REQUEST BLOCK
	RET 				;RETURN FALSE

SUBTTL ADRSEN		SEND THE ADDRESSEES TO THE VAX

;THIS ROUTINE RETURNS WITH T2 CONTAINING THE NUMBER OF BYTES IN THE TO: LIST
;RETURNS WITH SCRAT2(VARPTR) POINTING TO END OF THE TO: LIST
;THESE ARE USED BY ROUTINE TOSEND
;THE MAXIMUM NUMBER OF BYTES ACCEPTED BY THE VAX IS 255, THEREFORE, IF THE
;TO: LIST CONTAINS MORE THAN 255, WE CANNOT SEND AS IS.
;INITIALIZE

ADRSEN:	SKIPN	T7,RCPT(VARPTR)		;FIRST PASS?
	HLRZ	T7,4(WRKREQ)		;NO, GET FIRST RECIPIENT FROM WORK REQ
	MOVEM	T7,FSRCPT(VARPTR)	;STORE AS FIRST RECIPIENT THIS PASS
	SKIPA				;SKIP THE FIRST TIME
ADRSN1:	MOVE	T7,FSRCPT(VARPTR)	;GET THE FIRST RECIPIENT
	SETZM	NUMSUC(VARPTR)		;NO SUCCESSFUL SENDS YET
	SETZM	TOHOLD(VARPTR)		;ROOM SO FAR IN THE TO: LIST BUFFER
	MOVE	T3,TOLIST(VARPTR)	;8 BIT BYTE POINTER TO TO: LIST BUFFER
	SETZ	T2,			;NO CHARACTERS YET IN TO: LIST BUFFER
	MOVEM	T3,SCRAT3(VARPTR)	;SAVE FOR LATER
	MOVEM	T2,SCRAT4(VARPTR)	;SAVE FOR LATER

	MOVE	T5,WRKBUF(VARPTR)	;ADDRESS OF THE WORKING BUFFER
	HRLI	T5,(POINT 8)		;MAKE IT INTO A POINTER
	MOVEM	T5,SCRAT1(VARPTR)	;SAVE FOR LATER

;EACH ADDRESSEE STRING IS OF THE FORM @NODE1,@NODE2,...,@NODE3:USERNAME@NODE4.
;THE VAX EXPECTS THE FORM NODE1::NODE2::...NODE4::USERNAME.

;INITIALIZE, DETERMINE IF THE CURRENT ADDRESSEE NAME IS PRECEDED BY A NODE NAME

NXTADR:	MOVE	T6,1(T7)		;GET ADDRESSEE'S FLAG WORD
	TXNE	T6,REJECT		;WAS MAIL PREVIOUSLY REJECTED?
	JRST	GETNXT			;YES, GET THE NEXT ADDRESSEE
	HLR	T6,0(T7)		;ADDRESS OF ADDRESSEE STRING
	HRLI	T6,(POINT 7)		;MAKE IT INTO A POINTER
	MOVEM	T6,SCRAT2(VARPTR)	;MAY NEED TO RESET POINTER
	MOVE	T5,SCRAT1(VARPTR)	;8 BIT BYTE POINTER TO WORKING BUFFER
	MOVE	T0,SNDERR(VARPTR)	;7 BIT BYTE POINTER TO USER NAME
	SETZ	T10,			;NO CHARACTERS IN WORKING BUFFER YET
	MOVE	T3,SCRAT3(VARPTR)	;POINT TO CURRENT POSITION IN TO: LIST
	MOVE	T2,SCRAT4(VARPTR)	;CURRENT NUMBER OF BYTES IN TO: LIST

	ILDB	T1,T6			;GET THE FIRST ADDRESSEE CHARACTER
	CAIE	T1,"@"			;NODE NAME?
	JRST	[ MOVE T6,SCRAT2(VARPTR) ;NO, RESET TO START OF ADDRESSEE 
		  JRST FINALN ]		 ;GET THE FINAL NODE NAME

;TRANSFER THIS NODE NAME TO THE WORKING BUFFER TO BE SENT TO THE VAX, AND IF
;ROOM, PLACE IN THE TO: LIST BUFFER

NXNDCH:	ILDB	T1,T6			;GET THE NEXT NODE NAME CHARACTER
	CAIN	T1,","			;END OF THE NODE NAME?
	JRST	FINNDE			;YES, APPEND TWO COLONS
	CAIN	T1,":"			;LAST NODE NAME?
	JRST	LSTNDE			;YES, GET THE USER NAME

	CALL	CHNUPC			;CHANGE ANY LOWER CASE TO UPPER CASE
	IDPB	T1,T5			;PLACE IN THE WORKING BUFFER
	AOS	T10			;INCREMENT WORKING BUFFER BYTE COUNT
	CAIL	T2,^D256		;ROOM IN TO: LIST BUFFER
	JRST	NXNDCH			;NO, SO GET NEXT NODE NAME CHARACTER

	IDPB	T1,T3			;PLACE CHARACTER IN THE TO: LIST BUFFER
	AOS	T2			;INCREMENT THE TO: LIST BYTE COUNT
	JRST	NXNDCH			;GET THE NEXT NODE NAME CHARACTER

;A COMMA HAS BEEN FOUND IN THE ADDRESSEE STRING. APPEND TWO COLONS TO THE NODE
;NAME IN THE WORKING BUFFER AND THE TO: LIST BUFFER, IF ROOM, THEN GET THE NEXT
;NODE NAME

FINNDE:	CALL	ADDCOL			;ADD TWO COLONS
	IBP	T6			;GET RID OF THE @
	JRST	NXNDCH			;LOOK FOR THE NEXT NODE

;THE LAST NODE BEFORE THE USER NAME HAS BEEN FOUND. APPEND TWO COLONS IN
;WORKING BUFFER AND THE TO: LIST BUFFER IF SPACE.

LSTNDE:	CALL	ADDCOL			;ADD TWO COLONS

;ADD THE NODE NAME FOLLOWING THE USER NAME

	MOVEM	T6,SCRAT2(VARPTR)	;SAVE POINTER TO USER NAME
FINALN:	MOVEI	T4,"@"			;ASSUME NAME NOT SURROUNDED BY QUOTES
	ILDB	T1,T6			;GET FIRST USER NAME CHARACTER
	CAIN	T1,QUOTE		;IS IT A QUOTE?
	MOVEI	T4,QUOTE		;YES, SET END OF NAME CHARACTER

FINAL2:	ILDB	T1,T6			;GET THE NEXT CHARACTER
	CAME	T1,T4			;END OF THE USER NAME?
	JRST	FINAL2			;NO, GET THE NEXT CHARACTER
	CAIN	T4,QUOTE		;IS QUOTE END OF USER NAME?
	IBP	T6			;YES, STRIP OFF THE FOLLOWING @

FINAL3:	ILDB	T1,T6			;GET THE NEXT NODE NAME CHARACTER
	CAIN	T1,0			;THE END OF THE NODE NAME?
	JRST	RESPTR			;YES, COPY OVER THE USER NAME
	CALL	CHNUPC			;CHANGE ANY LOWER CASE TO UPPER CASE
	JUMPE	T10,FINAL4		;IF ONLY 1 NODE NAME, DO NOT INCLUDE
	IDPB	T1,T5			;PLACE CHARACTER IN WORKING BUFFER
	AOS	T10			;INCREMENT WORKING BUFFER BYTE COUNT
FINAL4:	CAIL	T2,^D256		;ROOM IN TO: LIST BUFFER
	JRST	FINAL3			;NO, SO GET NEXT NODE NAME CHARACTER

	IDPB	T1,T3			;PLACE CHARACTER IN THE TO: LIST BUFFER
	AOS	T2			;INCREMENT THE TO: LIST BYTE COUNT
	JRST	FINAL3			;GET THE NEXT NODE NAME CHARACTER
	
RESPTR:	JUMPG	T10,RESPT2		;DO NOT ADD COLONS TO WORK BUFFER
	MOVEI	T1,":"			;PICK UP A COLON
	CALL	ADDCO2			;ADD TO TO: BUFFER
	SKIPA				;DON'T DO IT AGAIN
RESPT2:	CALL	ADDCOL			;ADD TWO COLONS
	MOVE	T6,SCRAT2(VARPTR)	;POINT TO USER NAME
	ILDB	T1,T6			;GET THE FIRST USER NAME CHARACTER
	CAIE	T4,QUOTE		;Is name surrounded by quotes
	JRST	GETUS2			;PLACE IN THE BUFFER
	MOVE	T1,8(WRKREQ)		;Get the strip quotes flag
	CAIE	T1,2			;Strip them?
	JRST	[MOVEI	T1,QUOTE	   ;No, reset T1
		 JRST	GETUS2]		   ;Place in the buffer
	ILDB	T1,T6			;Skip the quote
	JRST GETUS2			;Place next character in the buffer

;MOVE THE USERS NAME OVER TO THE WORKING BUFFER

GETUSR:	ILDB	T1,T6			;GET THE NEXT CHARACTER
	CAMN	T1,T4			;END OF THE USER NAME?
	JRST	LASTN1			;YES, MAKE THE STRING ASCIZ
GETUS2:	CAIE	T4,QUOTE		;NAME SURROUNDED BY QUOTES?
	CALL	CHNUPC			;NO, CONVERT ANY L.C. TO U.C.
	IDPB	T1,T5			;PLACE CHARACTER IN WORKING BUFFER
	IDPB	T1,T0			;PLACE IN 7 BIT BYTE ERROR MESSAGE
	AOS	T10			;INCREMENT THE BYTE COUNT
	CAIL	T2,^D255		;ROOM IN THE TO: LIST?
	JRST	GETUSR			;NO, GET THE NEXT CHARACTER
	IDPB	T1,T3			;YES, PLACE IN THE TO: LIST
	AOS	T2			;INCREMENT THE TO: LIST BYTE COUNT
	JRST	GETUSR			;GET THE NEXT CHARACTER

;MAKE THE ADDRESSEE STRING ASCIZ

LASTN1:	CAIE	T1,QUOTE		;IS TERMINATION CHARACTER A QUOTE?
	JRST	MAKASZ			;NO, MAKE STRING ASCIZ NOW
	MOVE	T1,8(WRKREQ)		;Get the strip quotes flag
	CAIN	T1,2			;Strip it?
	JRST	MAKASZ			;Yes
	MOVEI	T1,QUOTE		;Reset T1
	IDPB	T1,T5			;PLACE THE QUOTE IN THE WORKING BUFFER
	IDPB	T1,T0			;PLACE IN THE 7 BIT BYTE ERROR MESSAGE
	AOS	T10			;INCREMENT THE BYTE COUNT
	CAIL	T2,^D255		;ROOM IN THE TO: LIST?
	JRST	MAKASZ			;NO, SO MAKE WORKING STRING ASCIZ
	IDPB	T1,T3			;PLACE IN THE TO: LIST
	AOS	T2			;INCREMENT ITS BYTE COUNT

MAKASZ:	MOVEI	T1,0			;ASCIZ STRING TERMINATOR
	IDPB	T1,T5			;PLACE IN THE TEMPORARY BUFFER
	IDPB	T1,T0			;PLACE IN 7 BIT BYTE ERROR MESSAGE

;SEND THE CURRENT ADDRESSEE NAME OFF TO THE VAX

SNDVAX:	PUSH	P,T2			;NEED LATER AND DESTROYED BY UN%WRI
	PUSH	P,T3			;NEED LATER AND DESTROYED BY UN%WRI
	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T10			;LENGTH OF STRING
	MOVE	T5,SCRAT1(VARPTR)	;POINT TO THE TO: LIST
	PUSH	P,T5			;PASS AS AN ARGUMENT
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	POP	P,T3			;RESTORE T3
	POP	P,T2			;RESTORE T2
	JUMPLE	T1,ADRESE		;NETWORK ERROR

;WAIT FOR THE SLAVE'S CONFIRMATION/REJECTION

	PUSH	P,T2			;DESTROYED BY UN%REA
	PUSH	P,T3			;DESTROYED BY UN%REA
	PUSH	P,DATLNK(VARPTR)	;DATA LINK NUMBER
	PUSH	P,[^D16]		;NUMBER OF BYTES IN THE BUFFER
	PUSH	P,BUFPTR(VARPTR)	;POINTER TO THE BUFFER
	CALL	UN%REA			;CHECK FOR CONFIRMATION
	ADJSP	P,-3			;ADJUST THE STACK
	POP	P,T3			;RESTORE T3
	POP	P,T2			;RESTORE T2
	JUMPLE	T1,ADRESE		;RETURN, A NETWORK ERROR OCCURRED

	HRRZ	T1,BUFPTR(VARPTR)	;ADDRESS OF THE SUCCESS/FAIL MESSAGE
	MOVE	T1,0(T1)		;PICK UP THE STATUS WORD
	TLNE	T1,SUCBIT		;CONFIRMATION?
	JRST	[ AOS NUMSUC(VARPTR)	 ;INCREMENT NUMBER OF SUCCESSFUL SENDS
		  JRST NXTONE ]		 ;SET UP FOR THE NEXT ADDRESSEE
	TRZ	T1,17			;Clear bits 32-35
	CAMN	T1,[LOGLNK]		;Is this an "Error creating log. link"?
	JRST	ADRESE			;Yes. Treat it as a network error
	SETOM	FALSND(VARPTR)		;No, VAX REJECTED THIS ADDRESSEE
	MOVE	T6,1(T7)		;GET THE ADDRESSEE FLAG WORD
	TXO	T6,REJECT		;ADDRESSEE REJECTED
	MOVEM	T6,1(T7)		;STORE UPDATED FLAG WORD

;GET THE ERROR TEXT MESSAGE

	HRRZ	T1,BUFPTR(VARPTR)	;ADDRESS OF THE ERROR MESSAGE
	MOVE	T2,T1			;SAVE A COPY FOR THE BLT
	SETZM	0(T1)			;ZERO THE FIRST WORD FOR THE BLT
	HRLS	T1			;STARTING ADDRESS IN LEFT 
	AOS	T1			;DESTINATION ADDRESS IN RIGHT
	BLT	T1,^D99(T2)		;ZERO THE BUFFER
	PUSH	P,DATLNK(VARPTR)	;DATA LINK NUMBER
	PUSH	P,[^D400]		;NUMBER OF BYTES IN THE BUFFER
	PUSH	P,BUFPTR(VARPTR)	;POINTER TO THE BUFFER
	CALL	UN%REA			;CHECK FOR CONFIRMATION
	ADJSP	P,-3			;ADJUST THE STACK
	JUMPLE	T1,ADRESE		;RETURN, A NETWORK ERROR OCCURRED
	MOVE	T1,BUFPTR(VARPTR)	;GET 8 BIT BYTE POINTER FOR ERROR 
	HRRZ	T2,SNDERR(VARPTR)	;ADDRESS OF 7 BIT BYTE ERROR MESSAGE
	MOVE	T3,T2			;SAVE FOR THE BLT
	SETZM	0(T2)			;ZERO OUT THE FIRST WORD
	HRLS	T2			;PUT ADDRESS IN BOTH HALVES
	AOS	T2			;SET UP FOR THE BLT
	BLT	T2,^D69(T3)		;ZERO OUT THE ENTIRE ERROR BUFFER
	MOVE	T2,SNDERR(VARPTR)	;POINTER TO 7 BIT BYTE ERROR MESSAGE
	MOVE	T4,T2			;SAVE FOR INFORMING MX OF THE ERROR
GETREA:	ILDB	T3,T1			;GET THE NEXT 8 BIT BYTE
	IDPB	T3,T2			;PLACE IN THE ASCIZ STRING
	CAIE	T3,0			;FINISHED?
	JRST	GETREA			;NO, GET THE NEXT BYTE
	PUSH	P,T4			;YES, PASS AS AN ARGUMENT
	CALL	ADRERR			;INFORM MX OF THE REJECTED ADDRESSEE
	ADJSP	P,-1			;RESET THE STACK
	CALL	ABTLNK			;ABORT THE LINK
	CALL	CONECT			;OPEN THE NEW LINK
	JRST	[ ADJSP P,-1		;NETWORK ERROR, FAKE A RET
		  JRST RELBUF ]		  ;RELEASE THE BUFFER SPACE
	CALL	SENSEN			;SEND THE STRINGER STRING TO THE VAX
	RET				;A NETWORK ERROR OCCURRED
	JRST	ADRSN1			;TRY AGAIN, IGNORE REJECTED RECIPIENTS

;SET UP FOR THE NEXT ADDRESSEE

NXTONE:	CAIL	T2,^D255		;ROOM IN THE TO: LIST?
	JRST	GETNXT			;NO, GET THE NEXT ADDRESSEE
	MOVEM	T3,SCRAT2(VARPTR)	;SAVE CURRENT END OF TO: LIST
	MOVEI	T1,","			;PICK UP A COMMA
	IDPB	T1,T3			;PLACE IN THE TO: LIST BUFFER
	MOVEI	T1," "			;PICK UP A BLANK
	IDPB	T1,T3			;PLACE IN THE TO: LIST BUFFER
	AOS	T2			;INCREMENT THE TO: LIST BYTE COUNT
	AOS	T2			;AGAIN
	MOVEM	T3,SCRAT3(VARPTR)	;SAVE CURRENT POSITION IN THE TO: LIST
	MOVEM	T2,SCRAT4(VARPTR)	;SAVE CURRENT BYTE COUNT IN TO: LIST

GETNXT:	HRRZ	T7,0(T7)		;GET THE NEXT ADDRESSEE ADDRESS
	CAIE	T7,0			;THE LAST ONE?
	JRST	[ MOVE T1,NUMSUC(VARPTR)  ;GET NUMBER OF SUCCESSFUL RECIPIENTS
		  CAIGE T1,MAXSND	  ;GREATER THAN THE VAX CAN HANDLE?
		  JRST NXTADR		  ;NO, VALIDATE THE NEXT ADDRESSEE
		  MOVEM T7,RCPT(VARPTR)	  ;YES, 1ST ADDRESSEE OF THE NEXT PASS
		  JRST SNDEND ]		  ;SEND EOA MESSAGE FOR THIS PASS
	SKIPG	NUMSUC(VARPTR)		;ANY SUCCESSFUL RECIPIENTS?
	JRST	[ MOVEI T1,$REJECT	  ;NO, SET THE RETURN CODE
		  JRST RETSND ]		  ;AND RETURN FALSE
	SETZM	RCPT(VARPTR)		;FIRST PASS?
	CAILE	T2,^D255		;TO: LIST BUFFER EXHAUSTED?
SNDEND:	SETOM	TOHOLD(VARPTR)		;YES, SO MUST USE "DISTRIBUTION"
	SUBI	T2,2			;CORRECT THE BYTE COUNT

;SEND THE END OF ADDRESSEES MESSAGE

	HRRZ	T1,BUFPTR(VARPTR)	;ADDRESS OF THE MESSAGE
	SETZM	0(T1)			;ALL ZEROES
	HRLI	T1,(POINT 8)		;MAKE IT A POINTER
	PUSH	P,T2			;NEED CONTENTS FOR ROUTINE TOSEND
	PUSH	P,DATLNK(VARPTR)	;DATA LINK NUMBER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,[1]			;LENGTH OF THE MESSAGE
	PUSH	P,T1			;POINTER TO THE MESSAGE
	CALL	UN%WRI			;SEND THE MESSAGE
	ADJSP	P,-4			;ADJUST THE STACK
	POP	P,T2			;RESTORE THE TO: LIST BYTE COUNT
	JUMPLE	T1,ADRESE		;NETWORK ERROR OCCURRED
	RETSKP				;RETURN TRUE, NO NETWORK ERRORS

;ROUTINE TO ADD TWO COLONS

ADDCOL:	MOVEI	T1,":"			;PICK UP A COLON
	IDPB	T1,T5			;PLACE IN THE WORKING BUFFER
	IDPB	T1,T5			;THE VAX WANTS TWO
	AOS	T10			;INCREMENT THE BYTE COUNT
	AOS	T10			;AGAIN

ADDCO2:	CAIL	T2,^D255		;ROOM IN THE TO: LIST?
	RET				;NO, SO GET THE NEXT NODE
	IDPB	T1,T3			;YES, PLACE IN THE TO: LIST BUFFER
	IDPB	T1,T3			;AGAIN
	AOS	T2			;INCREMENT THE TO: LIST BYTE COUNT
	AOS	T2			;AGAIN
	RET				;GET THE NEXT NODE

;A NETWORK ERROR OCCURRED

ADRESE:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred during recipient validation/]]
	PUSH	P,T1			;PASS THE REASON FOR THE ERROR
	CALL	NETERR			;INFORM MX OF THE NETWORK ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
RETSND:	MOVEM	T1,5(WRKREQ)		;PLACE IN THE WORK REQUEST BLOCK
	RET				;RETURN FALSE

;ROUTINE TO CONVERT LOWER CASE CHARACTERS TO UPPER CASE CHARACTERS

CHNUPC:	CAIL	T1,"a"
	CAILE	T1,"z"
	SKIPA
	SUBI	T1,40
	RET

SUBTTL TOSEND		SEND THE TO: LIST

;DETERMINE IF THE TO: LIST BUFFER CONTAINS ALL THE ADDRESSEES
;T2 AND SCRAT2(VARPTR) VALUES COME FROM ROUTINE ADRSEN

TOSEND:	SKIPE	TOHOLD(VARPTR)		;TO: LIST GOOD AS IS?
	JRST	SENTO			;NO, MAKE ONE UP
	MOVE	T1,SCRAT2(VARPTR)	;POINTER TO END OF TO: LIST
	MOVEI	T3,0			;GET A 0
	IDPB	T3,T1			;MAKE IT AN ASCIZ STRING
	JRST	SNDTOL			;SEND IT OFF TO THE VAX

;MAKE UP A TO: LIST

SENTO:	HRLI	T1,DISTRI		;ADDRESS OF STRING TO COPY
	HRR	T1,TOLIST(VARPTR)	;WHERE TO COPY TO
	HRRZ	T3,T1			;STARTING ADDRESS OF WHERE TO COPY
	BLT	T1,3(T3)		;COPY THE TO: STRING
	MOVEI	T2,^D13			;THE NUMBER OF BYTES IN THE STRING

;SEND TO THE VAX

SNDTOL:	MOVE	T1,TOLIST(VARPTR)	;8 BIT BYTE POINTER TO TO: LIST
	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T2			;LENGTH OF STRING
	PUSH	P,T1			;POINTER TO STRING
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	JUMPLE	T1,TOERR		;NETWORK ERROR
	RETSKP				;RETURN TRUE

TOERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred while sending the To: list/]]
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	NETERR			;INFORM MX OF THE ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;PLACE IN THE WORK REQUEST BLOCK
	RET				;RETURN FALSE

DISTRI:	BYTE(8)"D","i","s","t","r","i","b","u","t","i","o","n"
	EXP 0

REPEAT 0,<
SUBTTL SUBSEN		SEND THE SUBJ: LINE

;SEND A READY MADE SUBJECT LINE

SUBSEN:	MOVEI	T1,SUBLIN		;POINT TO THE SUBJECT LINE
	HRLI	T1,(POINT 8)		;MAKE IT INTO A POINTER
	MOVEI	T2,^D22			;THE LENGTH OF THE SUBJECT LINE

	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T2			;LENGTH OF STRING
	PUSH	P,T1			;POINTER TO STRING
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	JUMPLE	T1,SUBERR		;NETWORK ERROR
	RETSKP				;RETURN TRUE

SUBERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred while sending the SUBJECT: line/]]
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	NETERR			;INFORM MX OF THE ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;STORE IN THE WORK REQUEST
	RET				;RETURN FALSE

SUBLIN:	BYTE(8)"M","a","i","l"," ","f","r","o","m"," ","a"," ","T","O","P","S"
	BYTE(8)" ","N","o","d","e"
>
SUBTTL SUBSEN		SEND THE SUBJ: LINE

;SEND THE SUBJECT LINE

SUBSEN:	HLRZ	T1,4(MSGBLK)		;GET ADDRESS OF THE SUBJECT LINE
	JUMPN	T1,SNDSUB		;GO SEND IT, IF IT EXISTS
	HLR	T1,0(MSGBLK)		;GET ADDRESS OF THE FILE SPEC
	HRLI	T1,(POINT 7)		;MAKE IT INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	GETSUB			;GET THE SUBJECT LINE
	ADJSP	P,-1			;RESET THE STACK
	JUMPE	T1,BLKSUB		;THERE IS NONE, SEND A BLANK
	HRLM	T1,4(MSGBLK)		;SAVE, MAY NEED ANOTHER TIME
SNDSUB:	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	MOVE	T4,WRKBUF(VARPTR)	;ADDRESS OF BUFFER TO PLACE 8 BIT BYTES
	HRLI	T4,(POINT 8)		;MAKE INTO A POINTER
	SETZ	T2,			;NUMBER OF BYTES IN THE SUBJECT
NXTSUB:	ILDB	T3,T1			;GET THE NEXT CHARACTER
	IDPB	T3,T4			;PLACE IN 8 BIT BYTE BUFFER
	JUMPE	T3,NXTSU2		;DON'T INCLUDE THE NULL IN BYTE COUNT
	AOS	T2			;INCREMENT THE BYTE COUNT
	JRST	NXTSUB			;NO, GET THE NEX CHARACTER
NXTSU2:	MOVE	T1,WRKBUF(VARPTR)	;ADDRESS OF THE 8 BIT BYTE BUFFER
	HRLI	T1,(POINT 8)		;MAKE INTO A POINTER
	CALL	SNDSJT			;SEND OFF TO THE VAX
	JUMPLE	T1,SUBERR		;NETWORK ERROR OCCURED IF NEGATIVE
	JRST	COMSUB			;SUCCESS, RETURN

BLKSUB:	MOVEI	T1,WRKBUF(VARPTR)	;NO SUBJECT LINE GIVEN, SEND A BLANK
	HRLI	T1,(POINT 8)		;MAKE IT INTO A POINTER
	MOVE	T2,T1			;SAVE FOR THE CALL TO SNDSJT
	MOVEI	T3," "			;PICK UP A BLANK
	IDPB	T3,T2			;PLACE IN THE BUFFER
	SETZ	T3,			;GET THE ASCIZ TERMINATION CHARACTER
	IDPB	T3,T2			;MAKE IT ASCIZ FOR UN%WRI
	MOVEI	T2,1			;LENGTH OF MESSAGE
	CALL	SNDSJT			;SEND OFF TO THE VAX
	SKIPLE	T1			;NETWORK ERROR?
COMSUB:	RETSKP				;NO, RETURN SUCCESSFULLY

SUBERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred while sending the SUBJECT: line/]]
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	NETERR			;INFORM MX OF THE ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;STORE IN THE WORK REQUEST
	RET				;RETURN FALSE

SNDSJT:	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T2			;LENGTH OF STRING
	PUSH	P,T1			;POINTER TO STRING
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	RET				;RETURN TRUE

SUBTTL MAIOPN		OPEN THE MAIL FILE

MAIOPN:	HLR	T1,0(MSGBLK)		;MAIL FILE SPEC  FROM MESSAGE BLOCK
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	MOVEM	T1,MAIPTR(VARPTR)	;SAVE FOR MAIL FILE TRANSFER IN MAISEN
	PUSH	P,T1			;PASS AS AN ARUGMENT
	PUSH	P,[1]			;READ ACCESS
	PUSH	P,[0]			;NO ERROR BUFFER
	CALL	UF%OPE			;OPEN THE MAIL FILE
	ADJSP	P,-3			;RESTORE THE STACK
	JUMPLE	T1,OPNERR		;AN ERROR OCCURRED
	MOVEM	T1,FILNB(VARPTR)	;SAVE THE FILE NUMBER FOR LATER
	RETSKP				;RETURN TRUE

OPNERR:	MOVE	T1,FGWRD1		;GET THE FLAG WORD
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	FILERR			;INFORM MX OF THE MAIL FILE ERROR
	ADJSP	P,-1			;RESET THE STACK
	MOVEI	T1,$REJECT		;NO USERS GOT THIS MAIL
	MOVEM	T1,5(WRKREQ)		;PLACE IN THE WORK REQUEST BLOCK
	RET				;RETURN FALSE

FGWRD1:	EXP	FLD(1,1B3)!FLD($MESSA,37777B17)!FLD(1,1B18)!FLD(UF$FOF,37777B32)!FLD($ERR,7B35)

SUBTTL MAISEN		TRANSFER THE MAIL FILE

;PLACE A DELIMITER LINE BETWEEN THE HEADER AND MAIL FILE

MAISEN:	SETOM	T7			;LOOP COUNTER
	MOVEI	T1,TOPLIN		;DELIMITER LINE
	SKIPA
MAISE2:	MOVEI	T1,SNDLIN		;SEND A BLANK LINE OVER
	HRLI	T1,(POINT 8)		;MAKE IT INTO A POINTER
	MOVEI	T2,^D11			;THE LENGTH OF THE SUBJECT LINE

	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T2			;LENGTH OF STRING
	PUSH	P,T1			;POINTER TO STRING
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	JUMPLE	T1,OUTERR		;NETWORK ERROR
	AOJE	T7,MAISE2		;SEND A BLANK LINE OVER
	SETZ	T7,			;NO BYTES IN THE OUTPUT BUFFER
	MOVE	T6,SNDSTR(VARPTR)	;8 BIT BYTE POINTER TO OUTPUT BUFFER

;READ IN THE NEXT BUFFER FROM THE MAIL FILE

NXTBUF:	PUSH	P,FILNB(VARPTR)		;FILE NUMBER OF THE MAIL FILE
	MOVE	T14,WRKBUF(VARPTR)	;POINT TO THE START OF THE BUFFER
	HRLI	T14,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T14			;PASS AS AN ARGUMENT
	PUSH	P,[^D255]		;MAXIMUM NUMBER OF BYTES IN BUFFER
	PUSH	P,[0]			;NO ERROR BUFFER
	CALL	UF%REA			;READ THE NEXT MAIL FILE BUFFER
	ADJSP	P,-4			;RESET THE STACK
	SETZ	FLGWRD,			;NO CR OR LF SEEN

	JUMPL	T1,REAERR		;AN ERROR OCCURRED
	JUMPE	T1,EOFFND		;END OF FILE
	MOVE	T10,T1			;THE NUMBER OF BYTES IN THE BUFFER

;READ THE NEXT CHARACTER. WHEN BOTH A CR AND LF HAS BEEN FOUND SEND THE
;OUTPUT BUFFER

NXTCHR:	ILDB	T1,T14			;GET  NEXT CHARACTER FROM INPUT BUFFER
	CAIE	T1,.CR			;IS IT A CARRIAGE RETURN?
	JRST	CHKLF			;NO, CHECK IF IT IS A LINE FEED
	TXO	FLGWRD,CRFLG		;LITE THE CARRIAGE RETURN FLAG
	TXNN	FLGWRD,LFFLG		;HAS A LF ALSO BEEN SEEN?
	JRST	DECCNT			;NO,CHECK FOR END OF INPUT BUFFER
	CALL	SENDIT			;SEND THE OUTPUT BUFFER
	RET				;NETWORK ERROR OCCURRED
	JRST	DECCNT			;CHECK FOR END OF INPUT BUFFER

CHKLF:	CAIE	T1,.LF			;IS IT A LINE FEED?
	JRST	DEPBYT			;NO, DEPOSIT IN THE OUTPUT BUFFER
	TXO	FLGWRD,LFFLG		;LITE THE LINE FEED FLAGE
	TXNN	FLGWRD,CRFLG		;HAS A CR RETURN ALSO BEEN SEEN?
	JRST	DECCNT			;NO, CHECK FOR END OF INPUT BUFFER
	CALL	SENDIT			;SEND THE OUTPUT BUFFER
	RET				;NETWORK ERROR OCCURRED
	JRST	DECCNT			;CHECK FOR END OF INPUT BUFFER

;CHARACTER IS NOT A CR OR LF, DEPOSIT IN THE OUTPUT BUFFER. IF NO ROOM, SEND
;TO THE VAX AND REINIALIZE THE OUTPUT BUFFER

DEPBYT:	IDPB	T1,T6			;DEPOSIT CHARACTER IN OUTPUT BUFFER
	AOS	T7			;NUMBER OF BYTES IN OUTPUT BUFFER
	CAIGE	T7,^D255		;ANY ROOM LEFT IN THE BUFFER?
	JRST	DECCNT			;YES, JUST CHECK FOR END INPUT BUFFER
	CALL	SENBUF			;SEND  OUTPUT BUFFER, REINITIALIZE IT
	RET				;NETWORK ERROR OCCURRED

;DECREMENT INPUT BUFFER BYTE COUNT AND EITHER GET THE NEXT CHARACTER OR IF
;EMPTY, GET THE NEXT BUFFER

DECCNT:	SOSE	T10			;DECREMENT INPUT BUFFER BYTE COUNT
	JRST	NXTCHR			;NOT EMPTY, GET THE NEXT BYTE
	JRST	NXTBUF			;EMPTY, READ IN THE NEXT BUFFER

;A CR AND LF HAVE BOTH BEEN FOUND. SEND THE OUTPUT BUFFER TO THE VAX
;IF THE SEQUENCE CR,LF,CR,LF ...CR,LF HAS BEEN FOUND, REPLACE EACH NULL
;LINE WITH A SINGLE BLANK CHARACTER. FINALLY REINITIALIZE THE OUTPUT BUFFER

SENDIT:	SETZ	FLGWRD,			;RESET THE CR AND LF FLAG WORD
	SKIPE	T7			;IS THE OUTPUT BUFFER EMPTY?
	JRST	SENBUF			;NO, SEND IT AS IS
	MOVEI	T1," "			;GET A BLANK
	IDPB	T1,T6			;AND PLACE IN THE OUTPUT BUFFER
	MOVEI	T7,1			;BYTE COUNT OF OUTPUT BUFFER

SENBUF:	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,T7			;LENGTH OF STRING
	MOVE	T6,SNDSTR(VARPTR)	;POINTER TO OUTPUT BUFFER
	PUSH	P,T6			;PASS AS AN ARGUMENT
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	JUMPLE	T1,OUTERR		;NETWORK ERROR OCCURRED

	SETZ	T7,			;RESET OUTPUT BUFFER BYTE COUNT
	RETSKP				;RETURN TRUE

;THE MAIL FILE HAS BEEN TRANSFERED, SEND AN END OF MESSAGE TO THE VAX

EOFFND:	HRRZ	T1,SNDSTR(VARPTR)	;ADDRESS OF THE MESSAGE
	SETZM	0(T1)			;THE MESSAGE IS A ZERO BYTE
	MOVE	T1,SNDSTR(VARPTR)	;POINTER TO THE MESSAGE
	PUSH	P,DATLNK(VARPTR)	;DATA LINK IDENTIFIER
	PUSH	P,[1]			;END OF MESSAGE FLAG
	PUSH	P,[1]			;LENGTH OF STRING
	PUSH	P,T1			;POINTER TO THE MESSAGE
	CALL	UN%WRI			;SEND THE STRING OFF TO THE VAX
	ADJSP	P,-4			;ADJUST THE STACK
	JUMPLE	T1,OUTERR		;AN ERROR OCCURRED
	CALL	MAICLO			;CLOSE THE MAIL FILE
	RETSKP				;RETURN TRUE

OUTERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred while transmitting mail file/]]
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	NETERR			;INFORM MX OF THE NETWORK ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR
	SKIPE	FSTPSS(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;PLACE IN THE WORK REQUEST BLOCK
	JRST	COMRET			;RETURN FALSE

REAERR:	MOVE	T1,FGWRD2		;GET THE FLAG WORD
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	FILERR			;INFORM MX OF THE ERROR
	ADJSP	P,-1			;RESET THE STACK
	MOVEI	T1,$REJECT		;NO ONE RECEIVED THIS MAIL
	MOVEM	T1,5(WRKREQ)		;PLACE IN WORK REQUEST BLOCK

COMRET:	PUSH	P,T1			;SAVE THE STATUS
	CALL	MAICLO			;CLOSE THE MAIL FILE
	POP	P,T1			;RESTORE THE STATUS
	RET				;RETURN FALSE

FGWRD2:	EXP	FLD(1,1B3)!FLD($MESSA,37777B17)!FLD(1,1B18)!FLD(UF$FRF,37777B32)!FLD($ERR,7B35)

TOPLIN:	BYTE(8) " "," "," ","=","=","=","=","=","=","=","="
SNDLIN: BYTE(8) " "," "," "," "," "," "," "," "," "," "," "

SUBTTL SFMSG		PICK UP THE SUCCESS/FAIL MESSAGES FROM THE VAX

;INITIALIZE

SFMSG:	MOVE	T7,FSRCPT(VARPTR)	;POINT TO THE FIRST ADDRESSEE
	MOVN	T14,NUMSUC(VARPTR)	;NEGATIVE NUMBER OF RECIPIENTS
	HRRZ	T5,BUFPTR(VARPTR)	;MESSAGE ADDRESS
	PUSH	P,DATLNK(VARPTR)	;DATA LINK NUMBER
	PUSH	P,[^D16]		;NUMBER OF BYTES IN THE BUFFER
	PUSH	P,BUFPTR(VARPTR)	;BUFFER POINTER

SFLOOP:	MOVE	T6,1(T7)		;GET THE ADDRESSEE FLAG WORD
	TXZE	T6,REJECT		;REJECTED PREVIOUSLY BY THE VAX?
	JRST	[ MOVEM T6,1(T7)	  ;YES, STORE THE UPDATED FLAG WORD
		  HRRZ T7,0(T7)		  ;GET THE NEXT ADDRESSEE
		  JRST SFLOOP ]		  ;CHECK THIS ONE'S FLAG WORD
	CALL	UN%REA			;GET THE NEXT MESSAGE
	JUMPLE	T1,SFERR		;NETWORK ERROR OCCURRED
	HRRZ	T5,BUFPTR(VARPTR)	;GET THE ADDRESS OF THE MESSAGE
	MOVE	T2,0(T5)		;PICK UP THE MESSAGE
	TLNN	T2,SUCBIT		;SUCCESS MESSAGE?
	JRST	ADRFAI			;NO, INFORM MX
	TXO	T6,DELVER		;SET THE MAIL DELIVERED BIT
	MOVEM	T6,1(T7)		;STORE IN ADDRESSEE FLAG WORD
	JRST	NEXTAD			;GET THE NEXT ADDRESSEE

ADRFAI:	SETOM	FALSND(VARPTR)		;NOT ALL RECIPIENTS RECEIVED MAIL

;GET THE ERROR TEXT MESSAGE

	HRRZ	T1,BUFPTR(VARPTR)	;ADDRESS OF THE ERROR MESSAGE
	MOVE	T2,T1			;SAVE A COPY FOR THE BLT
	SETZM	0(T1)			;ZERO THE FIRST WORD FOR THE BLT
	HRLS	T1			;STARTING ADDRESS IN LEFT 
	AOS	T1			;DESTINATION ADDRESS IN RIGHT
	BLT	T1,^D99(T2)		;ZERO THE BUFFER
	PUSH	P,DATLNK(VARPTR)	;DATA LINK NUMBER
	PUSH	P,[^D400]		;NUMBER OF BYTES IN THE BUFFER
	PUSH	P,BUFPTR(VARPTR)	;POINTER TO THE BUFFER
	CALL	UN%REA			;CHECK FOR CONFIRMATION
	JUMPLE	T1,SFERR		;RETURN, A NETWORK ERROR OCCURRED
	ADJSP	P,-3			;ADJUST THE STACK
	MOVE	T1,BUFPTR(VARPTR)	;GET 8 BIT BYTE POINTER FOR ERROR 
	HRRZ	T2,SNDERR(VARPTR)	;ADDRESS OF 7 BIT BYTE ERROR MESSAGE
	MOVE	T3,T2			;SAVE FOR THE BLT
	SETZM	0(T2)			;ZERO OUT THE FIRST WORD
	HRLS	T2			;PUT ADDRESS IN BOTH HALVES
	AOS	T2			;SET UP FOR THE BLT
	BLT	T2,^D69(T3)		;ZERO OUT THE ENTIRE ERROR BUFFER
	MOVE	T2,SNDERR(VARPTR)	;POINTER TO 7 BIT BYTE ERROR MESSAGE
	MOVE	T4,T2			;SAVE FOR INFORMING MX OF THE ERROR
FNDREA:	ILDB	T3,T1			;GET THE NEXT 8 BIT BYTE
	IDPB	T3,T2			;PLACE IN THE ASCIZ STRING
	CAIE	T3,0			;FINISHED?
	JRST	FNDREA			;NO, GET THE NEXT BYTE
	PUSH	P,T4			;YES, PASS AS AN ARGUMENT
	CALL	ADRERR			;INFORM MX OF THE ADDRESSEE REJECTION
	ADJSP	P,-1			;RESET THE STACK

NEXTAD:	HRRZ	T7,0(T7)		;GET THE NEXT ADDRESSEE
	AOJL	T14,SFLOOP		;GET THE NEXT MESSAGE
	ADJSP	P,-3			;RESET THE STACK
	MOVE	T14,NUMSUC(VARPTR)	;GET THE NUMBER OF SUCCESSFULL SENDS
	CAIL	T14,MAXSND		;IS IT THE MAXIMUM?
	RETSKP				;YES, FINISH WITH THIS PASS
	SKIPN	T7			;MORE ADDRESSESS?
	RETSKP				;NO, FINISH WITH THIS PASS

	MOVEM	T7,FSRCPT(VARPTR)	;ADDRESS OF FIRST ADDRESSEE
	CALL	ZREJEC			;ZERO ANY REJECT BITS	
	RETSKP				;FINISHED

SFERR:	MOVEI	T1,DSTNDE(VARPTR)	;ADDRESS OF THE NODE NAME
	HRLI	T1,(POINT 7)		;MAKE INTO A POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	MOVE	T1,[POINT 7,[ASCIZ/occurred during recipient confirmation of recieving mail/]]
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	NETERR			;INFORM MX OF THE NETWORK ERROR
	ADJSP	P,-2			;RESET THE STACK
	MOVEI	T1,$DEFER		;NETWORK ERROR OCCURRED
	SKIPE	RCPT(VARPTR)		;FIRST PASS?
	MOVEI	T1,$REJECT		;NO, SO SOME ADDRESSEES RECEIVED MAIL
	MOVEM	T1,5(WRKREQ)		;PLACE IN THE WORK REQUEST BLOCK
	ADJSP	P,-3			;RESET THE STACK
	CALL	RSTPKT
	RET				;RETURN AN ERROR

SUBTTL CLOLIN		CLOSE THE CONNECTION

CLOLIN:	PUSH	P,DATLNK(VARPTR)	;DATA LINK
	PUSH	P,[0]			;NO OPTIONAL DATA
	PUSH	P,[0]			;NO OPTIONAL DATA POINTER
	CALL	UN%CLO			;CLOSE THE LINK
	ADJSP	P,-3			;RESET THE STACK
	MOVEI	T1,$DONE		;EVERYONE RECEIVED MAIL
	SKIPE	FALSND(VARPTR)		;REALLY?
	MOVEI	T1,$REJECT		;NO, INDICATE SO
	MOVEM	T1,5(WRKREQ)		;SAVE IN THE WORK REQUEST BLOCK
	RET

ABTLNK:	PUSH	P,DATLNK(VARPTR)	;DATA LINK
	PUSH	P,[.DCX11]		;UNDEFINED ERROR
	PUSH	P,[0]			;NO OPTIONAL DATA
	PUSH	P,[0]			;NO OPTIONAL DATA POINTER
	CALL	UN%ABO			;ABORT THE LINK
	ADJSP	P,-4			;RESET THE STACK
	RET

CSLINK:	PUSH	P,DATLNK(VARPTR)	;DATA LINK
	PUSH	P,[0]			;NO OPTIONAL DATA
	PUSH	P,[0]			;NO OPTIONAL DATA POINTER
	CALL	UN%CLO			;CLOSE THE LINK
	ADJSP	P,-3			;RESET THE STACK
	SKIPLE	T1			;ERROR?
	RET				;NO, SO RETURN NOW

	PUSH	P,DATLNK(VARPTR)	;DATA LINK
	PUSH	P,[.DCX11]		;UNDEFINED ERROR
	PUSH	P,[0]			;NO OPTIONAL DATA
	PUSH	P,[0]			;NO OPTIONAL DATA POINTER
	CALL	UN%ABO			;ABORT THE LINK
	ADJSP	P,-4			;RESET THE STACK
	RET

;CLOSE THE MAIL FILE

MAICLO:	PUSH	P,FILNB(VARPTR)		;FILE NUMBER OF THE MAIL FILE
	PUSH	P,[0]			;DO NOT ABORT THE FILE
	PUSH	P,[0]			;NO ERROR STRING
	CALL	UF%CLO			;CLOSE AND DELETE THE MAIL FILE
	ADJSP	P,-3			;RESET THE STACK
	SKIPE	T1			;AN ERROR OCCURRED
	JRST	MAIRET			;RETURN

	MOVE	T1,FGWRD3		;GET THE FLAG WORD
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	FILERR			;INFORM MX OF THE MAIL FILE ERROR
	ADJSP	P,-1			;RESET THE STACK

MAIRET:	RET

FGWRD3:	EXP	FLD(1,1B3)!FLD($MESSA,37777B17)!FLD(1,1B18)!FLD(UF$FCF,37777B32)!FLD($ERR,7B35)


;RESET THE REJECTED BIT OF ADDRESSESS UPON AN ERROR

ZREJEC:	SETZ	T2,			;ZERO THE FLAG WORD
	TXO	T2,REJECT		;LIGHT THE REJECT BIT
	MOVE	T1,FSRCPT(VARPTR)	;PICK UP FIRST ADDRESSEE OF THIS PASS
RESERR:	ANDCAM	T2,1(T1)		;ZERO OUT THE REJECTED BIT
	HRRZ	T1,0(T1)		;GET THE NEXT ADDRESSEE
	CAIE	T1,0			;LAST ONE?
	JRST	RESERR			;NO
	RET				;YES


SUBTTL		ERROR HANDLING ROUTINES

;THIS ROUTINE INFORMS MX OF ANY NETWORK ERRORS THAT OCCURRED

NETERR:	MOVEI	T1,ERRBLK		;GET ADDRESS OF THE ARGUMENT BLOCK
	MOVE	T2,-1(P)		;GET THE REASON FOR ERROR POINTER
	MOVEM	T2,6(T1)		;PLACE IN THE SECOND ARGUMENT BLOCK
	MOVE	T2,-2(P)		;GET THE NODE NAME POINTER
	MOVEM	T2,5(T1)		;PLACE IN THE FIRST ARGUMENT BLOCK
	MOVE	T2,2(WRKREQ)		;GET THE I.D.
	MOVEM	T2,2(T1)		;PLACE IN THE ARGUMENT BLOCK
	HRLS	T1			;START OF WHAT TO PUT ON THE STACK
	HRRI	T1,1(P)			;WHERE TO PUT ON THE STACK
	BLT	T1,7(P)			;PLACE ON THE STACK
	MOVEI	T1,1(P)			;ADDRESS OF THE ARGUMENT BLOCK
	ADJSP	P,7			;UPDATE THE STACK POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	ER%PRC			;INFORM MX OF THE USER REJECTION
	ADJSP 	P,-10			;RESET THE STACK POINTER
	RET

;A MAIL FILE ERROR OCCURED EITHER IN OPENING, READING OR CLOSING

FILERR:	MOVEI	T1,FILBLK		;GET ADDRESS OF THE ARGUMENT BLOCK
	MOVE	T2,MAIPTR(VARPTR)	;FILE SPEC POINTER
	MOVEM	T2,5(T1)		;PLACE IN THE ARGUMENT BLOCK
	MOVE	T2,-1(P)		;GET THE FLAG WORD
	MOVEM	T2,1(T1)		;PLACE IN THE ARGUMENT BLOCK
	MOVE	T2,2(WRKREQ)		;GET THE I.D.
	MOVEM	T2,2(T1)		;PLACE IN THE ARGUMENT BLOCK

	HRLS	T1			;FIRST WORD TO COPY TO THE STACK
	HRRI	T1,1(P)			;WHERE TO PLACE 1ST WORD ON THE STACK
	BLT	T1,6(P)			;PLACE ON THE STACK
	MOVEI	T1,1(P)			;ADDRESS OF THE BLOCK
	ADJSP	P,6			;ADJUST THE STACK FOR THE ARG. BLOCK
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	ER%PRC			;INFORM MX OF THE ERROR
	ADJSP	P,-7			;RESET THE STACK
	RET

;AN ADDRESSEE WAS REJECTED BY THE VAX

ADRERR:	MOVEI	T1,ADRBLK		;GET ADDRESS OF THE ARGUMENT BLOCK
	MOVE	T2,-1(P)		;GET THE ADDRESSEE POINTER
	MOVEM	T2,5(T1)		;PLACE IN THE ARGUMENT BLOCK
	MOVE	T2,2(WRKREQ)		;GET THE I.D.
	MOVEM	T2,2(T1)		;PLACE IN THE ARGUMENT BLOCK
	HRLS	T1			;START OF WHAT TO PUT ON THE STACK
	HRRI	T1,1(P)			;WHERE TO PUT ON THE STACK
	BLT	T1,6(P)			;PLACE ON THE STACK
	MOVEI	T1,1(P)			;ADDRESS OF THE ARGUMENT BLOCK
	ADJSP	P,6			;UPDATE THE STACK POINTER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	CALL	ER%PRC			;INFORM MX OF THE USER REJECTION
	ADJSP 	P,-7			;RESET THE STACK POINTER
	RET

SUBTTL BUFREL		RELEASE THE BUFFERS

;RELEASE SPACE FOR THE CONNECT BLOCK

BUFREL:	MOVE	T1,CNNBLK(VARPTR)	;ADDRESS OF THE CONNECTION BLOCK
	PUSH	P,T1			;PASS AS AN ARGUMENT
	PUSH	P,[CBKSIZ]		;SIZE OF THE CONNECTION BLOCK
	CALL	UM%REL			;RELEASE THE SPACE
	ADJSP	P,-2			;RESET THE STACK

;RELEASE THE SPACE FOR THE TO: LIST

	HRRZ	T1,TOLIST(VARPTR)	;ADDRESS OF THE TO: LIST BUFFER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	PUSH	P,[^D70]		;SIZE OF THE TO: LIST BUFFER
	CALL	UM%REL			;RELEASE THE SPACE
	ADJSP	P,-2			;RESET THE STACK

;RELEASE SPACE FOR THE FROM STRING (8 BIT)

	HRRZ	T1,SNDSTR(VARPTR)	;ADDRESS OF FROM STRING BUFFER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	PUSH	P,[^D70]		;SIZE OF THE FROM STRING BUFFER
	CALL	UM%REL			;RELEASE THE SPACE
	ADJSP	P,-2			;RESET THE STACK

;RELEASE SPACE FOR THE FROM STRING (7 BIT)

	HRRZ	T1,SNDERR(VARPTR)	;ADDRESS OF FROM STRING BUFFER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	PUSH	P,[^D70]		;SIZE OF THE FROM STRING BUFFER
	CALL	UM%REL			;RELEASE THE SPACE
	ADJSP	P,-2			;RESET THE STACK


;RELEASE SPACE FOR THE WORKING BUFFER

	HRRZ	T1,WRKBUF(VARPTR)	;ADDRESS OF THE WORKING BUFFER
	PUSH	P,T1			;PASS AS AN ARGUMENT
	PUSH	P,[^D100]		;SIZE OF THE WORKING BUFFER
	CALL	UM%REL			;RELEASE THE SPACE
	ADJSP	P,-2			;RESET THE STACK

;RELEASE SPACE FOR LIST OF ADDRESSES AND POINTERS

	PUSH	P,VARPTR		;ADDRESS OF ADDRESS LIST
	PUSH	P,[NUMVAR]		;SIZE OF ADDRESS LIST
	CALL	UM%REL			;RELEASE THE SPACE
	ADJSP	P,-2			;RESET THE STACK

	RET

;A RECIPIENT WAS REJECTED, RESET ALL DELIVERED BITS

RSTPKT:	SETZ	T1,0			;ZERO THE FLAG WORD
	TXO	T1,DELVER		;LITE THE DELIVERED BIT
RSTPK2:	ANDCAM	T1,1(T7)		;TURN OFF THE DELIVERED BIT
	HRRZ	T7,0(T7)		;GET THE NEXT RECIPIENT
	CAIE	T7,0			;IS THIS THE LAST ONE?
	JRST	RSTPK2			;NO, GO TURN OFF THE DELIVERED BIT
	RET				;YES, GO CLOSE THE LINK

RSKP:	AOS 0(P)
R:	RET

	END