Trailing-Edge
-
PDP-10 Archives
-
BB-KL11M-BM_1990
-
t20src/smtsen.mac
There are 21 other files named smtsen.mac in the archive. Click here to see a list.
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1989.
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
; TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
; CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
; SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
TITLE SENDER - SMTP Sender
TWOSEG
RELOC 400000
;Call with the address of the work request and the common info block address
; on the stack. Returns the status in T1 and in the work request.
SEARCH MACSYM
EXTERN DB%VD8,NODNAM,UF%CLO,UN%OPE,ER%PRC
EXTERN UF%OPE,UF%REA,UM%GET,UM%REL,UN%CLO,UN%REA,UN%WRI,MXERRS
EXTERN S2$ERR,MG$MFC,NMLDIE,LOG ;[321]
INTERN SMTPSN
FTLOG==0
;Various offsets and values for MX data structures
.DESTN==3
.FILSP==1
.POST==1
.SENDR==2
.RECNM==0
.RECTY==1
.RECLE==2
.RECTX==3
.PKTYP==0
.PKID==1
.PKSEQ==2
.PKSTS==3
.PKRCT==4
;AC's
F==0
T1==1
T2==2
T3==3
T4==4
T5==5
T6==6
CONBLK==7 ;ADDRESS OF A CONNECT BLOCK
CMNBLK==10 ;ADDRESS OF COMMON INFO BLOCK
WRKREQ==11 ;ADDRESS OF WORK REQUEST BLOCK
RCPTPT==12 ;POINTER TO NODENAME
;DO NOT USE 13
DECNET==14 ;DECNET LINK NUMBER
;DO NOT USE 15
VR==16 ;POINTER TO VARIABLE SPACE
P==17
;FLAGS
F.N421==1B0 ;IF NOT TRAPPING THE 421 RESPONSE
F.NOTS==1B1 ;NOT SURE IF SMTP YET
;WHAT TO TELL MX WHEN THE TRANSACTION'S DONE (OR DEAD)
.NOOBJ==-2 ;NO MX AT REMOTE NODE
.DONE==2 ;POSTED THERE, WE CAN DROP THE REQUEST
.RETRY==3 ;RETRY LATER, THEY HAD PROBLEMS
.FAIL==5 ;THEY CAN'T HANDLE THIS AT ALL, COMPLAIN
;OFFSETS INTO BLOCK OF INFORMATION AT VR
TMPPTR==0 ;POINTER TO TEMP. STRING SPACE
CMDPTR==1 ;POINTER TO COMMAND TO SEND
GIVFRM==2 ;POINTER TO GIVEN "FROM" STRING
MSGPTR==3 ;POINTER INTO CMDPTR, REAL TEXT TO SEND
FRMPTR==4 ;FROM STRING
TXTPTR==5 ;TEXT FROM LISTENER
TXTLEN==6 ;LENGTH OF TEXT
FILE==7 ;FILE NUMBER, 0 MEANS TEXT ISN'T FROM A FILE
OUTCNT==10 ;CHARACTERS IN OUTPUT BUFFER
SAVAC==11 ;SPACE FOR AC SAVES FOR BLISS
N%VAR=11+4+1 ;NUMBER OF VARIABLES NEEDED
MAXOUT==^D1300
MAXSTR==^D1000
CONLEN==^D64 ;LENGTH OF A CONNECT BLOCK
IDMSK==77777777 ;MASK FOR NEW ID FIELD
define logger(txt),<
IFN FTLOG,<
CALL [PUSH P,[ -1,,[ASCIZ/
********** txt
/]]
call logers
adjsp p,-1
RET]
> >
define logget(addr),<
IFN FTLOG,<
CALL [PUSH P,addr
call logers
adjsp p,-1
RET]
> >
IFN FTLOG,<
logers: PUSH P,T1
PUSH P,T2
MOVX T1,GJ%SHT+GJ%OLD
HRROI T2,[ASCIZ/MX:SMTSEN.LOG/]
GTJFN%
ERJMP NOLOGR
MOVX T2,OF%APP+7B5
OPENF%
ERJMPS NOLOGX
PUSH P,T3
SETZ T3,
move t2,-4(p)
sout%
erjmps .+1
pop p,T3
nologx: closf%
erjmps .+1
nologr: pop p,t2
pop p,t1
ret
>
;SAVE MANY AC'S AT START
SMTPSN: MOVE T2,P ;FRAME POINTER OF SORTS
PUSH P,0
PUSH P,6 ;SAVE ACS FOR BLISS
PUSH P,7
PUSH P,10
PUSH P,11
PUSH P,12
PUSH P,14
PUSH P,16
MOVE WRKREQ,-2(T2) ;FETCH WORK REQUEST
MOVE T1,[-1000]
MOVEM T1,5(WRKREQ) ;set "impossible" value in status word
MOVE CMNBLK,-1(T2) ;CALLER PASSES COMMON BLOCK ADDRESS
PUSH P,[N%VAR] ;GET VARIABLE SPACE
CALL UM%GET
ADJSP P,-1
SKIPN VR,T1 ;STORE POINTERS TO VARIABLES
CALL NOMEME ;NO MEMORY??
SETZB DECNET,FILE(VR) ;NO FILE YET, NO LINK
SETZB F,CONBLK ;NO FLAGS ON YET
PUSH P,[<SENMEM=CONLEN+3*<MAXSTR/5+1>+<MAXOUT/5+1>+1>]
CALL SVACSE
CALL UM%GET
CALL RSACSE
ADJSP P,-1
SKIPN CONBLK,T1
CALL NOMEME
ADD T1,[POINT 7,CONLEN] ;SET UP STRING SPACE AND POINTERS
MOVEM T1,TXTPTR(VR)
ADDI T1,MAXOUT/5+1
MOVEM T1,CMDPTR(VR)
ADDI T1,MAXSTR/5+1
MOVEM T1,FRMPTR(VR)
ADDI T1,MAXSTR/5+1
MOVEM T1,TMPPTR(VR)
logger <SMTSEN starting up...>
HLRZ RCPTPT,4(WRKREQ) ;GET SENDER
JUMPE RCPTPT,DONE ;NO SENDERS! THAT WAS EASY...
HLRZ T1,(CMNBLK) ;POINTER TO FILENAME
LDB T2,[POINT 7,(T1),6] ;SNAG FIRST CHARACTER OF FILENAME
CAIN T2,";" ;IS IT NOT A FILENAME?
JRST SEND1 ;YES, THIS IS SEND, NOT MAIL
HRLI T1,(POINT 7) ;MAKE A BP
PUSH P,T1 ;STORE FILENAME
PUSH P,[1] ;STORE READ REQUEST
PUSH P,[0] ;DON'T WANT ERROR INFO
CALL SVACSE
CALL UF%OPE ;OPEN IT
CALL RSACSE
ADJSP P,-3 ;TOSS ARGS
JUMPLE T1,DONE ;NO FILE? WE ARE DONE..
MOVEM T1,FILE(VR)
SEND1: HRRZ T4,1(CMNBLK) ;GET "FROM" STRING
HRLI T4,(POINT 7) ;PREPARE TO SCAN IT
MOVEM T4,GIVFRM(VR) ;STORE STRING POINTER AT GIVFRM
SCANAT: ILDB T2,T4 ;LOOK FOR "@" OR <NUL>
JUMPE T2,NOATSI ;NO "@", SO JUST A USER NAME
CAIE T2,"@"
JRST SCANAT ;KEEP LOOKING
SKIPA T5,TMPPTR(VR)
FNDENN: IDPB T2,T5
ILDB T2,T4 ;LOOK FOR NODENAME TERMINATIOR
CAIE T2,","
CAIN T2,":"
TDZA T2,T2
JUMPN T2,FNDENN
IDPB T2,T5
PUSH P,TMPPTR(VR) ;SET UP TO VALIDATE FIRST NODE SEEN
PUSH P,[1]
PUSH P,[-1]
CALL SVACSE
CALL DB%VD8
CALL RSACSE
ADJSP P,-3
JUMPE T1,OURNDE ;0 IF IT WAS A LOCAL NODE
MOVEI T3,"@" ;NOT LOCAL (OR NOT KNOWN)
MOVE T2,FRMPTR(VR) ;SO PREPEND @OURNAME {,|:} TO STRING
IDPB T3,T2 ;BUILD "@" + OURNODENAME
MOVE T1,[POINT 7,NODNAM]
CALL CSTRB
MOVE T4,GIVFRM(VR) ;POINT TO FIRST CHAR OF GIVEN FROM
MOVE T1,T4 ;WILL WANT THIS SOON
ILDB T5,T4 ;WHAT IS IT? @ OR USERNAME?
MOVEI T3,":" ;ASSUME FIRST ADDITION
CAIN T5,"@" ;@ MEANS ALREADY FORWARDED...
MOVEI T3,"," ;SO USE , INSTEAD
IDPB T3,T2 ;PUT CHARACTER IN
CALL CSTR ;FINISH BUILDING THS STRING
JRST GOTFRM ;OK, GOT THE FROM STRING
OURNDE: MOVE T1,GIVFRM(VR) ;OUR NODE, JUST COPY IT VERBATIM
MOVE T2,FRMPTR(VR)
CALL CSTR
JRST GOTFRM
NOATSI: MOVE T2,FRMPTR(VR) ;JUST A USER NAME, COPY IT
MOVE T1,GIVFRM(VR)
CALL CSTRB
MOVEI T3,"@" ;AND ADD @OURNODENAME
IDPB T3,T2
MOVE T1,[POINT 7,NODNAM]
CALL CSTR
GOTFRM:
HRRZ T2,4(WRKREQ) ;POINTER TO NODE TO CONNECT TO
HRLI T2,(POINT 8)
MOVEM T2,0(CONBLK) ;STORE TO WHERE STRING WILL GO
IBP T2
IBP T2 ;SKIP 2 NULLS
ILDB T4,T2 ;FETCH LENGTH
MOVEM T4,1(CONBLK) ;STORE
SETZM 2(CONBLK) ;CLEAR EVERYTHING ELSE
MOVSI T1,2(CONBLK) ;..
HRRI T1,3(CONBLK) ;..
BLT T1,CONLEN-1(CONBLK) ;..
;
;SET UP A SOURCE TASK NAME IN CB_TASK
;
MOVE T1,[POINT 7,[ASCII /MX-SENDER/]] ;Who we are
MOVEM T1,3(CONBLK)
MOVEI T1,^D9 ;LENGTH OF ABOVE TASK NAME
MOVEM T1,4(CONBLK)
;
;SET UP A TARGET TASK NAME IN CB_DESCRIPTOR
;
MOVE T1,[POINT 7,[ASCII /MX-LISTENER/]] ;Who we want to talk to
MOVEM T1,15(CONBLK)
MOVEI T1,^D11 ;LENGTH OF ABOVE TASK NAME
MOVEM T1,16(CONBLK)
PUSH P,[2] ;CONNECT TYPE 2, SOURCE
PUSH P,CONBLK
PUSH P,[0]
PUSH P,[0]
PUSH P,[0]
CALL SVACSE
CALL UN%OPEN ;HELLO, REMOTE MX
CALL RSACSE
ADJSP P,-5
SKIPG DECNET,T1 ;GOT LINK?
JRST NOSMTP ;NO...
TXO F,F.NOTS ;NOT SURE IF SMTP LISTENER YET...
;Here we will wait for the destination to send us "220", meaning "Yes,
; I am a SMTP listener and I am alive". We JRST to DNTINR with T2
; pointing to a vector of 5 possible addresses, which we jump to
; according to the response we get: 1xx, 2xx, 3xx, 4xx, 5xx. The actual
; response code ends up in T1. If we get total garbage, we go straight
; to BADRSP.
MOVEI T2,[EXP RETRY,MAYBE,RETRY,RETRY,RETRY]
JRST DNTINR ;GET SOME INPUT AND DISPATCH
MAYBE: CAIE T1,^D220 ;PROPER STARTUP MESSAGE?
JRST RETRY ;NO, BAG IT
SETZ T4, ;YES, RESPOND
TXZ F,F.NOTS ;OK, IT IS CERTAINLY SMTP
HRROI T1,[ASCIZ/HELO /] ;SO BUILD HELO COMMAND
MOVE T2,CMDPTR(VR)
CALL CSTRB
MOVE T1,[POINT 7,NODNAM] ;"HELO <nodename> READY"
CALL CSTRB
HRROI T1,[ASCIZ/ Ready
/]
CALL CSTR
MOVE T1,CMDPTR(VR) ;T1/BP, T2/ DISPATCH VECTOR, T4/ LENGTH
;We expect a "250", anything else causes a RSET and we'll tell MX to try
; again later
MOVEI T2,[EXP RSTRTY,HELOOK,RSTRTY,RSTRTY,RSTRTX]
JRST OUTCMD ;AND SEND AND DISPATCH ON RESPONSE
RSTRTX: logger <Protocol error on Startup>
PUSH P,[[ASCIZ/SMTSEN: Protocol error on startup/]]
PUSH P,[0] ;[318]Push a 0 for "id"
CALL LOG
ADJSP P,-2 ;[318]Adjust the stack accordingly.
;HERE TO RESET AND GO TO RETRY (IE, WE GOT TOLD WE CAN'T GO ON NOW)
RSTRTY: HRROI T1,[ASCIZ/RSET
/]
MOVEI T4,6 ;LENGTH IS 6 CHARS
MOVEI T2,[EXP 0,RETRY] ;ALWAYS GO TO RETRY
;A DISPATCH VERTOR OF THE FOPRM 0,ADDR MEANS ALWAYS GO TO ADDR ON ANY NUMERIC
; RESPONSE
JRST OUTCMD ;SEND THE RSET
;BUILD A "MAIL FROM:" COMMAND
HELOOK: SETZ T4,
HRROI T1,[ASCIZ/MAIL FROM:/]
SKIPN FILE(VR) ;IS THIS A SEND COMMAND?
HRROI T1,[ASCIZ/SEZZ FROM:/] ;YUP
MOVE T2,CMDPTR(VR)
CALL CSTRB
MOVE T1,FRMPTR(VR) ;GET FROM STRING
CALL CSTRB
HRROI T1,CRLF ;TERMINATE PROPERLY
CALL CSTR
MOVE T1,CMDPTR(VR)
MOVEI T2,[EXP RSTRTY,DORECV,RSTRTY,RSTRTY,RSTRTY]
JRST OUTCMD
DORECV: SETZ T6, ;COUNT "OK" RECIPIENTS
RECEIL: SETZ T4, ;COUNT STRING LENGTH
HRROI T1,[ASCIZ/RCPT TO:</]
MOVE T2,CMDPTR(VR)
CALL CSTRB
HLRO T1,(RCPTPT)
CALL CSTRB
HRROI T1,[ASCIZ/>
/]
CALL CSTR ;STRING IS ENCLOSED IN <>
;1xx, 3xx and 4xx imply Try Again Later; 2xx is OK; 5xx is Sorry Not Here
MOVEI T2,[EXP RSTRTY,ACCPT,RSTRTY,RSTRTY,FLUNK]
MOVE T1,CMDPTR(VR) ;SEND WHAT WE BUILT
JRST OUTCMD
;Format up a complaint message. This mail can't be delivered.
FLUNK:: MOVEI T1,1(P)
PUSH P,[6]
PUSH P,[1B3+0B17+1B18+<S2$ERR>B32+4B35] ;[318]
MOVE T3,3(CMNBLK)
AND T3,[IDMSK]
PUSH P,T3
PUSH P,[0,,2] ;[318]
HLR T3,(RCPTPT) ;[321]
HRLI T3,(POINT 7) ;[321]
PUSH P,T3 ;[321]
PUSH P,TXTPTR(VR)
PUSH P,[0] ;[318]
PUSH P,T1
CALL ER%PRC
ADJSP P,-8
logger <At FLUNK, username not allowed at remote>
JRST SKIPON ;OK, TRY TO DELIVER TO TNE NEXT RECPIENT
ACCPT: ADDI T6,1 ;ACCEPTED, COUNT ANOTHER GOOD ONE
SKIPON: HRRZ RCPTPT,(RCPTPT) ;GET NEXT USER
JUMPN RCPTPT,RECEIL ;IF THERE IS ONE, GO BACK AND HANDLE
JUMPE T6,NOSEND ;GOT *ANY* GOOD USERS?
HRROI T1,[ASCIZ/DATA
/]
MOVEI T4,6 ;YES. SEND THE "DATA" COMMAND
;ALLOW 2xx and 3xx (354 is the correct value)
MOVEI T2,[EXP RSTRTY,DATAGO,DATAGO,RSTRTY,RSTRTY]
JRST OUTCMD
;Here to read the message file and ship it over, adding any "."s at the
;beginning of lines that require them.
DATAGO: SETO T6, ;SAY AT THE BEGINNING OF A LINE
SETZM OUTCNT(VR) ;NO CHARACTERS IN OUT BUFFER YET
MOVE T1,CMDPTR(VR) ;INIT OUT BUFFER POINTER
MOVEM T1,MSGPTR(VR) ;..
logger <Shoving DATA out...>
FILLBF: SKIPE T1,FILE(VR)
JRST NORMML ;NORMAIL MAIL
HLRZ T3,(CMNBLK) ;GET THE POINTER TO THE MESSAGE
HRLI T3,(POINT 7,0,6);..
LDB T2,T3 ;GET THAT FIRST CHARACTER
CAIE T2,";" ;ALREADY DONE THIS?
JRST [MOVEI T2,";"
DPB T2,T3 ;YES, REPAIR STRING..
JRST EOFFIL] ;AND LEAVE
MOVEI T2,"!" ;CHANGE THE STRING BRIEFLY
DPB T2,T3 ;SO WE KNOW WE DID IT.
SETZ T4, ;WE NEED THE STRING LENGTH
MOVE T1,T3
CNTSND: ILDB T2,T1
CAIN T2,.CHLFD ;LINEFEED IS THE LAST CHARACTER
AOJA T4,GCHARM ;COUNT IT AND LEAVE
JUMPE T2,GCHARM ;IN CASE OF WIERDNESS
AOJA T4,CNTSND
NORMML: PUSH P,FILE(VR) ;READ A BUFFER FROM THE FILE
PUSH P,TMPPTR(VR)
PUSH P,[MAXOUT] ;BIG CHUNK
PUSH P,[0]
CALL SVACSE
CALL UF%REA ;THIS READS SINGLE LINES, SADLY
CALL RSACSE
ADJSP P,-4
SKIPN T4,T1 ;GET COUNT INTO T4
JRST EOFFIL ;0 MEANS EOF, GO EMPTY OUTPUT BUFFER, ETC.
JUMPL T4,FREAK ;FILE ERROR? SERIOUS STUFF
MOVE T3,TMPPTR(VR) ;GET POINTER TO INPUT BUFFER
GCHARM: SOJL T4,FILLBF ;COUNT OFF A CHARACTER; IF NONE, REFIL BUFFER
ILDB T1,T3 ;GRAB OUR CHARACTER
CAIN T1,.CHLFD ;LINE ENDING?
JRST [SETO T6, ;FLAG: NEXT CHARACTER STARTS A NEW LINE
JRST WRICHR] ;GO OUTPUT IT
NORCHR: JUMPE T6,WRICHR ;ARE WE STARTING A LINE?
CAIE T1,"." ;YES. DO WE WANT TO SEND A DOT?
WRICH0: TDZA T6,T6 ;NO. HERE TO SEND A REGULAR CHARACTER
MOVEI T6,1 ;HERE TO SEND DOUBLED DOT
WRICHR: IDPB T1,MSGPTR(VR) ;OUTPUT THE CHARACTER
AOS T2,OUTCNT(VR) ;ANOTHER ONE IN..
CAIGE T2,MAXOUT-^D135 ;BUFFER GETTING FULL?
JRST CHKREP ;NO, FINISH STORE OF CHARACTER
JUMPL T6,DUMPIT ;YES, IF WE JUST READ A <LF> GO DUMP BUFFER
;We endeavour to send buffers that end on a line boundary, just for neatness.
;If we can't, though, we don't.
CAIGE T2,MAXOUT-1 ;IS BUFFER *VERY* FULL?
JRST CHKREP ;NO, KEEP GOING (HOPING FOR A <LF>)
DUMPIT: CALL DUMPDT ;DUMP THE BUFFER OVER THE WIRE
JRST FAILED ;UH-OH
CHKREP: JUMPLE T6,GCHARM ;IF T6 .LE. 0, GET NEXT CHARACTER
MOVEI T1,"." ;ELSE, SEND ANOTHER DOT
JRST WRICH0 ;AND THEN GET NEXT CHARACTER
DUMPDT: MOVE T1,CMDPTR(VR) ;SEND TEXT REF'D BY T1
EXCH T4,OUTCNT(VR) ;SAVE T4. T4 NOW HAS NUMBER OF CHARS TO DUMP
CAIG T4,0 ;ARE THERE ANY?
SKIPA T1,[1] ;NO, FAKE A GOOD RETURN
CALL DTNOUT ;YES, SEND THEM
MOVE T4,OUTCNT(VR) ;RESTORE T4
MOVE T2,CMDPTR(VR) ;SET UP A NEW OUTPUT BUFFER POINTER
MOVEM T2,MSGPTR(VR) ;..
SETZM OUTCNT(VR) ;AND SAY "EMPTY"
TRNE T1,1 ;WAS THE OUTPUT OK?
AOS (P) ;SKIP IF OK
RET ;UH-OH
;FILE CORRUPTION. SAY WE CAN'T DELIVER
FREAK: PUSH P,[[ ;Push address of complaint string
ASCIZ/ SMTSEN: File corruption in outgoing mail, aborting/]]
PUSH P,[0] ;[318]
CALL LOG
ADJSP P,-2 ;[318]
logger <At FREAK, file corruption>
MOVEI T1,1(P)
PUSH P,[4]
PUSH P,[1B3+0B17+1B18+<MG$MFC>B32+4B35] ;[318]
MOVE T3,3(CMNBLK)
AND T3,[IDMSK]
PUSH P,T3
PUSH P,[0]
PUSH P,[0]
PUSH P,T1
CALL ER%PRC
ADJSP P,-6
JRST FAILED ;AND ABORT THIS MESS
;Reached EOF. Send the contents of the output buffer, and then send the
; termination sequence (.<CR> AFTER A <LF>)
EOFFIL: CALL DUMPDT ;DUMP WHAT WE HAVE
JRST FAILED
JUMPL T6,FINMSG ;LAST CHARACTER SHOULD HAVE BEEN A <LF>
logger <Last character wasn't a CRLF, sending an extra LF>
MOVEI T1,.CHLFD ;REALLY! WELL, SEND ONE NOW..
IDPB T1,MSGPTR(VR)
AOS OUTCNT(VR)
CALL DUMPDT
JRST FAILED
FINMSG: HRROI T1,[BYTE(7) ".", .CHCRT, .CHLFD] ;TERMINATED STRING
MOVEI T4,3 ;LENGTH OF 3
MOVEI T2,[EXP NOSEND,DONE,NOSEND,NOSEND,NOSEND]
logger <Dumping dot terminator>
JRST OUTCMD
;HERE IF WE GET A FAIL RETURN
NOSEND: HRROI T1,[ASCIZ/RSET
/]
MOVEI T4,6 ;6 CHARS
MOVEI T2,[EXP 0,FAILED]
logger <Got to NOSEND!>
JRST OUTCMD
;OUTCMD should be jrst'd to, not called.
; It sends a string and waits for a response, and dispatches according
; to the given address vector on the response.
;T1/ STRING POINTER (CAN BE -1,,ADDR)
;T2/ ADDRESS VECTOR (5 ADDRESSES, OR EXP 0,ONLY-RETURN-ADDRESS)
;T4/ NUMBER OF CHARACTERS TO SEND
;F/ F.N421 IF LIT, PASS 421 TO CALLER (DON'T TRAP IT)
; May not return (on a bad response). If it returns, T1 contains the
; response value.
OUTCMD: CALL DTNOUT
TRNN T1,1
JRST HUNGUP
;JRST DNTINR
;DNTINR - takes dispatch vector in T2. Reads in a line, checks it for
; sanity, and dispatches accoring to T2, with T1/ number read.
DNTINR: CALL DNTIN
MOVE T1,TXTPTR(VR) ;GET POINTER TO TEXT
SETZ T3,
DECCHK: ILDB T4,T1
CAIL T4,"0"
CAILE T4,"9"
JRST CHKVCM
IMULI T3,^D10
ADDI T3,-"0"(T4)
CAIG T3,^D599 ;IF ALREADY OUT OF RANGE, GIVE UP
JRST DECCHK
JRST BADRSP
CHKVCM: CAIGE T3,^D100
JRST BADRSP ;IF TOO SMALL, NO GOOD
MOVE T1,T3 ;SAVE VALUE FOR CALLER
TXNE F,F.N421 ;LOOKING FOR A 421 RESPONSE?
JRST PASSIT ;WE SHOULD PASS IT BACK
CAIN T1,^D421 ;TRAP THEM. IS THIS ONE?
JRST FADING ;YES. THE LISTENER IS RUNNING OUT OF TIME
PASSIT: IDIVI T3,^D100 ;GET FIRST DIGIT IN T3
SKIPN (T2) ;IS THIS A SPECIAL LIST?
JRST @1(T2) ;YES, JUMP TO SECOND ADDRESS
ADDI T2,-1(T3) ;ADD ONE LESS TO ADDRESS IN T2
JRST @(T2) ;GO TO ADDRESS FOR THAT RESPONSE
FADING: MOVEI T2,[EXP 0,HUNGUP]
TXO F,F.N421 ;SEND HIM QUIT, AND ON ANY RESPONSE, HANGUP
HRROI T1,[ASCIZ/QUIT
/]
MOVEI T4,6
JRST OUTCMD
;Call with T1 as byte pointer, T4 as length of string. Returns T1/ 1 if OK
; 0 otherwise.
DTNOUT: TLC T1,-1
TLCN T1,-1
HRLI T1,(POINT 7)
PUSH P,DECNET
PUSH P,[1]
PUSH P,T4
PUSH P,T1
CALL SVACSE
CALL UN%WRI
CALL RSACSE
ADJSP P,-4
RET
;Return a null terminated string starting at TXTPTR(VR)
;On a channel death, dispatch to DIENOW (does not return)
;Must preserve T2
DNTIN: PUSH P,DECNET
PUSH P,[MAXSTR+5]
PUSH P,TXTPTR(VR)
CALL SVACSE
CALL UN%READ
CALL RSACSE
ADJSP P,-3
JUMPLE T1,NOANSW
MOVEM T1,TXTLEN(VR)
ADJBP T1,TXTPTR(VR)
SETZ T3,
IDPB T3,T1
logget TXTPTR(VR)
CPOPJ: RET
NOANSW: ADJSP P,-1 ;LOSE RETURN ADDRESS
LOGGER <Got length of 0 or less from decnet input>
JRST HUNGUP ;OTHER HUNGUP, TIME TO QUIT
BADRSP: PUSH P,[[
ASCIZ/ SMTSEN: Bad SMTP response seen, hanging up/]]
PUSH P,[0] ;[318]
CALL LOG
ADJSP P,-2 ;[318]
HUNGUP: PUSH P,DECNET
PUSH P,[0]
PUSH P,[0]
logger <Hanging up link>
CALL SVACSE
CALL UN%CLO ;DUMP DECNET LINK
CALL RSACSE
ADJSP P,-3
SETZ DECNET,
PUSH P,[[ASCIZ/SMTP(SEN): HUNGUP connection/]]
PUSH P,[0] ;[318]
CALL LOG
ADJSP P,-2 ;[318]
; JRST RETRY ;TRY AGAIN LATER
RETRY: logger <Logging retry code>
MOVX T1,.RETRY
TXZN F,F.NOTS ;MESSUP ON FIRST CONNECT?
JRST SETRES ;NO, ASSUME THEY HAVE SMTP
logger <Changed to a NO OBJECT ocde (error on first connect)>
NOSMTP: MOVX T1,.NOOBJ ;YES. HERE IF NO SMTP THERE, SAY SO
JRST SETRES
DONE: logger <Logging a DONE>
MOVX T1,.DONE
JRST SETRES
FAILED: MOVX T1,.FAIL
logger <Logging abject failure>
SETRES: MOVE T2,5(WRKREQ)
CAMN T2,[-1000]
MOVEM T1,5(WRKREQ) ;SET STATUS
JUMPLE DECNET,ENDALL ;DECNET OPEN? IF NOT, SKIP CLOSE
HRROI T1,[ASCIZ/QUIT
/]
MOVEI T4,6
MOVEI T2,[EXP 0,CLOSIT] ;TO CLOSIT IN ALL CASES
JRST OUTCMD
CLOSIT: PUSH P,DECNET
PUSH P,[0]
PUSH P,[0]
CALL SVACSE
CALL UN%CLO
CALL RSACSE
ADJSP P,-3
ENDALL: SKIPN T1,FILE(VR)
JRST NOFILE
PUSH P,T1
PUSH P,[0] ;CLOSE
PUSH P,[0] ;DON'T WANT ERROR STRING
CALL SVACSE
CALL UF%CLO
CALL RSACSE
ADJSP P,-3
NOFILE: PUSH P,CONBLK
PUSH P,[SENMEM]
CALL UM%REL
ADJSP P,-2
PUSH P,VR
PUSH P,[N%VAR]
CALL UM%REL
ADJSP P,-2
MOVE T1,5(WRKREQ) ;RETURN OK OR FAILED OR DEFERED
SENEND: POP P,16
POP P,14
POP P,12
POP P,11
POP P,10
POP P,7
POP P,6
POP P,0
RET ;RETURN TO CALLER
CSTR: CALL CSTRB
IDPB T3,T2
RET
CSTRB: TLCE T1,-1
TLCN T1,-1
HRLI T1,(POINT 7)
TLC T2,-1
TLCN T2,-1
HRLI T2,(POINT 7)
CSTRC: ILDB T3,T1
JUMPE T3,CPOPJ
IDPB T3,T2
AOJA T4,CSTRC
CRLF: ASCIZ/
/
RSACSE: DMOVE T2,SAVAC(VR)
DMOVE T4,SAVAC+2(VR)
RET
SVACSE: DMOVEM T2,SAVAC(VR)
DMOVEM T4,SAVAC+2(VR)
RET
NOMEME: PUSH P,[POINT 7,[ASCIZ/No memory at SMTSEN start up/]]
CALL NMLDIE
;NO RETURN
END