Google
 

Trailing-Edge - PDP-10 Archives - BB-H348C-RM_1982 - swskit-v21/vax-mail/vmail.mac
There are 6 other files named vmail.mac in the archive. Click here to see a list.
;<MIERSWA.DECNET.SWSKIT.VAX-MAIL>VMAIL.MAC.6,  4-Jan-82 11:49:01, EDIT BY GRANT
;Fix test for null line in REPEAT:
;<STEVENS.VMAILR>VMAIL.MAC.76 25-Nov-81 16:18:00 Edit by STEVENS
; Repaired error in PRSUSR routine which cause TOOBUF to be wrong
;<STEVENS.VMAILR>VMAIL.MAC.75 25-Nov-81 14:57:00 Edit by STEVENS
; Change last part of error string to VAX to a SOUTR monitor
; call to force transmission of the error string
;<STEVENS.VMAILR>VMAIL.MAC.74 25-Nov-81 12:23:00 Edit by STEVENS
; Fixed error in checking username to check for RC%NOM
;<STEVENS.VMAILR>VMAIL.MAC.73 23-Nov-81 10:54:00 Edit by STEVENS
; Repaired error in clearing temp1
;<STEVENS.VMAILR>VMAIL.MAC.72 23-Nov-81 10:02:00 Edit by STEVENS
; Fix receive to prevent buffer overflow and clear buffer before
; receive to ensure ASCIZ
;<STEVENS.VMAILR>VMAIL.MAC.71 20-Nov-81 14:24:00 Edit by STEVENS
; Fix headers so host name appears
;<STEVENS.VMAILR>VMAIL.MAC.70 20-Nov-81 13:29:00 Edit by STEVENS
; Add blank line between headers and body of message
;<STEVENS.VMAILR>VMAIL.MAC.69 20-Nov-81 13:13:00 Edit by STEVENS
; Set file byte size and remove extra crlf in mail file
;<STEVENS.VMAILR>VMAIL.MAC.68 20-Nov-81 12:04:00 Edit by STEVENS
; Fix filnam on forwarding to always take next higher generation
;<STEVENS.VMAILR>VMAIL.MAC.67 20-Nov-81 11:19:00 Edit by STEVENS
; Put file byte count on forwarding file
;<STEVENS.VMAILR>VMAIL.MAC.66 20-Nov-81 10:00:00 Edit by STEVENS
; Repaired assorted problem in forwarding message
;<STEVENS.VMAILR>VMAIL.MAC.65 20-Nov-81 09:30:00 Edit by STEVENS
; Cleaned up quefil routine by inserting jerr of fatals
;<STEVENS.VMAILR>VMAIL.MAC.64 20-Nov-81 09:01:00 Edit by STEVENS
; REPAIRED BUG IN QUEFIL ROUTINE (JFCL AFTER GETJI)

	Title Vmail - Vax Mail Listener

	Search Macsym,Monsym
	.require Sys:Macrel
	Sall
	.directive Flblst

T1=1
T2=2
T3=3
T4=4
T5=5
P1=6
P2=7
P3=10
P4=11
P5=12
Ptr=13				;Global Byte Pointer To Receive Mail
Cnt=14				;Global Byte Count For Same
Cx=16
P=17

.ver==1
.edt==^D89

	Loc 137
	Exp <.ver>B11+.edt
	Reloc
Define Jerr(String),<
	Xlist
	Erjmp [ Hrroi T1,[Asciz /Vmail Error: /]
		Esout%
		Hrroi T1,[Asciz /String/]
		Psout%
		Hrroi T1,[Asciz / Because: /]
		Psout%
		Movx T1,.priou
		Hrloi T2,.fhslf
		Erstr%
		 Jfcl
		 Jfcl
		Call Lgcrlf
		Call Dtstmp	;; Log This Lossage Also
		Log <String>
		Log < Because: >
		Move T1,Logjfn
		Hrloi T2,.fhslf
		Erstr%
		 Jfcl
		 Jfcl
		CALL LGCRLF
		Jrst Fatal]
	List
>

Define Log(String),<		;; Put Message Into Log File
	Xlist
	Hrroi T1,[Asciz \String\] ;; So It Can Type Slashes
	Call Logmsg
	List
>
Define Debug(String),<
	Skipe Dbugsw
	 Jrst [ Hrroi T1,[Asciz /String/]
		Psout%
		Jrst .+1 ]
>

Define Debstr(String),<
	Skipe Dbugsw
	 Jrst [ Hrroi T1,String
		Psout%
		Jrst .+1 ]
>

Define Clrbuf(bufnam,Buflen),<
	Setzm Bufnam
	Move  T1,[Bufnam,,Bufnam+1]
	Blt   T1,Bufnam+buflen-1
>

Define Nchar ,<
	Move T1,Netjfn
	Bin%
	 jerr <BIN from network failed>
	Move T1,T2
>

Define Nrecord(Buffer,Nchar),<
	Move  T1,Netjfn
	Hrroi T2,Buffer
	Movni T3,Nchar
	Setz  T4,
	Sinr%
	 Jerr <Sinr failed at Nrecord>
>

Define Vaxsuccess,<
	Move  T1,Netjfn
	Hrroi T2,[Ascii//]
	Movei T3,-4
	Setz  T4,
	Soutr%
	 jerr <soutr to network failed>
>

Define Vaxerr(Errmsg),<
	Move  T1,Netjfn
	Hrroi T2,[Ascii//]
	Movei T3,-4
	Setz  T4,
	Sout%
	 jerr <sout to network failed>
	Move  T1,Netjfn
	Hrroi T2,[Asciz /Errmsg/]
	Setzb T3,T4
	Sout%
	 jerr <sout to network failed>
	Hrroi T2,Atmbuf
	Setzb T3,T4
	Sout%
	 jerr <sout to network failed>
	Hrroi T2,[Asciz/ At Node /]
	Setzb T3,T4
	Sout%
	 jerr <sout to network failed>
	Hrroi T2,ournam
	Setzb T3,T4
	Sout%			; force string transmission
	 jerr <sout to network failed>
	Hrroi T2,[0]
	Movei T3,-1
	Setz  T4,
	Soutr%
	 jerr <soutr to network failed>
>

Define Die(String),<		;; Fatal Internal Error
	Xlist
	Jrst [  Hrroi T1,[Asciz /Vmail Fatal Internal Error: /]
		Esout%
		Hrroi T1,[Asciz /String/]
		Psout%
		Hrroi T1,[Asciz /
/]
		Psout%
		Call Lgcrlf	;; Log This Error
		Call Dtstmp	;; Time Stamp It
		Hrroi T1,[Asciz /Fatal Error: /]
		Call Logmsg
		Hrroi T1,[Asciz /String/]
		Call Logmsg
		Jrst Fatal]
	List
>

Define Herald(Ver,Edt),<
	Xlist
;	Tmsg <Vmail Version Ver(Edt) Running>
	Hrroi T1,[Asciz /
Vmail Version Ver(Edt) Running/]
	Call Logmsg
	List
>

Define Log(String),<
	Xlist
	Hrroi T1,[Asciz \String\]
	Call Logmsg
	List
>
;Storage
FLGPAG==600			;page into which we map DECNET-MAILER.FLAGS
FLGADR==FLGPAG*1000		;address of DECNET-MAILER.FLAGS
Tmplen==50			; Temporary Storage
Natmbf==40			; Length Of Atom Buffer In Words
Bbflen==40000			; Length Of Big Buffer Into Which Mail Is Read
Nfrmbf==20			; Length Of Sender Name Buffer
Timen==^d180000			; Milliseconds Before Sender Declared Tardy
Stklen==200			; Size Of Stack

Dbugsw:	0			; -1 If Debug
Flgjfn:	Block 1			;Jfn of Decnet-mailer.flags
Atmbuf:	Block Natmbf		; Atom Buffer
Subbuf:	Block Natmbf		; Subject Buffer
Toocnt:	Block 1			; Count of recipients per line in TOOBUF
Tooptr:	Block 1			; Pointer to current position in TOOBUF
Toobuf:	Block Natmbf		; To Names Buffer
Bigbuf:	Block Bbflen		; Where It All Is Combined To
Nodtab:	Block ^D101		; Table space for tbluk call
Nodstr:	Block ^D200		; String space for recipient nodes
Ulist:	Block ^D200		; Where To Store Mailbox Directory Numbers
Frmmsg:	Block 20		; String To Type On Recipient'S Terminal
Frmbuf:	Block Nfrmbf		; Where To Put Sender'S Name Plus Host
Frmnam:	Block Nfrmbf		; Where To Put Sender'S Name
Ournam:	Block 2			; Our Host Name
Hstnam:	Block 2			; Host name we are sending to
Usrnum:	Block 1			; User number we are sending to
Filnam:	Block 1			; File name for forwarded mail
Temp1:	Block Tmplen
Temp2:	Block Tmplen
Gtinf:	Block 20		; Getji Block
Stack:	Block Stklen		; One Stack For Each Fork
Netjfn:	Block 1			; Network File Jfn
Logjfn:	Block 1			; Log File Jfn
Ntime:	Block 1			; Time Receipt Of Mail Initiated (For Status)
Elptim:	Block 1			; Elapsed Time For Receipt Of Mail
Bytcnt:	Block 1			; Length Of Mail In Bytes
Capenb:	Block 1			; Saved Capabilities
Pc1:	Block 1			; Pc Save Location For Psi Code
Pc2:	Block 1
Pc3:	Block 1
Levtab:	Pc1
	Pc2
	Pc3
Chntab:	2,,Conect		; Connect Initiate On Level 2
	1,,Timout		; Timeout Psi On Level 1
	Xlist			; Nothing Else
	Repeat ^d34,<Exp 0>
	List
Vmail::	Reset%
	Move P,[-Stklen,,Stack]
	Move T1,[Sixbit /Vmail/]
	Move T2,[Sixbit /Vmail/]
;	Setsn%			; Declare Our Name For Statistics
;	 Jfcl

	MOVX T1,GJ%SHT!GJ%PHY	;find mailer flags, physical-only please
	HRROI T2,[ASCIZ /SYSTEM:DECNET-MAILER.FLAGS.1;P777777/]
	GTJFN%
	 Jerr<Can't find SYSTEM:DECNET-MAILER.FLAGS.1>
	MOVX T2,<440000,,0>!OF%RD!OF%WR!OF%THW
	OPENF%			;open thawed (so updates OK)
	 Jerr<Can't OPENF PS:<SYSTEM>DECNET-MAILER.FLAGS>
	MOVEM T1,FLGJFN		;remember handle
	HRLZ T1,T1		;from file page zero
	MOVE T2,[.FHSLF,,FLGPAG] ;to fork page FLGPAG
	MOVX T3,PM%RD!PM%WR	;read and write access
	PMAP%			;get the page in
	 jerr <Can't PMAP SYSTEM:DECNET-MAILER.FLAGS>
	Movx T1,.ndgln		; Get Local Node Name Function
	Move T2,[Point 7,Ournam]
	Movem T2,1(P)		; Put Pointer On Stack
	Movei T2,1(P)		; And Point To It
	Node%			; Get Node Name
	 Jerr <Can'T Get Local Node Name>

	Movx T1,.fhslf		; This Process
	Move T2,[Levtab,,Chntab]
	Sir%			; Init Psi System
	Eir%
	Call Opnlog		; Open Log File
	Movem T1,Logjfn		; Save Jfn
	Call Dtstmp		; Time Stamp It
	Herald \.ver,\.edt
	Log< On Node >
;	Tmsg < On Node >
;	Hrroi T1,Ournam
;	Psout
;	Tmsg <
;>
	Hrroi T1,Ournam
	Call Logmsg
	Call Lgcrlf		; Crlf To Log File
Vmail0:	Call Opnlsn		; Open Connection And Set Interrupt Up
	Move T1,Logjfn		; Close Log File For Perusers
	Closf%
	 Jfcl
	Wait%			; For Connect Initiate
;Here When Connection Initiated

Conect:	Move P,[-Stklen,,Stack]	; Reset Stack
	Call Timeit		; Time This Guy
	Call Opnlog		; Open Log File
	Movem T1,Logjfn
	Call Dtstmp		; Time Stamp This Transaction
	Log <----Connect From >
	Debug <----Connect From >
	Call T4nhst		; Type Foreign Host Name At Log File
	Call Lgcrlf		; Log A Crlf

	Clrbuf Subbuf,Natmbf

	Move T1,Netjfn		; Accept Connection
	Movx T2,.mocc
	Setzb T3,T4		; No Additional Data
	Mtopr%
	 Jerr <Couldn'T Accept Net Connection>
def:	move t1,netjfn
	MOVEI T2,.MORLS		;GET LINK STATUS
	MTOPR%
	 JERR <Couldn't get link status after accepting a connection>
	txne t3,mo%con		;is the link connected?
	jrst abc		;yes
	movei t1,^d1000
	disms%
	jrst def
abc:	Movx T1,.hpelp		; Elapsed Time Since System Startup
	Hptim%			; Snarf It
	 Jerr <Hptim Failed>
	Movem T1,Ntime		; Remember Time This Reception Started
	Call Parse		; Parse The Mail
	 Jrst Errxit		; Failed, Quit Now
	Call Dtstmp		; Time Stamp Log
	Log <Message From >
	Hrroi T1,Frmbuf		; Sender'S Name
	Call Logmsg		; Log It
	Log < Received >
	Call Lgcrlf
	Call Lstats		; Log Statistics
	Call Mailit		; Send The Mail Off
	 Die <Failure Returned From Mailit>

Errxit:	Call Clznet		; Close And Reopen Net Link
	Call Cncltm		; Cancel Timeout Request
	Call Dtstmp
	Log <----Connection Closed

>
	Move T1,Logjfn
	Closf%			; Close Log File For Perusers
	 Jfcl
	Debrk%			; Return To Background
; Parse Mail Received.  Place Sender Name In Frmbuf, Recipient Directory
; Numbers In Ulist, Terminated With A Zero Entry
; Headers Must Appear In The Following Order.
;			From, To, Cc
; Returns +1: Failure
;	  +2: Success
;
;PROGRAM FLOW DESCRIPTION NOT ALL ITEMS IN FLOW ARE IN THIS ROUTINE BUT
;IT DOES REPRESENT THE PROCEDURE TO SEND TO A VAX WHICH IS WHY IT IS
;INCLUDED HERE
;
;	RECEIVE FROM FIELD FROM VAX
;	PARSE FROM FIELD CONVERTING IT TO MS TYPE FIELD IN FRMBUF
;	REPEAT UNTIL NULL RECEIVED
;	:  RECEIVE A RECIPIENT NAME FOR VERIFICATION
;	:  IF NULL RECEIVED
;	:  :  THEN
;	:  :  :  EXIT REPEAT LOOP
;	:  ENDIF
;	:  PARSE USER NAME AND NODE
;	:  IF NODE SAME AS THIS NODE
;	:  :  THEN
;	:  :  :  IF USER IS ON THIS SYSTEM
;	:  :  :  :  THEN
;	:  :  :  :  :  SEND SUCCESS CODE TO VAX
;	:  :  :  :  :  PUT USER NUMBER INTO ULIST
;	:  :  :  :  ELSE
;	:  :  :  :  :  SEND FAILURE CODE TO VAX
;	:  :  :  :  :  SEND ERROR MESSAGE TO VAX
;	:  :  :  :  :  SEND NULL TERMINATING ERROR MESSAGE TO VAX
;	:  :  :  :  :  RETURN FROM ROUTINE
;	:  :  :  ENDIF
;	:  :  ELSE
;	:  :  :  SEND SUCCESS TO VAX (MESSAGE WILL BE QUEUED)
;	:  :  :  PUT -1 INTO ULIST
;	:  :  :  PUT NODE NAME INTO NODLST
;	:  ENDIF
;	END REPEAT
;	RECEIVE TO FIELD FROM VAX
;	PARSE TO FIELD CONVERTING IT TO MS TYPE FIELD IN TOOBUF
;	RECEIVE SUBJECT FIELD FROM VAX
;	BEGIN FORMATING MESSAGE INTO MS TYPE MESSAGE
;	REPEAT UNTIL NULL RECEIVED
;	:  RECEIVE A LINE FROM VAX
;	:  IF NULL RECEIVED
;	:  :  THEN
;	:  :  :  EXIT REPEAT LOOP
;	:  ENDIF
;	:  OUTPUT TO MS MESSAGE BUFFER
;	END REPEAT
;	REPEAT UNTIL NULL DETECTED
;	:  GET FIRST ITEM IN ULIST
;	:  IF FIRST ITEM IN ULIST = -1
;	:  :  THEN
;	:  :  :  GET NODE FROM NODLST
;	:  :  :  PUT MAIL INTO FILE FOR DMAILR
;	:  :  :  SET FLAG IN DECNET-FLAGS SO FILE GETS SENT
;	:  :  ELSE
;	:  :  :  PUT MAIL INTO USERS MAIL FILE
;	:  :  :  SPLAT OBNOXIOUS MESSAGE ACCRESS USERS SCREEN
;	:  ENDIF
;	:  IF NO ERROR
;	:  :  THEN
;	:  :  :  SEND POSITIVE ACKNOWLEDGEMENT TO VAX
;	:  :  ELSE
;	:  :  :  SEND NEGATIVE ACKNOWLEDGEMENT TO VAX
;	:  :  :  SEND ERROR MESSAGE TO VAX
;	:  :  :  SEND NULL TERMINATOR TO VAX
;	:  ENDIF
;	END REPEAT
;	RETURN +2

Parse:	Clrbuf Frmnam,Nfrmbf

	Move  T1,Netjfn			; Save It
	Movei T2,.morss			; Read Max Record Size
	Mtopr%
	 JERR <Failed to read record size with MTOPR in PARSE>
	Nrecord <Frmnam>,<Nfrmbf*5-1>	; Read From Field

	Hrroi T1,Temp1			; Setup Default Host
	Hrroi T2,Hstnam
	Setzb T3,T4
	Sout%
	Hrroi T1,Frmbuf			;Parse from field, results to FRMBUF
	Move  T2,[Point 7,Frmnam]
	Call  Prsnam

	Setzm Toobuf		; Clear first location of TOOBUF
	Hrroi T1,Toobuf		; Setup pointer to TOOBUF
	Movem T1,Tooptr
	Movei T1,2		; Setup count of recipients per line in TOOBUF
	Movem T1,Toocnt
	Movei T1,^D100		; Setup TBLUK table for PRSUSR
	Movem T1,Nodtab
	Movsi P1,-^D100		; Maximum Of 100 Names In List

Parse3:	Clrbuf Atmbuf,Natmbf	; Clear receive area
	Nrecord <Atmbuf>,<Natmbf*5-1> ; Receive recipient from VAX
	Skipn Atmbuf		; Skip if not end of list
	Jrst  Parse6		;   End of recipient list
	Call  Prsusr		; Parse recipient
	 Jrst [ Call Dtstmp		; None Found, Complain
		Vaxerr <%network Mail Error : No Such User >
		Log <%network Mail Error : No Such User >
		Hrroi T1,Atmbuf		; Also Log Losing Name
		Call Logmsg
		Call Lgcrlf
		Ret]			; Failure Return
	Movem T1,Ulist(P1)	; Save number returned for mailing
	Vaxsuccess		; Send VAX the success code
	Aobjn P1,Parse3		; Jump if not too many recipients

	Call Dtstmp		; Woops, Too Many
	Hrroi T1,Atmbuf		; Also Tell Log File
	Call Logmsg
	Call Lgcrlf
	Ret			; Failure return

Parse6:	Setzm Ulist(P1)		; Tie Off Recipient List

;
; Now Get Mailed To Field With Node Name And Subject
;

	Clrbuf Atmbuf,Natmbf
	Nrecord <Atmbuf>,<Natmbf*5-1>
	Nrecord <Subbuf>,<Natmbf*5-1>

; Now Conbine It All Into Bigbuf

	Setzm Bytcnt
	Hrroi T1,Bigbuf
	Hrroi T2,[Asciz /Date: /]
	Setzb T3,T4
	Sout%
	Seto  T2,
	Movsi T3,(Ot%4yr!Ot%spa!Ot%nco!Ot%nsc!Ot%scl!Ot%tmz)
	Odtim%

	Hrroi T2,[Asciz/
From: /]
	Setzb T3,T4
	Sout%

	Hrroi T2,Frmbuf
	Setzb T3,T4
	Sout%

	Hrroi T2,[Asciz/
To: /]
	Setzb T3,T4
	Sout%

	Hrroi T2,Toobuf
	Setzb T3,T4
	Sout%

	Hrroi T2,[Asciz/
Subject: /]
	Setzb T3,T4
	Sout%

	Hrroi T2,Subbuf
	Setzb T3,T4
	Sout%

	Hrroi T2,[Asciz/
Mailed to: /]
	Setzb T3,T4
	Sout%

	Hrroi T2,Atmbuf
	Setzb T3,T4
	Sout%

	Hrroi T2,[Asciz/
 
/]
	Setzb T3,T4
	Sout%

	Move  T5,T1

Repeat:	Clrbuf Temp1,Tmplen	; Clear storage area
	Nrecord <Temp1>,<Tmplen*5-1> ; Get a message line from the VAX
	CAMN T3,[-<TMPLEN*5-1>]	;WAS IT A BLANK LINE?
	 Jrst Crlf		; Yes, output CRLF
	Skipn Temp1		; End of message ?
	 Jrst Done		; Yes
	Move  T1,T5		; Output message line to BIGBUF
	Hrroi T2,Temp1
	Setzb T3,T4
	Sout%
	Move  T5,T1
Crlf:	Move  T1,T5		; Output CRLF to BIGBUF
	Hrroi T2,[Asciz/
/]
	Setzb T3,T4
	Sout%
	Move  T5,T1
	Jrst Repeat

Done:	Move  T1,T5		; Close off message
	Hrroi T2,[Asciz/    --------
/]
	Setzb T3,T4
	Sout%

	Call Gtbfsz		; Get Buffer Size Into Bigbug
	Debug <
>
	Debstr <Bigbuf>

	Retskp			; All Done!
;
;Store Size Of Bigbuf Into Bytcnt
;

Gtbfsz:	Setz  T3,
	Setz  T2,
	Move  T1,[Point 7,Bigbuf]
Geta:	Ildb  T2,T1
	Jumpe T2,Go
	Addi  T3,1
	Jrst  Geta
Go:	Movem T3,Bytcnt
	Jrst  R
;Routine to parse a node and user name and convert it to a TOPS-20
;string compatable with MS
;
;CALL:
;	T1     = STRING POINTER TO THE DESTINATION
;	T2     = STRING POINTER TO FIELD RECEIVED
;	CALL PRSNAM
;
;VARIABLES RETURNED ON SUCCESSFUL COMPLETION
;	DESTINATION CONTAINS THE MS STRING
;	TEMP1  = HOST
;	TEMP2  = USER NAME
;	T1     = UPDATED STRING POINTER
;
;RETURNS:
;	+1 ALWAYS

PRSNAM:
	ACVAR  <SPTR,DPTR>		; STORAGE FOR SOURCE/DEST. POINTERS
	MOVEM T1,DPTR			; SAVE DESTINATION POINTER
	MOVEM T2,SPTR			; SAVE SOURCE POINTER
PRSNM1:	MOVE  T1,[POINT 7,TEMP2]	; GET POINTER TO WHERE TO STORE STRING
PRSNM2:	ILDB  T3,SPTR			; GET CHARACTER
	JUMPE T3,PRSNMD			; NULL, DONE
	CAIN  T3,":"			; END OF NODE SPECIFIER
	JRST  [ ILDB  T3,SPTR		; YES, EAT NEXT COLON
		SETZ  T3,		; TERMINATE STRING
		IDPB  T3,T1
		HRROI T1,TEMP1		; UPDATE ORIGINATING HOST
		HRROI T2,TEMP2
		SETZB T3,T4
		SOUT
		JRST  PRSNM1 ]
	IDPB  T3,T1			; SAVE CHARACTER IN TEMP2
	JRST  PRSNM2

PRSNMD:	IDPB  T3,T1			; TERMINATE STRING
	MOVE  T1,DPTR			; BUILD STRING IN DESTINATION BUFFER
	HRROI T2,TEMP2			; OUTPUT USER NAME
	SETZB T3,T4
	SOUT%
	HRROI T2,[ASCIZ/ AT /]		; OUTPUT SEPARATOR
	SOUT%
	HRROI T2,TEMP1			; OUTPUT NODE NAME
	SOUT%
	RET				; SUCCESS RETURN
;Routine to parse addressing of VAX mail and build TO string in TOOBUF
;
;CALL:
;	ATMBUF = ADDRESS STRING RECEIVED FROM THE VAX
;	CALL PRSUSR
;
;VARIABLES RETURNED ON SUCCESS:
;	TEMP1  = NODE OF RECIPIENT
;	TEMP2  = NAME OF RECIPIENT
;	T1     = USER NUMBER IF ON CURRENT NODE OR
;		 TBLUK ENTRY IF ON A REMOTE NODE OR
;		 -1 IF ON A REMOTE NODE ALREADY RECEIVEING MESSAGE
;
;RETURNS:
;	+1: ERROR, MAIL WAS ADDRESSED TO THIS NODE AND USER WAS UNKNOWN
;	+2: OK, ALL RETURNED VARIABLES VALID

PRSUSR:
	ACVAR <PRSTMP>		; TEMPORARY STORAGE
	MOVE  T1,TOOPTR		; GET POINTER TO TOOBUF
	SKIPN TOOBUF		; SKIP IF TOOBUF NOT EMPTY
	JRST  PRSUS1
	SOSN  TOOCNT		; SUBTRACT FROM COUNT/LINE - SKIP IF .NE. 0
	JRST  [ HRROI T2,[ASCIZ/,
    /]				; START A NEW LINE
		SETZB T3,T4
		SOUT%
		MOVEI T2,3	; RESET COUNT OF USERS PER LINE IN TOOBUF
		MOVEM T2,TOOCNT
		JRST  PRSUS1 ]
	HRROI T2,[ASCIZ/, /]	; OUTPUT SEPARATOR
	SETZB T3,T4
	SOUT%

PRSUS1:	MOVEM T1,TOOPTR		; SAVE STRING DESTINATION POINTER
	HRROI T1,TEMP1			; SETUP DEFAULT HOST
	HRROI T2,OURNAM
	SETZB T3,T4
	SOUT%
	MOVE  T1,TOOPTR		; GET DESTINATION POINTER
	MOVE  T2,[POINT 7,ATMBUF] ; GET POINTER IN INPUT STRING
	CALL  PRSNAM		; GET TOPS-20 MS STRING
	MOVEM T1,TOOPTR		; SAVE POINTER TO TOOBUF

	HRROI T1,OURNAM		; GET POINTER TO THIS SYSTEMS NODE NAME
	HRROI T2,TEMP1		; GET HOST NAME FROM FIELD
	STCMP%			; IS MESSAGE FOR THIS HOST ?
	JUMPE T1,PRSUS2		; JUMP IF FOR THIS HOST

;MAIL IS FOR A REMOTE HOST.  SETUP TO QUEUE MESSAGE.

	MOVEI T1,NODTAB		; GET START OF NODE TABLE
	HRROI T2,TEMP1		; GET NODE SENDING TO
	TBLUK%			; IS MAIL ALREADY BEING QUEUE TO THIS NODE ?
	TXNE  T2,TL%EXM		;   SKIP IF NOT
	JRST  [ SETO T1,	;   YES, RETURN FLAG SAYING SO
		RETSKP ]	;     AND GIVE SUCCESS RETURN

	HLRZ  T2,NODTAB		; CREATE ADDRESS TO STORE NODE STRING
	ASH   T2,1
	MOVEI PRSTMP,NODSTR(T2)	; SAVE ADDRESS OF NODE STRING

	HRRO  T1,PRSTMP		; PUT NODE NAME INTO NODE STRING TABLE
	HRROI T2,TEMP1
	SETZB T3,T4
	SOUT%
	
	MOVEI T1,NODTAB		; ADD ENTRY TO NODTAB FOR TBLUK
	HRLZ  T2,PRSTMP
	TBADD%			; ADD IT IN
	RETSKP			; RETURN ADDRESS OF TBLUK ENTRY

;MAIL IS FOR THIS SYSTEM.  CHECK TO SEE IF USER NAME IS VALID.

PRSUS2:	HRROI T2,TEMP2		; POINT TO USER NAME STRING
	MOVX  T1,RC%EMO		; EXACT MATCH ONLY
	RCUSR%			; IS THIS USER NAME VALID ?
	 ERJMP R		; NO, ERROR
	TXNE  T1,RC%NOM		; SKIP IF USERNAME FOUND
	 RET			; NO SUCH USER - ERROR
	MOVE  T1,T3		; RETURN DIRECTORY NUMBER IN T1
	RETSKP			; RETURN SUCCESS
; Here To Actually Append The Mail To Users' Mail.txt Files
; Also Type Annoying Message On Their Terminal If They'Re Logged In

; Returns +1: Problems Of Some Sort
;	  +2: Ok

Mailit:	Hrroi T1,Frmmsg		; Build Annoying Msg To Splat Across Screems
	Hrroi T2,[Asciz /
[You Have Netmail From /]
	Setzb T3,T4
	Sout%
	Hrroi T2,Frmbuf		; Name Of Sender
	Sout%
	Hrroi T2,[Asciz/ At /]
	Setz  T3,
	Sout%
	Seto  T2,
	Move  T3,[Ot%nda!Ot%12h!Ot%nsc!Ot%scl]
	Odtim%
	Hrroi T2,[Asciz /]
/]
	Setz  T3,
	Sout%
	Setzb P1,P2		; Init Index And Failure Flag

Mailt1:	Move  T1,Ulist(P1)	; Get Next Recipient
	Jumpe T1,Mailt5		; End Of List
	Aoje  T1,Mailt2		; Jump if already queued
	Sos   T1
	Call  Sendit		; Use Code Stolen From Mailer To Do It
	 Jrst Mailt3		; Send failure
Mailt2:	Vaxsuccess
	Aoja  P1,Mailt1

Mailt3:	Seto  P2,		; Remember That A Failure Occured
	Hrroi T1,Temp1		; Build error string for VAX
	Hrroi T2,[Asciz/%SNDERR - Unable to send message to /]
	Sout%
	Skipl T2,Ulist(P1)	; Get dirnum/pointer
	 Jrst [ Hlro  T2,0(T2)
		Sout%
		Jrst  Mailt4 ]
	Dirst%
	 Jerr <Dirst Failure>

Mailt4:	Move  T1,Netjfn		; Send failure code to VAX
	Hrroi T2,[Asciz//]
	Movni T3,4
	Setz  T4,
	Sout%
	 jerr <Error sending failure code on the logical link>
	Hrroi T2,Temp1		; Output error string
	Setzb T3,T4
	Sout%
	 jerr <Error sending failure code on the logical link>
	Hrroi T2,[0]
	Movni T3,1
	Setz  T4,
	Soutr%
	 jerr <Error sending failure code on the logical link>
	Aoja  P1,Mailt1

Mailt5:	Skipe P2		; Any Problems?
	Jrst  Rskp		; Yes, Don'T Log Success Then
	Skipn P1		; Anything Sent?
	Jrst [  Call Dtstmp		; Yes, Loc Lack Of Local Users
		Log <No Local Electronic Recipients>
		Call Lgcrlf
		Jrst .+1]
	Call  Dtstmp		; log success
	Log   <sent OK>
	Call  Lgcrlf		; CRLF the log file
	Retskp
; Append Mail To User'S Mail File
; Call With User Number Of Recipient In T1

Sendit:	Acvar <W6>
	Stkvar <<Getsiz,2>,Eofptr,Usrno,Dirnum>
	Movem T1,Usrno		; Save Recipients User Number
	Skipl Usrno		; Forwarded Mail?
	 Jrst Quefil		; Yes, queue mail to remote host
	Hrroi T1,Filnam		; Where To Build Filespec String
	Hrroi T2,[Asciz /Ps:</]	; Prefix
	Setzb T3,T4
	Sout%
	 Jerr <Sout Failed At Sendit>
	Move  W6,T1		; Preserve String Pointer
	Call Dtstmp		; Time Stamp Log File
	Hrroi T1,[Asciz /Sending To /]
	Call  Logmsg
	Move  T1,Logjfn		; Write Username To Log File
	Move  T2,Usrno		;  ..
	Dirst%
	 Jerr <Dirst Failure To Log File>
	Call  Lgcrlf		; Crlf To The Log File
	Move  T1,W6		; Restore String Pointer
	Move  T2,Usrno		; Get User Number
	Dirst%			; Add User Name
	 Jerr <Dirst Failure>
	Hrroi T2,[Asciz />Mail.txt/]
	Setzb T3,T4
	Sout%
	 Jerr <Sout Failed At Sendr 2>
	Movx  T1,Gj%sht!Gj%del+1
	Hrroi T2,Filnam		; Where Filespec Lives
	Gtjfn%
	 Jerr <Can'T Gtjfn Mail.txt>
	Movei W6,^D40		; Number Of 1/2 Sec. Intervals To Wait
;	Jrst Sendt1
Sendt1:	Move  T2,[070000,,300000]
	Move  T3,T1		; Preserve Jfn In Case Openf Loses
	Openf%
	 Erjmp [Cain T1,Opnx9		; Message File Busy?
		Sojge W6,[Movei T1,^D500	; Yes, If Not Too Long
			Disms			; Wait 1/2 Second
			Move T1,T3		; Restore Jfn
			Jrst Sendt1]		; And Retry Openf
		Call Dtstmp
		Ret]			;Failure Return
	Move  T2,[2,,.fbbyv]	; Get 2 Words
	Movei T3,Getsiz		; Where To Get It
	Gtfdb%			; Read File Data
	Load  T3,Fb%bsz,Getsiz	; Get File Byte Size
	Cain  T3,7		; Already Have 7-Bit Byte Count?
	Jrst [  Move T2,1+Getsiz	; Yes, Fetch It
		Jrst Sendt2]		; Skip Fancy Gyrations
	Movei T2,44		; No, Get Bits Per Word
	Idivi T2,0(T3)		; Compute Total Bytes Per Word
	Exch  T2,1+Getsiz		; Get Bytes In B
	Idiv  T2,1+Getsiz		; Compute Words
	Imuli T2,5		; Now Compute # Of Characters
Sendt2:	Movem T2,Eofptr		; Save It
	Sfptr%			; Set To Eof
	 Jfcl

	Call  Capoff		; Disable Caps, So Quota Is Checked
	Setom T2		; Get Date And Time
	Movsi T3,(Ot%tmz)	; In This Form
	Odtim%
	 Erjmp Ovrqta		; Error
	Movei T2,","
	Bout%			; Separate Time From Count
	 Erjmp Ovrqta		; Error
	Rfptr%			; Read Position In File
	 Jfcl
	Addi  T2,6		; At Least 6 Digits For Count
	Idivi T2,5		; Get Part Of Word In C
	Movns T3		; Get Negitive Remainder
	Addi  T3,5+6		; Get Width Of Count Field
	Hrl   T3,T3		; Get In Right Position For Nout
	Txo   T3,No%lfl!No%zro	; Put In Leading Zeros
	Move  T2,Bytcnt		; Number Of Chars
	Hrri  T3,12		; In Decimal
	Nout%
	 Erjmp Ovrqta		; Error
	Hrroi T2,[Asciz /;000000000000
/]
	Movei T3,0		; Put On The Flag Field
	Sout%
	 Erjmp Ovrqta		; Error
	Move  T2,[Point 7,Bigbuf]
	Movn  T3,Bytcnt		; Get Negative Byte Count
	Sout%
	 Erjmp Ovrqta		; Error
	Call  Capon		; Enable Again
	Call  Updfil		; Update File Pages
	Hrli  T1,.fbctl		; Change Status Bits
	Movx  T2,Fb%del		; Change Deleted Bit
	Setz  T3,		; Make It A Zero(Undelete)
	Txo   T1,Cf%nud		; Don'T Update Dir (Sfust/Closf Will)
	Chfdb%			; Do It
	Movx  T2,Fb%prm		; Change Permanent Bit
	Movx  T3,Fb%prm		; To Be Set
	Chfdb%
	Movei T1,(T1)		; Jfn Only
	Move  W6,T1		; preserve JFN
	Hrroi T1,Temp1		; where to put string
	Call  Quote		; move ctrl-V'ed "from" string to TEMP1
	Move  T1,W6		; restore JFN
	Hrli  T1,.sflwr		;set last writer
	Hrroi T2,Temp1		;sender string
	Sfust%
	 Jerr <Sfust Failure>
	Movei T1,(T1)		; Jfn Only
	Closf%			;Close The Output File
	 Jfcl

	Setz  W6,		; Init Job Number For Scan
Topdir:	Movei T1,0(W6)		; Job Number
	Move  T2,[-<.jicpj-.jitno+1>,,Gtinf] ; Get Values From Monitor
	Movei T3,.jitno		; Get Term # And Logged In Dir
	Getji%			; Get Them
	 Erjmp [Cain T1,Gtjix3	; Out Of Range?
		Jrst Rskp	; Yes, All Done -- Success Return
		Aoja W6,Topdir]	; No. Do Next One Then
	Skipl <.jicpj-.jitno>+Gtinf ; Is This A Pty?
	Aoja  W6,Topdir		; Yes. Skip It Then
	Dmove T1,Gtinf		; Get Getji Data In Regs
	Jumpl T1,[Aoja W6,Topdir] ; If Detached, Go On.
	Came  T2,Usrno		; Is This Logged Into The Same Dir?
	Aoja  W6,Topdir		; No. Skip It Then
	Tro   T1,(1b0)		; Make It A Device Designator
	Rfmod%			; Get Mode Bits
	Txne  T2,Tt%dam		; Is He In Ascii?
	Txnn  T2,Tt%alk		; Is He Accepting?
	Aoja  W6,Topdir		; No. Don'T Tell Him Then
	Movei T2,.mornt		; See If He Wants Messages
	Mtopr%
	Jumpn T3,Incdir		; Jump If No Message
	Hrroi T2,Frmmsg		; Get Message Block
	Ttmsg%			; Send To This User
Incdir:	Aoja  W6,Topdir		; Do All Jobs

;Sending to a remote host.

Quefil:	Seto  T1,		; Build file name string for forwarding
	Hrroi T2,Dirnum		; Results to DIRNUM
	Movei T3,17
	Getji%
	 Jerr <Getji Failure>
	Hrroi T1,Filnam
	Move  T2,Dirnum		; Get name of login directory
	Dirst%
	 Jerr <Dirst Failure>
	Hrroi T2,[Asciz/[--Decnet-Mail--]./]
	Setzb T3,T4
	Sout%
	Move  T2,Usrno		; Output host message is being forwarded to
	Hlro  T2,0(T2)
	Sout%
	Hrroi T2,[Asciz/.-1/]
	Setzb T3,T4
	Sout%
	Call  Dtstmp		; Time Stamp Log File
	Hrroi T1,[Asciz / Forwarding Mail To /]
	Call  Logmsg
	Move  T2,Usrno
	Hlro  T1,0(T2)
	Call  Logmsg
	Call  Lgcrlf
	Movx  T1,<Gj%sht!Gj%new> ; Get jfn of queue file
	Hrroi T2,Filnam
	Gtjfn%
	 Jerr <Can't Gtjfn to forward message>
	Movx  T2,<Fld(7,Of%bsz)+Of%rd+Of%wr> ; Open queue file
	Openf%
	 Jerr <Can't Openf to forward message>
	Call  Capoff		; Disable Caps, So Quota Is Checked

	Move  T2,[Point 7,Bigbuf] ; Shove message into queue file
	Movn  T3,Bytcnt		; Get negative byte count
	Sout%
	 Erjmp Ovrqta
	Call  Capon		; Enable Again

	Hrli  T1,.fbbyv		; Set generation retention count to zero
	Txo   T1,Cf%nud		; Don't update disk yet
	Movx  T2,Fb%ret
	Setz  T3,
	Chfdb%

	Hrli  T1,.fbbyv		; Set file byte size
	Txo   T1,Cf%nud		; Don't update disk yet
	Movx  T2,Fb%bsz
	Movx  T3,<Fld(7,Fb%bsz)>
	Chfdb%

	Hrli  T1,.fbsiz		; Set file byte count
	Seto  T2,
	Move  T3,Bytcnt
	Chfdb%

	Hrrzi T1,(T1)		; Jfn only
	Closf%			; Close the output file
	 Jfcl

	MOVE T4,[IORM T3,FLGADR(T1)] ; light it (in case not lit now)
	HRRZ T1,DIRNUM		;get directory number
	IDIVI T1,^D36		;get word number in DECNET-MAILER.FLAGS
	MOVSI T3,400000		;bit zero
	MOVN T2,T2		;negate bit number
	LSH T3,(T2)		;position bit correctly
	XCT T4			; light or clear it appropriately
	RETSKP			;all done
;Here to copy (and quote) "from" string into area pointed to by T1
; Quotes all characters (to save trouble of checking need for it)

QUOTE:	MOVE T2,[POINT 7,FRMBUF]
	TLC T1,-1		; lh of byte pointer all ones?
	TLCN T1,-1		;  ..
	HRLI T1,(POINT 7,)	; yes, make real byte pointer
	MOVEI T4,<24*5>-1	; maximum characters allowed in string
QUOTE1:	MOVEI T3,""		; quote character
	IDPB T3,T1		; stuff it
	ILDB T3,T2		; next char of source string
	IDPB T3,T1		; stuff it
	JUMPE T3,[MOVNI T2,1		; if zero, back up over last ctrl-V
		ADJBP T2,T1		;  ..
		DPB T3,T1		; wipe it out with null
		RET]			; and return
	SOJGE T4,QUOTE1		; insure no overflow
	DIE <QUOTE overflow>
;Routine To Force Write Of Pages Just Written In Case Of Crash
;Call:  T1/Jfn
;Return +1: Always

Updfil:	Rfbsz%			; Get Byte Size
	 Jfcl
	Movei T3,^D36		; Bits In A Word
	Idivi T3,(T2)		; Compute Bytes In A Word
	Movem T3,Temp2		; Save For Later
	Rfptr%			; Get Eof Pointer
	 Jfcl
	Idiv  T2,T3		; Compute Words In File
	Skipn T3		; Even Number Of Words?
	Subi  T2,1		; Yes, Don'T Cross Over To Nonex. Page
	Move  T3,Eofptr		; Get Original Eof Pointer
	Idiv  T3,Temp2		; Compute Original Word Count
	Lsh   T2,-^D9		; Compute Page Number Just Written
	Lsh   T3,-^D9		; Compute Original Last Page Number
	Move  T4,T2		; Copy Page No. Just Written
	Subi  T4,(T3)		; Pages Written
	Addi  T4,1		; Plus One For Partial Page
	Hrlzs T1		; Jfn In Lh For Ufpgs
	Hrri  T1,(T3)		; First Page To Update
	Movei T2,(T4)		; Page Count
	Txo   T2,Uf%now		; Don'T Block
	Ufpgs%			; Write These Pages To Disk
	 Jerr <Ufpgs Failure>
	Hlrzs T1		; Restore T1 To Good State
	Ret			;  And Return
;Here On Quota Error

;	T1/ Jfn

Ovrqta:	Call  Capon		; Re-Enable Caps
	Rfbsz%			; Get Current Byte Size
	 Jfcl
	Movei T3,^D36		; Compute Bytes Per Word
	Idivi T3,(T2)		;  ..
	Movem T3,Temp2		; Save
	Rfptr%			; Get Current Eof Pointer
	 Jfcl
	Idiv  T2,Temp2		; Compute Words
	Lsh   T2,-11		; Make It A Page Number
	Move  T3,Eofptr		; Get Original Pointer
	Idiv  T3,Temp2		; Compute Word Number
	Lsh   T3,-11		; Get Page Number
	Sub   T2,T3		; Compute No. Of Pages Added
	Jumpe T2,Ovrqt2		; If None Added, All Set
	Exch  T3,T2		; Put Count In Proper Register
	Txo   T3,1b0		; Repeat Count For Pmap
	Hrl   T2,T1
	Addi  T2,1		; Starting Page
	Setom T1
	Pmap%			; Zap The File Pages
	Hlrz  T1,T2		; Jfn Again

;Extra Pages Now Deleted.  Set Byte Count In Fdb

Ovrqt2:	Hrli  T1,.fbbyv		; Word Containing Byte Size
	Movx  T2,Fb%bsz		; Set Byte Size
	Movx  T3,Fld(7,Fb%bsz)	;  To 7 Bits
	Chfdb%			; If Failed, Quit Now
	 Erjmp Ovrqt0
	Hrli  T1,.fbsiz		; Set Size Of File
	Seto  T2,		;  Entire Word
	Move  T3,Eofptr		;  To Original Count
	Chfdb%			; Zap
	 Jfcl
Ovrqt0:	Closf%			; Close The File
	 Jfcl
	Call  Dtstmp		; Pretty Up The Log File
	Move  T1,Logjfn
	Dirst%
	 Jerr <Dirst Failure>
	Ret
;Open Log File

Opnlog:	Movx  T1,Gj%sht		; Try Logical Name First
	Hrroi T2,[Asciz /Decnet-Log:Vmail.log/]
	Gtjfn%
	 Ercal [Movx  T1,Gj%sht	; Failed, Write Onto System:
		Hrroi T2,[Asciz /System:Vmail.log/]
		Gtjfn
		 Erjmp Opnerr
		Ret]
	Movx  T2,<070000,,0>+Of%app
	Openf%			; Open For Append
	 Erjmp Opnerr
	Hrrz  T1,T1		; Return Jfn Only
	Ret

Opnerr:	Hrroi T1,[Asciz /Vmail: Can'T Open Log File Because: /]
	Esout%
	Movx  T1,.priou
	Hrloi T2,.fhslf
	Erstr%
	 Jfcl
	 Jfcl
	Jrst Fatal

;Time Stamp Log File

Dtstmp:	Move  T1,Logjfn
	Seto  T2,		; Current Time
	Setz  T3,		; Default Format
	Odtim%
	 Erjmp [Hrroi T1,[Asciz /Vmail: Odtim Failed: /]
		Esout%
		Movx  T1,.priou
		Hrloi T2,.fhslf
		Erstr%
		 Jfcl
		 Jfcl
		Tmsg <
Dtstmp Called From >
		Movx  T1,.priou		; Type Pc Of Caller On Terminal
		Hrrz  T2,(P)
		Movx  T3,^D8		; In Octal
		Nout%
		 Jfcl
		Jrst  Fatal]		; Go Fire Up The World Again
	Movei T2," "		; Space
	Bout%
	Ret
;Write Asciz String Pointed To By T1 To Log File

Logmsg:	Move  T2,T1		; Copy String Pointer
	Move  T1,Logjfn
	Setzb T3,T4
	Sout%
	 Jerr <Can'T Write To Log File>
	Move  T1,T2
	Ret


;Crlf To Log File

Lgcrlf:	Move  T1,Logjfn
	Movei T2,15
	Bout%
	 Jerr <Can'T Write To Log File>
	Movei T2,12
	Bout%
	 Jerr <Can'T Write To Log File>
	Ret


;Write Statistics To Log File

Lstats:	Stkvar<Elptm0>
;	Move  T1,Logjfn
;	Move  T2,Elptim		; Elapsed Time For Mail Receipt
;	Fltr  T2,T2		; Flost It
;	Fdvr  T2,[100000.0]	; Compute Seconds
;	Movx  T3,<1b1+Fl%one+Fl%pnt+3b23+3b29>
;	Flout%			; Type Seconds
;	 Erjmp [Haltf]		; Never Happens
;	Movem T2,Elptm0		; Save Time
;	Log < Seconds, >
	Log < : >
	Move  T1,Logjfn
	Move  T2,Bytcnt		; Byte Count
	Movx  T3,^D10		; Base 10
	Nout%
	 Erjmp [Haltf]
	Log < Chars
>
;	Move  T1,Logjfn
;	Fltr  T2,Bytcnt		; Float Byte Count
;	Fdvr  T2,Elptm0		; Compute Bytes Per Second
;	Movx  T3,<1b1+Fl%one+Fl%pnt+5b23+3b29>
;	Flout%
;	 Jerr <Flout Failure
;	Log < Chars/Sec/
;>
	Ret
;Close Net Connection And Reopen It.  Re-Enable For Interrupts
; On Connect Initiate Messages

Clznet:	Move  T1,Netjfn		; Normal Close
	Closf%
	 jrst [move t1,netjfn
		txo t1,cz%abt
		closf%
		 jerr <Abort close failed at CLZNET>
		jrst .+1]
	Call  Opnlsn		; Open Connection Again
	Ret			; Return

;Open The Net Connection And Listen For Connect Initiates

Opnlsn:	Movx  T1,Gj%sht
	Hrroi T2,[Asciz /Srv:27/]	 ; Magic Number For Vax Mail Server
	Gtjfn%
	 Jerr <Can'T Get Net Jfn For Server>
	Movx  T2,Of%rd!Of%wr!<070000,,0> ; 7-Bit Bytes
	Openf%
	 Jerr <Can'T Open Net Jfn>
	Movem T1,Netjfn
	Movx  T2,.moacn		; Enable For Psi On Network Transitions
	Movx  T3,0b8+<.mocia>B17+<.mocia>B26 ; Channel Zero
	Mtopr%
	Movx  T1,.fhslf
	Movx  T2,1b0		; Activate Channel Zero
	Aic%
	Ret


;Log Name Of Foreign Host

T4nhst:	Setzm Hstnam		; Zero This String
	Setzm 1+Hstnam		;  ..
	Move  T1,Netjfn		; Get Net Jfn
	Movx  T2,.morhn		; Return Host Name
	Hrroi T3,Hstnam		; Where To Put It
	Mtopr%
	 Erjmp [Hrroi T1,[Asciz /Unknown-Host/]
		Call  Logmsg
		Ret]		; Log Confusion
	Hrroi T1,Hstnam		; Copy Name To Log File
	Skipe Dbugsw
	 Psout%
	Hrroi T1,Hstnam		; Copy Name To Log File
	Call  Logmsg		;  ..
	Ret
;Set Up To Time Out If Network Too Slow

Timeit:	Move  T1,[.fhslf,,.timel]
	Move  T2,[Timen]		; Milliseconds To Allow
	Movei T3,1		; Channel One
	Timer%
	 Jerr <Can'T Time Myself>
	Movx  T1,.fhslf		; Activate Timer Channel
	Movx  T2,<1b1>
	Aic%
	Ret

;Cancel Above Timer Request

Cncltm:	Move  T1,[.fhslf,,.timal] ; Remove All Pending Timer Requests
	Movei T3,1		; For This Channel
	Timer%
	 Jerr <Can'T Remove Pending Timer Request>
	Ret


;Here On Timeout

Timout:
;	Call Dtstmp
	DIE <Timeout Occured>
;Here If Net Link Dies While Outputting To It

Dmplnk:	Cis			; Zap Things
	Call  Lgcrlf		; Log A Crlf
	Movx  T1,Cz%abt		; Abort The Net Jfn
	Hrr   T1,Netjfn		;  ..
	Closf%			;  ..
	 Jfcl			; Don'T Care
	Call  Dtstmp
	Log <----Connection Aborted

>
	Movx  T1,.fhslf		; Deactivate Connect Initiate Channel
	Movx  T2,<1b0>		;  ..
	Dic%			;  ..
	Call  Cncltm		; Cancel Pending Timer Requests
	Move  T1,Logjfn		; Close Log File
	Closf%
	 Jfcl
	Jrst  Vmail0		; Go Wait For New Mail


;Here On Fatal Wipeout (Jsys Which Can'T Fail Does, For Instance)

Fatal:	Movx  T1,.fhslf
	Dir%			; Disbale Interrupts
	Cis%			; Clear Interrupts
	Move  T1,Netjfn		; Type A Record To Force Net Buffers Out
	Hrroi T2,[Asciz /
?Vmail Internal Error/]
	Setzb T3,T4		; Add Question Mark So Mail Isn'T Requeued
	Soutr%			;  ..
	 Erjmp .+1
	Movei T1,^D5000		; Wait Five Seconds
	Disms%
	Movx  T1,.fhslf		; Abort All Jfns
	Clzff%			;  ..
	Call  Opnlog		; Reopen Log File
	Movem T1,Logjfn
	Call  Lgcrlf
	Call  Dtstmp
	Log <Error Restart...
>
	Tmsg <Vmail Error Restart...
>
	MOVE T1,LOGJFN
	CLOSF
	 JFCL
	Movei T1,^D5000		; Wait Some More
	Disms%
	Jrst Vmail		; And Fire Up The World Again

;Disable Capabilities So Quota-Checking Happens

Capoff:	Push  P,T1		; Don'T Clobber
	Movx  T1,.fhslf		; Get My Caps
	Rpcap%
	Movem T3,Capenb		; Remember For Later
	Setz  T3,		; No Caps At All
	Epcap%
	Pop   P,T1		; Restore
	Ret


;Re-Enable Caps

Capon:	Push  P,T1		; No Clobberage
	Movx  T1,.fhslf
	Move  T3,Capenb		; Caps We Had Before
	Epcap%
	Pop   P,T1
	Ret


	End Vmail