Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
mit/monitor/tttvdv.mac
There are no other files named tttvdv.mac in the archive.
;[MIT-XX]SSY:<MONITOR.NEW>TTTVDV.MAC.2, 5-Nov-83 17:45:32, Edit by BERLIN
;3051 Add TVRFIL routine to signal tvt buffer refill (from CLYNN and MRC)
;3031 Fix for supdup - cknnvt has a double skip return now!
;#473 Make monitor listen on TCP port 231
; Use DLAYPZ before OPSCA7 instead of ENC/FRCPKT (closed window problem)
;[BBNF]<BBN-5-MONITOR.TCP4>TTTVDV.MAC.2, 2-Jun-82 16:55:54, Edit by RBASCH
; Added new TVSBE1 routine, called instead of TTSOBE from OPSCAN
; and PKTZ00, to check for send-all as well as normal output
;CWL:<403-TCP>TTTVDV.MAC.40303 3-May-82 16:14:41, Edit by CLYNN
; Fix DM option after error loop bug
;<403-TCP>TTTVDV.MAC.7, 23-Apr-82 12:05:15, Edit by TAPPAN
; PREVENT TVTCOB FROM PUTTING STUFF IN THE OUTPUT BUFFER
; IF CONNECTION IS UNUSABLE
;<403-TCP>TTTVDV.MAC.6, 1-Apr-82 12:27:50, Edit by TAPPAN
; Add test of SF%NVT before starting up a TVT LISTEN
;REL5:<MNET-TCP>TTTVDV.MAC.31 7-Feb-82 17:26:05, Edit by RBASCH
;IN TVTOSP, CHECK NEW XOFF BIT TTRXF
;REL5:<MNET-TCP>TTTVDV.MAC.30 5-Feb-82 17:00:37, Edit by RBASCH
;IN TVMSNT, USE SASUBR INSTEAD OF PUSH/POP, AND JRST TO TVMSN1 INSTEAD
;OF TTMSN1 (FOR REL-5)
;<403-TCP>TTTVDV.MAC.40301 29-Jan-82 15:08:58, Edit by CLYNN
; Updated for TCP release 3
;<MNET-TCP>TTTVDV.MAC.6, 5-Jan-82 15:00:31, Edit by TAPPAN
; Release 5 fixes
;<401-TCP>TTTVDV.MAC.88, 13-Oct-81 19:05:00, Edit by CLYNN
; Fix: SNDALL with no TVTs in configuration
;<401-TCP>TTTVDV.MAC.87, 13-Oct-81 09:54:52, Edit by TAPPAN
; Change default retransmittion timeount to 1 second
;[BBNF]<401-TCP>TTTVDV.MAC.86, 14-Aug-81 15:07:00, Ed: CLYNN
; WARNING: Changes are also required to TTNTDV.MAC:
; after TMSNR1:, before SETZRO TSALP,(T2) insert SETZRO TSALC,(T2)
; after NVTDT2:, before SETZRO TSALP,(T2) insert SETZRO TSALC,(T2)
; Fix: Zero TSALC when cancelling a SNDALL, TVTOSP returns sum of
; regular & sendall buffers, TVTCLS does a listen if EFP+^D7 & no TVTL,
; Added TVSBE1 to check for sendall characters
;<401-TCP>TTTVDV.MAC.85, 17-Jul-81 12:13:53, Edit by TAPPAN
; experimental re-doing of "when-to-listen" algorithm (to
; prevent hung listening sockets)
;[BBNF]<401-TCP>TTTVDV.MAC.85, 14-Jul-81 14:33:00, Ed: CLYNN
; Fix: TCB is in INTSEC in TVTDOB, Error code for ABTCON at TVTOP9
;[BBND]<401-TCP>TTTVDV.MAC.84, 29-May-81 13:38:33, Ed: EONEIL
;CHANGED SKIPN TO SKIPL AT TVTOPR
;[BBND]<JDELSIGNORE.MONITOR>TTTVDV.MAC.4, 22-Jan-81 16:29:36, Ed: JDELSIGNORE
;REMOVED OFFSETS FOR LINE ACCOUNTING AND LINE USAGE NUMBERS 41,42
IFNDEF .TVFLG,<.TVFLG==:1>
IFN .TVFLG,< ; If supporting TCP terminals
IF1 <PRINTX IN TTTVDV PASS 1>
IF2 <PRINTX IN TTTVDV PASS 2>
IFNKA <IFNDEF %%REL,<
PRINTX % %%REL NOT SET IN PROLOG0.MAC. %%REL 50 ASSUMED.
%%REL==50
>>
IFNKA <
IFLE %%REL-40,<IFE TTNTVT-TTDMVT,<PRINTX ? TVTs require TTNTDV to be included>>
IFGE %%REL-50,<IFE .NTFLG,<PRINTX ? TVTs require TTNTDV to be included>>
> ; End of IFNKA
IFNKA < IFLE %%REL-40,< SEARCH INPAR,TCPPAR >>
IFKA < SEARCH PROLOG
TTITLE TTTVDV
> ; End of IFKA
SUBTTL TVT DEPENDENT CODE
COMMENT !
These routines support TCP Virtual Terminals, which are very similar
to ARPANET NVTs. They speak "new" TELNET protcol. TVTs are
operated by the TCP portion of the Internet fork. This fork
does the listen, etc. and there is no usermode equivalent of
NETSER. The listen is special in that it is marked as a TVT,
which means that the buffers involved are TTYSRV buffers in
monitor space and not user-supplied buffers in some user's
space. Further, no PSI are generated for buffer completions.
Allocation (window) is set by the number of bytes available in
the TTY buffers.
TVTs use the TELNET protocol through TCP connections. Most of the
TELNET code is in TTNTDV and this module uses that code.
#TVSBE1 ... 4 ...... See if send-all has any output too
#TVMSNT ... 4 ...... See if send-all should be done
* TVMNTR ... 4 ...... Clear all TVT Send-all requests
ASNTVT ... 5 ...... Assign a TCP Virtual Terminal
* TVTCSO ... 6 ...... TVT Console start output routine
#TVTDOB ... 7 ...... TVT Dismiss until output buffer empty routine
#TVTCOB ... 8 ...... TVT lear output buffer routine
* TVTNCK ... 9 ...... Check for overdue TELNET negotiations on TVTs
* SNDTVT ... 10 ...... Send bytes to TVT
* PRCTVT ... 11 ...... Process bytes received from TVT
* CHKTVT ... 12 ...... Check to see if line is a TVT
* TVTCHK ... 12 ...... Check for TVT and lock line if so.
* TVTISP ... 13 ...... Get number of holes in TVT input buffer
* TVTOSP ... 13 ...... Get number of bytes in TVT output buffer
#TVTDTS ... 15 ...... Close TCP connection upon carrier-off condition
#TVTDET ... 15 ...... Detach job from TVT
#TVTIGA ... 16 ...... Input TELNET Go-Ahead
* TVTOPR ... 17 ...... Main routine to operate TVTs
LISTEN ... 17 ...... TELNET server listen routine
* TVTOPN ... 18 ...... Handle TVT connection as it is opening
* TVTCLS ... 19 ...... Handle TVT connection as it is closing
OPSCAN ... 20 ...... Scan all TVTs for possible output
!
OPDEF %OPEN% [JSYS 742] ; 'Cause MACRO is finding CALLI nowdays
IFNKA < IFLE %%REL-40,<
;TVT VECTOR TABLE ENTRYS
RESCD
TTTVVT=.
TVTLEN ;LENGTH OF DYNAMIC DATA FOR THIS TYPE
-1 ;FIRST LINE OF THIS TYPE/-1 NO LINES
IFIW!R ;00 - INITALIZATION
IFIW!R ;01 - RESTART
IFIW!TVTCOB ;02 - CLEAR OUTPUT BUFFER
IFIW!R ;03 - SET LINE SPEED
IFIW!TTRSP2 ;04 - READ TTY SPEED
IFIW!TTSNT2 ;05 - SET NON-TERM STATUS
IFIW!TTRNT1 ;06 - READ NON-TERM STATUS
IFIW!TTSTO5 ;07 - REMOVE CHAR FROM OUTPUT BUFFER
IFIW!TVTPAR ;08 - STPAR JSYS
IFIW!R ;09 - CHECK PHYSICAL LINE
IFIW!TTXON2 ;10 - XON
IFIW!TVTDET ;11 - DEASIGN DYNAMIC DATA
ANDI T1,177 ;12 - TTY OUTPUT PARITY OFF
IFIW!TVTCSO ;13 - START OUTPUT LINE
IFIW!R ;14 - XOFF
IFIW!R ;15 - XON
IFIW!TTCQ1 ;16 - EMPTY BUFFER
IFIW!R ;17 - CARRIER ON
IFIW!TVTCOF ;18 - CARRIER OFF
IFIW!TVTDTS ;19 - HANGUP
IFIW!R ;20 - ^S
IFIW!TVC7SN ;21 - NO LOGINS
IFIW!R ;22 - STORE CHARACTER
IFIW!R ;23 - SEND CHARACTER
IFIW!TVDAL6 ;24 - DEALLOCATE LINE
IFIW!DLSSX2 ;25 - BUFFER OVERFLOW
IFIW!R ;26 - EMPTY BUFFER
IFIW!RSKP ;27 - SENDALL TO SINGLE LINE
IFIW!R ;28 - ENABLE/DISABLE DATASETS
IFIW!R ;29 - INIT
IFIW!R ;30 - CLEAR INPUT BUFFER
IFIW!TVTDOB ;31 - DOBE
IFIW!TVTIGA ;32 - INPUT GA
IFIW!TVSET1 ;33 - SET INIT. VALUES FOR A LINE
IFIW!TVSBE1 ;34 - SOBE
IFIW!TVOBE1 ;35 - WAKEUP IF OUTPUT BUFFER EMPTY
IFIW!TVMSNT ;36 - SENDALL TO SINGLE LINE
IFIW!TVMSNT ;37 - SENDALL TO ALL LINES
JFCL ;38 - ADJUST WAKEUP CLASS
IFIW!R ;39 - STOP LINE
IFIW!R ;40 - XOFF RECOGNITION
IFN <.-TTVTMX>-TTTVVT,<PRINTX %%INVALID DEVICE DEPENDENT TABLE SIZE>
>> ; End of IFLE %%REL-40 ; End of IFNKA
; TVT Block length is same as NVT:
IFNKA <TVTLEN==NVTLEN>
; Routines in TTNTDV which are suitable for TVTs:
IFKA <EXTERN NVTSTD,STADYN,LCKTTY,ULKTTY>
IFNKA < IFLE %%REL-40,<TVSET1==TTSET1>>
TVTPAR==NVTPAR
TVTCOF==NTYCOF
IFNDEF ISI,<IFKA <TVTCOF==NTYCOF>>
IFDEF ISI,<
IFKA <TVTCOF==NVTCOF>
IFKA <RCTOPT==7>
IFKA <WILOPT==10>
> ; End of IFDEF ISI
TVTCHI==TTCHI
IFKA < TTCOBN==TTCOBI
TCOBN==TCOBQ
>
IFKA < INTERN TVTCIB,TVTCOB,TVTDOB,TVTCAP,TVTDET>
IFKA <
NTTTVT==TVTHI-TVTLO+1
NVTMO==NEGTMO_^D18
>
; Structure analagous to PTNTO and PTNTI:
IF1 <IFNDEF PTVT,< ; Its also defined in TCPPAR
DEFSTR(PTVT,TTNETW,35,18) ; Holds pointer to a TVT TCB
>>
IFKA < ; Note: Some of these definitions must parallel those in MIMPDV
DEFSTR TTTYP,TTYPE,35,18 ; Terminal type
DEFSTR TCJOB,TTFORK,17,18 ; Controlling job number
DEFSTR TIMAX,TTBFRC,26,9 ; Max bytes in input buffer
DEFSTR PBRCT,TTBRKC,8,9 ; Outstanding BREAKS count
DEFSTR TTOTP,TTFLGS,0,1 ; Output active flag
DEFSTR NVSTP,TTNETW,14,3 ; Current NVT state
>
; TCP Parameters:
LSNPRT==^D101 ;#473 Port TELNET listens on
LSNTMO==^D<5*60> ; Timeout
TVTRXP==0000,,0 ; TVT Retransmission parameters
RS LSNTIM ; temp holder for time to try another listen
IFNKA <
;DOES SKIPE TTOCT(B) AND SKIPE TSALC(B) FOR TVTS
;SKIPS ONLY IF ABSOLUTELY NO CHARS TO BE HANDLED FOR LINE
;ACCEPTS DYN LINE # IN B
;RETURNS TTOCT+TSALC IN T1
TVSBE1::CALL TTSOBE
JRST TVSBE2 ;NO SKIP IF NORMAL OUTPUT TO BE DONE
OPSTR <SKIPN>,TSALC,(B) ;NO SKIP IF SENDALL TO BE DONE
RETSKP ;SKIP ONLY IF ABSOLUTELY NO CHARS
TVSBE2: OPSTR <ADD A,>,TSALC,(B)
RET ;NO-SKIP, COUNT IN A
;TVMSNT - TEST TO SEE IF SEND ALL SHOULD BE DONE
; FNCALL OFF TTVT36 One Line
; FNCALL OFF TTVT37 All Lines
;ACCEPTS:
; T2/ LINE NUMBER
;RETURNS: +1 DO NOT SEND MESSAGE
; +2 SEND MESSAGE
SWAPCD
TVMSNT: SASUBR <MSPT,MSLN,MSCT>
JUMPL T2,R ; return now if no such lines
CALL LCKTTY ;GET DYNAMIC DATA ADDRESS IF IT EXIST
JRST TVMSN1 ;NO DYNAMIC DATA DO NOT SEND
SKIPG TTNETW(T2) ;ANY CONNECTIONS?
JRST TVMSN1 ;NO DO NOT SEND MESSAGE
CALL ULKTTY ;YES UNLOCK TTY DATABASE
AOS TVTNOF ;INDICATE OUTPUT FOR TVTS
MOVE T2,MSCT ;GET COUNT OF CHARACTERS IN MESSAGE
IMULI T2,TMSNTT ;MULTIPLY BY ALLOWABLE TIME PER CHAR.
ADD T2,TODCLK ;GET TIME MESSAGE TO BE DISCARDED
MOVEM T2,TVMSTM ;SAVE TIME FOR TCP FORK
RETSKP ;SEND MESSAGE
TVMSN1: CALL ULKTTY ;UNLOCK TTY
RETBAD ;NO DO NOT SEND MESSAGE
;TVMNTR - ROUTINE TO CLEAR ALL TVT SNDALL REQUEST
;Called NOSKED from OPSCAN on TVMSTM timeout set by TVMSNT
RESCD
TVMNTR::MOVE T3,TVTPTR ;GET AOBJN COUNTER FOR TVT'S
JRST TMSNR1 ; Use code in TTNTDV
REPEAT 0,<
TMSTR1: SKIPN T2,TTACTL(T3) ;GET ADDRESS OF DYNAMIC DATA
JRST TMSTR2 ;IF NON-STANDARD BLOCK CHECK
HRRZ T2,T2 ;GET JUST ADDRESS
JE TTSAL,(T2),TMSTR2 ;IF DOING SENDALL CLEAR IT
; SETZRO TTSAL,(T2) ;ZERO SENDALL BIT
; SOS SALCNT ;DECREMENT COUNT OF LINES DOING SENDALL
; SETZRO TSALC,(T2) ;ZERO SENDALL COUNT (TVTs)
; SETZRO TSALP,(T2) ;ZERO SENDALL POINTER
CALL CLRSAL ; Interrupt-proof decrement
TMSTR2: AOBJN T3,TMSTR1 ;HAVE WE DONE ALL OF THE LINES
RET ;YES RETURN
>
> ; end IFNKA
;ASNTVT - ASSIGN A TCP VIRTUAL TERMINAL
;ACCEPTS:
; T1/ TCB (WITH AN%NTP flag for new protocol)
; CALL ASNNVT
;RETURNS +1: FAILURE
; +2: SUCESS
; T1/ LINE NUMBER
; T2/ ADDRESS OF DYNAMIC DATA AND DATA BASE LOCKED
SWAPCD
ASNTVT::STKVAR <FLGTCB,TVLIN>
MOVEM T1,FLGTCB
HRRZ T1,TVTPTR ;GET FIRST TVT LINE NUMBER
SETZ T3, ;START WITH FIRST TVT
NOSKED
ASNTV1: MOVE T2,T1 ;GET FIRST TVT OFFSET
ADD T2,T3 ;ADD CURRENT TVT
MOVEM T2,TVLIN ;SAVE LINE NUMBER
CALL STADYN ;IS IT INITIALIZED
JUMPE T2,ASNTV4 ;NO. NO DYNAMIC DATA
SKIPG TTNETW(T2) ;FREE?
JRST ASNTV3 ;YES.
ASNTV2: CAIGE T3,NTTTVT-1 ;LOOKED AT ALL TVT'S?
AOJA T3,ASNTV1 ;NO
OKSKED ;YES,
RETBAD ;RETURN BAD
ASNTV3: LOAD T2,TCJOB,(T2) ;GET JOB FOR WHICH THIS IS A CNTRL TTY.
CAIN T2,-1 ;IS THERE ONE
JRST ASNTV4 ; No, use this one
HLRZ T2,JOBPT(T2) ; Yes, is it really there?
CAMN T2,TVLIN ; Skip if TCJOB has obsolete data
JRST ASNTV2 ;YES. TTY ALREADY ATTACHED?
ASNTV4: IFNKA <
; if job-0 ought to use TTYASC
; if other job, ought to use TTYASO
; For now, they are essentially the same
MOVE T2,TVLIN ;GET LINE NUMBER BACK
CALL TTYASC ;ASSIGN TVT
JRST ASNTV6 ;COULD NOT ASSIGN IT
>
MOVE T2,TVLIN ;GET LINE NUMBER
CALL LCKTTY ;AND LOCK DATA BASE
JRST ASNTV5 ;CANNOT LOCK DATA BASE. SHOULD'NT HAPPEN
SETONE TCJOB,(T2) ;INDICATE NO CONTROLLING JOB FOR TERM.
IFNKA < SETONE TTPRM,(T2)> ;MAKE DATA PERMANENT UNTIL NVT CLOSED
MOVE T1,FLGTCB ; Get arg back
TXNN T1,AN%NTP ;NEW TELENET PROTOCOL REQUEST?
TLZA T3,-1 ;NO, MAKE ZEROES
IFNKA < MOVX T3,NVNNV> ;YES, MAKE NEW NVB BIT
IFNDEF ISI,<IFKA <MOVX T3,NVNNV>> ;YES, MAKE NEW NVB BIT
IFDEF ISI,<IFKA <MOVSI T3,NEWNVB>> ;YES, MAKE NEW NVB BIT
HLLZM T3,TTNETW(T2) ;CLEAR TTNETW EXCEPT FOR NVNNV
SETZM NVTOPF(T2) ;CLEAR OPTION STATUS
HRRZ T1,FLGTCB ; Get the TCB
; HRRZ T1,JCNTCB(T1)
STOR T1,PTVT,(T2) ;REMEMBER UNIT
SETONE TT%DUM,TTFLGS(T2) ;SET DUPLEX MODE
MOVEI T1,.TTIDL ;SET TO BE AN "IDEAL" TERMINAL
STOR T1,TTTYP,(T2)
IFDEF ISI,<
IFKA < CALL TTCOBI ; Clear input, output buffers
CALL TTCIBF> ; End of IFKA
> ; End of IFDEF ISI
MOVE T1,TVLIN ;RETURN LINE NUMBER
OKSKED
RETSKP
ASNTV5: CALL ULKTTY ;UNLOCK DATA BASE
ASNTV6: HRRZ T1,TVTPTR ;GET FIRST TVT
MOVE T3,TVLIN ;SET UP TO TRY NEXT LINE
SUB T3,T1 ;GET TVT NUMBER IN 3
JRST ASNTV2 ;AND TRY NEXT TVT
IFNKA < ENDSV.
>
;TVTCSO - START OUTPUT TO A LINE CALLED FROM STRTOU
; FNJRST OF TTVT13
;RETURNS +2: ALWAYS
RESCD
TVTCSO::
AOS TVTNOF ;REQUEST TTY SCAN
AOS TCPFLG ; Say it is TCP that needs to run
AOS INTFLG ; Get the Internet fork to run it
RETSKP
;TVTDOB - TVT dismiss until output buffer empty
;FNCALL off of TTVT31
;
;Avoid doing a TELNET timing mark option negotiation if the connection
;is closing since the other end will not respond.
SWAPCD
TVTDOB: LOAD TCB,PTVT,(T2) ; Get TCB if exists
JUMPE TCB,R ; Return if none
SETSEC TCB,INTSEC ; TCBs are in INTSEC
LOAD T1,TSSYN,(TCB) ; Get send state
CAIE T1,SYNCED ; Can we send?
RET ; No
LOAD T1,TRSYN,(TCB) ; Get receive side state
CAIE T1,SYNCED ; Can other end reply?
RET ; No
JRST NVTDOB ; Yes and yes. Do normal TELNET stuff
;TVTCOB - TVT CLEAR OUTPUT BUFFER CALLED FROM TTCBF2
;ACCEPTS:
; T2/ ADDRESS OF DYNAMIC DATA
; FNJRST OFF TTVT02
;RETURNS +1: ALWAYS
RESCD
TVTCOB:
SKIPE INSKED ;IN SCHEDULER
RET ;YES RETURN IMMEDIATELY
;;;IFNKA < OKSKED>
PUSH P,TCB
SKIPG TCB,TTNETW(T2) ;STILL CONNECTED TO NETWORK?
JRST TVTCO3 ;NO. RETURN
SETSEC TCB,INTSEC ; TCBs in Internet section
JN TERR,(TCB),TVTCO3 ; Don't DM if connection error
NOINT ;PROTECT POSSIBLE ILOCKS
CALL CKNNVT ;NEW STYLE NVT?
JRST TVTCO1 ;OLD STYLE
JFCL ;3031 Supdup?
MOVEI T1,DMCH ;DATA MARK CHARACTER
CALL NVTSSP ;SEND NEW DM
JRST TVTCO2
TVTCO1: MOVX T1,1 ;RESERVE ONE CHARACTER
CALL NVTRSV ;GO REESERVE IT
JRST TVTCO2 ;NONE AVAILABLE CANNOT WAIT
MOVX T1,200
CALL TCOBN ;SEND CHARACTER
OKSKD1
TVTCO2:
OKINT
TVTCO3: POP P,TCB
;;; IFNKA < CALL TTXON> ;REACTIVATE OUTPUT IF NECESSARY
RET
;CHECK OVERDUE NEGOTIATIONS
RESCD
TVTNCK::STKVAR <TVTCTR>
MOVE T2,TVTPTR ;POINTER TO TVTS
TVTNCL: MOVEM T2,TVTCTR ;SAVE TVT COUNTER
HRRZ T2,T2 ;GET JUST RIGHT HALF
CALL LCKTTY ;GET ADDRESS OF DYAMIC DATA AND LOCK
JRST TVTNCE ;NOT ACTIVE
SKIPGE TTNETW(T2) ;ATTACHED?
JRST TVTNCE ;NO, SKIP IT
MOVX T3,NVTMO ;TIME OUT
HLLZ T1,NVTOPF(T2) ;GET OUTSTANDING OPTIONS
JUMPE T1,[ANDCAM T3,TTNETW(T2) ;NONE, CANCEL TIME-OUT IF ANY
JRST TVTNCE]
XORB T3,TTNETW(T2) ;YES, COUNT COUNTER
TXNN T3,NVTMO ;COUNT FROM 1 TO 0?
HRRZS NVTOPF(T2) ;YES, CANCEL OUTSTANDING OPTION
TVTNCE: CALL ULKTTY ;UNLOCK DATA BASE
MOVE T2,TVTCTR ;GET AOBJ COUNTER
AOBJN T2,TVTNCL ;ANY MORE TVT'S
MOVE T1,TODCLK ;NO. GET TIME OF DAY
ADDI T1,NEGTM0 ;ADD TIME OUT QUANITY
MOVEM T1,TVTNTM ;SAVE TIME FOR NEXT CHECK
RET
IFNKA < ENDSV.
>
; SNDTVT ; Send virtual terminal data
;TCB/ Locked connection block
;PKT/ Pointer to Internet portion of packet being filled
;TPKT/ Pointer to TCP portion of packet
;T1/ Max number of characters to send
;T2/ Line block address
;
; CALL SNDTVT
;Ret+1: Always. Terminal data moved into packet. T1 has number of chrs.
SNDTVT::INTLAC <XFRCNT,LINBLK,PKTPTR,CNT>
DMOVEM T1,XFRCNT ; T1,2 to XFRCNT and LINBLK
IFN .TTYLG,<
SKIPN TTDEV2(T2) ; Log file already?
CALL OPNLOG ; open log file if possible
JFCL
>
LOAD PKTPTR,PTDO,(TPKT) ; Get TCP data offset
HRLI PKTPTR,(<POINT 8,.-.(TPKT)>) ; Pointer to data area
MOVEI CNT,0 ; Init number moved to packet
IFNDEF ISI,< MOVEI T3,(1B<RCTOPT+WILOPT>)> ; RCTE-on bit
IFDEF ISI,<IFNKA <MOVEI T3,(1B<RCTOPT+WILOPT>)>> ; RCTE-on bit
IFDEF ISI,<IFKA <MOVE T3,[RCTWIL##]>>
TDNE T3,NVTOPF(T2) ; Have we said we will do RCTE?
CALL CKNNVT ; And is this a "new" TELNET terminal?
JRST SNDTV1 ; No.
JFCL ;3031 Supdup?
JE PBRCT,(T2),SNDTV1 ; Check the break count
CALL NVTRRR ; Try to send
SNDTV1: SKIPG TTNETW(T2) ; Still connected?
JRST SNDTV2 ; No
JE TERR,(TCB),SNDTV3 ; Error on connection (retrans timeout)?
SNDTV2: CALL CLRSAL ; Flush sendall - DEC calls TTCOB5
; instead of TTCBF2 - Why?
CALL TTCOBN ; Flush output buffer
JRST SNDTV9 ; And return
SNDTV3: SETONE TTOTP,(T2) ; Indicate output active
; Move characters from the terminal output buffer(s) into the packet.
; XFRCNT has space left in packet and CNT will be left with number
; moved.
SNDTV4: SOJL XFRCNT,SNDTV5 ; Jump if packet filled
MOVE T2,LINBLK ; Restore address of data area
NOSKD1
IFNKA < CALL TTSND ; Get a chr from output buf to T3
JRST SNDTV6> ; Failed to get any
IFKA < JSP T4,TTSND> ; Get a chr from output buf to T3
OKSKD1
IFKA <
JE TTOTP,(LINBLK),SNDTV6 ; Jump if we did not get it
IDPB T3,PKTPTR ; Add to packet
>
IFNKA <
IDPB T1,PKTPTR ; Add to packet
>
IFN .TTYLG,<
CALL LOGCHR ; Log it
>
AOJA CNT,SNDTV4 ; Count it up and try for another
;;; Here if we didn't get a charcter
SNDTV6:
IFNKA <OKSKD1> ; Go OKSKED again
JRST SNDTV9 ; And join below
SNDTV5: SETZRO TTOTP,(LINBLK) ; Clear output active bit
SNDTV9: MOVE T1,CNT ; Return number in packet
SNDTVX: RESTORE
RET
; PRCTVT Process TCP Virtual Terminal data
;T1/ Byte pointer into packet where to begin (index by TPKT)
;T2/ Pointer to dynamic line data block
;T3/ Maximum number of characters to do
;PKT/ Pointer to Internet portion of packet
;TPKT/ Pointer to TCP portion of packet
;TCB/ Locked connection block
;
; CALL PRCTVT
;Ret+1: Always. Given number of characters have been moved.
PRCTVT::INTLAC <LINBLK,XFRCNT,PKTPTR>
MOVEM T1,PKTPTR
DMOVEM T2,LINBLK
PRCTV1: SOJL XFRCNT,PRCTVX ; Jump if all done
ILDB T1,PKTPTR ; Get a character
MOVE T2,LINBLK ; Line block address
LOAD T3,NVSTP,(T2) ; Current Telnet command state
SETZRO NVSTP,(T2) ; Reset for normal dispatch next time
PUSH P,LINBLK ; Some of these are crashed by TTYSRV
PUSH P,XFRCNT ; or TELNET
PUSH P,PKTPTR
CALL @NVTSTD(T3) ; Dispatch to Telnet routine
POP P,PKTPTR
POP P,XFRCNT
POP P,LINBLK
JRST PRCTV1 ; Do another
PRCTVX: RESTORE
RET
;CHKTVT - SEE IF THIS LINE NUMBER IS A TVT
;ACCEPTS:
; T2/ INTERNAL LINE NUMBER
; CALL CHKTVT
;RETURNS +1: IF NOT TVT
; +2: IF TVT
RESCD
CHKTVT::
IFNKA < ACVAR <W1> ;GET AN AC TO WORK WITH
LOAD W1,TTSTY,(T2) ;GET LINE TYPE FOR THIS LINE
CAIE W1,TT.TVT ;IS IT A TVT?
RETBAD ;NO. FAILURE
RETSKP ;RETURN SUCCESS
ENDAV. ;END ACVAR
>
IFKA < CAIL T2,TVTLO
CAILE T2,TVTHI
RETBAD
RETSKP
>
SWAPCD
; TVTCHK See if this line is a TCP Virtual terminal
;T2/ Internal line number
;
; CALL TVTCHK
;Ret+1: Line not initialized. T2 0 Inactive Not locked, okint
; T2 -1 Becoming active Not locked, okint
; T2 adr Non-standard blk Locked, noint
; +2: Line initialized. T2 adr Std dynamic data Locked, noint
TVTCHK::
IFNKA < CAIL T2,NLINES ; Legal terminal line number?
JRST TVTCH8 ; TCP Never calls with non-TVT
LOAD T1,TTSTY,(T2) ; Line type for this line
CAIE T1,TT.TVT ; Is it a TVT?
JRST TVTCH8 ; No.
>
IFKA < CAIL T2,TVTLO
CAILE T2,TVTHI
JRST TVTCH8
>
CALL LCKTTY ; Get addr of dynamic data and lock
RET ; Line not initialized
JRST TVTCHX ; Return with line blk addr in T2
TVTCH8: TCPBUG(HLT,<TVTCHK called with non-TVT>,TVTNTV)
TVTCHX: RETSKP
; TVTISP Get number of holes in input buffer
;T2/ Pointer to line block
;
; CALL TVTISP
;Ret+1: Always. Space available in T1
TVTISP::LOAD T1,TIMAX,(T2) ; Max capacity of line
SUB T1,TTICT(T2) ; Less what is already there
RET ; Gives amount left
; TVTOSP Get number of bytes in output buffer
;T2/ Line block pointer
;
; CALL TVTOSP
;Ret+1: Always. Number in T1.
TVTOSP::LOAD T1,TSALC,(T2) ; Sendall count plus
SKIPE T1 ; If sendall, bump count so
ADDI T1,1 ; extra TTSND clears sndall info
ADD T1,TTOCT(T2) ; regular count
IFNKA < JE <TTSFG,TTRXF,TTSHT>,(T2),TVTOSX
MOVEI T1,0 ; Hung on ^S, say no avail for output
>
TVTOSX: RET
; TVTDTS Close a full duplex TCP virtual terminal connection
; upon carrier-off
;
;T2/ Line number
;
; CALL TVTDTS (FNJRST off off TTVT19)
;Ret+1: Always
RESCD
TVTDTS: CALL TVTDTT ; Detach the TVT
RET
RET ; Success
; TVTDET Detach a job from a TCP virtual terminal connection
; For TOPS20 TVTDET returns to caller's caller, TVTDTT returns to caller.
IFNKA <
; Called from HLTJB when a job logs off
;T2/ Line number
;
; CALL TVTDET (FNCALL off of TTVT11, TTVT19)
;Ret+1: Failure. T1/ 1B0 + Addr of routine if dismiss needed
; or, Error code if failed
;Ret+2: Success
TVTDET: POP P,0(P) ; Flush return address
;;; Here to not flush return
TVTDTT: SE1CAL ; Enter section 1
SAVEPQ ; Save local ACs
STKVAR <TVTDLN,TVTDAD> ; Space for line number and block addr
MOVEM T2,TVTDLN ; Save the line number
CALL TVTCHK ; See if this is a TVT
RETSKP ; Not assigned. Return.
MOVEM T2,TVTDAD ; Save addr of dynamic data area
CALL CLRPRM ; Clear permanent bit, allowing deassign
SKIPG TTNETW(T2) ; Is there a connection?
JRST TVTDE1 ; No
PUSH P,TCB
LOAD TCB,PTVT,(T2) ; Get the TCB
SETSEC TCB,INTSEC ; Make extended address
JE TSUOP,(TCB),TVTDE0 ; Already closed?
XMOVEI T1,TCBLCK(TCB) ; Lock to lock
XMOVEI T2,CLOSE1 ; Function to call
CALL LCKCAL ; Do a cross-job close
TVTDE0:
SETZRO TVTL,(TCB) ; Prevent OPSCAN from finding this TCB
POP P,TCB
MOVE T2,TVTDAD ; Restore pointer to data block
TVTDE1:
SETZM TTNETW(T2) ; Flush the connection
LOAD T3,TCJOB,(T2) ; Get owning job
CAIN T3,-1 ; Is there one?
JRST TVTDT2 ; No. Just go deallocate data block.
MOVE T2,TVTDLN ; Get TTY line number
MOVEI T1,.TTDES(T2) ; Make into device designator
CALL CHKDES ; Get index to device tables
JRST [ MOVE T2,TVTDAD ; Get dynamic data address back
CALL ULKTTY
RETBAD] ; Invalid device designator?????
SETZRO DV%OPN,DEVCHR(T2) ; Permit RELD at LGOUT to win
MOVE T2,TVTDAD ; Dynamic data block address
MOVE T1,TVTDLN ; Terminal line number
CAMN T1,CTRLTT ; Controlling terminal for this job?
JRST TVTDT2 ; Yes. Go deassign database
LOAD T3,TCJOB,(T2) ; Get owning job
HLRZ T3,JOBPT(T3) ; Get controlling terminal of job
CAME T1,T3 ; Is this a controlling terminaL
JRST TVTDT2 ; No. Go detach it
; A job exists on this line and the net connection has been broken.
; Generate a carrier off PSI for the top fork. This will cause the
; terminal data block to be deassigned.
MOVE T2,TVTDLN ; Get line number
NOSKD1
CALL TVTCOF ; Start the carrier off action
OKSKD1
MOVE T2,TVTDAD ; Get address
CALL ULKTTY ; Unlock the data block
RETSKP ; And give a good return
; Deassign the terminal's data block
TVTDT2: JE TTSAL,(T2),TVTDT3 ; Doing a Send-All?
; SETZRO TTSAL,(T2) ; No longer.
; SOS SALCNT ; Now one less line doing it
; SETZRO TSALC,(T2) ; Clear send-all count
; SETZM TTSAL2(T2) ; Clear send-all pointer
CALL CLRSAL ; Interrupt-proof decrement
TVTDT3:
CALL ULKTTY ; Unshare the data block
MOVE T2,TVTDLN ; TVT Line number
MOVEI T1,.TTDES(T2) ; Form device designator
CALL CHKDES ; Get index to device tables
RETBAD ; Invalid device designator????
MOVEM T2,TVTDAD ; Save index to device tables
MOVE T2,TVTDLN ; Get terminal line number
CALL TTYDE0 ; Deallocate the line
RETBAD ; Return error or test routine
MOVE T2,TVTDAD ; Device table index
HRROS DEVUNT(T2) ; Set owning job to -1
SETZRO DV%ASN!DV%OPN,DEVCHR(T2) ; Not assigned or openned
MOVE T2,TVTDLN ; Get line number
CAME T2,CTRLTT ; Controlling terminal
RETSKP ; No.
SETOM CTRLTT ; Yes. Indicate no terminal
MOVE T2,JOBNO ; Get job number
HRROS JOBPT(T2) ; This nob no longer has a terminal
RETSKP
ENDSV.
> ; end IFNKA
IFKA <
TVTDET::
TVTDTT: PUSH P,T2
SKIPL TTFORK(T2) ; Line attached?
CALL TVTCOF ; Yes, initiate carrier off psi
MOVE T2,0(P)
SKIPG TTNETW(T2) ; Reasonable units?
JRST TVTDT1 ; No
PUSH P,TCB
LOAD TCB,PTVT,(T2)
SETSEC TCB,INTSEC
JE TSUOP,(TCB),TVTDE0
XMOVEI T1,TCBLCK(TCB)
XMOVEI T2,CLOSE1
CALL LCKCAL
TVTDE0: SETZRO TVTL,(TCB)
POP P,TCB
TVTDT1: POP P,T2
SETZM NVTOPF(T2)
SETOM TTNETW(T2)
SETZM TTPSI(T2)
CALL TTCOBI
CALL TTCIBF
RET
> ; end IFKA
IF1 <PRINTX %TVTIGA ABSENT
>
TVTIGA: RET
IFKA <
IF1 <PRINTX %TVTCAP ABSENT
>
TVTCAP::RET
IF1 <PRINTX %TVTCIB ABSENT
>
TVTCIB::RET
>; END IFKA
; TVTOPR Main routine to operate TVTs
;(no args)
;
; CALL TVTOPR
;Ret+1: Always.
TVTOPR::SKIPLE TVTNOF ; Output scan needed?
CALL OPSCAN ; Yes. Signal PZ where possible
MOVE T1,TODCLK ; Now
CAML T1,TVTNTM ; Time for check on overdue
CALL TVTNCK ; Telnet negotiations
MOVE T1,LSNTIM ; Get time for listening
SKIPE TVTLSN ; if no socket
CAMG T1,TODCLK ; time for another stab?
CALL LISTEN ; Try a listen
RET
; LISTEN Set up a TCB listening on the TELNET port
;(No args)
;
; CALL LISTEN
;Ret+1: Always. TVTLSN set ge 0 if error, le 0 if OK.
LISTEN: MOVE T1,FACTSW ;BROADCAST REQ
TXNN T1,SF%NVT ; NVT logins allowed?
JRST LSN1 ; No, Don't open
MOVE T1,[TCP%PS+TCP%VT+TVTCDB]
MOVEI T2,LSNTMO ; Timeout
SETZ T3, ; Default re-transmission algorithm
%OPEN% ; Do the listen
CAIA ; Don't save if failed
MOVEM T1,TVTLSN ; Save
;;; Join here if remote logins not allowed
LSN1: MOVE T1,TODCLK ; Get clock
ADDI T1,^D60000 ; in one minute
MOVEM T1,LSNTIM ; try again regardless
RET ; Return
TVTCDB: BLOCK .TCPCS ; Connection block
.X==.
RELOC TVTCDB+.TCPLP
LSNPRT
RELOC .X
PURGE .X
; TVTOPN Open a TCP Virtual Terminal; Called in Job-0 context
;TCB/ Pointer to TCB
;
; CALL TVTOPN
;Ret+1: Always, T1 zero if OK or error code (ELT+^D4) otherwise
TVTOPN::HRRZ T1,TCB ; Needs TCB
TXO T1,AN%NTP ; Say it will speak new Telnet
CALL ASNTVT ; Assign a virtual terminal
JRST TVTOP7 ; Failed (not available, etc)
STOR T1,TVTL,(TCB) ; Save in connection block
PUSH P,T2 ; Save line block address
MOVE T2,T1 ; Put line number in right place
MOVEI T1,"C"-100 ; Get a control-C to awaken the job
NOSKD1
CALL TVTCHI ; Type it for the guy
JFCL ; Ignore error return
OKSKD1
SETZM TVTLSN ; Get another listen done
SETZM TVTNTM ; Get done quickly
POP P,T2 ; Restore line block address
CALL ULKTTY ; Block now stable
SETZ T1, ; No error
JRST TVTOPX
TVTOP7: MOVX T1,ELT+^D4 ; Out of resources error
TVTOPX: RET
; TVTCLS Close a TCP Virtual Terminal
;T1/ Code for reason
;TCB/ Pointer to connection block
;
; CALL TVTCLS
;Ret+1: Always.
RESCD
TVTCLS::INTLAC <CCODE>
MOVEM T1,CCODE
CAIE CCODE,XFP+^D12 ; "Closing" or
CAIN CCODE,EFP+^D7 ; "Connection error or rejected"
CAIA ; (other end restarted)
JRST TVTCL1 ; No. Something else
; Here when other end restarted and we received a RESET.
; PRCRST called [USRERR with EFP+^D7] ABTCON with EFP+^D7.
; Beware: it may be THE listening connection.
; Here when remote end is closing. We are in the process of sending
; and ACK for his FIN, but may not be done sending everything from
; this end yet -- for instance, "Detached job N ..." msg.
; So, get the job to clean itself up and call TVTDTS via TTHNGU
; (from FLOGO1 as called from JOBCOF by top fork of the job), or
; via TTYDEA as called from TTYDAS from LDTACH or HLTJB.
LOAD T2,TVTL,(TCB) ; Get the line number
JUMPE T2,TVTCL2 ; TVT may not be assigned if during
NOSKD1 ; OPEN (if so, need another listen)
CALL TVTCOF ; Start the carrier off sequence
OKSKD1
JRST TVTCLX ; and leave
TVTCL1: CAIN CCODE,XLP+^D3 ; "Closed"
JRST TVTCL4 ; Yes, just go detach it
CAIN CCODE,ELT+^D4 ; "No free terminals"
JRST TVTCL2 ; Go fake CLOSE & release JCN
CAIE CCODE,ELP+^D14 ; "Connection reset" due to
; Retransmission timeout?
JRST TVTCLX ; No, Something else. Ignore it.
; Here when a connection OPENed correctly but there were no free TVTs.
; PRCACK (or PRCSYN) called USREVT(OK) which called TVTOPN which
; called ASNTVT which failed. TVTOPN tried to send a message and then
; a RST to the other end before calling ABTCON(ELT+^D4) which called
; USREVT(ELT+^D4) which called TVTCLS(ELT+^D4). The state is NOT.NOT
; but we have to fake a CLOSE and release the JCN.
; Here when we have suffered a retransmission timeout on an open
; connection. REXMIT called [USRERR with ELP+^D9, "RX timeout", and]
; ABTCON with ELP+^D14, "Connection reset", which made the connection
; dead (state is NOTSYN in both directions) and called USREVT with
; ELP+^D14 who called us. All that remains is to get the job
; detached. Note that the job may or may not be logged in.
TVTCL2: SETZRO TSUOP,(TCB) ; Don't send a FIN
; If this is a valid Job0 JCN we are dealing with the LISTENing port.
; The "said open" bit tells whether the timeout happened while the
; connection was opening (must do another listen) or after it had
; opened (next listen is already in progress).
JN TSOPN,(TCB),TVTCL4 ; Jump if next listen already done
LOAD T1,TJCN,(TCB) ; or if not a valid Job0
CAIN T1,-1 ; JCN
JRST TVTCL4
SETZM TVTLSN ; Get another listen done
SETZM TVTNTM ; Now.
TVTCL4:
LOAD T2,TVTL,(TCB) ; Get line number
SKIPE T2 ; TVT not assigned if during open
CALL TVTDTS ; Detach owning job
JN TOWNR,(TCB),TVTCL5 ; Jump if TVT not owned by Job-0 (never)
LOAD T1,TJCN,(TCB) ; Get our (Job-0) handle on the TCB
CALL RETJCN ; Release it
SETZRO TJCN,(TCB) ; (RETJCN can't do this if TJCN was -1)
TVTCL5:
TVTCLX: RESTORE
RET
SWAPCD
; OPSCAN Get packets sent on each connection with output waiting
;(no args)
;
; CALL OPSCAN
;Ret+1: Always.
; Following note is no longer valid since some TVTs may be owned
; by other jobs
; Note: TVT TCBs are owned by job-0 which includes the Internet fork
; which runs this code. No user fork has (write) access to any of them.
; The TCB might, however, be locked by a user STAT JSYS.
OPSCAN: INTLAC <TVTP,LINADR>
PUSH P,TCB
SETZM TVTNOF ; Clear the run request flag
MOVE TVTP,TVTPTR ; AOBJN for all TVTs
JFCL ;NOSKED ; Keep TCBs
OPSCA1: HRRZ T2,TVTP ; Next line number
CALL LCKTTY ; Lock and get dynamic area to T2, NOINT
JUMPLE T2,OPSCA8 ; Non standard block
MOVE LINADR,T2 ; Save the terminal block ptr
LOAD TCB,PTVT,(T2) ; Have a TCB?
JUMPE TCB,OPSCA7 ; Jump if not there (??)
SETSEC TCB,INTSEC ; Make extended address
; Following should never jump
JE TTVT,(TCB),OPSCA7 ; Jump if not a TVT (??)
LOAD T3,TVTL,(TCB) ; Get the line number
JUMPE T3,OPSCA7 ; USREVT released the TVT line (??)
CALL TVSBE1 ; Any output waiting?
SKIPA T4,T1 ; Yes. Get PZ to call SNDTVT
JRST OPSCA7 ; No.
MOVX T1,^D200 ; The function to queue for PZ if a lot
CAIGE T4,^D8 ; Less that 8 is echoing so
MOVX T1,-1 ; Run the packetizer "now"
CALL DLAYPZ ; Schedule the packetizer
OPSCA7: MOVE T2,LINADR ; Restore address of terminal block
OPSCA8: CALL ULKTTY ; Decrease reference count, OKINT
OPSCA9: AOBJN TVTP,OPSCA1 ; Loop over all TVTs
JFCL ;OKSKED
IFNKA < SKIPE T2,TVMSTM ; Any TTMSG's out?
CAMLE T2,TODCLK ; Yes, time to flush yet?
JRST OPSCAX ; No, return.
NOSKED ; Prevent anyone from changing data
CALL TVMNTR ; Flush all TTMSG's to TVTs
OKSKED
SETZM TVMSTM ; Clear timer
>
OPSCAX: POP P,TCB
RESTORE
RET
;3051 begin addition
;TVRFIL - ROUTINE TO SIGNAL TVT BUFFER REFILL WHEN EMPTY
;CALLED FROM GTTCI
TVRFIL: SKIPG TTNETW(T2) ;STILL CONNECTED TO NETWORK?
RET ;NO, NOTHING TO DO
SAVET ;SAVE DYNAMIC DATA
PUSH P,TCB ;SAVE TTYSRV CONTEXT
NOSKED ;OWN THE SYSTEM
SKIPL RA+PRCLCK ;IS REASSEMBLER RUNNING ALREADY?
IFSKP.
LOAD TCB,PTVT,(T2) ;GET TCB IF EXISTS
IFN. TCB ;HAVE ONE?
SETSEC TCB,INTSEC ;TCB'S ARE IN INTSEC
DO.
IFQE. TRCB,(TCB) ;RECV% BUFFER EXISTS?
LOAD T1,QNEXT,<+TCBRPQ(TCB)> ;NO, GET NEXT ITEM ON RA QUEUE
CAIN T1,TCBRPQ(TCB) ;IS RA QUEUE EMPTY?
EXIT. ;YES, NO NEED TO RUN REASSEMBLER
ENDIF.
$SIGNL(RA,20) ;RUN REASSEMBLER AFTER SHORT DELAY
ENDDO.
ENDIF.
ENDIF.
OKSKED ;RETURN THE SYSTEM
POP P,TCB ;RESTORE TTYSRV CONTEXT
RET
;3051 end addition
IFKA < TNXEND
END
> ; end of IFKA
> ; End of IFN .TVFLG at start of file