perm filename MGMSER.MID[S,NET] blob
sn#820029 filedate 1986-06-27 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00015 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 TITLE MGMSER
C00005 00003 TERMID CORBEG TERSTR NETCMP RCBINP TRBINP ECHOP SUPGAP FLSCHP MRCIBH MRCOBH GOTINT PDL COREND PUPP
C00007 00004 TPLTAB TPLMIN WDOTAB WDOMAX EXOPL
C00010 00005 DTLSER DTLSE1
C00012 00006 ARPHST CPYHST 1DIGTP NOTTIP
C00014 00007 MRCINI OPNLUP OPNRTY
C00017 00008 DILGOT NODOG LOOP
C00020 00009 NETSER NETSR1 NETSR2
C00022 00010 MRCSRV MRCSR1 MRCSR2 MRCSR3
C00023 00011 IACSER PRSTAB WHOLIN
C00025 00012 DOSR DONTSR
C00027 00013 WILLSR WONTSR
C00028 00014 OPTMSG RNDMSG SNDMSG MSGLUP SUICID DEATH
C00030 00015 DIALTB DIALEN ...LIT SVRRTS ERRTNS ERRHAN ERRINS HSTTAB NW%SU NW$BYT HSTSIX
C00032 ENDMK
C⊗;
TITLE MGMSER
SUBTTL Mark Crispin
; (This is a slightly hacked version of MRC's DTLSER.)
; Assembly switches
IFNDEF SVRSKT,SVRSKT==99. ; default listen socket
IFNDEF LOKTMO,LOKTMO==5 ; # of 15-second frobs of lock timeout
IFNDEF PDLLEN,PDLLEN==50 ; stack length
; AC definitions. 0→3 are used by NETWRK
X=4 ? A=5 ? B=6 ? C=7 ? ? D=10 ? P=17
MRC==2 ; MRC's I/O channel (NETWRK uses 0 and 1)
; Macro to send a TELNET command
DEFINE TELCMD CMDLST
OUTSTR [ASCIZ/⊗!CMDLST!*
/]
IRPS CMD,,CMDLST
MOVEI CMD
PUSHJ P,NETOCH
TERMIN
PUSHJ P,NETSND
TERMIN
; SAIL system bit definitions
INTTTY==020000,, ; TTY interrupt
INTCLK==000200,, ; clock interrupt
INTIMS==000020,, ; status change interrupt
INTINP==000010,, ; input interrupt
INTBTS==INTTTY\INTCLK\INTINP\INTIMS
;TERMID CORBEG TERSTR NETCMP RCBINP TRBINP ECHOP SUPGAP FLSCHP MRCIBH MRCOBH GOTINT PDL COREND PUPP
; Terminal location string
TERMID: 'TERMID
CORBEG==. ; start of initialized core storage
TERSTR: BLOCK 10. ; console location string
; Protocol flags
NETCMP: BLOCK 1 ; -1 → IAC in progress
IRPS OPT,,WILL WONT DO DONT
OPT!P: BLOCK 1 ; -1 → option in effect
TERMIN
RCBINP: BLOCK 1 ; -1 → receiving binary
TRBINP: BLOCK 1 ; -1 → transmitting binary
ECHOP: BLOCK 1 ; -1 → remote echoing
SUPGAP: BLOCK 1 ; -1 → suppressing GA
FLSCHP: BLOCK 1 ; -1 → flush next character
; Other storage
MRCIBH: BLOCK 3 ; MRC input buffer header
MRCOBH: BLOCK 3 ; MRC output buffer header
GOTINT: BLOCK 1 ; -1 → got an interrupt
PDL: BLOCK PDLLEN ; stack
COREND==.-1 ; end of initialized storage
PUPP: BLOCK 1 ; -1 → dog shit protocol
;TPLTAB TPLMIN WDOTAB WDOMAX EXOPL
DEFINE TPC CODE
CODE
IRPS NAME,,CODE
[ASCIZ/NAME/]
.ISTOP
TERMIN
TERMIN
; Protocol codes
TPLTAB:
TPC SE==360 ; subnegotiation end
TPC NOP==361 ; no-op
TPC DM==362 ; data mark
TPC BRK==363 ; break key
TPC IP==364 ; interrupt process
TPC AO==365 ; abort output
TPC AYT==366 ; are you there?
TPC EC==367 ; erase character
TPC EL==370 ; erase line
TPC GA==371 ; go ahead
TPC SB==372 ; subnegotiation
TPC WILL==373 ; sender will do
TPC WONT==374 ; sender won't do
TPC DO==375 ; receiver asked to do
TPC DONT==376 ; receiver must not do
TPC IAC==377 ; interpret as command
TPLMIN==400-<.-TPLTAB>
; WILL/WONT/DO/DONT codes
WDOTAB:
TPC TRNBIN==0 ; transmit binary
TPC ECHO==1 ; echo
TPC RCP==2 ; reconnect
TPC SUPRGA==3 ; suppress GA
TPC NAMS==4 ; negotiate approx. message size
TPC STATUS==5 ; status option
TPC TIMMRK==6 ; timing mark
TPC RCTE==7 ; remote controlled trans/echo
TPC NAOL==10 ; negotiate output line width
TPC NAOP==11 ; negotiate page size
TPC NAOCRD==12 ; negotiate output CR
TPC NAOHTS==13 ; negotiate output horizontal tab stops
TPC NAOHTD==14 ; negotiate output HT
TPC NAOFFD==15 ; negotiate output FF
TPC NAOVTS==16 ; negotiate output vertical tab stops
TPC NAOVTD==17 ; negotiate output VT
TPC NAOLFD==20 ; negotiate output LF
TPC EXTASC==21 ; Tovar's cretinous idea of extended ASCII
TPC LOGOUT==22 ; logout option
TPC BM==23 ; byte macro
TPC DET==24 ; data entry terminal option
TPC SUPDUP==25 ; SUPDUP (not TELNET) protocol
TPC SDOTPT==26 ; SUPDUP output option
WDOMAX==.-WDOTAB-1
EXOPL==377 ; extended options (great idea Postel)
;DTLSER DTLSE1
DTLSER: TRN
RESET
SETZM PUPP ; flag ARPA protocol
GETNAM ; get our name
HLRZS
CAIE 'PUP ; Pup server?
JRST DTLSE1
MOVSI 'PUP ; yes, set device name
MOVEM NETDEV
SETOM PUPP ; Pup protocol
DTLSE1: MOVE ['MGMSER] ; set our name
SETNAM
SETZM CORBEG ; initialize core
MOVE [CORBEG,,CORBEG+1]
BLT COREND
MOVE P,[PDL(-PDLLEN)]
MOVEI [DEBREAK ? EXIT]
MOVEM JOBAPR
CLKINT 5.*60.*60. ; must die if around too long
OUTSTR [ASCIZ/MGMSER started
/]
MOVEI SVRSKT ; listen for connection
MOVEM LSNSKT
PUSHJ P,LISTEN
MOVEI [ SETOM GOTINT ; flag an interrupt
MOVE X,JOBCNI
TLNE X,(INTINR)
OUTSTR [ASCIZ/*INR*
/]
TLNE X,(INTINS) ; INS int
OUTSTR [ASCIZ/*INS*
/]
MOVSI 1,-1 ; requeue into TQ from any queue
DISMIS 1,]
MOVEM JOBAPR ; set up server location
CLKINT 60.*5. ; start slow ticking clock
MOVSI (INTBTS)
INTENB ; turn on interrupts
MOVEI TERMID
MOVEM JOBVER
;falls through
;ARPHST CPYHST 1DIGTP NOTTIP
; drops in
SKIPN PUPP ; must hack a bit if Pup
JRST ARPHST
MOVE [NW%SU] ; get SUnet number
IORM HOST
;; MOVEI NW%SU ; get SUnet number
;; DPB [NW$BYT,,HOST] ; set network number
ARPHST: OUTSTR [ASCIZ/Connected to /]
PUSHJ P,MAPHST ; map in host table
MOVE HOST
PUSHJ P,HSTNUM ; get HDB
TRN ; sorry about errors
MOVEI A,(1) ; host name
HRLI A,440700
SKIPA X,[440700,,TERSTR]
CPYHST: IDPB B,X
ILDB B,A
JUMPN B,CPYHST
HLRZ A,1 ; pointer to system name
MOVE B,(A) ; get system name
MOVE A,FSOCKT ; and ICP socket
CAMN B,[ASCII/TIP/] ; on a TIP?
TRNE A,177774 ; just paranoia; make sure a TIP port
JRST NOTTIP
MOVEI B,"#
IDPB B,X
LSH A,-16.
IDIVI A,8. ; ports are octal
JUMPE A,1DIGTP
ADDI A,"0 ? IDPB A,X
1DIGTP: ADDI B,"0 ? IDPB B,X
NOTTIP: PUSHJ P,SETANM ; set our alias name
PUSHJ P,UNMHST ; map out the host table
OUTSTR TERSTR
OUTSTR [ASCIZ/
/]
MOVEI X,[ASCIZ\SU-AI/Geoff Metacom gateway!
Trying... \]
PUSHJ P,SNDMSG
MOVE ['MGMSER]
NAMEIN
JRST [ MOVEI X,[ASCIZ/Gateway already in use, try again later
/]
PUSHJ P,SNDMSG
JRST SUICID]
; JRST MRCINI
;MRCINI OPNLUP OPNRTY
; Initialize the MRC channel
MRCINI: IMSKCL [INTCLK] ; turn off clock interrupts
MOVSI D,-DIALEN
OPNLUP: MOVEI 410 ; char at a time image, exit from losing init
DMOVE 1,[SIXBIT/TTY/ ? MRCOBH,,MRCIBH]
HRR 1,DIALTB(D) ; try this one
OPEN MRC,
OPNRTY: JRST [ AOBJN D,OPNLUP ; try next dialer
MOVEI X,[ASCIZ/No free dialers, try again later
/]
PUSHJ P,SNDMSG
JRST SUICID]
MOVEI 7. ; 7 bit bytes
DPB [300600,,MRCIBH+1]
DPB [300600,,MRCOBH+1]
INBUF MRC,3
OUTBUF MRC,3
HLLZ 1,DIALTB(D) ; claim dialer, dialer number from D
MOVEI 1 ; pointer to block
DIAL ; claim dialer
JRST [ MOVEI X,[ASCIZ/Can't claim dialer
/]
PUSHJ P,SNDMSG
JRST SUICID]
MOVEI 1 ; pointer to block
HLLZ 1,DIALTB(D) ; dialer number
HRRI 1,2 ; dial function
DMOVE 2,[0 ? <.BYTE 4 ? 0 ? 1 ? 9 ? 6 ? 7 ? 6 ? 3 ? 8 ? 2>]
DIAL ; dial number
CAIA
JRST DILGOT
CAIE 4 ; dialing error?
JRST [ MOVEI X,[ASCIZ/Dialing failed
/]
PUSHJ P,SNDMSG
JRST SUICID]
MOVEI 1 ; pointer to block
HLLZ 1,DIALTB(D) ; dialer number
HRRI 1,1 ; status function
DIAL ; get status
JRST [ MOVEI X,[ASCIZ/Dialer status error
/]
PUSHJ P,SNDMSG
JRST SUICID]
CAIN 102 ; call failed?
JRST [ MOVEI X,[ASCIZ/Busy or no answer, try again later
/]
PUSHJ P,SNDMSG
JRST SUICID]
CAIN 107 ; off hook?
JRST OPNRTY
MOVEI X,[ASCIZ/Dialer error
/]
PUSHJ P,SNDMSG
JRST SUICID
;DILGOT NODOG LOOP
DILGOT: MOVEI 1,MRC ; which TTY we are
DEVNUM 1,
JRST SUICID ; can't happen
MOVSI 1,440000(1) ; TTYSET index, explicit TTY flag
HRRI 1,3 ; 300 baud speed
HRROI 1 ; do the TTYSET
TTYSET
IMSKST [INTCLK] ; turn on clock interrupts
MOVEI X,[ASCIZ/Open
/]
PUSHJ P,SNDMSG
; Send ARPANET protocol commands
SKIPE PUPP ; doggie?
JRST NODOG
TELCMD [IAC WILL ECHO IAC WILL SUPRGA]
NODOG: SETOM ECHOP ? SETOM SUPGAP
LOCK ; lock us in core
; Main program loop
LOOP: SKIPN GOTINT ; got an interrupt?
IMSTW [INTBTS] ; wait for one to happen
INTMSK [0] ; mask off interrupts
SETZM GOTINT
MOVEI 2 ; check connection status
MTAPE NET,
TLNN 1,(CLSS\CLSR) ; send side gronked?
TLNE 2,(CLSS\CLSR) ; receive side?
JRST [HLLZ 1,DIALTB(D) ; dialer number from D
HRRI 1,3 ; hang up dialer
MOVEI 1 ; pointer to block
DIAL ; hang the bloody thing up
TRN
JRST SUICID]
; JRST NETSER
;NETSER NETSR1 NETSR2
; ARPANET server
NETSER: PUSHJ P,NETICH ; get character from ARPANET
JRST MRCSRV ; ARPANET input buffer empty
SKIPE PUPP ; don't do this for Pup
JRST NETSR2
AOSG NETCMP ; IAC in progress?
JRST IACSER
IRPS OPT,,WILL WONT DO DONT
AOSG OPT!P
JRST OPT!SR
TERMIN
CAIN IAC ; network command?
JRST [ SETOM NETCMP ; remember that one is coming
JRST NETSER]
NETSR1: SKIPE RCBINP
JRST NETSR2
AOSN FLSCHP ; flush this character?
JRST NETSER
CAIN ↑M ; CR?
SETOM FLSCHP ; yes, flush next character
NETSR2: SOSG MRCOBH+2 ; space in buffer?
OUTPUT MRC, ; no, output the byte
IDPB MRCOBH+1 ; stuff the character in the buffer
JRST NETSER ; try for more user characters
;MRCSRV MRCSR1 MRCSR2 MRCSR3
; MRC server
MRCSRV: OUTPUT MRC, ; force the buffer out
MRCSR1: SOSLE MRCIBH+2 ; data available?
JRST MRCSR3
HRRZ 1,MRCIBH
HRRZ 1,(1)
SKIPGE (1) ; anything in further buffers?
JRST MRCSR2
TTYSKP MRC, ; anything in the monitor?
JRST [ PUSHJ P,NETSND
JRST LOOP]
MRCSR2: INPUT MRC, ; yes - get it
MRCSR3: ILDB MRCIBH+1 ; get the byte
JUMPE MRCSR1 ; ignore nulls
PUSHJ P,NETOCH ; send it to the network
JRST MRCSR1
;IACSER PRSTAB WHOLIN
; IAC server
IACSER: OUTSTR [ASCIZ/*IAC /]
CAIGE TPLMIN ; big enough?
JRST [ PUSHJ P,RNDMSG ; unknown, flush
JRST NETSER]
MOVE 1,
OUTSTR @TPLTAB-TPLMIN(1)
CAIE IAC
CAIGE WILL
OUTSTR [ASCIZ/*
/]
XCT PRSTAB-TPLMIN(1)
JRST NETSER
DEFINE NC CODE,SERVER
IFN .+TPLMIN-PRSTAB-CODE,.ERR Lossage at CODE
SERVER
TERMIN
PRSTAB: ; Protocol command server table
NC SE,[JRST NETSER]
NC NOP,[JRST NETSER]
NC DM,[JRST NETSER]
NC BRK,[JRST NETSER]
NC IP,[JRST NETSER]
NC AO,[JRST NETSER]
NC AYT,[JRST WHOLIN]
NC EC,[JRST NETSER]
NC EL,[JRST NETSER]
NC GA,[JRST NETSER]
NC SB,[JRST NETSER]
NC WILL,[SETOM WILLP]
NC WONT,[SETOM WONTP]
NC DO,[SETOM DOP]
NC DONT,[SETOM DONTP]
NC IAC,[JRST NETSR1]
; IAC AYT
WHOLIN: MOVEI X,[ASCIZ/SU-AI <==> MRC gateway is alive
/]
PUSHJ P,SNDMSG
JRST NETSER
;DOSR DONTSR
; IAC DO/DONT
DOSR: PUSHJ P,OPTMSG
CAIN TRNBIN ; binary from host
JRST [ SKIPE TRBINP ; catch protocol loops
JRST NETSER
SETOM TRBINP
TELCMD [IAC WILL TRNBIN]
JRST NETSER]
CAIN ECHO ; remote echo (what a win!)
JRST [ SKIPE ECHOP ; catch protocol loops
JRST NETSER
SETOM ECHOP
TELCMD [IAC WILL ECHO]
JRST NETSER] ; command, we always accept it
CAIN SUPRGA ; suppress GA?
JRST [ SKIPE SUPGAP ; command or reply?
JRST NETSER
SETOM SUPGAP
TELCMD [IAC WILL SUPRGA]
JRST NETSER]
; Not an option we like, refuse it
PUSH P,
OUTSTR [ASCIZ/⊗IAC WONT/]
MOVEI IAC
PUSHJ P,NETOCH
MOVEI WONT
PUSHJ P,NETOCH
POP P,
PUSHJ P,OPTMSG
PUSHJ P,NETOCH
PUSHJ P,NETSND
JRST NETSER
DONTSR: PUSHJ P,OPTMSG
CAIN TRNBIN
JRST [ SKIPN TRBINP
JRST NETSER
SETZM TRBINP
TELCMD [IAC WONT TRNBIN]
JRST NETSER]
CAIN ECHO
JRST [ SKIPN ECHOP
JRST NETSER
SETZM ECHOP ; back to lossage
TELCMD [IAC WONT ECHO]
JRST NETSER]
CAIN SUPRGA
SKIPL SUPGAP
JRST NETSER ; protocol violator
SETZM SUPGAP
TELCMD [IAC WONT SUPRGA]
JRST NETSER ; loser
;WILLSR WONTSR
; IAC WILL/WONT
WILLSR: PUSHJ P,OPTMSG
CAIN TRNBIN ; binary to host
JRST [ SKIPE RCBINP ; catch protocol loops
JRST NETSER
SETOM RCBINP
TELCMD [IAC DO TRNBIN]
JRST NETSER]
; Not an option we like, refuse it
PUSH P,
OUTSTR [ASCIZ/⊗IAC DONT/]
MOVEI IAC
PUSHJ P,NETOCH
MOVEI DONT
PUSHJ P,NETOCH
POP P,
PUSHJ P,OPTMSG
PUSHJ P,NETOCH
PUSHJ P,NETSND
JRST NETSER
WONTSR: PUSHJ P,OPTMSG
CAIN TRNBIN
SKIPN RCBINP
JRST NETSER
SETZM RCBINP
TELCMD [IAC DONT TRNBIN]
JRST NETSER
;OPTMSG RNDMSG SNDMSG MSGLUP SUICID DEATH
; Subroutines
; WILL/WONT/DO/DONT option message
OPTMSG: CAIN EXOPL
JRST [ OUTSTR [ASCIZ/ EXOPL*
/]
POPJ P,]
OUTCHR [" ]
CAILE WDOMAX
JRST RNDMSG
MOVE 1,
OUTSTR @WDOTAB(1)
OUTSTR [ASCIZ/*
/]
POPJ P,
RNDMSG: IDIVI 100 ; output the octal for an unknown message
ADDI "0
OUTCHR
IDIVI 10
ADDI 1,"0
OUTCHR 1
ADDI 2,"0
OUTCHR 2
OUTSTR [ASCIZ/*
/]
POPJ P,
; Send a message, b.p. in X
SNDMSG: TLOA X,440700 ; set up b.p.
MSGLUP: PUSHJ P,NETOCH
ILDB X
JUMPN MSGLUP ; continue until a null hit
JRST NETSND
; Here to suicide on network errors or idle timeout
SUICID: PUSHJ P,CLOSER
DEATH: RESET
EXIT
;DIALTB DIALEN ...LIT SVRRTS ERRTNS ERRHAN ERRINS HSTTAB NW%SU NW$BYT HSTSIX
DIALTB: 1,,<'3'6' >
3,,<'2'6' >
5,,<'2'4' >
DIALEN==.-DIALTB
...LIT: CONSTANTS
; Wonderful network routines
SVRRTS==-1 ; include server routines
ERRTNS==-1 ; include error routines
ERRHAN==-1 ; include automagic error handling
ERRINS==<JRST DEATH> ; error instruction
HSTTAB==-1 ; include host table magic
;; NW%SU==:44 ; SUnet
;; NW$BYT==:331100 ; byte pointer to network number
HSTSIX==-1 ; and alias name kludge
.INSRT NETWRK[S,NET]
END DTLSER