home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ccdos / ccsser.asm < prev    next >
Assembly Source File  |  2020-01-01  |  69KB  |  1,542 lines

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