home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / MSKERMIT.ZIP / MSSERV.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-05-17  |  23.4 KB  |  837 lines

  1.     public    logout, bye, finish, remote, get, server
  2.     include msdefs.h
  3.  
  4. datas    segment public 'datas'
  5.     extrn    data:byte, flags:byte, trans:byte, pack:byte, curchk:byte
  6.     extrn    fcb:byte
  7.  
  8. remcmd    db    0        ; Remote command to be executed. [21c]
  9. rempac    db    0        ; Packet type: C (host) or G (generic). [21c]
  10.  
  11. cmer05    db    cr,lf,'?Filename must be specified$'     ; [21a]
  12. ermes7    db    '?Unable to receive initiate$'
  13. erms18    db    cr,lf,'?Unable to tell host that session is finished$'
  14. erms19    db    cr,lf,'?Unable to tell host to logout$'
  15. erms21    db    cr,lf,'?Unable to tell host to execute command$' ; [21c]
  16. infms1    db    'Entering server mode',cr,lf,'$'
  17. remms1    db    'Kermit-MS: Unknown server command$'
  18. remms2    db    'Kermit-MS: Illegal file name$'
  19. remms3    db    'Kermit-MS: Unknown generic command$'
  20. pass    db    lf,cr,' Password: $'    ; When change directory. [21c]
  21. crlf    db    cr,lf,'$'
  22. tmp    db    ?,'$'
  23. temp    dw    0
  24. oloc    dw    0        ; Original buffer location. [21c]
  25. osiz    dw    0        ; Original buffer size. [21c]
  26. inpbuf    dw    0        ; Pointer to input buffer. [21c]
  27. cnt    dw    0
  28. delinp    db    BS,BS,BS,'   ',BS,BS,BS,'$'     ; When DEL key is used. [21d]
  29. clrspc    db    ' ',10O,'$'             ; Clear space.
  30.  
  31. srvchr    db    'SRGIE'         ; server cmd characters
  32. srvfln    equ    $-srvchr    ; length of tbl
  33. srvfun    dw    srvsnd,srvrcv,srvgen,srvini,serv1
  34.  
  35. remhlp    db    cr,lf,'CWD connect to a directory'      ; [21c start]
  36.     db    cr,lf,'DELETE a file'
  37.     db    cr,lf,'DIRECTORY listing'
  38.     db    cr,lf,'HELP'
  39.     db    cr,lf,'HOST command'
  40.     db    cr,lf,'SPACE in a directory'
  41.     db    cr,lf,'TYPE a file$'                    ; [21c end]
  42.  
  43. remtab    db    07H        ; Seven entries. [21c start]
  44.     mkeyw    'CWD',remcwd
  45.     mkeyw    'DELETE',remdel
  46.     mkeyw    'DIRECTORY',remdir
  47.     mkeyw    'HELP',remhel
  48.     mkeyw    'HOST',remhos
  49.     mkeyw    'SPACE',remdis
  50.     mkeyw    'TYPE',remtyp           ; [21c end]
  51.  
  52. remfnm    db    ' Remote Source File: $'
  53. lclfnm    db    ' Local Destination File: $'
  54. filhlp    db    ' File name to receive as$'
  55. filmsg    db    ' Remote file specification or confirm with carriage return $'
  56. frem    db    ' Name of file on remote system $'
  57. genmsg    db    ' Enter text to be sent to remote server $'
  58. rdbuf    db    80H DUP(?)
  59. datas    ends
  60.  
  61. code    segment public
  62.     extrn comnd:near, serrst:near, spack:near, rpack5:near, init:near
  63.     extrn read12:near, serini:near, read2:near, rpar:near, spar:near
  64.     extrn rin21:near, rfile3:near, error1:near, clrfln:near
  65.     extrn dodel:near, clearl:near, dodec: near, doenc:near
  66.     extrn packlen:near, send11:near, errpack:near, init1:near
  67.     extrn rpack:near,nak:near, rrinit:near, cmblnk:near
  68.     extrn error:near, erpos:near, rprpos:near, clrmod:near
  69.     extrn prompt:near
  70.     assume    cs:code,ds:datas
  71.  
  72. ; LOGOUT - tell remote KERSRV to logout.
  73.  
  74. LOGOUT    PROC    NEAR
  75.     mov ah,cmcfm
  76.     call comnd        ; Get a confirm.
  77.      jmp r
  78.     call logo
  79.      jmp rskp        ; Go get another command whether we ....
  80.     jmp rskp        ; .... succeed or fail.
  81. LOGOUT    ENDP
  82.  
  83. LOGO    PROC    NEAR
  84.     mov pack.numtry,0    ; Initialize count.
  85.     mov pack.numrtr,0    ; No retries yet.
  86.     call serini        ; Initialize port.  [14]
  87.     mov ah,trans.chklen    ; Don't forget the checksum length.
  88.     mov curchk,ah
  89.     mov trans.chklen,1    ; Use one char for server functions.
  90. logo1:    cmp pack.state,'A'      ; Did user type a ^C?
  91.     je logo2x        ; Yes just leave.
  92.     mov ah,pack.numtry
  93.     cmp ah,maxtry        ; Too many times?
  94.     js logo3        ; No, try it.
  95. logo2:    mov ah,prstr
  96.     mov dx,offset erms19
  97.     int dos
  98. logo2x: call serrst        ; Reset port.  [14]
  99.     mov ah,curchk
  100.     mov trans.chklen,ah    ; Restore value.
  101.     ret
  102. logo3:    inc pack.numtry     ; Increment number of tries.
  103.     mov pack.argblk,0    ; Packet number zero.
  104.     mov pack.argbk1,1    ; One piece of data.
  105.     mov bx,offset data
  106.     mov ah,'L'
  107.     mov [bx],ah        ; Logout the remote host.
  108.     mov cx,1        ; One piece of data.
  109.     call doenc        ; Do encoding.
  110.     mov ah,'G'              ; Generic command packet.
  111.     call spack
  112.      jmp logo2        ; Tell user and die.
  113.      nop
  114.     call rpack5        ; Get ACK (w/o screen msgs.)
  115.      jmp logo1        ; Go try again.
  116.      nop
  117.     push ax
  118.     call dodec        ; Decode packet.
  119.     mov ah,curchk
  120.     mov trans.chklen,ah    ; Restore value.
  121.     pop ax
  122.     cmp ah,'Y'              ; ACK?
  123.     jne logo4
  124.     call serrst        ; Reset port.  [14]
  125.     jmp rskp
  126. logo4:    cmp ah,'E'              ; Error packet?
  127.     jnz logo1        ; Try sending the packet again.
  128.     call error1
  129.     call serrst        ; Reset port.  [14]
  130.     ret
  131. LOGO    ENDP
  132.  
  133. ; FINISH - tell remote KERSRV to exit.
  134.  
  135. FINISH    PROC    NEAR
  136.     mov ah,cmcfm        ; Parse a confirm.
  137.     call comnd
  138.      jmp r
  139.     mov pack.numtry,0    ; Initialize count.
  140.     mov pack.numrtr,0    ; No retries yet.
  141.     call serini        ; Initialize port.  [14]
  142.     mov ah,trans.chklen    ; Don't forget the checksum length.
  143.     mov curchk,ah
  144.     mov trans.chklen,1    ; Use one char for server functions.
  145. fin1:    cmp pack.state,'A'      ; ^C typed?
  146.     je fin2x
  147.     mov ah,pack.numtry
  148.     cmp ah,maxtry        ; Too many times?
  149.     js fin3         ; Nope, try it.
  150. fin2:    mov ah,prstr
  151.     mov dx,offset erms18
  152.     int dos
  153. fin2x:    call serrst        ; Reset port.  [14]
  154.     mov ah,curchk
  155.     mov trans.chklen,ah    ; Restore value.
  156.     jmp rskp        ; Go home.
  157. fin3:    inc pack.numtry     ; Increment number of tries.
  158.     mov pack.argblk,0    ; Packet number zero.
  159.     mov pack.argbk1,1    ; One piece of data.
  160.     mov bx,offset data
  161.     mov ah,'F'
  162.     mov [bx],ah        ; Finish running Kermit.
  163.     mov cx,1        ; One piece of data.
  164.     call doenc        ; Do encoding.
  165.     mov ah,'G'              ; Generic command packet.
  166.     call spack
  167.      jmp fin2        ; Tell user and die.
  168.      nop
  169.     call rpack5        ; Get ACK (w/o screen stuff).
  170.      jmp fin1        ; Go try again.
  171.      nop
  172.     push ax
  173.     call dodec        ; Decode data.
  174.     mov ah,curchk
  175.     mov trans.chklen,ah    ; Restore value.
  176.     pop ax
  177.     cmp ah,'Y'              ; Got an ACK?
  178.     jnz fin4
  179.     call serrst        ; Reset port. [14]
  180.     jmp rskp        ; Yes, then we're done.
  181. fin4:    cmp ah,'E'              ; Error packet?
  182.     jnz fin1        ; Try sending it again.
  183.     call error1
  184.     call serrst        ; Reset port.  [14]
  185.     jmp rskp
  186. FINISH    ENDP
  187.  
  188. ; BYE command - tell remote KERSRV to logout & exits to DOS.
  189.  
  190. BYE    PROC    NEAR
  191.     mov ah,cmcfm        ; Parse a confirm.
  192.     call comnd
  193.      jmp r
  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                    ; [8 end]
  198. BYE    ENDP
  199.  
  200. ; Tell remote server to send the specified file(s).
  201.  
  202. get    PROC    NEAR
  203.     mov flags.droflg,0    ; Reset flags from fn parsing.
  204.     mov flags.nmoflg,0    ; Reset flags from fn parsing.
  205.     mov flags.cxzflg,0    ; no ctl-c typed yet...
  206.     mov bx,offset data    ; Where to put text.  [8 start]
  207.     mov dx,offset filmsg    ; In case user needs help.
  208.     mov ah,cmtxt
  209.     call comnd        ; Get text or confirm.
  210.      jmp r            ; Fail.
  211.     cmp ah,0        ; Read in any chars?
  212.     jne get4        ; Yes, then OK.
  213. ; empty line, ask for file names
  214. get1:    mov dx,offset remfnm    ; ask for remote first
  215.     call prompt
  216.     mov bx,offset data
  217.     mov dx,offset frem
  218.     mov ah,cmtxt
  219.     call comnd        ; get a line of text
  220.      jmp r
  221.     cmp flags.cxzflg,'C'    ; ctl-C typed?
  222.     jne get2        ; no, continue
  223.     jmp rskp
  224. get2:    cmp ah,0
  225.     je get1     ; ignore empty lines
  226.     mov bl,ah
  227.     mov bh,0
  228.     mov byte ptr data[bx],'$' ; terminate name for printing
  229.     mov pack.argbk1,bx    ; remember length here
  230.     mov dx,offset lclfnm
  231.     call prompt
  232.     mov ah,cmifi
  233.     mov bx,offset filhlp
  234.     mov dx,offset fcb
  235.     call comnd
  236.      jmp r
  237.     mov ah,cmcfm
  238.     call comnd
  239.      jmp r
  240.     cmp flags.cxzflg,'C'    ; control-C typed?
  241.     jne get3        ; no, keep going
  242.     jmp rskp
  243. get3:    mov flags.nmoflg,1    ; remember changed name
  244.     jmp short get5
  245. get4:    mov al,ah
  246.     mov ah,0
  247.     mov pack.argbk1,ax    ; Remember number of chars we read.
  248.     mov byte ptr [bx],'$'   ; use for printing.
  249. get5:    cmp flags.remflg,0    ; remote mode?
  250.     jne get6        ; yes, don't print anything
  251.     call init        ; Clear line and initialize buffers.
  252.     call clrfln        ; Prepare to print filename.
  253.     mov ah,prstr
  254.     mov dx,offset data    ; Print file name.
  255.     int dos
  256. get6:    call init1        ; init buffers
  257.     mov pack.numtry,0    ; Initialize count.
  258.     mov pack.numrtr,0    ; No retries yet.
  259.     mov pack.state,'R'      ; this is what state will soon be...
  260.     call serini        ; Initialize port.
  261.     mov cx,pack.argbk1    ; Data size.
  262.     call doenc        ; Encode data.
  263.     mov ah,trans.chklen    ; Don't forget the checksum length.
  264.     mov curchk,ah
  265.     mov trans.chklen,1    ; Use one char for server functions.
  266. get7:    cmp pack.state,'A'      ; Did user type a ^C?
  267.     je get9         ; Yes - just return to main loop.
  268.     mov ah,pack.numtry
  269.     cmp ah,maxtry        ; Too many times?
  270.     jbe get10        ; Nope, try it.
  271. get8:    cmp flags.remflg,0    ; remote mode?
  272.     jne get9        ; yes, no printing
  273.     call erpos
  274.     mov ah,prstr
  275.     mov dx,offset ermes7    ; Can't get init packet.
  276.     int dos
  277. get9:    call serrst        ; Reset port.
  278.     mov ah,curchk
  279.     mov trans.chklen,ah    ; Restore value.
  280.     jmp rskp        ; Go home.
  281. get10:    inc pack.numtry     ; Increment number of tries.
  282.     mov pack.argblk,0    ; Start at packet zero.
  283.     mov ah,'R'              ; Receive init packet.
  284.     call spack        ; Send the packet.
  285.      jmp get8        ; Tell user we can't do it.
  286.      nop
  287.     call rpack5        ; Get ACK (w/o screen stuff).
  288.      jmp get7        ; Got a NAK - try again.
  289.      nop
  290.     push ax
  291.     mov ah,curchk
  292.     mov trans.chklen,ah    ; Restore value.
  293.     pop ax
  294.     mov pack.argbk2,ax    ; this is where rinit wants pkt type if getting
  295.     mov flags.getflg,1    ; "Get" as vs "Receive".
  296.     jmp read12        ; go join read code
  297. get11:    mov ah,prstr        ; Complain if no filename.
  298.     mov dx,offset cmer05
  299.     int dos
  300.     jmp rskp
  301. GET    ENDP
  302.  
  303. ; server command
  304.  
  305. server    proc    near
  306.     mov    ah,cmcfm
  307.     call    comnd
  308.      jmp    r
  309.     push    es
  310.     mov    ax,ds
  311.     mov    es,ax        ; address data segment
  312.     mov    al,flags.remflg ; get remote flag
  313.     push    ax        ; preserve for later
  314.     mov    flags.remflg,1    ; set remote if server
  315.     call    cmblnk        ; clear screen
  316.     mov    ah,prstr
  317.     mov    dx,offset infms1
  318.     int    dos
  319. ; should reset to default parms here...
  320. ; should increase timeout interval
  321. serv1:    call    serini        ; init serial line (send & recv reset it)
  322.     mov    trans.chklen,1    ; checksum len = 1
  323.     mov    pack.pktnum,0    ; pack number resets to 0
  324.     mov    pack.numtry,0    ; no retries yet.
  325.     call    rpack        ; get a packet
  326.      jmp    short serv2    ; no good, nak and continue
  327.      nop
  328.     jmp    short serv3    ; try to figure this out
  329. serv2:    cmp    flags.cxzflg,'C' ; ctl-C?
  330.     je    serv5        ; yes, stop this.
  331.     call    nak        ; nak the packet
  332.     jmp    serv1        ; and keep readiserv2 packets
  333.  
  334. serv3:    mov    di,offset srvchr ; server characters
  335.     mov    cx,srvfln    ; length of striserv2
  336.     mov    al,ah        ; packet type
  337.     repne    scasb        ; hunt for it
  338.     je    serv4        ; we know this one, go handle it
  339.     mov    bx,offset remms1 ; else give a message
  340.     call    errpack     ; back to local kermit
  341.     jmp    serv1        ; and keep lookiserv2 for a cmd
  342. serv4:    sub    di,offset srvchr+1 ; find offset, +1 for pre-increment
  343.     shl    di,1        ; convert to word index.
  344.     call    srvfun[di]    ; call the appropriate handler
  345.      jmp    serv5        ; someone wanted to exit...
  346. ; should we reset serial line?
  347.     jmp    serv1        ; else keep goiserv2 for more cmds.
  348.  
  349. serv5:
  350. ;** restore timer values
  351.     pop    ax        ; get this off stack
  352.     mov    flags.remflg,al ; restore old flag
  353.     call    serrst        ; reset serial handler
  354.     pop    es        ; restore register
  355.     jmp    rskp        ; and return
  356. server    endp
  357.  
  358. ; server commands.
  359.  
  360. ; srvsnd - receives a file that the local kermit is sending.
  361. srvsnd    proc    near
  362.     mov    bx,offset data
  363.     call    spar        ; parse the send-init packet
  364.     call    packlen     ; figure max packet
  365.     mov    bx,offset data
  366.     call    rpar        ; make answer for them
  367.     mov    al,ah        ; length of packet
  368.     mov    ah,0
  369.     mov    pack.argbk1,ax    ; store length for spack
  370.     mov    ah,'Y'          ; ack
  371.     call    spack        ; answer them
  372.      jmp    rskp        ; can't answer, forget this
  373.     call    rrinit        ; init variables for init
  374.     inc    pack.pktnum    ; count the send-init packet.
  375.     mov    pack.state,'F'  ; expecting file name about now
  376.     call    read2        ; and join read code
  377.      nop
  378.      nop
  379.      nop            ; ignore errors
  380.     jmp    rskp        ; and return for more
  381. srvsnd    endp
  382.  
  383. ; srvrcv - send a file that they're receiving.
  384. srvrcv    proc    near
  385.     mov    si,offset data    ; this should be filename
  386.     mov    di,offset fcb    ; this is where filename goes
  387.     mov    al,1        ; skip leading separators
  388.     mov    ah,prsfcb    ; parse an fcb
  389.     int    dos        ; let dos do the work
  390.     cmp    al,0ffh     ; invalid?
  391.     jne    srvrc1        ; no, keep going
  392.     mov    bx,offset remms2 ; complain
  393.     call    errpack     ; that we can't find it
  394.     jmp    rskp        ; and return
  395. srvrc1: mov    pack.state,'R'  ; remember state.
  396.     call    send11        ; this should send it
  397.      jmp    rskp
  398.     jmp    rskp        ; return in any case
  399. srvrcv    endp
  400.  
  401. ; srvgen - generic server commands.
  402. ; We only support Logout and Finish right now.
  403. srvgen    proc    near
  404.     mov    al,data     ; get 1st packet char
  405.     cmp    al,'F'          ; maybe finish?
  406.     je    srvge1        ; yup, handle
  407.     cmp    al,'L'          ; logout?
  408.     jne    srvge2        ; no.
  409. srvge1: mov    pack.argbk1,0    ; 0-length data
  410.     mov    ah,'Y'
  411.     call    spack        ; ack it
  412.      nop
  413.      nop
  414.      nop            ; *** ignore error?
  415.     ret            ; and return to signal exit.
  416. srvge2: mov    bx,offset remms3
  417.     call    errpack
  418.     jmp    rskp
  419. srvgen    endp
  420.  
  421. ; srvini - init parms based on init packet
  422. srvini    proc    near
  423.     mov    bx,offset data
  424.     call    spar        ; parse info
  425.     call    packlen     ; this should really be part of spar, but...
  426.     mov    bx,offset data
  427.     call    rpar        ; get receive info
  428.     mov    al,ah
  429.     mov    ah,0
  430.     mov    pack.argbk1,ax    ; set size of return info
  431.     mov    ah,'Y'
  432.     call    spack        ; send the packet off
  433.      jmp    rskp
  434.     jmp    rskp        ; and go succeed
  435. srvini    endp
  436.  
  437. ;    This is the REMOTE command. [21c]
  438.  
  439. REMOTE    PROC    NEAR
  440.     mov dx,offset remtab    ; Parse a keyword from the REMOTE table.
  441.     mov bx,offset remhlp
  442.     mov ah,cmkey
  443.     call comnd
  444.      jmp r
  445.     call bx         ; Call the appropriate routine.
  446.      jmp r            ; Command failed.
  447.     jmp rskp
  448. REMOTE    ENDP
  449.  
  450. ; REMDIS - Get disk usage on remote system. [21c]
  451.  
  452. REMDIS    PROC    NEAR
  453.     mov remcmd,'U'          ; Disk usage command.
  454.     mov rempac,'G'          ; Packet type = generic.
  455.     jmp genric        ; Execute generic Kermit command.
  456. REMDIS    ENDP
  457.  
  458.  
  459. ; REMHEL - Get help about remote commands. [21c]
  460.  
  461. REMHEL    PROC    NEAR
  462.     mov remcmd,'H'          ; Help......
  463.     mov rempac,'G'          ; Packet type = generic.
  464.     jmp genric        ; Execute generic Kermit command.
  465. REMHEL    ENDP
  466.  
  467. ; REMTYP - Print a remote file. [21c]
  468.  
  469. REMTYP    PROC    NEAR
  470.     mov remcmd,'T'          ; Type the file.
  471.     mov rempac,'G'          ; Packet type = generic.
  472.     jmp genric
  473. REMTYP    ENDP
  474.  
  475. ; REMHOS - Execute a remote host command. [21c]
  476.  
  477. REMHOS    PROC    NEAR
  478.     mov remcmd,' '          ; Don't need one.
  479.     mov rempac,'C'          ; Packet type = remote command.
  480.     jmp genric
  481. REMHOS    ENDP
  482.  
  483. ; REMDIR - Do a directory. [21c]
  484.  
  485. REMDIR    PROC    NEAR
  486.     mov remcmd,'D'
  487.     mov rempac,'G'          ; Packet type = generic.
  488.     jmp genric
  489. REMDIR    ENDP
  490.  
  491. ; REMDEL - Delete a remote file. [21c]
  492.  
  493. REMDEL    PROC    NEAR
  494.     mov remcmd,'E'
  495.     mov rempac,'G'          ; Packet type = generic.
  496.     jmp genric
  497. REMDEL    ENDP
  498.  
  499. ; REMCWD - Change remote working directory.  [21c]
  500.  
  501. REMCWD    PROC    NEAR
  502.     mov remcmd,'C'
  503.     mov rempac,'G'          ; Packet type = generic.
  504.     jmp genric
  505. REMCWD    ENDP
  506.  
  507. ; GENRIC - Send a generic command to a remote Kermit server. [21c]
  508.  
  509. GENRIC    PROC    NEAR
  510.     mov bx,offset rdbuf    ; Where to put the text.
  511.     cmp rempac,'C'          ; Remote host command?
  512.     je genra        ; Yes, leave as is.
  513.     add bx,2        ; Leave room for type and size.
  514. genra:    mov ah,cmtxt        ; Parse arbitrary text up to a CR.
  515.     mov dx,offset genmsg    ; In case they want text.
  516.     call comnd
  517.      jmp r
  518.     mov al,ah        ; Don't forget the size.
  519.     mov ah,0
  520.     mov cnt,ax        ; Save it here.
  521.     cmp rempac,'C'          ; Remote host command?
  522.     jne genrb        ; No, skip this part.
  523.     call ipack
  524.      jmp genr2
  525.     mov pack.numtry,0
  526.     mov ah,trans.chklen
  527.     mov curchk,ah        ; Save desired checksum length.
  528.     mov trans.chklen,1    ; Use 1 char for server functions.
  529.     mov pack.numrtr,0    ; No retries yet.
  530.     jmp genr1        ; Send the packet.
  531. genrb:    mov ax,cnt
  532.     cmp ax,0        ; Any data?
  533.     je genr0        ; Nope.
  534.     mov ah,al        ; Don't overwrite the real count value.
  535.     add ah,32        ; Do the char function.
  536.     mov temp,bx        ; Remember where we are.
  537.     mov bx,offset rdbuf+1    ; Size of remote command.
  538.     mov [bx],ah
  539.     mov ah,0
  540.     inc al            ; For the size field.
  541.     cmp remcmd,'C'          ; Change working directory?
  542.     jne genr0        ; No, so don't ask for password.
  543.     mov cnt,ax        ; Save here for a bit.
  544.     mov ah,prstr
  545.     mov dx,offset pass    ; Send along an optional password.
  546.     int dos
  547.     mov bx,temp        ; Where to put the password.
  548.     push bx         ; Is safe since subroutine never fails.
  549.     inc bx            ; Leave room for count field.
  550.     call input        ; Read in the password.
  551.     mov temp,bx        ; Remember end of data pointer.
  552.     pop bx            ; Where to put the size.
  553.     cmp ah,0        ; No password given?
  554.     jne genrc
  555.     mov ax,cnt
  556.     jmp genr0        ; Then that's it.
  557. genrc:    mov al,ah
  558.     add ah,32        ; Make it printable.
  559.     mov [bx],ah        ; Tell remote host the size.
  560.     mov ah,0
  561.     push ax         ; Remember the count.
  562.     call clearl        ; Clear to end-of-line.
  563.     pop ax
  564.     inc al            ; For second count value.
  565.     add ax,cnt        ; Total for both fields of input.
  566. genr0:    inc al            ; For the char representing the command.
  567.     mov pack.argbk1,ax    ; Set the size.
  568.     mov cnt,ax        ; And remember it.
  569.     mov pack.numtry,0    ; Initialize count
  570.     mov bx,offset rdbuf    ; Start of data buffer.
  571.     mov ah,remcmd        ; Command subtype.
  572.     mov [bx],ah
  573.     call ipack        ; Send init parameters.
  574.      jmp genr2
  575.      nop            ; Make it 3 bytes long.
  576.     mov ah,trans.chklen
  577.     mov curchk,ah        ; Save desired checksum length.
  578.     mov trans.chklen,1    ; Use 1 char for server functions.
  579.     mov pack.numrtr,0    ; No retries yet.
  580. genr1:    cmp pack.state,'A'      ; Did the user type a ^C?
  581.     je genr2x
  582.     mov ah,pack.numtry
  583.     cmp ah,maxtry        ; Too many tries?
  584.     js genr3        ; Nope, keep trying.
  585. genr2:    mov ah,prstr
  586.     mov dx,offset erms21    ; Print error msg and fail.
  587.     int dos
  588. genr2x: call serrst        ; Reset the port.
  589.     mov ah,curchk
  590.     mov trans.chklen,ah    ; Restore.
  591.     jmp rskp
  592. genr3:    push es         ; Prepare to put string into packet.
  593.     mov ax,ds
  594.     mov es,ax
  595.     mov si,offset rdbuf    ; Move from here
  596.     mov di,offset data    ; to here.
  597.     mov cx,cnt        ; Move this many characters.
  598.     rep movsb        ; Perform the string move.
  599.     pop es
  600.     mov ax,cnt
  601.     mov pack.argbk1,ax    ; How much data to send.
  602.     mov cx,ax        ; Size of data.
  603.     call doenc        ; Encode it.
  604.     inc pack.numtry     ; Increment number of trials.
  605.     mov pack.argblk,0    ; Packet number 0.
  606.     mov ah,rempac        ; Packet type.
  607.     call spack        ; Send the packet.
  608.      jmp genr2        ; Tell user we can't do it.
  609.      nop
  610.     call rpack5        ; Get ACK (w/o screen stuff)
  611.      jmp genr1        ; Got a NAK - try again.
  612.      nop
  613.     push ax
  614.     mov ah,curchk
  615.     mov trans.chklen,ah    ; Restore.
  616.     pop ax
  617.     cmp ah,'Y'              ; Is all OK?
  618.     jne genr4
  619.     cmp pack.argbk1,0    ; Any data in the ACK?
  620.     je genr31        ; Nope - just return.
  621.     call dodec        ; Decode data.
  622.     mov ah,prstr
  623.     mov dx,offset crlf    ; First go to a new line.
  624.     int dos
  625.     mov di,offset data    ; Where the reply is.
  626.     mov cx,pack.argbk1    ; How much data we have.
  627.     call prtscr        ; Print it on the screen.
  628. genr31: jmp rskp        ; And we're done.
  629. genr4:    cmp ah,'X'              ; Text packet?
  630.     je genr5
  631.     cmp ah,'S'              ; Handling this like a file?
  632.     jne genr6
  633.     mov pack.state,'R'      ; Set the state.
  634.     mov bx,offset rin21    ; Where to go to.
  635.     jmp genr51        ; Continue.
  636. genr5:    mov pack.state,'F'
  637.     call dodec        ; Decode data.
  638.     mov bx,offset rfile3    ; Jump to here.
  639. genr51: mov tmp,ah        ; Save packet type.
  640.     mov flags.xflg,1    ; Remember we saw an "X" packet.
  641.     mov pack.numtry,0
  642.     mov pack.numrtr,0
  643.     mov pack.numpkt,0
  644.     mov pack.pktnum,0
  645.     mov flags.cxzflg,0
  646.     mov ah,tmp        ; Packet type.
  647.     call bx         ; Handle it almost like filename.
  648.     call read2        ; Receive the rest.
  649.      jmp r            ; Oops, we failed.
  650.     jmp rskp        ; Done OK.
  651. genr6:    cmp ah,'E'              ; Error packet?
  652.     je genr6x
  653.     jmp genr1        ; Try again.
  654. genr6x: call dodec        ; Decode data.
  655.     call error1        ; Print the error messge.
  656.     call serrst
  657.     jmp rskp        ; And return.
  658. GENRIC    ENDP
  659.  
  660. ; Send "I" packet with transmission parameters. [21c]
  661.  
  662. IPACK    PROC    NEAR
  663.     mov ah,trans.chklen
  664.     mov curchk,ah        ; Initialize.
  665.     call serini
  666.     mov pack.pktnum,0    ; Use packet number 0.
  667.     mov pack.numtry,0    ; Number of retries.
  668. ipk0:    cmp pack.state,'A'      ; Did user type a ^C?
  669.     je ipk0x
  670.     cmp pack.numtry,imxtry    ; Reached our limit?
  671.     jl ipk1
  672. ipk0x:    ret            ; Yes, so we fail.
  673. ipk1:    inc pack.numtry     ; Save the updated number of tries.
  674.     mov bx,offset data    ; Get a pointer to our data block.
  675.     call rpar        ; Set up the parameter information.
  676.     xchg ah,al
  677.     mov ah,0
  678.     mov pack.argbk1,ax    ; Save the number of arguments.
  679.     mov pack.argblk,0    ; Use packet number 0.
  680.     mov ah,trans.chklen
  681.     mov curchk,ah        ; Save real value.
  682.     mov trans.chklen,1    ; One char for server function.
  683.     mov ah,'I'              ; "I" packet.
  684.     call spack        ; Send the packet.
  685.      jmp ipk4
  686.      nop
  687.     call rpack5        ; Get a packet.
  688.      jmp ipk4        ; Try again.
  689.      nop
  690.     push ax
  691.     mov ah,curchk
  692.     mov trans.chklen,ah    ; Reset.
  693.     pop ax
  694.     cmp ah,'Y'              ; ACK?
  695.     jne ipk3        ; If not try next.
  696.     mov ax,pack.pktnum    ; Get the packet number.
  697.     cmp ax,pack.argblk    ; Is it the right packet number?
  698.     je ipk2
  699.      jmp ipk0        ; If not try again.
  700. ipk2:    mov ax,pack.argbk1    ; Get the number of pieces of data.
  701.     mov bx,offset data    ; Pointer to the data.
  702.     call spar        ; Read in the data.
  703.     mov ah,trans.chklen
  704.     mov curchk,ah        ; This is what we decided on.
  705.     call packlen        ; Get max send packet size. [21b]
  706.     mov pack.numtry,0    ; Reset the number of tries.
  707.     jmp rskp
  708. ipk3:    cmp ah,'N'              ; NAK?
  709.     je ipk0         ; Yes, try again.
  710.     cmp ah,'E'              ; Is it an error packet.
  711.     je ipk3x
  712.     jmp ipk0        ; Trashed data.
  713. ipk3x:    jmp rskp        ; Other side doesn't know about "I" packet.
  714. ipk4:    mov ah,curchk
  715.     mov trans.chklen,ah    ; Reset.
  716.     jmp ipk0        ; Keep trying.
  717. IPACK    ENDP
  718.  
  719. ; Returns in AH the count of characters read in.
  720. ;      in BX the updated pointer to the input buffer.
  721.  
  722. INPUT    PROC    NEAR
  723.     mov cl,0        ; Keep a count.
  724.     mov inpbuf,bx        ; Where to put data.
  725. input0: mov ah,conin        ; Read in a char.
  726.     int dos
  727.     cmp al,CR        ; Done with input?
  728.     jne input1
  729.     mov ah,cl        ; Return count in AH.
  730.     jmp r
  731. input1: cmp al,BS        ; Backspace?
  732.     je inpt11        ;
  733.     cmp al,DEL        ; Or delete?
  734.     jne input3
  735.     call dodel        ; Erase weird character.
  736. inpt11: dec cl            ; Don't include in char count.
  737.     cmp cl,0        ; Backspaced too much?
  738.     jns input2        ; No, is OK.
  739.     push bx
  740.     call clearl
  741.     pop bx
  742.     mov ah,conout
  743.     mov dl,bell
  744.     int dos
  745.     mov cl,0
  746.     jmp input0
  747. input2: dec bx            ; 'Remove' from buffer.
  748.     mov ah,prstr
  749.     mov dx,offset clrspc
  750.     int dos
  751.     jmp input0        ; Go get more.
  752. input3: cmp al,'U'-64           ; Control-U?
  753.     jne input4
  754.     mov ah,prstr
  755.     mov dx,offset pass+1
  756.     int dos
  757.     push bx
  758.     push cx
  759.     call clearl        ; Blank out the line.
  760.     pop cx
  761.     pop bx
  762.     mov cl,0        ; Reset count to zero.
  763.     mov bx,inpbuf        ; Start at head of buffer.
  764.     jmp input0
  765. input4: cmp al,0        ; Two character sequence?
  766.     jne input5
  767.     mov ah,conin
  768.     int dos         ; Get second char.
  769.     cmp al,83        ; Delete key?
  770.     je inpt40        ; Yup.
  771.     cmp al,75        ; Backarrow key?
  772.     je inpt40
  773.     call dodel        ; Erase weird character.
  774.     jmp input0        ; And go on computing.
  775. inpt40: mov ah,prstr
  776.     mov dx,offset delinp    ; Erase weird character.
  777.     int dos
  778.     jmp inpt11        ; Remove the offending char.
  779. input5: mov [bx],al        ; Add char to buffer.
  780.     inc cl            ; Include in count.
  781.     inc bx
  782.     jmp input0
  783. INPUT    ENDP
  784.  
  785. ; Print data onto the screen.  If text has no "$" in it, just print
  786. ; it.  Else, do special output for the "$".
  787. ; Routine expects: DI = Start of buffer we are to print.
  788. ;           CX = Number of characters to print.     [21c]
  789.  
  790. PRTSCR    PROC    NEAR
  791.     mov al,'$'              ; This is what we're looking for.
  792.     mov oloc,di        ; Remember original buffer address.
  793.     mov osiz,cx        ; And original size.
  794.     push es
  795.     mov bx,ds
  796.     mov es,bx        ; Have ES point to data area.
  797. prts0:    repnz scasb        ; Search for "$" in the buffer.
  798.     cmp cx,0        ; Found one?
  799.     je prts1        ; No, do a regular DOS call.
  800.     mov ah,prstr
  801.     mov dx,oloc        ; Print up to the "$".
  802.     int dos
  803.     mov ah,dconio
  804.     mov dl,'$'
  805.     int dos         ; Print the "$"
  806.     mov oloc,di        ; New starting location.
  807.     mov osiz,cx        ; New size.
  808.     jmp prts0
  809. prts1:    mov bx,oloc        ; The buffer location.
  810.     add bx,osiz        ; Point past the data.
  811.     mov [bx],al        ; Add "$" for printing.
  812.     mov ah,prstr
  813.     mov dx,oloc
  814.     int dos
  815.     pop es
  816.     ret
  817. PRTSCR    ENDP
  818.  
  819. ; Jumping to this location is like retskp.  It assumes the instruction
  820. ;   after the call is a jmp addr.
  821.  
  822. RSKP    PROC    NEAR
  823.     pop bp
  824.     add bp,3
  825.     push bp
  826.     ret
  827. RSKP    ENDP
  828.  
  829. ; Jumping here is the same as a ret.
  830.  
  831. R    PROC    NEAR
  832.     ret
  833. R    ENDP
  834.  
  835. code    ends
  836.     end
  837.