home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msr313src.zip / msntni.asm < prev    next >
Assembly Source File  |  1993-07-12  |  23KB  |  835 lines

  1.     NAME    MSNTNI
  2. ; File MSNTNI.ASM
  3. ; Telnet interface to MS-DOS Kermit
  4. ;
  5. ;  Copyright (C) 1985, 1993, Trustees of Columbia University in the 
  6. ;  City of New York.  Permission is granted to any individual or institution
  7. ;  to use this software as long as it is not sold for profit.  This copyright
  8. ;  notice must be retained.  This software may not be included in commercial
  9. ;  products without written permission of Columbia University.
  10. ; Written by Joe R. Doupnik, Utah State University, 
  11. ;  jrd@cc.usu.edu, jrd@usu.Bitnet.
  12. ;
  13. ; Edit history
  14. ; 27 August 1992 version 3.13
  15. ; 6 Sept 1991 version 3.11
  16. ; Last edit 17 May 1993
  17. ;
  18. ; Some rules of the road.
  19. ; Starting a session: call ktpcopen. This will ensure the interrupts are
  20. ; hooked and will start a new session. Ktcpopen will return the ident of
  21. ; the new session, or -1 upon failure.
  22. ; Stopping a session: this must be done from outside Telnet. Call ktcpclose
  23. ; with a particular session ident (0.. MAXSESSIONS-1) to close that session
  24. ; or call it with an ident of -1 to close all and shutdown TCP. Ktcpclose
  25. ; will return with the ident of the next (cyclic) active session, or -1 if
  26. ; none remain active. Register AX holds incoming indent, outgoing status.
  27. ; When TCP/IP shuts down it releases all interrupts and disengages from the
  28. ; Packet Driver. This will occur upon closing the last active connection.
  29. ;
  30. ; Swapping active sessions: call ktcpswap with a new session ident to change
  31. ; to that new one. This will return with the new ident if successful, or -1.
  32. ; We have to guess session idents so an outside manager can pick and choose.
  33. ; Use ktcpswap to resume a session because ktcpstart always tries to start a
  34. ; new one.
  35.  
  36.     include    mssdef.h
  37.  
  38. bapicon    equ    0a0h        ; 3Com BAPI, connect to port
  39. bapidisc equ    0a1h        ; 3Com BAPI, disconnect
  40. bapiwrit equ    0a4h        ; 3Com BAPI, write block
  41. bapiread equ    0a5h        ; 3Com BAPI, read block
  42. bapibrk    equ    0a6h        ; 3Com BAPI, send short break
  43. bapistat equ    0a7h        ; 3Com BAPI, read status (# chars to be read)
  44. bapihere equ    0afh        ; 3Com BAPI, presence check
  45. bapieecm equ    0b0h        ; 3Com BAPI, enable/disable ECM char
  46. bapiecm    equ    0b1h        ; 3Com BAPI, trap Enter Command Mode char
  47.  
  48. data    segment public 'kdata'
  49.     extrn    tcptos:word        ; top of stack for TCP code
  50.     extrn    flags:byte, yflags:byte, portval:word, ttyact:byte
  51.     extrn    ftogmod:dword, crt_lins:byte, crt_cols:byte, tcpdata:word
  52. data    ends
  53.  
  54. _TEXT    SEGMENT  WORD PUBLIC 'CODE'
  55. _TEXT    ENDS
  56. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  57. _DATA    ENDS
  58. CONST    SEGMENT  WORD PUBLIC 'CONST'
  59. CONST    ENDS
  60. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  61. _BSS    ENDS
  62. DGROUP    GROUP    CONST, _BSS, _DATA
  63.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  64.  
  65. _DATA      SEGMENT
  66.     public    _kmyip, _knetmask, _kdomain, _kgateway, _kns1, _kns2, _khost
  67.     public    _kbcast, _bapiadr, _bapireq, _bapiret
  68.     public    _display_mode, _kport, _kpdint, _kserver, _kdebug, _kterm
  69.     public    _ktttype, _kterm_lines, _kterm_cols, _kbtpserver
  70.  
  71.     extrn    _msgcnt:word, _msgbuf:byte, _echo:word
  72.  
  73.         db 10 dup (0)        ; guard
  74.         db 'DUMMY',0           ; null pointer guard
  75. _kmyip        db 17 dup (0)        ; our IP number
  76. _knetmask    db 17 dup (0)        ; our netmask
  77. _kdomain    db 33 dup (0)        ; our domain
  78. _kgateway     db 33 dup (0)        ; our gateway
  79. _kns1        db 17 dup (0)        ; our nameserver #1
  80. _kns2        db 17 dup (0)        ; our nameserver #2
  81. _khost        db 61 dup (0)        ; remote host name/IP #
  82. _kbcast        db 17 dup (0)        ; broadcast IP
  83. _ktttype    db 33 dup (0)        ; terminal-type override string
  84. _kbtpserver    db 17 dup (0)        ; Bootp server which responded
  85. _kserver    dw    0        ; non-zero for Kermit server
  86. _kport        dw    23        ; TCP port (Telnet = 23)
  87. _kpdint        dw    0        ; Packet Driver Int, 0 = search
  88. _kdebug        dw    0        ; if SET DEBUG ON is effective
  89. _kterm        dw    0        ; terminal type index, see mssdef.h
  90. _kterm_lines    db    0        ; terminal screen height (24)
  91. _kterm_cols    db    0        ; terminal screen width (80)
  92. oldint8    dd    0            ; original Int 8 owner
  93. tcpstack dd    0            ; TCP code stack
  94. stack8    dd    0            ; stack at Int 8 invokation
  95. kstack    dw    0            ; Kermit mainline stack pointer
  96. tempax    dw    0            ; a temp
  97. tcpflag    db    0        ; who is running TCP code: 1=Kermit, 2=Int 8
  98. ourtcpdata dw    0            ; Kermit offset of "tcpdata" block
  99. int8cnt    db    0            ; Int 8 times called counter
  100. hooked    db    0            ; Int 8 hooked status (0 = unhooked)
  101. _display_mode db 0            ; msg, none if == 0
  102. _bapireq dw    0            ; BAPI count of chars requested
  103. _bapiret dw    0            ; BAPI count of chars processed
  104. _bapiadr dd    0
  105. _DATA      ENDS
  106.  
  107.  
  108. _TEXT    segment
  109.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, es:nothing
  110.     extrn    _serial_handler:near, _main:near, _exit:near 
  111.     extrn    _pkt_release:near, _tcp_tick:near, _bcopy:near, _itoa:near
  112.     extrn    _strlen:near, _strcpy:near, _session_close:near
  113.     extrn    _session_change:near
  114.  
  115. public    _enable
  116. enable    proc    near
  117. _enable    equ    this byte
  118.     sti
  119.     ret
  120. enable    endp
  121.  
  122. public    _disable
  123. disable    proc    near
  124. _disable equ    this byte
  125.     cli
  126.     ret
  127. disable    endp
  128.  
  129. ; Hook Interrupt 8h. Return AX = 1 if successful else 0.
  130. ; For use only by Telnet code as an internal procedure.
  131.     public    _hookvect
  132. hookvect proc    near
  133. _hookvect equ    this byte
  134.     cmp    hooked,0        ; hooked already?
  135.     je    hook0            ; e = no
  136.     mov    ax,1            ; say success
  137.     ret
  138. hook0:    push    bp
  139.     mov    bp,sp
  140.     mov    ax,bp
  141.     add    ax,2+2            ; C sp just before this call
  142.     cmp    word ptr tcpstack+2,0    ; have setup stack?
  143.     jne    hook1            ; ne = yes
  144.     mov    word ptr tcpstack,ax    ; save as main prog stack level
  145. hook1:    push    es
  146.     mov    ah,getintv        ; get interrupt vector
  147.     mov    al,8            ; vector number
  148.     int    dos
  149.     mov    ax,es
  150.     mov    cx,cs
  151.     cmp    ax,cx            ; points to us now?
  152.     je    hook2            ; e = yes, do not touch
  153.     mov    word ptr DGROUP:oldint8+2,ax    ; save segment
  154.     mov    word ptr DGROUP:oldint8,bx    ; save offset
  155.     mov    dx,offset ourtimer     ; new handler
  156.     push    ds
  157.     mov    ax,cs            ; segment
  158.     mov    ds,ax
  159.     mov    al,8            ; for Int 8
  160.     mov    ah,setintv        ; set interrupt address from ds:dx
  161.     int    dos
  162.     pop    ds
  163.     mov    hooked,1        ; say have hooked vector
  164. hook2:    mov    tcpflag,1     ; say Kermit but not Int 8 is running TCP
  165.     mov    ax,1            ; return 1 for success
  166.     pop    es
  167.     pop    bp
  168.     ret
  169. hook3:    call    unhookvect        ; put any back
  170.     xor    ax,ax            ; return 0 for failure
  171.     pop    es
  172.     pop    bp
  173.     ret
  174. hookvect endp
  175.  
  176. ; For use only by Telnet code as an internal procedure.
  177.     public    _unhookvect
  178. unhookvect proc    near
  179. _unhookvect equ    this byte
  180.     cmp    hooked,0        ; hooked the vector?
  181.     jne    unhook1            ; ne = yes
  182.     mov    ax,1            ; say success
  183.     ret
  184. unhook1:push    bp
  185.     mov    bp,sp
  186.     push    es
  187.     push    bx
  188.     push    cx
  189.     clc
  190.     mov    tempax,0        ; assume failure status
  191.     mov    ah,getintv        ; get interrupt vector
  192.     clc
  193.     mov    al,8            ; vector number
  194.     int    dos
  195.     jc    unhook2            ; c = failed
  196.     mov    ax,es            ; es:bx is current owner, us?
  197.     mov    cx,cs
  198.     cmp    ax,cx            ; seg should be right here
  199.     jne    unhook2            ; ne = is not
  200.     cmp    bx,offset ourtimer    ; should be the same too
  201.     jne    unhook2            ; ne = is not, let them have the int
  202.     mov    ax,word ptr DGROUP:oldint8+2    ; segment
  203.     mov    dx,word ptr DGROUP:oldint8    ; offset
  204.     mov    cx,dx
  205.     or    cx,ax            ; was it used by us?
  206.     jz    unhook2            ; z = no, leave alone
  207.     push    ds
  208.     mov    ds,ax
  209.     mov    al,8            ; for Int 8
  210.     mov    ah,setintv        ; set interrupt address from ds:dx
  211.     int    dos
  212.     pop    ds
  213.     and    tcpflag,not 2        ; Int 8 no longer touches TCP
  214.     mov    word ptr DGROUP:oldint8,0
  215.     mov    word ptr DGROUP:oldint8+2,0
  216.     mov    hooked,0        ; say not hooked
  217.     mov    tempax,1        ; success status
  218.     jmp    short unhook3
  219. unhook2:mov    tempax,0        ; failure
  220. unhook3:mov    ax,tempax        ; return status (1=success, 0=fail)
  221.     pop    cx
  222.     pop    bx
  223.     pop    es
  224.     pop    bp
  225.     ret
  226. unhookvect endp
  227.  
  228. ; Int 8 routine to call the TCP code if Kermit main body does not.
  229. ; For use only by Telnet code as an internal procedure.
  230. ourtimer proc near
  231.     push    ds
  232.     push    ax
  233.     mov    ax,dgroup        ; set addressibility to our dgroup
  234.     mov    ds,ax
  235.     pushf                ; simulate interrupt invokation
  236.     call    dword ptr DGROUP:oldint8 ; call previous owner of Int 8
  237.     mov    ax,DGROUP        ; set addressibility to our dgroup
  238.     mov    ds,ax
  239.     test    tcpflag,1+2        ; is TCP code running now?
  240.     jnz    ourtim2            ; nz = yes, so we don't run now
  241.     mov    al,int8cnt        ; get our times-called counter
  242.     inc    al            ; up once again
  243.     and    al,7            ; keep 3 bits, about .5 sec @18.2tic/s
  244.     mov    int8cnt,al        ; store
  245.     or    al,al            ; is it zero?
  246.     jnz    ourtim2            ; nz = no, go away for awhile
  247.     or    tcpflag,2        ; say we are running the TCP code
  248.     push    bp
  249.     push    bx
  250.     push    cx
  251.     push    dx
  252.     push    si
  253.     push    di
  254.     push    es
  255.     mov    ax,dgroup
  256.     mov    es,ax
  257.     cli
  258.     mov    ax,ss
  259.     mov    word ptr stack8+2,ax    ; save current stack
  260.     mov    word ptr stack8,sp
  261.     mov    ax,word ptr tcpstack+2    ; get TCP stack seg
  262.     mov    ss,ax            ; set to TCP stack
  263.     mov    sp,word ptr tcpstack
  264.     sti                ; restart interrupts
  265.     xor    ax,ax            ; socket pointer, null
  266.     push    ax            ; set call frame for tcp_tick(NULL)
  267.  
  268.     call    _tcp_tick        ; process some incoming packets
  269.     pop    ax            ; clean call frame
  270.     mov    ax,word ptr stack8+2    ; get original stack seg
  271.     cli
  272.     mov    ss,ax
  273.     mov    sp,word ptr stack8
  274.     sti
  275.     pop    es
  276.     pop    di
  277.     pop    si
  278.     pop    dx
  279.     pop    cx
  280.     pop    bx
  281.     pop    bp
  282.     and    tcpflag,not 2        ; finished our running of TCP code
  283. ourtim2:pop    ax
  284.     pop    ds
  285.     iret
  286. ourtimer endp
  287.  
  288. ; This routine is invoked from outside by a Far call. Enter with the caller's
  289. ; registers but our CS. Switch stacks and data segments.
  290. ; This version supports 3Com BAPI calls and does the near/far stuff via
  291. ; a local buffer.
  292.     public    ktcpcom
  293. ktcpcom     proc    FAR            ; i/o service routine
  294.     assume    ds:DGROUP, es:nothing
  295.     push    ds
  296.     push    ax
  297.     mov    ax,dgroup        ; set addressibility to our dgroup
  298.     mov    ds,ax
  299.     pop    ax
  300.     test    tcpflag,2        ; is Int 8 running TCP?
  301.     jz    ourser8            ; z = no, opposite should never happen
  302. ourser7:mov    ah,1            ; say no char written
  303.     xor    cx,cx            ; chars written
  304.     pop    ds
  305.     ret
  306.  
  307. ourser8:or    tcpflag,1        ; say we are running TCP
  308.     cmp    hooked,0        ; have we inited (hooked vectors)?
  309.     jz    ourser7            ; z = no, report nothing
  310.     push    es            ; save regs on the user's stack
  311.     push    di
  312.     push    si
  313.     push    dx
  314.     push    bx
  315.     push    bp
  316.     mov    kstack,sp        ; remember caller's stack now
  317.     mov    sp,word ptr tcpstack    ; move to our TCP stack
  318.     mov    word ptr _bapiadr,bx    ; remember caller's es:bx
  319.     mov    word ptr _bapiadr+2,es    ;  (i/o buffer address)
  320.     mov    _bapireq,cx        ; requested char count to TCP code
  321.     mov    _bapiret,0        ; init returned CX char count
  322.     cmp    ah,bapihere        ; presence check?
  323.     jne    ourser2            ; ne = no
  324.     mov    ax,0af01h        ; return this value
  325.     jmp    ourser4            ; done
  326.  
  327. ourser2:cmp    ah,bapiread        ; read?
  328.     jne    ourser3            ; ne = no
  329.     cmp    _msgcnt,0        ; any outstanding msgs from TCP?
  330.     je    ourser3            ; e = no msgs
  331.     call    oursmsg            ; send back the msgs instead
  332.     jmp    short ourser4        ; ax has status of ok
  333. ourser3:sti                ; let other ints happen
  334.     mov    bx,dgroup        ; set up es to dgroup too
  335.     mov    es,bx            ; bx is not needed at this time
  336.     ASSUME    DS:DATA
  337.     push    ds
  338.     mov    bx,seg data        ; address main body
  339.     mov    ds,bx
  340.     mov    es:_kserver,0        ; assume not a server
  341.     test    flags.remflg,dserver    ; Server mode?
  342.     jz    ourser3a        ; z = no
  343.     mov    es:_kserver,1        ; say being a server
  344. ourser3a:mov    bx,offset tcpdata    ; offset of Kermit tcp data block
  345.     mov    bx,[bx+26]        ; debug-Options
  346.     mov    bx,[bx]
  347.     mov    es:_kdebug,bx
  348.     pop    ds            ; return ds to dgroup
  349.  
  350.     ASSUME    DS:DGROUP
  351.     xchg    ah,al            ; put BAPI function code in al
  352.     xor    ah,ah
  353.     push    ax            ; setup call frame
  354.  
  355.     call    _serial_handler        ; a near call, _serial_handler(ax)
  356.                     ; reg ax has return status
  357.     add    sp,2            ; clean stack
  358.     mov    cx,dgroup        ; safety check, not really needed
  359.     mov    ds,cx
  360.     mov    cx,_bapiret        ; count of chars returned
  361.  
  362. ourser4:clc                ; assume success
  363.     xchg    ah,al            ; put return status in ah
  364.     xor    al,al
  365.     cmp    ah,3            ; serious error status?
  366.     jb    ourserx            ; b = no, zero is success
  367.     stc                ; set carry too
  368. ourserx:mov    sp,kstack         ; move to caller's stack
  369.     and    tcpflag,not 1        ; say we are not running TCP
  370.     pop    bp
  371.     pop    bx
  372.     pop    dx
  373.     pop    si
  374.     pop    di
  375.     pop    es
  376.     pop    ds
  377.     ret                ; AX and CX are changed as returns
  378. ktcpcom endp
  379.  
  380. ; Copy contents of msgbuf (local Telnet msg collector buffer) to main body.
  381. ; For use only by Telnet code as an internal procedure.
  382. oursmsg    proc    near
  383.     assume    ds:DGROUP, es:nothing
  384.     mov    cx,_msgcnt
  385.     jcxz    ourser3            ; z = no msgs
  386.     cmp    cx,_bapireq        ; longer than request?
  387.     jbe    oursmsg1        ; be = no
  388.     mov    cx,_bapireq        ; do this much now
  389. oursmsg1:push    cx
  390.     mov    si,offset DGROUP:_msgbuf ; whence it comes
  391.     les    di,_bapiadr        ; where it goes
  392.     cld
  393.     rep    movsb            ; copy our buffer to theirs
  394.     pop    cx            ; return count in cx
  395.     mov    _bapiret,cx        ; return count to user
  396.     sub    _msgcnt,cx        ; deduct chars relayed
  397.     cmp    _msgcnt,0        ; examine remainder
  398.     je    oursmsg3        ; e = none
  399.     mov    ax,_msgcnt        ; count
  400.     push    ax
  401.     mov    ax,offset DGROUP:_msgbuf
  402.     push    ax            ; destination
  403.     add    ax,_msgcnt        ; source
  404.     push    ax
  405.     call    _bcopy            ; copy to beginning of buffer
  406.     add    sp,6            ; clean stack
  407. oursmsg3:xor    ax,ax            ; return status of success
  408.     ret
  409. oursmsg    endp
  410.  
  411.  
  412. ; tcpaddress db    'unknown',(32-($-tcpaddress)) dup (0),0
  413. ; tcpsubnet  db    '255.255.255.0',(32-($-tcpsubnet)) dup (0),0
  414. ; tcpdomain  db    'unknown',(32-($-tcpdomain)) dup (0),0
  415. ; tcpgateway db    'unknown',(32-($-tcpgateway)) dup (0),0
  416. ; tcpprimens db    'unknown',(32-($-tcpprimens)) dup (0),0
  417. ; tcpsecondns db 'unknown',(32-($-tcpsecondns)) dup (0),0
  418. ; tcphost db    (60 -($-tcphost)) dup (0),0
  419. ; tcpbcast db    '255.255.255.255',(32-($-tcpbcast)) dup (0),0
  420. ; tcpport dw    23
  421. ; tcppdint dw    0
  422. ; tcpttbuf db    32 dup (0),0        ; term-type-override buffer
  423. ; tcpdata dw    offset tcpaddress ; externally visible far pointers
  424. ;     dw    offset tcpsubnet    + 2
  425. ;     dw    offset tcpdomain    + 4
  426. ;     dw    offset tcpgateway    + 6
  427. ;     dw    offset tcpprimens    + 8
  428. ;     dw    offset tcpsecondns    + 10
  429. ;    dw    offset tcphost        + 12
  430. ;    dw    offset tcpbcast        + 14
  431. ;    dw    offset tcpport        + 16
  432. ;    dw    offset tcppdint        + 18
  433. ;    dw    offset tcpttbuf        + 20
  434. ;    dw    offset tcpbtpserver    + 22
  435. ;    dw    offset tcpnewline    + 24
  436. ;    dw    offset tcpdebug        + 26
  437.  
  438. ; Open a TCP/IP Telnet connection. Returns -1 if failure or if success it
  439. ; returns the small int session ident code. Creates a new session; use
  440. ; ktcpswap to reactivate existing sessions.
  441.     public    ktcpopen
  442. ktcpopen proc    far
  443.     ASSUME    DS:DATA, ES:DGROUP
  444.     push    es            ; save regs on main Kermit stack
  445.     push    ds
  446.     push    di
  447.     push    si
  448.     push    dx
  449.     push    cx
  450.     push    bx
  451.     push    bp
  452.     mov    ax,DGROUP
  453.     mov    es,ax            ; destination is the TCP module
  454.  
  455.     or    es:tcpflag,1        ; say this is running TCP code
  456.  
  457.     cld
  458.     mov    bx,offset tcpdata    ; offset of Kermit tcp data block
  459.     mov    es:ourtcpdata,bx    ; copy to local data seg
  460.     mov    si,[bx]            ; get offset of our IP address
  461.     mov    di,offset DGROUP:_kmyip    ; our storage slot
  462.     mov    cx,16            ; max bytes
  463. start5:    lodsb
  464.     stosb
  465.     or    al,al
  466.     loopne    start5            ; copy IP address string, asciiz
  467.     xor    al,al            ; extra terminator
  468.     stosb
  469.     mov    si,[bx+2]        ; get offset in Kermit
  470.     mov    di,offset DGROUP:_knetmask
  471.     mov    cx,16
  472. start6:    lodsb
  473.     stosb
  474.     or    al,al
  475.     loopne    start6
  476.     xor    al,al
  477.     stosb
  478.     mov    si,[bx+4]            ; get offset in Kermit
  479.     mov    di,offset DGROUP:_kdomain
  480.     mov    cx,32
  481. start7:    lodsb
  482.     stosb
  483.     or    al,al
  484.     loopne    start7
  485.     xor    al,al
  486.     stosb
  487.     mov    si,[bx+6]            ; get offset in Kermit
  488.     mov    di,offset DGROUP:_kgateway
  489.     mov    cx,16
  490. start8:    lodsb
  491.     stosb
  492.     or    al,al
  493.     loopne    start8
  494.     xor    al,al
  495.     stosb
  496.     mov    si,[bx+8]            ; get offset in Kermit
  497.     mov    di,offset DGROUP:_kns1
  498.     mov    cx,16
  499. start9:    lodsb
  500.     stosb
  501.     or    al,al
  502.     loopne    start9
  503.     xor    al,al
  504.     stosb
  505.     mov    si,[bx+10]            ; get offset in Kermit
  506.     mov    di,offset DGROUP:_kns2
  507.     mov    cx,16
  508. start10:lodsb
  509.     stosb
  510.     or    al,al
  511.     loopne    start10
  512.     xor    al,al
  513.     stosb
  514.     mov    si,[bx+12]            ; get offset in Kermit
  515.     mov    di,offset DGROUP:_khost
  516.     mov    cx,60
  517. start11:lodsb
  518.     stosb
  519.     or    al,al
  520.     loopne    start11
  521.     xor    al,al
  522.     stosb
  523.     mov    si,[bx+14]            ; broadcast address
  524.     mov    di,offset DGROUP:_kbcast
  525.     mov    cx,16
  526. start12:lodsb
  527.     stosb
  528.     or    al,al
  529.     loopne    start12
  530.     xor    al,al
  531.     stosb
  532.     mov    si,[bx+16]        ; TCP port
  533.     mov    ax,[si]
  534.     mov    es:_kport,ax
  535.     mov    si,[bx+18]        ; Packet Driver Interrupt
  536.     mov    ax,[si]
  537.     mov    es:_kpdint,ax        ; 0 means scan
  538.     mov    si,[bx+20]        ; offset of term-type string
  539.     mov    di,offset DGROUP:_ktttype ; local storage of the string
  540.     mov    cx,32
  541. start13:lodsb
  542.     stosb
  543.     or    al,al
  544.     loopne    start13
  545.     xor    al,al
  546.     stosb
  547.     mov    si,[bx+26]        ; debug-Options
  548.     mov    ax,[si]
  549.     mov    es:_kdebug,ax
  550.  
  551.     mov    es:_display_mode,0    ; presume quiet screen
  552.     test    flags.remflg,dquiet    ; quiet display mode?
  553.     jnz    start14            ; nz = yes. Don't write to screen
  554.     inc    es:_display_mode    ; say can write to screen
  555. start14:mov    es:_kserver,0        ; assume not a server
  556.     test    flags.remflg,dserver    ; Server mode?
  557.     jz    start16            ; z = no
  558.     mov    es:_kserver,1        ; say being a server (do Listen)
  559. start16:mov    ax,flags.vtflg        ; get terminal type index
  560.     mov    es:_kterm,ax
  561.     mov    al,crt_lins        ; get display height
  562.     mov    es:_kterm_lines,al
  563.     mov    al,crt_cols        ; get display width
  564.     mov    es:_kterm_cols,al
  565.  
  566. start20:mov    bx,portval
  567.     mov    al,[bx].ecoflg        ; get mainline SET echo flag
  568.     xor    ah,ah
  569.     mov    es:_echo,ax        ; init Telnet echo status
  570.     mov    bx,tcptos        ; top of stack for tcp code
  571.  
  572.     assume    ds:DGROUP, ES:NOTHING
  573.     
  574.     mov    ax,dgroup        ; set addressibility to our dgroup
  575.     mov    ds,ax
  576.     mov    es,ax
  577.                     ; cold vs warm start
  578.     mov    word ptr kstack,sp    ; store Kermit's stack ptr
  579.     cmp    word ptr tcpstack+2,0    ; defined setup yet?
  580.     je    start1            ; e = no, get stack segment
  581.     mov    ax,word ptr tcpstack    ; set sp to existing TCP sp
  582.     mov    sp,ax            ; warm restart
  583.     jmp    short start2
  584.  
  585. start1:    mov    word ptr tcpstack+2,ax    ; set TCP stack seg to DGROUP
  586.     mov    word ptr tcpstack,bx    ; cold start
  587.     mov    sp,bx            ; new TCP stack pointer, DGROUP based
  588.  
  589. start2:    mov    bp,sp            ; preset this as insurance
  590.     or    tcpflag,1        ; say this is running TCP code
  591.  
  592.     call    _main            ; call the C code
  593.     mov    sp,word ptr kstack    ; restore for Kermit's main stack
  594.     ASSUME    ES:DATA
  595.     mov    bx,data            ; main Kermit data segment
  596.     mov    es,bx
  597.     mov    bx,offset tcpdata    ; pointer to storage word
  598.     mov    cx,_kpdint        ; report back Packet Driver Int
  599.     mov    bx,es:[bx+18]        ; get address of storage slot
  600.     mov    es:[bx],cx        ; store value in main data seg
  601.     ASSUME    ES:NOTHING
  602.     and    tcpflag,not 1        ; finished running tcp code
  603.     pop    bp            ; restore regs, Kermit's main stack
  604.     pop    bx
  605.     pop    cx
  606.     pop    dx
  607.     pop    si
  608.     pop    di
  609.     pop    ds
  610.     pop    es
  611.     ret                ; return to caller, status in AX
  612. ktcpopen endp
  613.  
  614. ; Close session whose session ident is in register AL. If AL holds -1
  615. ; then shut down all sessions and shutdown Telnet. Returns ident of next
  616. ; active session (cyclic from the current session ident) or -1 if none
  617. ; remains active.
  618.     public    ktcpclose
  619. ktcpclose proc    far
  620.     assume    ds:dgroup, es:nothing
  621.     push    es            ; save regs on the user's stack
  622.     push    ds
  623.     push    di
  624.     push    si
  625.     push    dx
  626.     push    cx
  627.     push    bx
  628.     push    bp
  629.     mov    cx,dgroup        ; set addressibility to dgroup
  630.     mov    ds,cx
  631.     mov    es,cx
  632.     mov    kstack,sp        ; remember Kermit's main sp
  633.     or    tcpflag,1        ; say we are running TCP code
  634.     mov    cx,word ptr tcpstack    ; set sp to TCP sp
  635.     mov    sp,cx
  636.     mov    bp,sp            ; preset this as insurance
  637.     cbw                ; sign extend
  638.     cmp    al,-1            ; close all sessions and TCP/IP?
  639.     je    ktcpclo5        ; e = yes
  640.     push    ax            ; AL = session number
  641.     call    _session_close        ; close this session
  642.     add    sp,2            ; returns status in AL
  643.     jmp    short ktcpclo6        ; common completion code
  644.  
  645. ktcpclo5:                ; forceful shutdown of TCP/IP Telnet
  646.     xor    ax,ax
  647.     push    ax            ; exit(0) setup
  648.     call    _exit
  649.     add    sp,2            ; returns status in AX
  650.     mov    tempax,ax
  651.     mov    ax,word ptr tcpstack    ; set sp to TCP sp again
  652.     mov    sp,ax
  653.     mov    bp,sp            ; preset this as insurance
  654.     call    _pkt_release        ; do this as insurance
  655.     call    unhookvect        ; ditto
  656.     mov    ax,tempax        ; regain status
  657. ktcpclo6:cbw                ; sign extend
  658.     mov    tcpflag,0        ; no one is running the TCP code
  659.     mov    sp,kstack
  660.     pop    bp            ; restore regs, Kermit's main stack
  661.     pop    bx
  662.     pop    cx
  663.     pop    dx
  664.     pop    si
  665.     pop    di
  666.     pop    ds
  667.     pop    es
  668.     ret                ; return to caller
  669. ktcpclose endp
  670.  
  671. ; Change active sessions. Enter with AL holding desired session ident.
  672. ; Returns -1 if failure, else returns active session ident.
  673.     public    ktcpswap
  674. ktcpswap proc    far
  675.     assume    ds:dgroup, es:nothing
  676.     push    es            ; save regs on the user's stack
  677.     push    ds
  678.     push    di
  679.     push    si
  680.     push    dx
  681.     push    cx
  682.     push    bx
  683.     push    bp
  684.     mov    cx,dgroup        ; set addressibility to our dgroup
  685.     mov    ds,cx
  686.     mov    es,cx
  687.     or    tcpflag,1        ; say we are running TCP code
  688.     mov    kstack,sp        ; remember Kermit's main sp
  689.     mov    sp,word ptr tcpstack    ; move to our TCP stack
  690.     mov    bp,sp            ; preset this as insurance
  691.  
  692.     cbw                ; sign extend now
  693.     push    AX            ; new session number
  694.     call    _session_change
  695.     add    sp,2            ; pop argument, status is in AX
  696.     mov    tcpflag,0        ; no one is running the TCP code
  697.     mov    sp,kstack
  698.     pop    bp            ; restore regs, Kermit's main stack
  699.     pop    bx
  700.     pop    cx
  701.     pop    dx
  702.     pop    si
  703.     pop    di
  704.     pop    ds
  705.     pop    es
  706.     ret                ; return to caller
  707. ktcpswap endp
  708.  
  709. ; Copies TCP/IP info from Telnet space to main Kermit space via table of
  710. ; pointers tcpdata (in segment data, file mssset.asm).
  711. ; For use only by Telnet code as an internal procedure.
  712.     public    _readback
  713. _readback proc    near
  714.     assume    ds:dgroup, es:nothing
  715.     push    bp
  716.     mov    bp,sp
  717.     push    si
  718.     push    di
  719.     push    es
  720.     mov    si,offset dgroup:_kmyip
  721.     push    si
  722.     push    si                ; argument
  723.     call    _strlen                ; get length of string
  724.     add    sp,2                ; ax has string length
  725.     pop    si
  726.  
  727.     assume    ds:dgroup, es:data
  728.  
  729.     mov    di,data
  730.     mov    es,di
  731.  
  732.     mov    di,ourtcpdata            ; copy to Kermit main body
  733.     push    di
  734.     mov    di,es:[di]            ; offset of the string
  735.     mov    cx,ax                ; length
  736.     cld
  737.     rep    movsb
  738.     xor    al,al
  739.     stosb                    ; terminator
  740.     mov    si,offset dgroup:_knetmask
  741.     pop    di
  742.     push    di
  743.     mov    di,es:[di+2]
  744.     mov    cx,17
  745.     rep    movsb
  746.     stosb                    ; terminator
  747.     mov    si,offset dgroup:_kdomain
  748.     pop    di
  749.     push    di
  750.     mov    di,es:[di+4]
  751.     mov    cx,32
  752.     rep    movsb
  753.     stosb                    ; terminator
  754.     pop    di
  755.     mov    si,offset dgroup:_kgateway
  756.     push    di
  757.     mov    di,es:[di+6]
  758.     mov    cx,17
  759.     rep    movsb
  760.     stosb                    ; terminator
  761.     mov    si,offset dgroup:_kns1
  762.     pop    di
  763.     push    di
  764.     mov    di,es:[di+8]
  765.     mov    cx,17
  766.     rep    movsb
  767.     stosb                    ; terminator
  768.     mov    si,offset dgroup:_kns2
  769.     pop    di
  770.     push    di
  771.     mov    di,es:[di+10]
  772.     mov    cx,17
  773.     rep    movsb
  774.     stosb                    ; terminator
  775.     mov    si,offset dgroup:_khost
  776.     pop    di
  777.     push    di
  778.     mov    di,es:[di+12]
  779.     mov    cx,60
  780.     rep    movsb
  781.     stosb                    ; terminator
  782.     pop    di
  783.     mov    di,es:[di+22]
  784.     mov    cx,16
  785.     mov    si,offset dgroup:_kbtpserver
  786.     rep    movsb
  787.     stosb                    ; terminator
  788.     pop    es
  789.     pop    di
  790.     pop    si
  791.     pop    bp
  792.     ret
  793. _readback endp
  794.  
  795. ; Track Telnet echo variable (0 do not do local echo) into terminal emulator
  796. ; and Kermit main body. Call this each time Telnet options change echo.
  797. ; For use only by Telnet code as an internal procedure.
  798.     public    _kecho
  799. _kecho    proc    near
  800.     assume    ds:data, es:dgroup
  801.     push    bp
  802.     mov    bp,sp
  803.     push    ds
  804.     push    es
  805.     push    si
  806.     push    ax
  807.     mov    ax,data            ; Kermit main data segment
  808.     mov    ds,ax
  809.     mov    ax,dgroup
  810.     mov    es,ax
  811.     mov    ax,[bp+4+0]        ; get Telnet _echo variable
  812.     and    yflags,not lclecho    ; assume no local echo in emulator
  813.     or    al,al            ; Telnet local echo is off?
  814.     jz    kecho1            ; z = yes
  815.     mov    al,lclecho        ; lclecho flag for emulator
  816. kecho1:    or    yflags,al        ; set terminal emulator
  817.     mov    si,portval
  818.     mov    [si].ecoflg,al        ; set mainline SET echo flag
  819.     cmp    ttyact,0        ; acting as a Terminal?
  820.     je    kecho2            ; e = no
  821.     call    dword ptr ftogmod    ; toggle mode line
  822.     call    dword ptr ftogmod    ; and again
  823. kecho2:    pop    ax
  824.     pop    si
  825.     pop    es
  826.     pop    ds
  827.     pop    bp
  828.     ret
  829. _kecho    endp
  830. _TEXT    ends
  831.         end
  832.  
  833.