home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msk230s1.zip / MSSSER.ASM < prev    next >
Assembly Source File  |  1988-02-12  |  78KB  |  1,637 lines

  1.         NAME    mssser
  2. ; File MSSSER.ASM
  3. ; Edit history:
  4. ; Last edit: 1 Jan 1988
  5. ; 1 Jan 1988 version 2.30
  6. ; 26 Dec 1987 Telescope Bye, Fin, Logout commands, clean up. [jrd]
  7. ; 12 Dec 1987 Add TEK denyflg to defeat automatic invokation of Tek graphics
  8. ;  by ESC Control-L when in Connect mode. [jrd]
  9. ; 24 Oct 1987 Ignore received Naks in Server idle loop
  10. ; 21 Sept 1987 Add error exit in GET for filenames too long for packet. [jrd]
  11. ; 26 Aug 1987 Add Remote Send to remote help response. [jrd]
  12. ; 19 Aug 1987 Correct local override name for files sent to/from server. [jrd]
  13. ; 31 July 1987 Redo Logo, Bye, Fin to not shift block check when repeating.
  14. ; 25 July 1987 Add global word denyflg to control server restrictions,
  15. ;  and revise server functions accordingly. [jrd]
  16. ; 6 July 1987 Correct Server mode ACKs to use 1 char checksum throughout.[jrd]
  17. ; 25 June 1987 Add exit to DOS for LOGO and exit to Kermit prompt for
  18. ;  FIN command reception, for use with CTTY operation of server. [jrd]
  19. ; 7 June 1987 Add DOS errlev of 4 when REMOTE commands to Server fail. [jrd]
  20. ; 16 April 1987 Clear local filename in Server idle loop, from Jack Bryans.
  21. ; 5 April 1987 Set flags.xflg around Generic I-pkt sends to suppress on-screen
  22. ;  display of retry counts. Put cursor on line 25 at end of Server cmds. [jrd]
  23. ; 25 March 1987 Add Disable/Enable Delete/Host commands. [jrd]
  24. ; 9 March 1987 Add calls to statistics functions. [jrd]
  25. ; 6 March 1987 Respond to FIN, LOGO, BYE while in server mode
  26. ;   with 1 byte checksums. Thanks to Jack Bryans.
  27. ;   Triple waiting time in Server idle loop (fewer NAKs/minute). [jrd]
  28. ; 22 Feb 1987 Add Server SEND and WHO commands (both directions). [jrd]
  29. ; 1 Oct 1986 Version 2.29a
  30. ; 10 Sept 1986 Add display of ACK pkt in LOGO and FIN. Remove forced output
  31. ;  to screen for REMOTE cmds; thanks to Bill Porteous.
  32. ;  Add ACK message for received Bye, Logo, Fin commands. [jrd]
  33. ; 6 Sept 1986 Output cr/lf for REMote commands before rcving 1st pkt. [jrd]
  34. ; 14 August 1986 Allow changing EOL chars. [jrd]
  35. ; Modify Srvsnd to handle Set Dest Screen properly. [jrd]
  36. ; Correct negotiation on 8 bit quoting, fix checksum resetting. [jrd]
  37. ; 26 July 1986 Change ref to ext symbol rpack5 to be rpack. [jrd]
  38. ; 16 June 1986 Clear packet counters at start of Get command.
  39. ;  Also correct use of wrong block check type in Server mode. [jrd]
  40. ; 26 May 1986 Revise code to permit serial display. [jrd]
  41. ; 14 May 86 - Modify action routine for reception of 'E' packets in server
  42. ;  mode to be rskp rather than serv1. From Tad Marshall.
  43. ; Insert tests for Remote Kermit commands in proc genric to avoid counted
  44. ;  strings. [jrd]
  45. ; [2.29] code frozen on 6 May 1986 [jrd]
  46.  
  47.         public  logout, bye, finish, remote, get, server, srvdsa, srvena
  48.         public  denyflg
  49.         include mssdef.h
  50.  
  51. datas   segment public 'datas'
  52.         extrn   data:byte, flags:byte, trans:byte, pack:byte, curchk:byte
  53.         extrn   curdsk:byte, diskio:byte, locfil:byte, comand:byte, rptq:byte
  54.         extrn   filtst:byte, maxtry:byte, imxtry:byte, dtrans:byte,fmtdsp:byte
  55.         extrn   inichk:byte, errlev:byte, portval:word
  56.  
  57. scrser  equ     0023H           ; place for server state display line
  58. scrsrm  equ     1000H           ; place for messages and dos echoes
  59. cwdflg  equ     1               ; deny remote cwd
  60. delflg  equ     2               ; deny remote del
  61. dirflg  equ     4               ; deny remote dir
  62. hostflg equ     8               ; deny remote host
  63. spcflg  equ     10H             ; deny remote space
  64. finflg  equ     20H             ; deny fin, bye, logo to server
  65. getsflg equ     40H             ; deny paths in get cmds to server
  66. sndflg  equ     80H             ; deny paths in send cmds to server
  67. typflg  equ     100H            ; deny paths in type
  68. tekxflg equ     200h            ; deny automatic Tektronix invokation
  69.  
  70. remcmd  db      0               ; Remote command to be executed.
  71. rempac  db      0               ; Packet type: C (host) or G (generic).
  72.  
  73. cmer05  db      cr,lf,'?Filename must be specified$'
  74. ermes6  db      '?Filename too long for packet$'
  75. erms18  db      cr,lf,'?Unable to get response from host$'
  76. erms21  db      cr,lf,'?Unable to tell host to execute command$'
  77. infms1  db      'Server mode',cr,lf,'$'
  78. remms1  db      'Kermit-MS Server: Unknown server command$'
  79. remms2  db      'Kermit-MS Server: Illegal file name$'
  80. remms3  db      'Kermit-MS Server: Could not create help file$'
  81. remms4  db      'Kermit-MS Server: Unable to change directories$'
  82. remms5  db      'Kermit-MS Server: No such file(s)$'
  83. remms6  db      'Kermit-MS Server: Could not create directory listing$'
  84. remms7  db      'Kermit-MS Server: Could not create space listing$'
  85. remms8  db      'Kermit-MS Server: Protected or no such file(s)$'
  86. remms9  db      'Kermit-MS Server: Command is Disabled$'
  87. remms10 db      'Kermit-MS Server: Could not create work file$'
  88. byemsg  db      'Kermit-MS Server:  Goodbye!',0
  89. whomsg  db      'Kermit-MS Server: Just this Server',0
  90. sdshlp  db      cr,lf,'Server restricts access of selected commands:',cr,lf
  91.         db      '  CWD, DEL, DIR, FIN (incl BYE & LOGO), GET, SEND, SPACE,'
  92.         db      ' TYPE, and ALL.'
  93.         db      cr,lf,'Also TEK (automatic invokation of Tek4010 graphics);'
  94.         db      ' not a member of ALL.$'
  95. senhlp  db      cr,lf,'Server permits full access of selected commands:',cr,lf
  96.         db      '  CWD, DEL, DIR, FIN (incl BYE & LOGO), GET, SEND, SPACE,'
  97.         db      ' TYPE, and ALL.'
  98.         db      cr,lf,'Also TEK (automatic invokation of Tek4010 graphics);'
  99.         db      ' not a member of ALL.$'
  100. pass    db      lf,cr,' Password: $'    ; When change directory
  101. srvtmp  db      ' >$kermit$.tmp ',0     ; asciiz, kermit's temp output file
  102. delstr  db      'del ',0
  103. dirstr  db      'dir ',0
  104. spcstr  db      'chkdsk.com ',0
  105. crlf    db      cr,lf,'$'
  106. curstim db      ?                       ; normal waiting time for packets
  107. denyflg dw      0                       ; bit field of denied commands
  108. temp    dw      0
  109. inpbuf  dw      0                       ; Pointer to input buffer.
  110. cnt     dw      0
  111.  
  112. srvchr  db      'SRGIEC'                ; server cmd characters
  113. srvfln  equ     $-srvchr                ; length of tbl
  114. srvfun  dw      srvsnd,srvrcv,srvgen,srvini,rskp,srvhos ; order as in srvchr
  115.  
  116. remhlp  db      cr,lf,'CWD        change working directory'     ; Answer to
  117.         db      cr,lf,'Delete     a file'                       ; local
  118.         db      cr,lf,'Directory  filespec'                     ; REM HELP
  119.         db      cr,lf,'Help'
  120.         db      cr,lf,'Host       command'
  121.         db      cr,lf,'Kermit     command'
  122.         db      cr,lf,'Send       short one line message'
  123.         db      cr,lf,'Space      in a directory'
  124.         db      cr,lf,'Type       a file'
  125.         db      cr,lf,'Who        user spec$'
  126.  
  127.                                         ; Answer from Server to REMOTE HELP
  128. hlprem  db      cr,lf,'Kermit-MS Server commands:',lf
  129.         db      cr,lf,'GET filespec          REMOTE DELETE filespec     '
  130.         db      'REMOTE SEND message'
  131.         db      cr,lf,'SEND filespec         REMOTE DIRECTORY filespec  '
  132.         db      'REMOTE SPACE'
  133.         db      cr,lf,'FIN, LOGO, and BYE    REMOTE HELP                '
  134.         db      'REMOTE TYPE filespec'
  135.         db      cr,lf,'REMOTE CWD directory  REMOTE HOST command        '
  136.         db      'REMOTE WHO',0                          ; null terminated
  137.  
  138. remtab  db      10              ; 10 entries
  139.         mkeyw   'CWD',remcwd
  140.         mkeyw   'Delete',remdel
  141.         mkeyw   'Directory',remdir
  142.         mkeyw   'Help',remhel
  143.         mkeyw   'Host',remhos
  144.         mkeyw   'Kermit',remker
  145.         mkeyw   'Send',remsen
  146.         mkeyw   'Space',remdis
  147.         mkeyw   'Type',remtyp
  148.         mkeyw   'Who',remwho
  149.  
  150. srvtab  db      11                      ; Server Enable/Disable list
  151.         mkeyw   'All',01ffh
  152.         mkeyw   'Cwd',cwdflg
  153.         mkeyw   'Delete',delflg
  154.         mkeyw   'Dir',dirflg
  155.         mkeyw   'Fin',finflg
  156.         mkeyw   'Get',getsflg
  157.         mkeyw   'Host',hostflg
  158.         mkeyw   'Send',sndflg
  159.         mkeyw   'Space',spcflg
  160.         mkeyw   'Tek4010',tekxflg       ; for automatic Tektronix invokation
  161.         mkeyw   'Type',typflg
  162.  
  163. remfnm  db      ' Remote Source File: $'
  164. lclfnm  db      ' Local Destination File: $'
  165. filhlp  db      ' File name to use locally$'
  166. filmsg  db      ' Remote filename or confirm with carriage return $'
  167. frem    db      ' Name of file on remote system $'
  168. genmsg  db      ' Enter text to be sent to remote server $'
  169. srvbuf  db      80H dup (0)
  170. rdbuf   db      20 dup (0)
  171. datas   ends
  172.  
  173. code    segment public 'code'
  174.         extrn comnd:near, serrst:near, spack:near, rpack:near, init:near
  175.         extrn read12:near, serini:near, read2:near, rpar:near, spar:near
  176.         extrn rin21:near, rfile3:near, error1:near, clrfln:near
  177.         extrn dodel:near, clearl:near, dodec: near, doenc:near
  178.         extrn packlen:near, send11:near, errpack:near, pktsize:near
  179.         extrn nak:near, rrinit:near, cmblnk:near, poscur:near
  180.         extrn erpos:near, rprpos:near, clrmod:near, crun:near
  181.         extrn prompt:near, updrtr:near, cmgetc:near, prtfn:near, prtscr:near
  182.         extrn strcat:near, strlen:near, strcpy:near, fparse:near, isfile:near
  183.         extrn prtasz:near, ihosts:near, begtim:near, endtim:near
  184.         assume  cs:code, ds:datas, es:nothing
  185.  
  186.  
  187. ; BYE command - tell remote KERSRV to logout & exits to DOS.
  188.  
  189. BYE     PROC    NEAR
  190.         mov     ah,cmcfm                ; Parse a confirm.
  191.         call    comnd
  192.          jmp    r
  193.         mov     remcmd,'L'              ; Logout command letter
  194.         call    logo                    ; Tell the mainframe to logout.
  195.          jmp    rskp                    ; Failed - don't exit.
  196.         mov     flags.extflg,1          ; Set exit flag.
  197.         jmp     rskp
  198. BYE     ENDP
  199.  
  200. ; FINISH - tell remote KERSRV to exit.
  201.  
  202. FINISH  PROC    NEAR
  203.         mov     ah,cmcfm                ; Parse a confirm.
  204.         call    comnd
  205.          jmp    r
  206.         mov     remcmd,'F'              ; Finish command letter
  207.         call    logo
  208.          jmp    rskp
  209.         jmp     rskp
  210. FINISH  ENDP
  211.  
  212. ; LOGOUT - tell remote KERSRV to logout.
  213.  
  214. LOGOUT  PROC    NEAR
  215.         mov     ah,cmcfm
  216.         call    comnd                   ; Get a confirm.
  217.          jmp    r
  218.         mov     remcmd,'L'              ; Logout command letter
  219.         call    logo
  220.          jmp    rskp                    ; Go get another command whether we
  221.         jmp     rskp                    ;  succeed or fail.
  222. LOGOUT  ENDP
  223.  
  224. ; Common routine for FIN, LOGOUT, BYE
  225. LOGO    PROC    NEAR
  226.         mov     pack.numtry,0           ; Initialize count.
  227.         mov     pack.numrtr,0           ; No retries yet.
  228.         call    serini                  ; Initialize port.
  229.         call    ihosts                  ; initialize the host
  230.         mov     ah,trans.chklen         ; Don't forget the checksum length.
  231.         mov     curchk,ah
  232.         mov     trans.chklen,1          ; Use one char for server functions.
  233.         call    begtim                  ; start statistics
  234. logo1:  cmp     pack.state,'A'          ; Did user type a ^C?
  235.         je      log2x               ; e = yes, leave in failure state for Bye.
  236.         mov     ah,pack.numtry
  237.         cmp     ah,maxtry               ; Too many times?
  238.         jl      logo3                   ; No, try it.
  239. logo2:  mov     ah,prstr
  240.         mov     dx,offset erms18
  241.         int     dos
  242. log2x:  call    serrst                  ; Reset port
  243.         mov     ax,1            ; tell statistics this was a send operation
  244.         call    endtim                  ; finish statistics
  245.         mov     ah,curchk
  246.         mov     trans.chklen,ah         ; Restore value.
  247.         ret                             ; and exit in failure state for Bye
  248. logo3:  inc     pack.numtry             ; Increment number of tries.
  249.         mov     pack.argblk,0           ; Packet number zero.
  250.         mov     pack.argbk1,1           ; One piece of data.
  251.         mov     ah,remcmd               ; get command letter ('L' or 'F')
  252.         mov     data,ah                 ; Logout the remote host.
  253.         mov     cx,1                    ; One piece of data.
  254.         call    doenc                   ; Do encoding.
  255.         mov     ah,'G'                  ; Generic command packet.
  256.         call    spack
  257.          jmp    logo2                   ; Tell user and die.
  258.          nop
  259.         call    rpack                   ; Get ACK (w/o screen msgs.)
  260.          jmp    logo1                   ; Go try again.
  261.          nop
  262.         push    ax
  263.         call    dodec                   ; Decode packet.
  264.         pop     ax
  265.         cmp     ah,'Y'                  ; ACK?
  266.         jne     logo4
  267.         cmp     pack.argbk1,0           ; Any data in the ACK?
  268.         je      logo6                   ; Nope - just return.
  269.         mov     ah,prstr                ; output a cr/lf
  270.         mov     dx,offset crlf
  271.         int     dos
  272.         mov     di,offset data          ; Where the reply is.
  273.         mov     cx,pack.argbk1          ; How much data we have.
  274.         call    prtscr                  ; Print it on the screen.
  275.         jmp     logo6                   ; and exit
  276. logo4:  cmp     ah,'E'                  ; Error packet?
  277.         je      logo5                   ; e = yes
  278.         jmp     logo1                   ; try sending again
  279. logo5:  call    error1
  280. logo6:  call    serrst                  ; Reset port
  281.         mov     ax,1            ; tell statistics this was a send operation
  282.         call    endtim                  ; finish statistics
  283.         mov     ah,curchk
  284.         mov     trans.chklen,ah         ; Restore value.
  285.         jmp     rskp                    ; use rskp so Bye succeeds
  286. LOGO    ENDP
  287.  
  288. ; GET command. Ask remote server to send the specified file(s).
  289. ; Queries for remote filename and optional local override path/filename.
  290. GET     PROC    NEAR
  291.         mov     flags.nmoflg,0          ; Reset flags from fn parsing.
  292.         mov     byte ptr locfil,0       ; clear, for safety
  293.         mov     byte ptr srvbuf,0       ; ditto
  294.         mov     flags.cxzflg,0          ; no Control-C typed yet
  295.         mov     cnt,0                   ; count of filename chars
  296.         mov     bx,offset srvbuf        ; Where to put text.
  297.         mov     byte ptr [bx],0         ; clear for safety
  298.         mov     dx,offset filmsg        ; In case user needs help.
  299.         mov     ah,cmtxt                ; filenames with embedded whitespace
  300.         call    comnd                   ; Get text or confirm.
  301.          jmp    r                       ; Fail.
  302.         mov     al,ah
  303.         mov     ah,0
  304.         mov     cnt,ax                  ; Remember number of chars we read.
  305.         cmp     al,0                    ; Read in any chars?
  306.         je      get1                    ; e = no.
  307.         jmp     get3                    ; yes, now check for override name.
  308.                                         ; if empty line, ask for file names
  309. get1:   mov     dx,offset remfnm        ; ask for remote name first
  310.         call    prompt
  311.         mov     bx,offset srvbuf        ; place for remote filename
  312.         mov     dx,offset frem          ; the help message
  313.         mov     ah,cmtxt                ; use this for embedded spaces
  314.         call    comnd                   ; get a filename
  315.          jmp    r
  316.         cmp     flags.cxzflg,0          ; ^X, ^Z, or ^C typed?
  317.         je      get2                    ; e = no, continue
  318.         jmp     rskp                    ; yes, quit
  319. get2:   mov     al,ah
  320.         mov     ah,0
  321.         mov     cnt,ax                  ; remember number of chars read.
  322.         mov     bx,offset srvbuf        ; look at string again.
  323.         push    es
  324.         push    di
  325.         push    si
  326.         mov     ax,ds                   ; use segment 'datas' for es:
  327.         mov     es,ax
  328.         mov     si,bx           ; look at start of string, remove whitespace
  329. get2c:  cmp     byte ptr [si],0         ; at terminator?
  330.         je      get2d                   ; e = yes
  331.         cmp     byte ptr [si],' '       ; text (greater than space)?
  332.         ja      get2d                   ; a = yes.
  333.         inc     si                      ; look at next char
  334.         jmp     get2c                   ; look some more
  335. get2d:  cmp     bx,si                   ; did we find leading whitespace?
  336.         je      get2e                   ; e = no
  337.         mov     di,bx                   ; place to copy chars
  338.         call    strcpy                  ;   from ds:si to ds:di
  339. get2e:  mov     dx,bx                   ; address of string
  340.         call    strlen                  ; get its new length (returned in cx)
  341.         mov     cnt,cx                  ; store it
  342.         pop     si
  343.         pop     di
  344.         pop     es
  345.         cmp     cnt,0                   ; count of entered chars
  346.         jne     get2f                   ; ne = got some
  347.         jmp     rskp                    ; empty so abort this command
  348. get2f:  mov     dx,offset lclfnm        ; prompt for local filename
  349.         call    prompt
  350. get3:   mov     flags.nmoflg,0          ; assume no local override name
  351.         mov     bx,offset filhlp
  352.         mov     dx,offset locfil        ; complete local filename
  353.         mov     byte ptr locfil,0       ; clear, for safety
  354.         mov     ah,cmfile               ; allow paths
  355.         call    comnd
  356.          jmp    r
  357.         mov     bx,offset locfil
  358.         cmp     byte ptr [bx],'#'       ; Is first char a replacement for '?'
  359.         jne     get3a                   ; ne = no
  360.         mov     byte ptr [bx],'?'       ; yes. Replace '#' by '?'
  361. get3a:  mov     al,ah           ; number of chars in locfil according to cmd
  362.         mov     flags.nmoflg,al         ; 0 = no override
  363.         mov     ah,0
  364.         add     bx,ax
  365.         mov     byte ptr [bx],0         ; force a termination null
  366.  
  367.         mov     bx,offset srvbuf        ; get remote filename address again
  368.         cmp     byte ptr [bx],'#'       ; Is first char a replacement for '?' ?
  369.         jne     get4                    ; ne = no.
  370.         mov     byte ptr [bx],'?'       ; yes. Replace '#' by '?'
  371.  
  372. get4:   cmp     flags.cxzflg,0          ; ^X, ^Z, or ^C typed?
  373.         je      get5                    ; e = no, keep going
  374.         mov     flags.cxzflg,0          ; clear the interrupt flag
  375.         or      errlev,2                ; say cannot receive
  376.         jmp     rskp
  377. get5:   call    begtim                  ; start statistics
  378.         cmp     flags.destflg,2         ; receiving to screen?
  379.         je      get5a                   ; e = yes, skip screen stuff
  380.         mov     flags.xflg,0            ; no, reset x flag
  381.         call    init                    ; init screen
  382. get5a:  call    ipack                   ; Send Initialize, 'I', packet.
  383.          jmp    get8                    ; Sorry can't do it.
  384.          nop
  385.         mov     cx,cnt                  ; Get back remote filename size.
  386.         mov     pack.argbk1,cx          ; Need it here to send packet.
  387.         mov     si,offset srvbuf        ; Move from here
  388.         mov     di,offset data          ; to here.
  389.         call    strcpy                  ; copy from srvbuf to data
  390.         test    flags.remflg,dquiet     ; quiet display mode?
  391.         jnz     get6                    ; nz = yes, don't print anything
  392.         cmp     flags.remflg,dserial    ; serial mode display?
  393.         je      get6                    ; e = yes, skip extra display item.
  394.         cmp     flags.destflg,2         ; Receiving to screen?
  395.         je      get6                    ; Yes skip screen stuff.
  396.         call    prtfn                   ; print filename in data
  397. get6:
  398.         call    rrinit                  ; clear pack.xxx counters
  399.         mov     pack.numrtr,-1  ; No retries yet (gets incremented below).
  400.         mov     pack.state,'R'          ; this is what state will be soon
  401.         mov     cx,pack.argbk1          ; Data size.
  402.         call    doenc                   ; Encode data.
  403.         jnc     get6a                   ; nc = success
  404.         jmp     get12           ; c = data could not all fit into packet
  405. get6a:  mov     ah,trans.chklen         ; Don't forget the checksum length.
  406.         mov     curchk,ah
  407.         mov     trans.chklen,1          ; Use one char for server functions.
  408. get7:   call    updrtr
  409.         cmp     pack.state,'A'          ; Did user type a ^C?
  410.         je      get9                    ; Yes - just return to main loop.
  411.         mov     ah,pack.numtry
  412.         cmp     ah,maxtry               ; Too many times?
  413.         jbe     get10                   ; Nope, try it.
  414. get8:   test    flags.remflg,dquiet     ; quiet display mode?
  415.         jnz     get9                    ; nz = yes, no printing
  416.         call    erpos
  417.         mov     ah,prstr
  418.         mov     dx,offset erms18        ; Can't get init packet.
  419.         int     dos
  420.         or      errlev,2                ; set DOS error level to cannot rcv.
  421. get9:   test    flags.remflg,dquiet+dserial ; quiet or serial display?
  422.         jnz     get9a                   ; nz = yes
  423.         call    clrmod
  424.         call    rprpos
  425. get9a:  call    serrst                  ; Reset port.
  426.         mov     ah,curchk
  427.         mov     trans.chklen,ah         ; Restore value.
  428.         xor     ax,ax                   ; say this was a receive operation
  429.         call    endtim                  ; do statistics
  430.         jmp     rskp
  431. get10:  inc     pack.numtry             ; Increment number of tries.
  432.         mov     pack.argblk,0           ; Start at packet zero.
  433.         call    pktsize                 ; report packet size
  434.         mov     ah,'R'                  ; Receive init packet.
  435.         call    spack                   ; Send the packet.
  436.          jmp    get8                    ; Tell user we can't do it.
  437.          nop
  438.         call    rpack                   ; Get ACK
  439.          jmp    get7                    ; Got a NAK - try again.
  440.          nop
  441.         push    ax
  442.         mov     ah,curchk
  443.         mov     trans.chklen,ah         ; Restore value.
  444.         pop     ax
  445.         mov     pack.argbk2,ax          ; where rinit wants pkt type if GET
  446.         mov     flags.getflg,1          ; note this is a GET
  447.         mov     pack.state,'R'          ; Set the state to receive initiate
  448.         jmp     read12                  ; go join read code
  449. get11:  mov     ah,prstr                ; Complain if no filename.
  450.         mov     dx,offset cmer05
  451.         int     dos
  452.         jmp     rskp
  453. get12:  mov     dx,offset ermes6    ; Complain if filename is too long for pkt
  454.         test    flags.remflg,dquiet     ; quiet display mode?
  455.         jnz     get13                   ; nz = yes, no printing
  456.         call    erpos                   ; position cursor on formatted screen
  457.         mov     ah,prstr
  458.         int     dos
  459. get13:  mov     bx,dx                   ; point to message, for errpack
  460.         call    errpack                 ; tell the host we are quiting
  461.         test    flags.remflg,dserial    ; serial display mode?
  462.         jnz     get14                   ; nz = yes
  463.         call    clrmod                  ; clear mode line
  464.         call    rprpos                  ; Put prompt here.
  465. get14:  or      errlev,2                ; set DOS error level to cannot rcv
  466.         jmp     rskp
  467. GET     ENDP
  468.  
  469. ; server command
  470.  
  471. SERVER  PROC    NEAR
  472.         mov     ah,cmcfm
  473.         call    comnd
  474.          jmp    r
  475.         push    es
  476.         mov     ax,ds
  477.         mov     es,ax                   ; address data segment
  478.         mov     al,flags.remflg         ; get display mode flag
  479.         push    ax                      ; preserve for later
  480. ; Enable the line below if the server screen is to be quiet (clear),
  481. ; or make the line a comment if the server screen is to show file transfers.
  482. ;===>   mov     flags.remflg,dquiet     ; set quiet display flag if server
  483.                                         ;
  484.         or      flags.remflg,dserver    ; signify we are a server now
  485.         mov     ax,0                    ; simulate empty parameter packet
  486.         call    spar                    ; and thus set our params to defaults
  487.         mov     ah,drpt                 ; force default repeat prefix char
  488.         mov     rptq,ah                 ;  char be our active one
  489.         test    flags.remflg,dquiet     ; quiet display?
  490.         jnz     serv1c                  ; nz = yes
  491.         mov     ah,prstr
  492.         mov     dx,offset crlf
  493.         int     dos
  494.         test    flags.remflg,dserial    ; serial display?
  495.         jnz     serv1a                  ; nz = yes
  496.         mov     fmtdsp,1                ; say using formatted display
  497.         call    cmblnk                  ; clear screen
  498.         mov     dx,scrser               ; move cursor to top of screen
  499.         call    poscur
  500. serv1a: mov     ah,prstr
  501.         mov     dx,offset infms1        ; say now in server mode
  502.         int     dos
  503. serv1c: mov     ah,inichk               ; set default checksum length
  504.         mov     curchk,ah               ; save it here
  505.  
  506. serv1:  test    flags.remflg,dquiet+dserial ; quiet or serial display?
  507.         jnz     serv1b                  ; nz = yes
  508.         mov     fmtdsp,1                ; say using formatted display
  509.         mov     dx,scrsrm               ; move cursor to server message area
  510.         add     dx,0100H        ; look at line below (DOS does CR/LF first)
  511.         call    poscur
  512.         call    clearl                  ; and clear the line
  513.         mov     dx,scrsrm               ; back to message line
  514.         call    poscur
  515.  
  516. serv1b: mov     flags.nmoflg,0  ; clear, say no local override filenames
  517.         mov     flags.cxzflg,0          ; clear ^X, ^Z, ^C seen flag
  518.         mov     flags.xflg,0            ; reset X packet flag
  519.         mov     locfil,0                ; say no local filename [JB]
  520.         mov     ah,dtrans.seol          ; restore default end-of-line char
  521.         mov     trans.seol,ah
  522.         mov     byte ptr srvbuf,0       ; plant terminator to clear
  523.         call    serini          ; init serial line (send & receive reset it)
  524.         mov     ax,1                    ; assume previous operation was a send
  525.         call    endtim                  ; do end of statistics, for loop back
  526.         mov     trans.chklen,1          ; checksum len = 1
  527.         mov     pack.pktnum,0           ; pack number resets to 0
  528.         mov     pack.numtry,0           ; no retries yet.
  529.         mov     al,trans.stime          ; get current timeout interval
  530.         mov     curstim,al              ; save current timeout interval
  531.         add     al,al                   ; triple it for server idle loop
  532.         add     al,curstim              ; times three
  533.         mov     trans.stime,al  ;  use this longer interval in the idle loop
  534.         call    rpack                   ; get a packet
  535.          jmp    short serv2             ; no good, nak and continue
  536.          nop
  537.         call    begtim                  ; start statistics
  538.         push    ax
  539.         mov     al,curstim              ; get original timeout interval
  540.         mov     trans.stime,al          ; restore timeout interval
  541.         pop     ax
  542.         cmp     ah,'I'                  ; never "decode" S, I, and A packets
  543.         je      serv3                   ; its an I packet
  544.         cmp     ah,'S'
  545.         je      serv3
  546.         cmp     ah,'A'
  547.         je      serv3
  548.         call    dodec           ;decode packet; protocol error if omitted
  549.         jmp     short serv3             ; try to figure this out
  550.  
  551. serv2:  push    ax
  552.         mov     al,curstim              ; get original timeout interval
  553.         mov     trans.stime,al          ; restore timeout interval
  554.         pop     ax
  555.         cmp     flags.cxzflg,'C'        ; Control-C?
  556.         je      serv5                   ; yes, stop this.
  557.         call    nak                     ; nak the packet
  558.         mov     al,curchk               ; restore checksum length
  559.         mov     trans.chklen,al
  560.         jmp     serv1                   ; and keep readiserv2 packets
  561.  
  562. serv3:  mov     al,curchk               ; restore checksum length
  563.         mov     trans.chklen,al
  564.         push    ds
  565.         pop     es                      ; set es to datas segment
  566.         mov     di,offset srvchr        ; server characters
  567.         mov     cx,srvfln               ; length of striserv2
  568.         mov     al,ah                   ; packet type
  569.         cld
  570.         repne   scasb                   ; hunt for it
  571.         je      serv4                   ; we know this one, go handle it
  572.         cmp     al,'N'                  ; received a Nak?
  573.         je      serv3a                  ; e = yes, ignore it
  574.         mov     bx,offset remms1        ; else give a message
  575.         call    errpack                 ; back to local kermit
  576. serv3a: jmp     serv1                   ; and keep lookiserv2 for a cmd
  577. serv4:  sub     di,offset srvchr+1      ; find offset, +1 for pre-increment
  578.         shl     di,1                    ; convert to word index.
  579.         call    srvfun[di]              ; call the appropriate handler
  580.          jmp    serv5                   ; someone wanted to exit...
  581.         jmp     serv1                   ; else keep goiserv2 for more cmds.
  582.  
  583. serv5:  mov     al,curchk               ; restore checksum length
  584.         mov     trans.chklen,al
  585.         pop     ax                      ; get this off stack
  586.         test    flags.remflg,dserial+dquiet ; serial or quiet display?
  587.         jnz     serv5a                  ; nz = yes
  588.         call    rprpos                  ; Put prompt here.
  589. serv5a: mov     flags.remflg,al         ; restore old flag
  590.         call    serrst                  ; reset serial handler
  591.         mov     ax,1            ; tell statistics this was a send operation
  592.         call    endtim                  ; stop statistics
  593.         mov     fmtdsp,0                ; end of formatted display
  594.         pop     es                      ; restore register
  595.         jmp     rskp                    ; and return
  596. SERVER  ENDP
  597.  
  598. ; server commands.
  599.  
  600. ; srvsnd - receives a file that a remote kermit is sending.
  601. srvsnd  proc    near
  602.         mov     bx,offset data
  603.         mov     ax,pack.argbk1          ; get number of data bytes
  604.         call    spar                    ; parse the send-init packet
  605.         mov     al,trans.chklen         ; get negotiated checksum length
  606.         mov     curchk,al               ;  and remember it here
  607.         call    packlen                 ; figure max packet
  608.         mov     bx,offset data
  609.         call    rpar                    ; make answer for them
  610.         mov     al,ah                   ; length of packet
  611.         mov     ah,0
  612.         mov     pack.argbk1,ax          ; store length for spack
  613.         mov     trans.chklen,1          ; reply with 1 char checksum
  614.         call    pktsize                 ; report packet size
  615.         mov     ah,'Y'                  ; ack
  616.         call    spack                   ; answer them
  617.          jmp    rskp                    ; can't answer, forget this
  618.         mov     al,curchk               ; restore checksum length
  619.         mov     trans.chklen,al
  620.         call    rrinit                  ; init variables for init
  621.         cmp     flags.destflg,2         ; file destination = screen?
  622.         jne     srvsnd0                 ; ne = no
  623.         mov     flags.xflg,1            ; say receiving to screen
  624.         jmp     srvsnd1
  625. srvsnd0:call    init                    ; setup display form
  626. srvsnd1:test    denyflg,sndflg          ; is command enabled?
  627.         jz      srvsnd2                 ; z = yes
  628.         mov     si,offset srvbuf        ; work buffer
  629.         mov     byte ptr[si],5ch        ; backslash
  630.         inc     si
  631.         mov     ah,gcd                  ; get current directory (path really)
  632.         xor     dl,dl                   ; use current drive
  633.         int     dos             ; returns ds:si with asciiz path (no drive)
  634.         mov     si,offset srvbuf
  635.         mov     di,offset locfil        ; destination is local override name
  636.         call    strcpy                  ; copy the path to local filename
  637.         mov     dx,di
  638.         call    strlen                  ; get length of string into cx
  639.         mov     di,cx                   ; length of local path
  640.         mov     locfil[di],5ch          ; add backslash
  641.         mov     locfil[di+1],0          ; null terminator
  642.         mov     flags.nmoflg,1  ; say have override name (zaps external path)
  643. srvsnd2:inc     pack.pktnum             ; count the send-init packet.
  644.         mov     pack.state,'F'          ; expecting file name about now
  645.         call    read12                  ; join read code. changed from read2
  646.          nop
  647.          nop
  648.          nop                            ; ignore errors
  649.         mov     flags.xflg,0
  650.         jmp     rskp                    ; and return for more
  651. srvsnd  endp
  652.  
  653. ; srvrcv - send a file to a distant kermit
  654.  
  655. srvrcv  proc    near
  656.         mov     si,offset data          ; received filename, asciiz from rpack
  657.         test    denyflg,getsflg         ; command enabled?
  658.         jz      srrcv2                  ; z = yes
  659.         mov     di,offset srvbuf        ; local path
  660.         mov     si,offset rdbuf         ; local filename
  661.         mov     dx,offset data          ; local string
  662.         call    fparse                  ; split string
  663.         mov     si,offset rdbuf         ; copy local filename to
  664. srrcv2: mov     di,offset diskio.string ; destination
  665.         call    strcpy                  ; copy data to diskio.string
  666.         mov     pack.state,'R'          ; remember state.
  667.         call    send11                  ; this should send it
  668.          jmp    rskp
  669.         jmp     rskp                    ; return in any case
  670. srvrcv  endp
  671.  
  672. ; srvgen - G generic server command dispatcher.
  673. ;
  674. srvgen  proc    near
  675.         mov     al,data                 ; get 1st packet char
  676. srvge2: cmp     al,'T'                  ; Type a file?
  677.         jne     srvge3                  ; ne = no
  678.         call    srvtyp                  ; do the typing
  679.         jmp     rskp
  680. srvge3: cmp     al,'D'                  ; do a directory?
  681.         jne     srvge4
  682.         call    srvdir                  ; do the directory command
  683.         jmp     rskp
  684. srvge4: cmp     al,'E'                  ; do a file erase (delete)?
  685.         jne     srvge5
  686.         call    srvdel                  ; do the delete command
  687.         jmp     rskp
  688. srvge5: cmp     al,'C'                  ; change working dir?
  689.         jne     srvge6                  ; ne = no
  690.         call    srvcwd                  ; do it
  691.         jmp     rskp
  692. srvge6: cmp     al,'U'                  ; do a space command?
  693.         jne     srvge7
  694.         call    srvspc                  ; do the space command
  695.         jmp     rskp
  696. srvge7: cmp     al,'F'                  ; FIN?
  697.         jne     srvge8                  ; ne = no
  698.         jmp     srvfin
  699. srvge8: cmp     al,'L'                  ; LOGO or BYE?
  700.         jne     srvge9                  ; ne = no
  701.         call    srvfin
  702.          jmp    short srvge8a           ; permitted to exit Kermit
  703.          nop
  704.         jmp     rskp                    ; stay active (command denied)
  705. srvge8a:mov     flags.extflg,1          ; set exit flag.
  706.         ret                             ; leave server mode and Kermit.
  707. srvge9: cmp     al,'M'                  ; one line Message?
  708.         jne     srvge10                 ; ne = no
  709.         call    srvsen
  710.         jmp     rskp
  711. srvge10:cmp     al,'W'                  ; WHO?
  712.         jne     srvge11                 ; ne = no
  713.         call    srvwho
  714.         jmp     rskp
  715. srvge11:cmp     al,'H'                  ; Help?
  716.         jne     srvgex                  ; ne = no
  717.         jmp     srvhlp
  718. srvgex: mov     bx,offset remms1        ; reply Unknown server command
  719.         mov     trans.chklen,1          ; reply with 1 char checksum
  720.         call    errpack
  721.         jmp     rskp
  722. srvgen  endp
  723.  
  724. ; srvfin - respond to remote host's Fin command. [jrd]
  725. srvfin  proc    near
  726.         test    denyflg,finflg          ; command enabled?
  727.         jz      srfin1                  ; z = yes
  728.         mov     bx,offset remms9        ; else give a message
  729.         mov     trans.chklen,1          ; reply with 1 char checksum
  730.         call    errpack                 ; back to local kermit
  731.         jmp     rskp                    ; stay in server mode
  732. srfin1: mov     si,offset byemsg        ; add brief msg of goodbye
  733.         mov     di,offset data          ; packet's data field
  734.         call    strcpy                  ; copy msg to pkt
  735.         mov     dx,si                   ; strlen works on dx
  736.         call    strlen
  737.         mov     ah,'Y'                  ; reply with an ack
  738.         mov     pack.argbk1,cx          ; length
  739.         mov     trans.chklen,1          ; reply with 1 char checksum
  740.         call    pktsize                 ; report packet size
  741.         call    spack                   ; send it, expect no response
  742.          nop                            ; ignore errors
  743.          nop
  744.          nop
  745.         ret                             ; ret exits server mode
  746. srvfin  endp
  747.  
  748. ; srvcwd - handle other side's Remote CWD dirspec [jrd]
  749. srvcwd  proc    near
  750.         test    denyflg,cwdflg          ; is command enabled?
  751.         jz      srcwd4                  ; z = yes
  752.         mov     bx,offset remms9        ; else give a message
  753.         mov     trans.chklen,1          ; reply with 1 char checksum
  754.         call    errpack                 ; back to local kermit
  755.         ret
  756. srcwd4: cmp     pack.argbk1,1           ; any data?
  757.         je      srcwd3                  ; e = no
  758.         mov     cl,data+1               ; get the filename byte count
  759.         sub     cl,' '                  ; ascii to numeric
  760.         mov     ch,0                    ; set up counter
  761.         cmp     cl,0                    ; anything there?
  762.         jle     srcwd3                  ; le = no, an error
  763.         mov     si,offset data+2        ; received dir spec, from rpack
  764.         mov     di,offset srvbuf        ; destination
  765.         push    es                      ; save es
  766.         push    ds
  767.         pop     es                      ; make es:di point to datas segment
  768.         cld
  769.         rep movsb                       ; copy data to srvbuf, cx chars worth
  770.         pop     es
  771.         mov     byte ptr [di],0         ; plant terminator
  772.         mov     dx,offset srvbuf        ; for DOS
  773.         mov     ax,dx                   ; dir spec pointer for isfile
  774.         cmp     byte ptr [di-1],':'     ; did user just type A: or similar?
  775.         je      srcwd1                  ; e = yes, so skip directory part
  776.         mov     ah,chdir                ; want to do change dir
  777.         int     dos
  778.         jnc     srcwd1                  ; nc = ok
  779. srcwd3: mov     bx,offset remms4        ; an error.
  780.         mov     trans.chklen,1          ; reply with 1 char checksum
  781.         call    errpack                 ; send the bad news
  782.         ret
  783. srcwd1: mov     dl,data+3               ; see if drive given (look for :)
  784.         cmp     dl,':'
  785.         jne     srcwd2                  ; ne = no drive
  786.         mov     dl,data+2
  787.         and     dl,5fH                  ; convert to upper case
  788.         sub     dl,'A'                  ; count A = 0 for seldsk call
  789.         mov     ah,seldsk
  790.         int     dos                     ; change disks
  791.         jc      srcwd3                  ; c = an error
  792.         inc     dl                      ; now make A = 1 etc internally
  793.         mov     curdsk,dl               ;and update internal current disk code
  794. srcwd2: mov     ah,'Y'                  ; return an ack
  795.         mov     pack.argbk1,0           ; no data
  796.         mov     trans.chklen,1          ; reply with 1 char checksum
  797.         call    pktsize                 ; report packet size
  798.         call    spack
  799.          nop
  800.          nop
  801.          nop
  802.         ret
  803. srvcwd  endp
  804.  
  805. ; srvtyp - handle other side's Remote Type filename request [jrd]
  806. ; expects "data" to hold  Tcfilename   where c = # bytes in filename.
  807. srvtyp  proc    near
  808.         cmp     pack.argbk1,1           ; any data in packet
  809.         je      srtyp2                  ; e = no
  810.         mov     cl,data+1               ; get the filename byte count
  811.         sub     cl,' '                  ; ascii to numeric
  812.         mov     ch,0                    ; set up counter
  813.         mov     si,offset data+2        ; received filename, asciiz from rpack
  814.         mov     di,si
  815.         add     di,cx
  816.         mov     byte ptr [di],0         ; make string asciiz
  817.         test    denyflg,typflg          ; paths permitted?
  818.         jz      srtyp1                  ; z = yes, else use just filename part
  819.         mov     di,offset srvbuf        ; local path
  820.         mov     si,offset rdbuf         ; local filename
  821.         mov     dx,offset data+2        ; local string
  822.         call    fparse                  ; split string
  823.         mov     si,offset rdbuf         ; copy local filename to
  824. srtyp1: mov     di,offset diskio.string ; destination
  825.         call    strcpy                  ; do the copy
  826.         mov     ax,offset diskio.string ; pointer to filename, for isfile
  827.         call    isfile                  ; does it exist?
  828.         jnc     srtyp3                  ; nc = yes
  829. srtyp2: mov     bx,offset remms5        ; "No such file(s)"
  830.         mov     trans.chklen,1          ; reply with 1 char checksum
  831.         call    errpack                 ; send error message
  832.         ret                             ; and exit
  833. srtyp3: mov     flags.xflg,1            ; say use X packet rather than F pkt
  834.         mov     pack.state,'R'          ; remember state.
  835.         call    send11                  ; this should send it
  836.          nop
  837.          nop
  838.          nop
  839.         mov     flags.xflg,0            ; clear flag
  840.         ret                             ; return in any case
  841. srvtyp  endp
  842.  
  843. ; serdir - handle other side's Remote Dir filespec(optional) request [jrd]
  844. srvdir  proc    near
  845.         mov     cx,0                    ; assume no data in packet
  846.         cmp     pack.argbk1,1           ; any data in the packet?
  847.         je      srdir4                  ; e = no
  848.         mov     cl,data+1               ; get the filename byte count
  849.         sub     cl,' '                  ; ascii to numeric
  850.         mov     ch,0                    ; set up counter
  851. srdir4: mov     di,offset data+2        ; received filespec, asciiz from rpack
  852.         add     di,cx
  853.         mov     byte ptr [di],0         ; make string asciiz
  854.         test    denyflg,dirflg          ; paths permitted?
  855.         jz      srdir1                  ; z = yes, else use just filename part
  856.         mov     di,offset srvbuf        ; local path
  857.         mov     si,offset rdbuf         ; local filename
  858.         mov     dx,offset data+2        ; local string
  859.         call    fparse                  ; split string
  860.         mov     si,offset rdbuf         ; copy local filename to
  861.         mov     di,offset data+2        ; final filename
  862.         call    strcpy                  ; do the copy
  863.         mov     ax,di
  864.         call    isfile                  ; is/are there any such file?
  865.         jc      srdir1                  ; c = there is none
  866.         test    byte ptr filtst.dta+21,1EH ; attr bits: is file protected?
  867.         jz      srdir1                  ; z = not protected.
  868.         mov     bx,offset remms8        ; "Protected or no such file(s)"
  869.         mov     trans.chklen,1          ; reply with 1 char checksum
  870.         call    errpack                 ; send error message
  871.         ret                             ; and exit
  872.  
  873. srdir1: mov     di,offset srvbuf        ; work area
  874.         mov     si,offset dirstr        ; prepend "dir "
  875.         call    strcpy
  876.         mov     si,offset data+2        ; directory spec, asciiz
  877.         mov     di,offset srvbuf
  878.         call    strcat
  879.         mov     si,offset srvtmp    ; add redirection tag of " >$kermit$.tmp"
  880.         mov     di,offset srvbuf
  881.         call    strcat
  882.         mov     si,offset srvbuf        ; command pointer for crun
  883.         call    crun
  884.          nop
  885.          nop
  886.          nop
  887.         mov     si,offset srvtmp+2      ; get name of temp file
  888.         mov     di,offset diskio.string ; destination
  889.         call    strcpy                  ; copy it there
  890.         mov     ax,di                   ; filename pointer for isfile
  891.         call    isfile                  ; did we make the temp file?
  892.         jnc     srdir3                  ; nc = yes
  893.         mov     bx,offset remms6        ; "Could not create directory listing"
  894.         mov     trans.chklen,1          ; reply with 1 char checksum
  895.         call    errpack                 ; send the error message
  896.         ret                             ; and exit
  897. srdir3: mov     flags.xflg,1            ; say use X rather than F packet
  898.         mov     pack.state,'R'          ; remember state.
  899.         call    send11                  ; this should send it
  900.          nop
  901.          nop
  902.          nop
  903.         mov     flags.xflg,0            ; clear flag
  904.         mov     dx,offset diskio.string
  905.         mov     ah,del2                 ; delete the file
  906.         int     dos
  907.         ret                             ; return in any case
  908. srvdir  endp
  909.  
  910. ; serdel - handle other side's request of Remote Del filespec [jrd]
  911. srvdel  proc    near
  912.         test    denyflg,delflg          ; command enabled?
  913.         jz      srvdel4                 ; z = yes
  914.         mov     bx,offset remms9        ; else give a message
  915.         mov     trans.chklen,1          ; reply with 1 char checksum
  916.         call    errpack                 ; back to local kermit
  917.         ret
  918.  
  919. srvdel4:cmp     pack.argbk1,1           ; any data?
  920.         je      srdel1                  ; e = no
  921.         mov     di,offset srvbuf        ; work area
  922.         mov     si,offset delstr        ; prepend "del "
  923.         call    strcpy
  924.         mov     dx,offset srvbuf
  925.         call    strlen
  926.         add     di,cx                   ; di points at terminator
  927.         mov     ax,di                   ; save pointer to incoming filespec
  928.         mov     cl,data+1               ; get the filename byte count
  929.         sub     cl,' '                  ; ascii to numeric
  930.         mov     ch,0                    ; set up counter
  931.         cmp     cl,0                    ; anything there?
  932.         jle     srdel3                  ; le = no
  933.         mov     si,offset data+2        ; received filespec, asciiz from rpack
  934.         push    es                      ; save es
  935.         push    ds
  936.         pop     es                      ; set es to datas segment
  937.         cld
  938.         rep     movsb                   ; append data to srvbuf
  939.         pop     es                      ; restore es
  940.         mov     byte ptr [di],0         ; plant terminator
  941.         call    isfile                  ; is/are there any to delete?
  942.         jc      srdel1                  ; c = there is none
  943.         test    byte ptr filtst.dta+21,1EH ; attr bits: is file protected?
  944.         jz      srdel2                  ; z = not protected.
  945. srdel1: mov     bx,offset remms8        ; "Protected or no such file(s)"
  946.         mov     trans.chklen,1          ; reply with 1 char checksum
  947.         call    errpack                 ; send error message
  948.         ret                             ; and exit
  949. srdel2: mov     si,offset srvbuf        ; set pointer for crun
  950.         call    crun
  951.          nop
  952.          nop
  953.          nop
  954. srdel3: mov     ah,'Y'                  ; return an ack
  955.         mov     pack.argbk1,0           ; no data
  956.         mov     trans.chklen,1          ; reply with 1 char checksum
  957.         call    pktsize                 ; report packet size
  958.         call    spack
  959.          nop
  960.          nop
  961.          nop
  962.         ret
  963. srvdel  endp
  964.  
  965. ; serspc - handle other side's request of Remote Space  [jrd]
  966. srvspc  proc    near
  967.         test    denyflg,spcflg          ; is command enabled?
  968.         jz      srspc1                  ; z = yes
  969.         mov     bx,offset remms9        ; else give a message
  970.         mov     trans.chklen,1          ; reply with 1 char checksum
  971.         call    errpack                 ; back to local kermit
  972.         ret
  973. srspc1: mov     di,offset srvbuf        ; work area
  974.         mov     si,offset spcstr        ; prepend "chkdsk.com "
  975.         call    strcpy
  976.         mov     si,offset srvtmp    ; add redirection tag of " >$kermit$.tmp"
  977.         call    strcat
  978.         mov     si,offset srvbuf        ; command pointer for crun
  979.         call    crun
  980.          nop
  981.          nop
  982.          nop
  983.         mov     si,offset srvtmp+2      ; get name of temp file
  984.         mov     di,offset diskio.string ; destination
  985.         call    strcpy                  ; copy it there
  986.         mov     ax,di                   ; filename pointer for isfile
  987.         call    isfile                  ; did we make the temp file?
  988.         jnc     srspc2                  ; nc = yes
  989.         mov     trans.chklen,1          ; reply with 1 char checksum
  990.         mov     bx,offset remms7        ; "Could not create space listing"
  991.         call    errpack                 ; send the error message
  992.         ret                             ; and exit
  993. srspc2: mov     flags.xflg,1            ; say use X rather than F packet
  994.         mov     pack.state,'R'          ; remember state.
  995.         call    send11                  ; this should send it
  996.          nop
  997.          nop
  998.          nop
  999.         mov     flags.xflg,0            ; clear flag
  1000.         mov     dx,offset diskio.string
  1001.         mov     ah,del2                 ; delete the file
  1002.         int     dos
  1003.         ret                             ; return in any case
  1004. srvspc  endp
  1005.  
  1006. ; srvwho - respond to remote host's WHO command. [jrd]
  1007. srvwho  proc    near
  1008.         mov     si,offset whomsg        ; add brief msg of just us chickens
  1009.         mov     di,offset data          ; packet's data field
  1010.         call    strcpy                  ; copy msg to pkt
  1011.         mov     dx,si                   ; strlen works on dx
  1012.         call    strlen
  1013.         mov     trans.chklen,1          ; reply with 1 char checksum
  1014.         mov     ah,'Y'                  ; reply with an ack
  1015.         mov     pack.argbk1,cx          ; length
  1016.         call    pktsize                 ; report packet size
  1017.         call    spack                   ; send it, expect no response
  1018.          nop                            ; ignore errors
  1019.          nop
  1020.          nop
  1021.         ret
  1022. srvwho  endp
  1023.  
  1024. ; srvmsg - respond to remote host's Message (Send) command
  1025. ;  show message on our screen. [jrd]
  1026. srvsen  proc    near
  1027.         cmp     pack.argbk1,1           ; Any data in the packet?
  1028.         jbe     srvsen1                 ; e = no, just ack the message.
  1029.         call    dodec                   ; Decode data.
  1030.         mov     di,offset data+2   ; Where the reply is. (skip M and byte cnt)
  1031.         cmp     byte ptr [di-2],'M'     ; Message packet?
  1032.         jne     srvsen1                 ; ne = no, ack and forget
  1033.         mov     cl,byte ptr [di-1]      ; How much data we have.
  1034.         sub     cl,' '                  ; remove ascii bias
  1035.         cbw                             ; make a whole word
  1036.         jle     srvsen1                 ; le = nothing
  1037.         call    prtscr                  ; Print it on the screen.
  1038. srvsen1:mov     ah,'Y'                  ; reply with an ack
  1039.         mov     pack.argbk1,0           ; length
  1040.         mov     trans.chklen,1          ; reply with 1 char checksum
  1041.         call    pktsize                 ; report packet size
  1042.         call    spack                   ; send it, expect no response
  1043.          nop                            ; ignore errors
  1044.          nop
  1045.          nop
  1046.         ret
  1047. srvsen  endp
  1048.  
  1049.  
  1050. ; srvhos - handle other side's request of REM Host command-line. [jrd]
  1051. ; We execute the command with STDOUT redirected to $kermit$.tmp and then
  1052. ; read and transmit that file to the other end. No such file results in
  1053. ; returning just an error msg ACK packet.
  1054. srvhos  proc    near
  1055.         test    denyflg,hostflg         ; command enabled?
  1056.         jz      srvhos2                 ; z = yes
  1057.         mov     trans.chklen,1          ; reply with 1 char checksum
  1058.         mov     bx,offset remms9        ; else give a message
  1059.         call    errpack                 ; back to local kermit
  1060.         jmp     rskp
  1061.  
  1062. srvhos2:mov     si,offset data          ; received filename, asciiz from rpack
  1063.         mov     di,offset srvbuf        ; destination
  1064.         call    strcpy                  ; copy data to srvbuf
  1065.         mov     si,offset srvtmp    ; add redirection tag of " >$kermit$.tmp"
  1066.         call    strcat
  1067.         mov     si,offset srvbuf        ; si = pointer for crun
  1068.         call    crun                    ; go do the command
  1069.          nop
  1070.          nop
  1071.          nop
  1072.         mov     si,offset srvtmp+2      ; get name of temp file
  1073.         mov     di,offset diskio.string ; destination
  1074.         call    strcpy                  ; copy it to diskio.string
  1075.         mov     ax,di                   ; filename pointer for isfile
  1076.         call    isfile                  ; did we make the temp file?
  1077.         jnc     srhos1                  ; nc = yes
  1078.         mov     si,offset remms10       ; say could not create work file
  1079.         mov     di,offset data          ; packet's data field
  1080.         call    strcpy                  ; copy msg to pkt
  1081.         mov     dx,si                   ; strlen works on dx
  1082.         call    strlen
  1083.         mov     trans.chklen,1          ; reply with 1 char checksum
  1084.         mov     ah,'Y'                  ; reply with an ack
  1085.         mov     pack.argbk1,cx          ; length
  1086.         mov     trans.chklen,1          ; reply with 1 char checksum
  1087.         call    pktsize                 ; report packet size
  1088.         call    spack
  1089.          nop
  1090.          nop
  1091.          nop
  1092.         jmp     rskp                    ; and exit
  1093. srhos1: mov     flags.xflg,1            ; say use X rather than F packet
  1094.         mov     pack.state,'R'          ; remember state.
  1095.         call    send11                  ; this should send it
  1096.          nop
  1097.          nop
  1098.          nop
  1099.         mov     flags.xflg,0            ; clear flag
  1100.         mov     dx,offset diskio.string
  1101.         mov     ah,del2                 ; delete the temp file
  1102.         int     dos
  1103.         jmp     rskp                    ; return in any case
  1104. srvhos  endp
  1105.  
  1106. ; Respond to other side's request of Remote Help. Write & read $kermit$.tmp.
  1107. ; Return rskp. [jrd]
  1108. srvhlp  proc    near
  1109.         mov     si,offset srvtmp+2      ; use filename of $kermit$.tmp
  1110.         mov     di,offset diskio.string ; put name here
  1111.         call    strcpy
  1112.         mov     ah,creat2               ; create the file
  1113.         mov     cx,0                    ; attributes r/w
  1114.         mov     dx,offset diskio.string ; use $kermit$.tmp name
  1115.         int     dos
  1116.         jc      srvhlp4                 ; c = could not open
  1117.         mov     diskio.handle,ax        ; file handle
  1118.         mov     dx,offset hlprem        ; data to be sent, strlen uses dx
  1119.         call    strlen                  ; put string length in cx
  1120.         mov     ah,write2               ; write to file
  1121.         mov     bx,diskio.handle
  1122.         int     dos                     ; write the info, ignore errors
  1123.         mov     ah,close2       ; close the file so we can reread it below
  1124.         mov     bx,diskio.handle
  1125.         int     dos
  1126.                                         ; Send temporary file to remote screen
  1127.         mov     flags.xflg,1            ; say use X rather than F packet
  1128.         mov     pack.state,'R'          ; remember state.
  1129.         call    send11                  ; this should send it
  1130.          nop
  1131.          nop
  1132.          nop
  1133.         mov     flags.xflg,0            ; clear flag
  1134.         mov     dx,offset diskio.string ; filename
  1135.         mov     ah,del2                 ; delete the temp file
  1136.         int     dos
  1137.         jmp     rskp                    ; and return
  1138.  
  1139. srvhlp4:mov     si,offset remms3        ; say could not create help file
  1140.         mov     di,offset data          ; packet's data field
  1141.         call    strcpy                  ; copy msg to pkt
  1142.         mov     dx,si                   ; strlen works on dx
  1143.         call    strlen
  1144.         mov     trans.chklen,1          ; reply with 1 char checksum
  1145.         mov     ah,'Y'                  ; reply with an ack
  1146.         mov     pack.argbk1,cx          ; length
  1147.         call    pktsize                 ; report packet size
  1148.         call    spack
  1149.          nop
  1150.          nop
  1151.          nop
  1152.         jmp     rskp                    ; and exit
  1153. srvhlp  endp
  1154.  
  1155. srvdsa  proc    near                    ; DISABLE Server commands
  1156.         mov     dx,offset srvtab
  1157.         mov     bx,offset sdshlp
  1158.         mov     ah,cmkey                ; parse key word
  1159.         call    comnd
  1160.          jmp    r                       ; bad parse
  1161.         mov     temp,bx                 ; save key value
  1162.         mov     ah,cmcfm                ; get a confirm
  1163.         call    comnd
  1164.          jmp    r                       ; no confirm
  1165.         mov     bx,temp                 ; get selected item
  1166.         or      denyflg,bx              ; turn on bit (deny) for that item
  1167.         jmp     rskp                    ; return successfully
  1168. srvdsa  endp
  1169.  
  1170. srvena  proc    near                    ; ENABLE Server commands
  1171.         mov     dx,offset srvtab        ; keyword table
  1172.         mov     bx,offset senhlp        ; help on keywords
  1173.         mov     ah,cmkey                ; parse key word
  1174.         call    comnd
  1175.          jmp    r                       ; bad parse
  1176.         mov     temp,bx                 ; save key value
  1177.         mov     ah,cmcfm                ; get a confirm
  1178.         call    comnd
  1179.          jmp    r                       ; no confirm
  1180.         mov     bx,temp                 ; item to be enabled
  1181.         not     bx                      ; invert bits
  1182.         and     denyflg,bx              ; turn off (enable) selected item
  1183.         jmp     rskp
  1184. srvena  endp
  1185.  
  1186.  
  1187. ; srvini - init parms based on init packet
  1188. srvini  proc    near
  1189.         mov     bx,offset data
  1190.         mov     ax,pack.argbk1          ; get number of data bytes
  1191.         call    spar                    ; parse info
  1192.         call    packlen         ; this should really be part of spar, but...
  1193.         mov     bx,offset data
  1194.         call    rpar                    ; setup info about our reception
  1195.         push    ax
  1196.         mov     al,trans.chklen         ; checksum length negotiated
  1197.         mov     curchk,al               ; use as new working length
  1198.         pop     ax
  1199.         mov     al,ah
  1200.         mov     ah,0
  1201.         mov     pack.argbk1,ax          ; set size of return info
  1202.         mov     trans.chklen,1          ; reply with 1 char checksum
  1203.         mov     ah,'Y'
  1204.         call    pktsize                 ; report packet size
  1205.         call    spack                   ; send the packet off
  1206.          nop
  1207.          nop
  1208.          nop
  1209.         mov     al,curchk       ; restore checksum length before proceeding
  1210.         mov     trans.chklen,al
  1211.         jmp     rskp                    ; and go succeed
  1212. srvini  endp
  1213.  
  1214. ;       This is the REMOTE command.
  1215.  
  1216. REMOTE  PROC    NEAR
  1217.         mov     dx,offset remtab      ; Parse a keyword from the REMOTE table.
  1218.         mov     bx,offset remhlp
  1219.         mov     ah,cmkey
  1220.         call    comnd
  1221.          jmp    r
  1222.         call    bx                      ; Call the appropriate routine.
  1223.          jmp    r                       ; Command failed.
  1224.         jmp     rskp
  1225. REMOTE  ENDP
  1226.  
  1227. ; REMDIS - Get disk usage on remote system.
  1228.  
  1229. REMDIS  PROC    NEAR
  1230.         mov     remcmd,'U'              ; Disk usage command.
  1231.         mov     rempac,'G'              ; Packet type = generic.
  1232.         jmp     genric                  ; Execute generic Kermit command.
  1233. REMDIS  ENDP
  1234.  
  1235.  
  1236. ; REMHEL - Get help about remote commands.
  1237.  
  1238. REMHEL  PROC    NEAR
  1239.         mov     remcmd,'H'              ; Help
  1240.         mov     rempac,'G'              ; Packet type = generic.
  1241.         jmp     genric                  ; Execute generic Kermit command.
  1242. REMHEL  ENDP
  1243.  
  1244. ; REMTYP - Type a remote file.
  1245.  
  1246. REMTYP  PROC    NEAR
  1247.         mov     remcmd,'T'              ; Type the file.
  1248.         mov     rempac,'G'              ; Packet type = generic.
  1249.         jmp     genric
  1250. REMTYP  ENDP
  1251.  
  1252. ; REMHOS - Execute a remote host command.
  1253.  
  1254. REMHOS  PROC    NEAR
  1255.         mov remcmd,' '                  ; Don't need one.
  1256.         mov rempac,'C'                  ; Packet type = remote command.
  1257.         jmp genric
  1258. REMHOS  ENDP
  1259.  
  1260. ; REMKER - Execute a remote Kermit command.
  1261.  
  1262. REMKER  PROC    NEAR
  1263.         mov     remcmd,' '              ; Don't need one.
  1264.         mov     rempac,'K'              ; Packet type = remote Kermit command.
  1265.         jmp     genric
  1266. REMKER  ENDP
  1267.  
  1268. ; REMDIR - Do a directory.
  1269.  
  1270. REMDIR  PROC    NEAR
  1271.         mov     remcmd,'D'
  1272.         mov     rempac,'G'              ; Packet type = generic.
  1273.         jmp     genric
  1274. REMDIR  ENDP
  1275.  
  1276. ; REMDEL - Delete a remote file.
  1277.  
  1278. REMDEL  PROC    NEAR
  1279.         mov     remcmd,'E'
  1280.         mov     rempac,'G'              ; Packet type = generic.
  1281.         jmp     genric
  1282. REMDEL  ENDP
  1283.  
  1284. ; REMCWD - Change remote working directory.
  1285.  
  1286. REMCWD  PROC    NEAR
  1287.         mov     remcmd,'C'
  1288.         mov     rempac,'G'              ; Packet type = generic.
  1289.         jmp     genric
  1290. REMCWD  ENDP
  1291.  
  1292. ; REMSEN - Send one line short message to remote screen. [jrd]
  1293.  
  1294. REMSEN  proc    near
  1295.         mov     remcmd,'M'
  1296.         mov     rempac,'G'
  1297.         jmp     genric
  1298. REMSEN  endp
  1299.  
  1300. ; REMWHO - ask for list of remote logged on users [jrd]
  1301.  
  1302. REMWHO  proc    near
  1303.         mov     remcmd,'W'
  1304.         mov     rempac,'G'
  1305.         jmp     genric
  1306. REMWHO  endp
  1307.  
  1308. ; GENRIC - Send a generic command to a remote Kermit server.
  1309.  
  1310. GENRIC  PROC    NEAR
  1311.         call    begtim                  ; start statistics
  1312.         mov     bx,offset srvbuf        ; Where to put the text.
  1313.         cmp     rempac,'C'              ; Remote host command?
  1314.         je      genra                   ; Yes, leave as is.
  1315.         cmp     rempac,'K'              ; Remote Kermit command?
  1316.         je      genra                   ; e = yes. Don't use counted string.
  1317.         add     bx,2                    ; Leave room for type and size.
  1318. genra:  mov     ah,cmtxt                ; Parse arbitrary text up to a CR.
  1319.         mov     dx,offset genmsg        ; In case they want text.
  1320.         call    comnd
  1321.          jmp    r
  1322.         mov     al,ah                   ; Don't forget the size.
  1323.         mov     ah,0
  1324.         mov     cnt,ax                  ; Save it here.
  1325.         mov     flags.xflg,1            ; output coming to screen
  1326.         cmp     rempac,'K'              ; Remote Kermit command?
  1327.         je      genra1                  ; e = yes
  1328.         cmp     rempac,'C'              ; Remote host command?
  1329.         jne     genrb                   ; No, skip this part.
  1330. genra1: call    ipack                   ; Remote Host or Kermit
  1331.          jmp    genr2
  1332.         mov     curchk,ah               ; Save desired checksum length.
  1333.         mov     trans.chklen,1          ; Use 1 char for server functions.
  1334.         mov     pack.numrtr,0           ; No retries yet.
  1335.         mov     pack.numtry,0
  1336.         jmp     genr1                   ; Send the packet.
  1337. genrb:  mov     ax,cnt
  1338.         cmp     ax,0                    ; Any data?
  1339.         je      genr0                   ; Nope.
  1340.         mov     ah,al                   ; Don't overwrite the real count value
  1341.         add     ah,32                   ; Do the char function.
  1342.         mov     temp,bx                 ; Remember where we are.
  1343.         mov     bx,offset srvbuf+1      ; Size of remote command.
  1344.         mov     [bx],ah
  1345.         mov     ah,0
  1346.         inc     al                      ; For the size field.
  1347.         cmp     remcmd,'C'              ; Change working directory?
  1348.         jne     genr0                   ; No, so don't ask for password.
  1349.         mov     cnt,ax                  ; Save here for a bit.
  1350.         mov     ah,prstr
  1351.         mov     dx,offset pass          ; Send along an optional password.
  1352.         int     dos
  1353.         mov     bx,temp                 ; Where to put the password.
  1354.         push    bx                      ; Is safe since subroutine never fails
  1355.         inc     bx                      ; Leave room for count field.
  1356.         call    input                   ; Read in the password.
  1357.         mov     temp,bx                 ; Remember end of data pointer.
  1358.         pop     bx                      ; Where to put the size.
  1359.         cmp     ah,0                    ; No password given?
  1360.         jne     genrc
  1361.         mov     ax,cnt
  1362.         jmp     genr0                   ; Then that's it.
  1363. genrc:  mov     al,ah
  1364.         add     ah,32                   ; Make it printable.
  1365.         mov     [bx],ah                 ; Tell remote host the size.
  1366.         mov     ah,0
  1367.         push    ax                      ; Remember the count.
  1368.         call    clearl                  ; Clear to end-of-line.
  1369.         pop     ax
  1370.         inc     al                      ; For second count value.
  1371.         add     ax,cnt                  ; Total for both fields of input.
  1372. genr0:  inc     al                      ; For char representing the command.
  1373.         mov     pack.argbk1,ax          ; Set the size.
  1374.         mov     cnt,ax                  ; And remember it.
  1375.         mov     pack.argbk1,ax          ; Set the size.
  1376.         mov     cnt,ax                  ; And remember it.
  1377.         mov     pack.numtry,0           ; Initialize count
  1378.         mov     bx,offset srvbuf        ; Start of data buffer.
  1379.         mov     ah,remcmd               ; Command subtype.
  1380.         mov     [bx],ah
  1381.         call    ipack                   ; Send init parameters.
  1382.          jmp    genr2
  1383.          nop                            ; Make it 3 bytes long.
  1384.         mov     ah,trans.chklen
  1385.         mov     curchk,ah               ; Save desired checksum length.
  1386.         mov     trans.chklen,1          ; Use 1 char for server functions.
  1387.         mov     pack.numrtr,0           ; No retries yet.
  1388. genr1:  cmp     pack.state,'A'          ; Did the user type a ^C?
  1389.         je      genr2x
  1390.         mov     ah,pack.numtry
  1391.         cmp     ah,maxtry               ; Too many tries?
  1392.         jl      genr3                   ; Nope, keep trying.
  1393. genr2:  mov     ah,prstr
  1394.         mov     dx,offset erms21        ; Print error msg and fail.
  1395.         int     dos
  1396. genr2x: call    serrst                  ; Reset the port.
  1397.         mov     ah,curchk
  1398.         mov     trans.chklen,ah         ; Restore.
  1399.         mov     flags.xflg,0         ; reset screen output flag before leaving
  1400.         xor     ax,ax                   ; tell statistics this was a read
  1401.         or      errlev,4             ; DOS error level, failure of REMote cmd
  1402.         call    endtim
  1403.         jmp     rskp
  1404. genr3:  mov     ah,prstr
  1405.         mov     dx,offset crlf          ; First go to a new line.
  1406.         int     dos
  1407.         push    es                      ; Prepare to put string into packet.
  1408.         push    ds
  1409.         pop     es
  1410.         mov     si,offset srvbuf        ; Move from here
  1411.         mov     di,offset data          ; to here.
  1412.         mov     cx,cnt                  ; Move this many characters.
  1413.         cld
  1414.         rep     movsb                   ; Perform the string move.
  1415.         pop     es
  1416.         mov     ax,cnt
  1417.         mov     pack.argbk1,ax          ; How much data to send.
  1418.         mov     cx,ax                   ; Size of data.
  1419.         call    doenc                   ; Encode it.
  1420.         inc     pack.numtry             ; Increment number of trials.
  1421.         mov     trans.chklen,1          ; use block check 1 to server
  1422.         mov     pack.argblk,0           ; Packet number 0.
  1423.         mov     ah,rempac               ; Packet type.
  1424.         call    pktsize                 ; report packet size
  1425.         call    spack                   ; Send the packet.
  1426.          jmp    genr2                   ; Tell user we can't do it.
  1427.          nop
  1428.         call    rpack                   ; Get ACK (w/o screen stuff)
  1429.          jmp    genr3a                  ; Got a NAK - try again.
  1430.          nop
  1431.         jmp     genr3b                  ; Ok.
  1432.  
  1433. genr3a: push    ax
  1434.         mov     ah,curchk
  1435.         mov     trans.chklen,ah         ; Restore after reception.
  1436.         pop     ax
  1437.         jmp     genr1                   ; NAK, try again
  1438.  
  1439. genr3b: push    ax                      ; Ok.
  1440.         mov     ah,curchk
  1441.         mov     trans.chklen,ah         ; Restore after reception.
  1442.         pop     ax
  1443.         cmp     ah,'Y'                  ; Is all OK?
  1444.         jne     genr4
  1445.         cmp     pack.argbk1,0           ; Any data in the ACK?
  1446.         je      genr31                  ; Nope - just return.
  1447.         call    dodec                   ; Decode data.
  1448.         mov     di,offset data          ; Where the reply is.
  1449.         mov     cx,pack.argbk1          ; How much data we have.
  1450.         call    prtscr                  ; Print it on the screen.
  1451.         mov     flags.xflg,0    ; reset screen output flag before leaving
  1452. genr31: xor     ax,ax                   ; tell statistics this was a read
  1453.         call    endtim                  ; tell statistics
  1454.         jmp     rskp                    ; And we're done.
  1455. genr4:  cmp     ah,'X'                  ; Text packet?
  1456.         je      genr5
  1457.         cmp     ah,'S'                  ; Handling this like a file?
  1458.         jne     genr6
  1459.         mov     pack.state,'R'          ; Set the state.
  1460.         mov     bx,offset rin21         ; Where to go to.
  1461.         jmp     genr51                  ; Continue.
  1462. genr5:  mov     pack.state,'F'
  1463.         call    dodec                   ; Decode data.
  1464.         mov     bx,offset rfile3        ; Jump to here.
  1465. genr51: mov     flags.xflg,1            ; Remember we saw an "X" packet.
  1466.         mov     pack.numtry,0
  1467.         mov     pack.numrtr,0
  1468.         mov     pack.numpkt,0
  1469.         mov     pack.pktnum,0
  1470.         call    bx                      ; Handle it almost like filename.
  1471.         call    read2                   ; Receive the rest.
  1472.          jmp    r                       ; Oops, we failed.
  1473.          nop
  1474.         xor     ax,ax                   ; tell statistics this was a read
  1475.         call    endtim
  1476.         jmp     rskp                    ; Done OK.
  1477. genr6:  cmp     ah,'E'                  ; Error packet?
  1478.         je      genr6x                  ; e = yes
  1479.         jmp     genr1                   ; Try again.
  1480. genr6x: call    dodec                   ; Decode data.
  1481.         call    error1                  ; Print the error messge.
  1482.         call    serrst
  1483.         xor     ax,ax                   ; tell statistics this was a read
  1484.         call    endtim
  1485.         mov     flags.xflg,0    ; reset screen output flag before leaving
  1486.         jmp     rskp                    ; And return.
  1487. GENRIC  ENDP
  1488.  
  1489. ; Send  "I" packet with transmission parameters
  1490.  
  1491. IPACK   PROC    NEAR
  1492.         call    serini                  ; Initialize port
  1493.         call    ihosts                  ; initialize the host
  1494.         mov     pack.pktnum,0           ; Use packet number 0.
  1495.         mov     pack.numtry,0           ; Number of retries.
  1496.         mov     pack.numrtr,-1          ; no retries (incremented below)
  1497. ipk0:   call    updrtr
  1498.         cmp     pack.state,'A'          ; Did user type a ^C?
  1499.         je      ipk0x                   ; e = yes
  1500.         push    dx
  1501.         mov     dl,imxtry
  1502.         cmp     pack.numtry,dl          ; Reached our limit?
  1503.         pop     dx
  1504.         jl      ipk1                    ; l = no
  1505. ipk0x:  ret                             ; Yes, so we fail.
  1506. ipk1:   inc     pack.numtry             ; Save the updated number of tries.
  1507.         mov     bx,portval
  1508.         mov     trans.ebquot,dqbin   ; default 8 bit quote, needed with parity
  1509.         cmp     [bx].parflg,parnon      ; using parity = none locally?
  1510.         jne     ipk1a           ; ne = using local parity, need 8 bit quoting
  1511.         mov     trans.ebquot,'Y'   ; say can do 8 bit quoting, if they insist
  1512. ipk1a:  mov     bx,offset data          ; Get a pointer to our data block
  1513.         call    rpar                    ; Set up the parameter information.
  1514.         xchg    ah,al
  1515.         mov     ah,0
  1516.         mov     pack.argbk1,ax          ; Save the number of arguments.
  1517.         mov     pack.argblk,0           ; Use packet number 0.
  1518.         mov     ah,dtrans.seol          ; restore default end-of-line char
  1519.         mov     trans.seol,ah
  1520.         mov     ah,trans.chklen
  1521.         mov     curchk,ah               ; Save real value.
  1522.         mov     trans.chklen,1          ; One char for server function.
  1523.         call    pktsize                 ; report packet size
  1524.         mov     ah,'I'                  ; "I" packet.
  1525.         call    spack                   ; Send the packet.
  1526.          jmp    ipk4
  1527.          nop
  1528.         call    rpack                   ; Get a packet.
  1529.          jmp    ipk4                    ; Try again.
  1530.          nop
  1531.         push    ax
  1532.         mov     ah,curchk
  1533.         mov     trans.chklen,ah         ; Reset.
  1534.         pop     ax
  1535.         cmp     ah,'Y'                  ; ACK?
  1536.         jne     ipk3                    ; If not try next.
  1537.         mov     ax,pack.pktnum          ; Get the packet number.
  1538.         cmp     ax,pack.argblk          ; Is it the right packet number?
  1539.         je      ipk2
  1540.          jmp    ipk0                    ; If not try again.
  1541. ipk2:   mov     ax,pack.argbk1          ; Get the number of pieces of data.
  1542.         mov     bx,offset data          ; Pointer to the data.
  1543. ipk2a:  call    spar                    ; Read in the data.
  1544.         mov     ah,trans.chklen
  1545.         mov     curchk,ah               ; This is what we decided on.
  1546.         call    packlen                 ; Get max send packet size.
  1547.         mov     pack.numtry,0           ; Reset the number of tries.
  1548.         jmp     rskp
  1549. ipk3:   cmp     ah,'N'                  ; NAK?
  1550.         jne     ipk3y                   ; Yes, try again.
  1551.         jmp     ipk0
  1552. ipk3y:  cmp     ah,'E'                  ; Is it an error packet.
  1553.         je      ipk3x
  1554.         jmp     ipk0                    ; Trashed data.
  1555. ipk3x:  mov     ax,0            ; Other side doesn't know about "I" packet.
  1556.                                 ; force defaults (zero length response)
  1557.         jmp     ipk2a           ;   to use lowest common denominator
  1558. ipk4:   mov     ah,curchk
  1559.         mov     trans.chklen,ah         ; Reset.
  1560.         cmp     flags.cxzflg,0          ; did user say quit?
  1561.         jne     ipk5                    ; ne = yes, quit
  1562.         jmp     ipk0                    ; Keep trying.
  1563. ipk5:   ret
  1564. IPACK   ENDP
  1565.  
  1566. ; Returns in AH the count of characters read in.
  1567. ;         in BX the updated pointer to the input buffer.
  1568.  
  1569. INPUT   PROC    NEAR
  1570.         mov     cl,0                    ; Keep a count.
  1571.         mov     inpbuf,bx               ; Where to put data.
  1572.         mov     comand.cmquiet,1        ; turn on quiet mode
  1573. input0: call    cmgetc                  ; get a character nicely
  1574.         cmp     al,CR                   ; Done with input?
  1575.         jne     input1
  1576.         push    cx                      ; save count
  1577.         mov     ah,prstr
  1578.         mov     dx,offset crlf
  1579.         int     dos                     ; echo a carriage return
  1580.         pop     cx
  1581.         mov     ah,cl                   ; Return count in AH.
  1582.         mov     comand.cmquiet,0        ; turn off quiet mode
  1583.         jmp     r
  1584. input1: cmp     al,BS                   ; Backspace?
  1585.         je      inpt11
  1586.         cmp     al,DEL                  ; Or delete?
  1587.         jne     input3
  1588. inpt11: dec     cl                      ; Don't include in char count.
  1589.         cmp     cl,0                    ; Backspaced too much?
  1590.         jns     input2                  ; No, is OK.
  1591.         mov     ah,conout
  1592.         mov     dl,bell
  1593.         int     dos
  1594.         mov     cl,0
  1595.         jmp     input0
  1596. input2: dec     bx                      ; 'Remove' from buffer.
  1597.         jmp     input0                  ; Go get more.
  1598. input3: cmp     al,'U'-64               ; Control-U?
  1599.         jne     input4
  1600.         mov     cl,0                    ; Reset count to zero.
  1601.         mov     bx,inpbuf               ; Start at head of buffer.
  1602.         jmp     input0
  1603. input4: mov     [bx],al                 ; Add char to buffer.
  1604.         inc     cl                      ; Include in count.
  1605.         inc     bx
  1606.         jmp     input0
  1607. INPUT   ENDP
  1608.  
  1609.  
  1610. ; Jumping to this location is like retskp.  It assumes the instruction
  1611. ;   after the call is a jmp addr.
  1612.  
  1613. RSKP    PROC    NEAR
  1614.         pop     bp
  1615.         add     bp,3
  1616.         push    bp
  1617.         ret
  1618. RSKP    ENDP
  1619.  
  1620. ; Jumping here is the same as a ret.
  1621.  
  1622. R       PROC    NEAR
  1623.         ret
  1624. R       ENDP
  1625.  
  1626. code    ends
  1627.         end
  1628.  
  1629. ; Jumping here is the same as a ret.
  1630.  
  1631. R       PROC    NEAR
  1632.         ret
  1633. R       ENDP
  1634.  
  1635. code    ends
  1636.         end
  1637.