home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msr313src.zip / mssser.asm < prev    next >
Assembly Source File  |  1993-07-12  |  70KB  |  2,244 lines

  1.     NAME    mssser
  2. ; File MSSSER.ASM
  3.     include mssdef.h
  4. ;  Copyright (C) 1985, 1993, Trustees of Columbia University in the 
  5. ;  City of New York.  Permission is granted to any individual or institution
  6. ;  to use this software as long as it is not sold for profit.  This copyright
  7. ;  notice must be retained.  This software may not be included in commercial
  8. ;  products without written permission of Columbia University.
  9. ;
  10. ; Edit history:
  11. ; 27 August 1992 version 3.13
  12. ; 6 Sept 1991 version 3.11
  13. ; Last edit 19 April 1993
  14.  
  15.     public    bye, finish, remote, get, server, denyflg, srvtmo
  16.     public    luser, lpass
  17.  
  18. data    segment
  19.     extrn    flags:byte, trans:byte, curdsk:byte, diskio:byte, auxfile:byte
  20.     extrn    comand:byte, filtst:byte, maxtry:byte, dtrans:byte
  21.     extrn    fmtdsp:byte, errlev:byte, fsta:word, kstatus:word
  22.     extrn    rpacket:byte, encbuf:byte, decbuf:byte, sstate:byte
  23.     extrn    rstate:byte, pktnum:byte, windlow:byte, takadr:word
  24.     extrn    prmptr:word, chkparflg:byte
  25.  
  26. scrser    equ    0209H        ; place for server state display line
  27. scrmsg    equ    0e16H        ; place for Last message
  28.  
  29. remcmd    db    0        ; Remote command to be executed
  30. rempac    db    0        ; Packet type: C (host) or G (generic)
  31. remlen    db    0        ; length of following text field
  32.  
  33. ermes6    db    'Filename too long for packet',0
  34. cemsg    db    'User intervention',0
  35. infms1    db    'Server mode: type C or Control-C to exit',cr,lf,'$'
  36. infms2    db    cr,lf,'?More parameters are needed$'
  37. infms3    db    'REMOTE command reply',0    ; for transaction logging
  38. infms4    db    'Help text',0            ; filename for REM Help reply
  39. inthlp    db    cr,lf,' Time-limit to remain in Server mode, seconds or'
  40.     db    ' specific hh:mm:ss (24h clock).'
  41.     db    cr,lf,' SET TIMER ON to time.  Return for no time limit.$'
  42. remms1    db    ' Unknown server command',0
  43. remms2    db    ' Invalid login information',0
  44. remms3    db    ' Kermit-MS Server ready',0
  45. remms5    db    ' File not found',0
  46. remms6    db    ' Command failed',0
  47. remms7    db    ' REMOTE LOGIN is required',0
  48. remms8    db    ' Command succeeded',0
  49. remms9    db    ' Command is Disabled',0
  50. remms10    db    ' Could not create work file',0
  51. byemsg    db    ' Goodbye!',0
  52. whomsg    db    ' Just this Server',0
  53. spcmsg    db    ' bytes available on drive '    ; remote space responses
  54. spcmsg1    db    ' ',0
  55. spcmsg2    db    ' Drive '
  56. spcmsg3    db    ' : is not ready',0
  57. user    db    ' Username: ',0        ; for Remote Login, asciiz
  58. password db    ' Password: ',0        ; for Remote Login and Remote CD
  59. account    db    ' Account: ',0        ; for Remote Login
  60. slogin    db    0            ; non-zero if successful local login
  61. luser    db    17 dup (0)        ; local Username, case insenstitive
  62. lpass    db    17 dup (0)        ; local Password, case sensitive
  63. srvtmp    db    ' > :$kermit$.tmp',0    ; asciiz, kermit's temp output file
  64. delstr    db    'del ',0
  65. dirstr    db    'dir ',0
  66. crlf    db    cr,lf,'$'
  67. emptymsg db    0            ; empty asciiz msg
  68. skertmp    dw    0            ; REMOTE KERMIT work word
  69. denyflg    dw    0            ; bit field of denied commands
  70. temp    dw    0
  71. temp2    dw    0
  72. cnt    dw    0
  73. bufptr    dw    0
  74. dsptmp    db    0            ; temp to hold fmtdsp during serving
  75. srvtmo    db    0            ; idle NAK time, default is no NAKs
  76. srvtime    db    0            ; non-zero if timing Server residence
  77. remfnm    db    ' Remote Source File: ',0    ; asciiz
  78. lclfnm    db    ' Local Destination File: ',0    ; asciiz
  79. filhlp    db    ' File name to use locally$'
  80. filmsg    db    ' Remote filename, or press ENTER for prompts$'
  81. frem    db    ' Name of file on remote system $'
  82. genmsg    db    ' Enter text to be sent to remote server $'
  83. numhlp    db    ' number$'
  84. xfrhlp    db    ' character set identifier string$'
  85. tmpbuf    db    20 dup (0)
  86. srvbuf    db    80 dup (0)        ; place After tmpbuf, for status
  87.  
  88. savflg    flginfo    <>            ; save area for flags.*
  89. savflgl    equ    $-savflg        ; length
  90. savdtr    trinfo <>            ; save area for dtrans.*
  91. savdtrl equ    $-savdtr        ; length
  92. savtr    trinfo    <>            ; save area for trans.*
  93. savmaxtry db    0            ; save area for maxtry
  94.  
  95. srvchr    db    'SRGIECK'        ; server cmd characters, use w/srvfun
  96. srvfln    equ    $-srvchr        ; length of table
  97.  
  98. srvfun    dw    srvsnd,srvrcv,srvgen,srvini,srverr,srvhos,srvker ; for srvchr
  99.  
  100. srvch2    db    'CDEFHLMSTUW'        ; server commands, use with srvdsp
  101. srvfl2    equ    $-srvch2
  102.  
  103. srvdsp    dw    srvcwd,srvdir,srvdel,srvfin,srvhlp,srvlog,srvmsg
  104.     dw    srvset,srvtyp,srvspc,srvwho
  105.  
  106. remhlp    db    cr,lf,' Command    Action performed by the server Kermit'
  107.     db    cr,lf,' -------    -------------------------------------'
  108.     db    cr,lf,' CD/CWD     change working directory'    ; Answer to
  109.     db    cr,lf,' Delete     a file'            ; local
  110.     db    cr,lf,' Directory  filespec'            ; REM HELP
  111.     db    cr,lf,' Help       show server''s remote help screen'
  112.     db    cr,lf,' Host       command  (to remote operating system)'
  113.     db    cr,lf,' Kermit     command  (to Kermit server)'
  114.     db    cr,lf,' Login      name password  to a Kermit server'
  115.     db    cr,lf,' Logout     exit remote Kermit (but keep remote host)'
  116.     db    cr,lf,' Message    short one line message'
  117.     db    cr,lf,' Print      local file  (on server''s printer)'
  118.     db    cr,lf,' Set        command  (modify server)'
  119.     db    cr,lf,' Space      drive/directory'
  120.     db    cr,lf,' Type       a file on this screen'
  121.     db    cr,lf,' Who        user parameters$'
  122.  
  123.                     ; Answer from Server to REMOTE HELP
  124. hlprem    db    cr,lf,'Kermit-MS Server commands:',lf
  125.     db    cr,lf,'GET  filespec             '
  126.     db    'REMOTE DIRECTORY filespec  REMOTE PRINT filespec'
  127.     db    cr,lf,'SEND filespec             '
  128.     db    'REMOTE HELP  this text     REMOTE SET command'
  129.     db    cr,lf,'BYE, FINISH, REMOTE LOGOUT'
  130.     db    'REMOTE HOST command        REMOTE SPACE drive-letter'
  131.     db    cr,lf,'REMOTE CD/CWD directory   '
  132.     db    'REMOTE LOGIN name password REMOTE TYPE filespec'
  133.     db    cr,lf,'REMOTE DELETE filespec    '
  134.     db    'REMOTE MESSAGE 1-line msg  REMOTE WHO'
  135.     db    0
  136.  
  137. remtab    db    15            ; 15 entries
  138.     mkeyw    'CD',remcwd
  139.     mkeyw    'CWD',remcwd
  140.     mkeyw    'Delete',remdel
  141.     mkeyw    'Directory',remdir
  142.     mkeyw    'Help',remhel
  143.     mkeyw    'Host',remhos
  144.     mkeyw    'Kermit',remker
  145.     mkeyw    'Login',remlogin
  146.     mkeyw    'Logout',remlogout
  147.     mkeyw    'Message',remmsg
  148.     mkeyw    'Print',remprn        ; top of SEND procedure in msssen
  149.     mkeyw    'Set',remset
  150.     mkeyw    'Space',remdis
  151.     mkeyw    'Type',remtyp
  152.     mkeyw    'Who',remwho
  153.  
  154. setval    dw    300,302,310            ; answer REMOTE SET workers
  155.     dw    400,401,402,403,404,405,406
  156. setvlen    equ    ($-setval)/2            ; number of entries
  157. setvec    dw    sftype,sfcoll,sfinc        ; routines paralleling setval
  158.     dw    sblkck,srpkt,srtmo,sretry,sstmo,sxfrch,swind
  159.  
  160. remstt1    db    9            ; REMOTE SET top level table
  161.     mkeyw    'Attributes',1
  162.     mkeyw    'File',2
  163.     mkeyw    'Incomplete',310
  164.     mkeyw    'Block-check',400
  165.     mkeyw    'Receive',3
  166.     mkeyw    'Retry',403
  167.     mkeyw    'Server',404
  168.     mkeyw    'Transfer',405
  169.     mkeyw    'Window-slots',406
  170.  
  171. remsat1    db    2            ; REMOTE SET ATTRIBUTES
  172.     mkeyw    'IN',0
  173.     mkeyw    'OUT',100
  174.  
  175. remsat2    db    17            ; REMOTE ATTRIBUTES {IN} item
  176.                     ; REM ATT {OUT} item is 100 greater
  177.     mkeyw    'All',132
  178.     mkeyw    'Length',133
  179.     mkeyw    'Type',134
  180.     mkeyw    'Date',135
  181.     mkeyw    'Creator',136
  182.     mkeyw    'Account',137
  183.     mkeyw    'Area',138
  184.     mkeyw    'Block-size',139
  185.     mkeyw    'Access',140
  186.     mkeyw    'Encoding',141
  187.     mkeyw    'Disposition',142
  188.     mkeyw    'Protection',143
  189.     mkeyw    'Gprotection',144
  190.     mkeyw    'System-ID',145
  191.     mkeyw    'Format',146
  192.     mkeyw    'Sys-Info',147
  193.     mkeyw    'Byte-count',148
  194.  
  195. remsfit    db    5            ; REMOTE SET FILE
  196.     mkeyw    'Type',300
  197.     mkeyw    'Names',301
  198.     mkeyw    'Collision',302
  199.     mkeyw    'Replace',303
  200.     mkeyw    'Incomplete',310
  201.  
  202. remsfty    db    2            ; REMOTE SET FILE TYPE
  203.     mkeyw    'Text',0
  204.     mkeyw    'Binary',1
  205.  
  206. remsfna    db    2            ; REMOTE SET FILE NAME
  207.     mkeyw    'Converted',0
  208.     mkeyw    'Literal',1
  209.  
  210. remsfco    db    7            ; REMOTE SET FILE COLLISION
  211.     mkeyw    'Append',3
  212.     mkeyw    'Ask',5
  213.     mkeyw    'Backup',2
  214.     mkeyw    'Discard',4
  215.     mkeyw    'Rename',0
  216.     mkeyw    'Replace',1
  217.     mkeyw    'Update',6
  218.  
  219. remsfre    db    2            ; REMOTE SET FILE REPLACE
  220.     mkeyw    'Preserve',0
  221.     mkeyw    'Default',1
  222.  
  223. remsfin    db    2            ; REMOTE SET FILE INCOMPLETE
  224.     mkeyw    'Discard',0
  225.     mkeyw    'Keep',1
  226.  
  227. remsrcv    db    2            ; REMOTE SET RECEIVE
  228.     mkeyw    'Packet-length',401
  229.     mkeyw    'Timeout',402
  230.  
  231. remsxfr    db    1            ; REMOTE SET TRANSFER
  232.     mkeyw    'Character-set',405
  233.  
  234.  
  235. onoff    db    2            ; ON, OFF table
  236.     mkeyw    'off',0
  237.     mkeyw    'on',1
  238.  
  239. data    ends
  240.  
  241. code1    segment
  242.     extrn bufclr:far, pakptr:far, bufrel:far, makebuf:far, chkwind:far
  243.     extrn firstfree:far, getbuf:far, pakdup:far, rpack:far, fcsrtype:far
  244. code1    ends
  245.  
  246. code    segment
  247.     extrn comnd:near, init:near, serini:near, rrinit:near
  248.     extrn read2:near, rpar:near, spar:near, intmsg:near, sparmax:near
  249.     extrn serhng:near, clrbuf:near, clearl:near
  250.     extrn dodec: near, doenc:near, packlen:near, send10:near, errpack:near
  251.     extrn pktsize:near, poscur:near, lnout:near, clrmod:near, ermsg:near
  252.     extrn rprpos:near, crun:near, prompt:near,  prtscr:near, strcat:near
  253.     extrn strlen:near, strcpy:near, fparse:near, isfile:near, ihostr:near
  254.     extrn inptim:near, chktmo:near, pcwait:near
  255.     extrn nakpak:near, sndpak:near, response:near
  256.     extrn msgmsg:near, ackpak:near, dskspace:near, cdsr:near, dec2di:near
  257.     extrn takopen:near, takclos:near, setcom:near
  258.     extrn remprn:near
  259.  
  260.     assume    cs:code, ds:data, es:nothing
  261.  
  262. ; Server command
  263.  
  264. SERVER    PROC    NEAR
  265.     mov    ah,cmword        ; get a word 
  266.     mov    dx,offset srvbuf    ; place to put text
  267.     mov    word ptr srvbuf,0    ; clear
  268.     mov    bx,offset inthlp    ; help message
  269.     call    comnd            ; get the pattern text
  270.     jnc    serv1a            ; nc = success
  271.     ret                ; failure
  272. serv1a:    mov    ah,cmeol
  273.     call    comnd
  274.     jnc    serv1b            ; nc = success
  275.     ret
  276. serv1b:    mov    srvtime,0        ; assume not doing timed residence
  277.     mov    si,offset srvbuf
  278.     mov    al,[si]
  279.     or    al,al            ; any time given?
  280.     jz    serv4            ; z = no
  281.     cmp    al,'0'            ; numeric or colon?
  282.     jb    serv2            ; b = not proper time value
  283.     cmp    al,':'            ; this covers the desired range
  284.     ja    serv2            ; a = no proper time value
  285.     call    inptim            ; convert text to timeout tod
  286.     jnc    serv3            ; c = syntax errors in time
  287. serv2:    stc                ; failure
  288.     ret
  289.  
  290. serv3:    mov    srvtime,1        ; say doing timed residence
  291. serv4:    or    flags.remflg,dserver    ; signify we are a server now
  292.     call    clrbuf            ; clear serial port buffer of junk
  293.     test    denyflg,pasflg        ; Login required?
  294.     jnz    serv4a            ; nz = no
  295.     or    denyflg,pasflg        ; assume no login info required
  296.     mov    al,luser        ; check for user/password required
  297.     or    al,lpass        ; if both null then no checks
  298.     jz    serv4a            ; z = null, no name/pass required
  299.     and    denyflg,not pasflg    ; say need name/password
  300. serv4a:    mov    dsptmp,0        ; assume no formatted server display
  301.     mov    al,dtrans.xchset    ; reset Transmission char set
  302.     mov    trans.xchset,al        ;  to the current user default
  303.     mov    al,dtrans.xtype        ; ditto for File Type
  304.     mov    trans.xtype,al
  305.     mov    si,offset flags        ; main flags structure
  306.     mov    di,offset savflg    ; save area
  307.     mov    cx,savflgl        ; length in bytes
  308.     push    es
  309.     push    ds
  310.     pop    es
  311.     cld
  312.     rep    movsb            ; save all of them
  313.     mov    si,offset dtrans    ; default transmission parameters
  314.     mov    di,offset savdtr    ; save area
  315.     mov    cx,savdtrl        ; length
  316.     rep    movsb            ; save all of them
  317.     mov    si,offset trans        ; active transmission paramters
  318.     mov    di,offset savtr        ; save area
  319.     mov    cx,savdtrl        ; same length
  320.     rep    movsb
  321.     mov    al,maxtry
  322.     mov    savmaxtry,al
  323.     pop    es
  324.     mov    si,offset rpacket    ; dummy packet
  325.     mov    rpacket.datlen,0    ; declare to be empty
  326.     call    spar            ; setup minimum operating conditions
  327.     test    flags.remflg,dquiet    ; quiet display?
  328.     jnz    serv9            ; nz = yes
  329.     mov    ah,prstr
  330.     mov    dx,offset crlf
  331.     int    dos
  332.     test    flags.remflg,dserial     ; serial display?
  333.     jnz    serv5            ; nz = yes
  334.     call    init            ; init formatted display
  335.     call    clrmod            ; but no modeline yet
  336.     mov    dl,fmtdsp
  337.     mov    dsptmp,dl        ; remember state of fmtdsp
  338.     jmp    short serv9
  339.  
  340. serv5:    mov    ah,prstr
  341.     mov    dx,offset infms1    ; say now in server mode
  342.     int    dos
  343.  
  344.                     ; TOP OF SERVER IDLE LOOP
  345. serv9:    test    flags.remflg,dquiet+dserial ; quiet or serial display?
  346.     jnz    serv10            ; nz = yes, do not change screen
  347.     mov    dx,scrmsg        ; move cursor to Last message area
  348.     add    dx,0100H    ; look at line below (DOS does CR/LF first)
  349.     call    poscur
  350.     call    clearl            ; and clear the line
  351.     mov    dl,cr            ; set cursor to left margin
  352.     mov    ah,conout
  353.     int    dos
  354. serv10:    xor    ax,ax
  355.     mov    flags.cxzflg,al        ; clear ^X, ^Z, ^C seen flag
  356.     mov    flags.xflg,al        ; reset X packet flag
  357.     mov    auxfile,al        ; say no override filename
  358.     mov    srvbuf,al        ; work buffer, clear
  359.     mov    al,dsptmp        ; get our fmtdsp state
  360.     mov    fmtdsp,al        ; and restore it
  361.     mov    trans.windo,1        ; but only 1 window slot here
  362.     mov    cx,drpsiz        ; default receive pkt length (94)
  363.     call    makebuf            ; remake all buffers for new windowing
  364.     call    packlen            ; determine max packet length
  365.     mov    dtrans.windo,31        ; set max windowing abilities
  366.     mov    trans.windo,31
  367.     mov    trans.chklen,1        ; checksum len = 1
  368.     mov    pktnum,0        ; pack number resets to 0
  369.     mov    al,srvtmo        ; use server mode timeout
  370.     or    al,al            ; is it zero?
  371.     jz    serv10b            ; z = yes, use regular timeout
  372.     mov    trans.stime,al        ; use this interval in the idle loop
  373. serv10b:call    serini            ; init serial line, just in case
  374.     jnc    serv11            ; nc = success
  375.     jmp    serv20            ; c = failure
  376. serv11:    cmp    srvtime,0        ; doing timed residence?
  377.     je    serv12            ; e = no
  378.     call    chktmo            ; check for time to exit Server mode
  379.     jnc    serv12            ; nc = ok
  380.     jmp    serv20            ; c = timeout, exit server mode
  381.  
  382. serv12:    mov    windlow,0        ; reset windowing
  383.     mov    pktnum,0        ; packet number to be used
  384.     call    getbuf            ; get a buffer
  385.     mov    chkparflg,1        ; check for unexpected parity
  386.     call    rpack            ; receive a packet, si has buffer ptr
  387.     mov    al,dtrans.stime        ; get default timeout interval
  388.     mov    trans.stime,al        ; restore active timeout interval
  389.     jc    serv13            ; c = timeout, bad pkt, intervention
  390.     mov    al,[si].seqnum        ; sequence number received
  391.     mov    rpacket.seqnum,al    ; for our reply
  392.     or    al,al            ; must be sequence number of zero
  393.     jnz    serv13            ; nz = bad packet
  394.     mov    ah,[si].pktype
  395.     cmp    ah,'I'            ; never "decode" S, I, and A packets
  396.     je    serv17            ; e = I packet
  397.     cmp    ah,'S'
  398.     je    serv17
  399.     cmp    ah,'A'
  400.     je    serv17
  401.     call     dodec            ; decode packet to decbuf
  402.     call    bufrel            ; release the packet buffer
  403.     jmp    short serv17        ; dispatch on packet type in ah
  404.  
  405. serv13:    cmp    flags.cxzflg,'C'     ; Control-C?
  406.     je    serv20            ; e = yes, exit server mode
  407.  
  408. serv14:    cmp    flags.cxzflg,'E'    ; ^E protocol abort?
  409.     jne    serv15            ; ne = no
  410.     call    bufclr            ; clear all buffers
  411.     mov    dx,offset cemsg    ; user intervention message for error packet
  412.     call    ermsg
  413.     mov    bx,dx
  414.     call    errpack            ; send error message
  415.     call    intmsg            ; show interrupt msg for Control-C-E
  416.     jmp    serv9
  417.  
  418. serv15:    cmp    [si].pktype,'T'        ; packet type of time-out?
  419.     jne    serv16            ; ne = no
  420.     cmp    srvtime,0        ; doing timed residence?
  421.     je    serv15a            ; e = no
  422.     call    chktmo            ; check for time to exit Server mode
  423.     jc    serv20            ; c = timeout, exit server mode
  424. serv15a:cmp    srvtmo,0        ; zero server pkt timeout?
  425.     je    serv16            ; e = yes, no NAKing
  426.     mov    rpacket.seqnum,0
  427.     call    nakpak            ; NAK the packet, uses rpacket
  428. serv16:    call    bufrel            ; release the buffer
  429.     jmp    serv9            ; to top of idle loop
  430.  
  431. serv17:    cmp    [si].pktype,'N'        ; received a NAK?
  432.     je    serv18            ; e = yes, ignore it
  433.     push    es
  434.     push    ds
  435.     pop    es            ; set es to data segment
  436.     mov    di,offset srvchr    ; server characters
  437.     mov    cx,srvfln        ; length of command set
  438.     mov    al,ah            ; packet type
  439.     cld
  440.     repne    scasb            ; hunt for it
  441.     pop    es
  442.     je    serv19            ; e = found that kind
  443.     mov    dx,offset remms1    ; say unknown server command
  444.     call    ermsg
  445.     mov    bx,dx
  446.     call    errpack            ; tell the other kermit
  447. serv18:    jmp    serv9            ; get another server command
  448.  
  449. serv19:    sub    di,offset srvchr+1    ; find offset, +1 for pre-increment
  450.     shl    di,1            ; convert to word index
  451.     call    srvfun[di]        ; call the appropriate handler
  452.     jc    serv20            ; c = someone wanted to exit
  453.     jmp    serv9            ; get another server command
  454.  
  455. serv20:    mov    di,offset flags        ; main flags structure
  456.     mov    si,offset savflg    ; save area
  457.     mov    cx,savflgl        ; length in bytes
  458.     push    es
  459.     push    ds
  460.     pop    es
  461.     mov    al,flags.extflg        ; leave server mode and Kermit flag
  462.     mov    ah,flags.cxzflg        ; interruption flag
  463.     cld
  464.     rep    movsb            ; restore all of them
  465.     mov    di,offset dtrans    ; default transmission parameters
  466.     mov    si,offset savdtr    ; save area
  467.     mov    cx,savdtrl        ; length
  468.     rep    movsb            ; restore all of them
  469.     mov    di,offset trans        ; active transmission paramters
  470.     mov    si,offset savtr        ; save area
  471.     mov    cx,savdtrl        ; same length
  472.     rep    movsb
  473.     mov    flags.extflg,al        ; set flag as current
  474. ;;    mov    flags.cxzflg,ah        ; restore interruption flag
  475.     mov    al,savmaxtry
  476.     mov    maxtry,al
  477.     pop    es
  478.     mov    al,1            ; underline cursor
  479.     call    fcsrtype        ; set IBM-PC cursor to underline
  480.     call    rprpos            ; put prompt here
  481.     and    flags.remflg,not dserver ; say not a server anymore
  482.     clc
  483.     ret
  484. SERVER    ENDP
  485.  
  486. ; commands executable while acting as a server
  487.  
  488. ; Validate LOGIN status. Return carry set if login is ok, else
  489. ; send Error Packet saying Login is required (but has not been done) and
  490. ; return carry clear. Carry bit is this way because returning to the server
  491. ; idle loop with carry set exits the server mode.
  492. logchk    proc    near
  493.     test    denyflg,pasflg        ; login required?
  494.     jnz    logchk1            ; nz = no (disabled)
  495.     cmp    slogin,0        ; logged in yet?
  496.     jne    logchk1            ; ne = yes
  497.     mov    dx,offset remms7    ; reply REMOTE LOGIN is required
  498.     call    ermsg
  499.     mov    bx,dx            ; errpack works from bx
  500.     mov    trans.chklen,1        ; reply with 1 char checksum
  501.     call    errpack
  502.     clc                ; say cannot proceed with command
  503.     ret
  504. logchk1:stc                ; say can proceed with command
  505.     ret
  506. logchk    endp
  507.  
  508. ; srvsnd - receives a file that a remote kermit is sending
  509. srvsnd    proc    near
  510.     call    logchk            ; check login status
  511.     jc    srvsnd1            ; c = ok
  512.     ret                ; else have sent error packet
  513. srvsnd1:call    init            ; setup display form
  514.     xor    ax,ax
  515.     test    denyflg,sndflg        ; command disabled?
  516.     jz    srvsnd2            ; z = no
  517.     mov    al,'.'            ; dot+nul forces use of current dir
  518. srvsnd2:mov    word ptr auxfile,ax    ; override name
  519.     mov    rstate,'R'        ; receive initiate state
  520.     jmp    read2            ; packet pointer is SI, still valid
  521. srvsnd    endp
  522.  
  523. ; srvrcv - send a file to a distant kermit
  524.  
  525. srvrcv    proc    near
  526.     call    logchk            ; check login status
  527.     jc    srrcv1            ; c = ok
  528.     ret                ; else have sent error packet
  529. srrcv1:    mov    si,offset decbuf    ; received filename, asciiz from dodec
  530.     test    denyflg,getsflg        ; command enabled?
  531.     jz    srrcv2            ; z = yes
  532.     mov    dx,si            ; source string, from other side
  533.     mov    di,offset srvbuf    ; local path
  534.     mov    si,offset tmpbuf    ; local filename
  535.     call    fparse            ; split string
  536. srrcv2:    mov    di,offset diskio.string    ; destination
  537.     call    strcpy            ; copy filename to diskio.string
  538.     mov    auxfile,0        ; no alias name
  539.     mov    sstate,'S'        ; set sending state
  540.     jmp    send10            ; this should send it
  541. srvrcv    endp
  542.  
  543. srverr    proc    near            ; incoming Error packet
  544.     clc                ; absorb and ignore
  545.     ret
  546. srverr    endp
  547.  
  548. ; srvgen - G generic server command dispatcher
  549. ;
  550. srvgen    proc    near
  551.     call    bufrel            ; release buffer
  552.     mov    al,decbuf        ; get first data character from pkt
  553.     cmp    al,'I'            ; LOGIN?
  554.     jne    srvge1            ; ne = no
  555.     jmp    srvlogin        ; yes
  556. srvge1:    call    logchk            ; check login status
  557.     jc    srvge2            ; c = ok
  558.     ret                ; else have sent error packet
  559. srvge2:    push    es
  560.     push    ds
  561.     pop    es            ; set es to data segment
  562.     mov    di,offset srvch2    ; command character list
  563.     mov    cx,srvfl2        ; length of command set
  564.     cld
  565.     repne    scasb            ; hunt for it
  566.     pop    es
  567.     jne    srvgex            ; ne = not found, complain
  568.     sub    di,offset srvch2+1    ; find offset, +1 for pre-increment
  569.     shl    di,1            ; convert to word index
  570.     jmp    srvdsp[di]        ; do the appropriate handler
  571.  
  572. srvgex:    mov    dx,offset remms1    ; reply Unknown server command
  573.     call    ermsg
  574.     mov    bx,dx
  575.     mov    trans.chklen,1        ; reply with 1 char checksum
  576.     call    errpack
  577.     clc
  578.     ret
  579. srvgen    endp
  580.  
  581. ; srvlog - respond to host's BYE and LOGOUT
  582. srvlog    proc    near
  583.     call    srvfin            ; do FIN part
  584.     pushf                ; save flag for the very end
  585.     jnc    srvlog1            ; nc = stay active (command denied)
  586.     mov    flags.extflg,1        ; leave server mode and Kermit
  587. srvlog1:call    serhng            ; hangup the phone and return
  588.     mov    di,offset flags        ; main flags structure
  589.     mov    si,offset savflg    ; save area
  590.     mov    cx,savflgl        ; length in bytes
  591.     push    es
  592.     push    ds
  593.     pop    es
  594.     mov    al,flags.extflg        ; leave server mode and Kermit flag
  595.     cld
  596.     rep    movsb            ; restore all of them
  597.     mov    di,offset dtrans    ; default transmission parameters
  598.     mov    si,offset savdtr    ; save area
  599.     mov    cx,savdtrl        ; length
  600.     rep    movsb            ; restore all of them
  601.     mov    di,offset trans        ; active transmission paramters
  602.     mov    si,offset savtr        ; save area
  603.     mov    cx,savdtrl        ; same length
  604.     rep    movsb
  605.     mov    flags.extflg,al        ; make flag current
  606.     mov    al,savmaxtry
  607.     mov    maxtry,al
  608.     pop    es
  609.     popf                ; recover carry flag, set = exit
  610.     ret
  611. srvlog    endp
  612.  
  613. ; srvfin - respond to remote host's Fin command
  614. srvfin    proc    near
  615.     mov    slogin,0        ; say not logged in anymore
  616.     mov    si,offset byemsg    ; add brief msg of goodbye
  617.     mov    di,offset encbuf    ; packet's data field
  618.     call    strcpy            ; copy msg to pkt
  619.     mov    dx,si            ; strlen works on dx
  620.     call    strlen
  621.     push    si
  622.     mov    si,offset rpacket    ; get a reply buffer
  623.     call    doenc            ; encode the reply in encbuf
  624.     pop    si
  625.     mov    trans.chklen,1        ; reply with 1 char checksum
  626.     call    ackpak
  627.     mov    ax,100            ; wait 0.1 sec for client to settle
  628.     call    pcwait
  629.     mov    si,offset rpacket    ; dummy packet
  630.     mov    rpacket.datlen,0    ; declare to be empty
  631.     call    spar            ; setup minimum operating conditions
  632.     test    denyflg,finflg        ; command enabled?
  633.     jz    srfin2            ; z = yes
  634.     clc                ; stay in server mode
  635.     ret
  636. srfin2:    stc                ; stc exits server mode
  637.     ret
  638. srvfin    endp
  639.  
  640. ; srvcwd - handle other side's Remote CWD dirspec
  641. srvcwd    proc    near
  642.     mov    trans.chklen,1        ; reply with 1 char checksum
  643.     test    denyflg,cwdflg        ; is command enabled?
  644.     jz    srcwd1            ; z = yes
  645.     mov    dx,offset remms9    ; say command is disabled
  646.     call    ermsg            ;  to us and
  647.     mov    bx,dx
  648.     call    errpack            ;  to the other Kermit
  649.     clc
  650.     ret
  651. srcwd1:    mov    si,offset decbuf+1    ; point to byte count
  652.     xor    bh,bh
  653.     mov    bl,[si]
  654.     sub    bl,' '            ; remove ascii bias from byte count
  655.     inc    si
  656.     mov    word ptr[si+bx],0    ; make ASCIIZ w/one extra null
  657.     call    cdsr            ; CD common sub-routine
  658.     mov    si,dx            ; returns msg in dx
  659.     mov    di,offset encbuf    ; put in encode buffer
  660.     call    strcpy
  661.     mov    dx,di
  662.     call    strlen            ; get its length to cx
  663.     mov    si,offset rpacket    ; use this packet for the reply
  664.     call    doenc            ; encode reply
  665.     call    ackpak            ; send ACK with data
  666.     clc
  667.     ret
  668. srvcwd    endp
  669.  
  670. ; srvtyp - handle other side's Remote Type filename request
  671. ; expects "data" to hold  Tcfilename   where c = # bytes in filename
  672. srvtyp    proc    near
  673.     cmp    decbuf+1,0        ; any data in packet
  674.     je    srtyp2            ; e = no
  675.     mov    cl,decbuf+1        ; get the filename byte count
  676.     sub    cl,' '            ; ascii to numeric
  677.     jle    srtyp2            ; le = no filename or error in length
  678.     xor    ch,ch            ; set up counter
  679.     mov    si,offset decbuf+2    ; received filename, asciiz from rpack
  680.     mov    di,si
  681.     add    di,cx
  682.     mov    byte ptr [di],0        ; make string asciiz
  683.     test    denyflg,typflg        ; paths permitted?
  684.     jz    srtyp1            ; z = yes, else use just filename part
  685.     mov    di,offset srvbuf    ; local path
  686.     mov    si,offset tmpbuf    ; local filename
  687.     mov    dx,offset decbuf+2    ; local string
  688.     call    fparse            ; split string
  689. srtyp1:    mov    di,offset diskio.string    ; copy local filename to destination
  690.     mov    ax,di            ; pointer to filename, for isfile
  691.     call    strcpy            ; do the copy
  692.     call    isfile            ; does it exist?
  693.     jnc    srtyp3            ; nc = yes
  694. srtyp2:    mov    si,offset remms5    ; "File not found"
  695.     mov    di,offset encbuf    ; destination for message
  696.     call    strcpy            ; move the message
  697.     mov    dx,di
  698.     call    strlen            ; length to cx
  699.     mov    si,offset rpacket    ; use this packet for reply
  700.     call    doenc            ; encode
  701.     mov    trans.chklen,1        ; reply with 1 char checksum
  702.     call    ackpak            ; send ACK with message
  703.     clc
  704.     ret
  705.  
  706. srtyp3:    mov    flags.xflg,1        ; say use X packet rather than F pkt
  707.     mov    auxfile,0        ; no alias name
  708.     mov    sstate,'S'        ; remember state
  709.     jmp    send10            ; this should send it
  710. srvtyp    endp
  711.  
  712. ; srvdir - handle other side's Remote Dir filespec(optional) request
  713. srvdir    proc    near
  714.     mov    di,offset decbuf+2      ; received filespec, asciiz from rpack
  715.     xor    cx,cx            ; assume no data in packet
  716.     mov    cl,decbuf+1        ; get the filename byte count
  717.     cmp    cl,' '            ; byte count present and > 0?
  718.     jg    srdir1            ; g = yes
  719.     mov    word ptr [di],0        ; clear data field
  720.     jmp    short srdir2        ; 0 = no info in pkt
  721. srdir1:    sub    cl,' '            ; ascii to numeric
  722.     add    di,cx            ; step to end of filename, terminate
  723.     mov    word ptr [di],0        ; ensure string is asciiz
  724.     mov    di,offset srvbuf    ; local path
  725.     mov    si,offset tmpbuf    ; local filename
  726.     mov    dx,offset decbuf+2    ; local string
  727.     call    fparse            ; split string
  728.     test    denyflg,dirflg        ; paths permitted?
  729.     jz    srdir2            ; z = yes, else use just filename part
  730.     mov    si,offset tmpbuf    ; copy local filename to
  731.     mov    di,offset decbuf+2    ; final filename
  732.     call    strcpy            ; copy just filename to buffer
  733. srdir2:    mov    cl,curdsk        ; current drive number
  734.     add    cl,'A'-1        ; to letter
  735.     cmp    decbuf+3,':'        ; drive specified?
  736.     jne    srdir3            ; ne = no
  737.     cmp    decbuf+2,0        ; drive letter specified?
  738.     je    srdir3            ; e = no
  739.     mov    cl,decbuf+2        ; get drive letter
  740.     and    cl,5fh            ; convert to upper case
  741. srdir3:    call    dskspace        ; check if drive ready (drive => CL)
  742.     jnc    srdir5            ; nc = success (drive is ready)
  743.     mov    spcmsg3,cl        ; insert drive letter
  744.     mov    si,offset spcmsg2    ; say drive not ready
  745.     mov    di,offset encbuf    ; destination for message
  746.     call    strcpy            ; move the message
  747.     mov    dx,di
  748.     call    strlen            ; length to cx
  749.     mov    si,offset rpacket    ; use this packet for reply
  750.     call    doenc            ; encode
  751.     mov    trans.chklen,1        ; reply with 1 char checksum
  752.     call    ackpak            ; send ACK with message
  753.     clc
  754.     ret
  755.  
  756. srdir5:    mov    di,offset srvbuf    ; work area
  757.     mov    si,offset dirstr    ; prepend "dir "
  758.     call    strcpy
  759.     mov    si,offset decbuf+2    ; directory spec, asciiz
  760.     mov    di,offset srvbuf
  761.     call    strcat
  762.  
  763. ; srdir6 does common processing for both REM DIR & REM HOST
  764. SRDIR6:    mov    si,di            ; srvbuf
  765.     mov    di,offset auxfile    ; send-as name is command line
  766.     call    strcpy
  767.     mov    dl,curdsk
  768.     add    dl,'A'-1        ; change to letter
  769.     mov    srvtmp+2,dl        ; insert current disk drive
  770.     mov    si,offset srvtmp    ; add redirection tag " >d:$kermit$.tmp"
  771.     mov    di,offset srvbuf
  772.     call    strcat
  773.     mov    si,offset srvbuf    ; command pointer for crun
  774.     call    crun
  775. ; fall thru!    jmp    srvtail            ; send contents of temp file
  776. srvdir    endp
  777.  
  778. ; Send contents of srvtmp+2 temporary file, or error packet if it does not
  779. ; exist.
  780. srvtail    proc    near
  781.     mov    si,offset srvtmp+2    ; get name of temp file
  782.     mov    di,offset diskio.string    ; destination
  783.     call    strcpy            ; copy it there
  784.     mov    ax,di            ; filename pointer for isfile
  785.     call    isfile            ; did we make the temp file?
  786.     jnc    srvtai1            ; nc = yes
  787.     mov    dx,offset remms10    ; "Could not create work file"
  788.     mov    trans.chklen,1        ; reply with 1 char checksum
  789.     call    ermsg
  790.     mov    bx,dx
  791.     call    errpack            ; send the error message
  792.     clc
  793.     ret
  794. srvtai1:mov    flags.xflg,1        ; say use X rather than F packet
  795.     mov    sstate,'S'        ; remember state
  796.     call    send10            ; this should send it
  797.     mov    flags.xflg,0        ; clear flag
  798.     mov    dx,offset srvtmp+2    ; name of temp file
  799.     mov    ah,del2            ; delete the file
  800.     int    dos
  801.     clc
  802.     ret                ; return in any case
  803. srvtail    endp
  804.  
  805. ; srvdel - handle other side's request of Remote Del filespec
  806. srvdel    proc    near
  807.     test    denyflg,delflg        ; command enabled?
  808.     jz    srvdel4            ; z = yes
  809.     mov    dx,offset remms9    ; else give a message
  810.     mov    trans.chklen,1        ; reply with 1 char checksum
  811.     call    ermsg
  812.     mov    bx,dx
  813.     call    errpack            ; back to local kermit
  814.     clc
  815.     ret
  816.  
  817. srvdel4:cmp    decbuf+1,0        ; any data?
  818.     je    srdel1            ; e = no
  819.     xor    bh,bh
  820.     mov    bl,decbuf+1        ; get the filename byte count
  821.     sub    bl,' '            ; ascii to numeric
  822.     jle    srdel3            ; le = nothing there
  823.     mov    decbuf [bx+2],0        ; plant terminator
  824.     mov    ax,offset decbuf+2    ; point to filespec
  825.     call     isfile            ; is/are there any to delete?
  826.     jc    srdel1            ; c = there is none
  827.     test    byte ptr filtst.dta+21,1EH ; attr bits: is file protected?
  828.     jz    srdel2            ; z = not protected
  829. srdel1:    mov    si,offset remms5    ; "File not found"
  830.     mov    di,offset encbuf    ; destination for message
  831.     call    strcpy            ; move the message
  832.     mov    dx,di
  833.     call    strlen            ; length to cx
  834.     mov    si,offset rpacket    ; use this packet for reply
  835.     call    doenc            ; encode
  836.     mov    trans.chklen,1        ; reply with 1 char checksum
  837.     call    ackpak            ; send ACK with message
  838.     clc
  839.     ret
  840.  
  841. srdel2:    mov    di,offset encbuf    ; work area
  842.     mov    si,offset delstr    ; prepend "del "
  843.     call    strcpy
  844.     mov    si,offset decbuf+2    ; append incoming filespec
  845.     call    strcat            ; append to "del "
  846.     mov    si,di            ; set pointer for crun
  847.     call    crun
  848. srdel3:    mov    dx,offset encbuf    ; where command lies
  849.     call    strlen            ; length to cx
  850.     push    si
  851.     mov    si,offset rpacket    ; packet to use for reply
  852.     call    doenc            ; encode reply
  853.     pop    si
  854.     mov    trans.chklen,1        ; reply with 1 char checksum
  855.     call    ackpak
  856.     clc
  857.     ret
  858. srvdel    endp
  859.  
  860. ; srvlogin - handle other side's request of REMOTE LOGIN, USERNAME, PASSWORD
  861.  
  862. srvlogin proc    near
  863.     mov    slogin,0        ; say not logged in yet
  864.     cmp    luser,0            ; local username specified?
  865.     je    srvlog9            ; e = no, do no checking
  866.     mov    cl,decbuf+1        ; ascii byte count of username
  867.     sub    cl,' '            ; to binary
  868.     jle    srvlog8            ; le = nothing there
  869.     xor    ch,ch
  870.     mov    si,offset decbuf+2    ; source, username field
  871.     mov    di,offset luser        ; local username template
  872.     push    cx
  873.     mov    ax,cx            ; external username length
  874.     mov    dx,di
  875.     call    strlen            ; get length of local username
  876.     cmp    ax,cx            ; same lengths?
  877.     pop    cx
  878.     jne    srvlog8            ; ne = not same length
  879.     cld
  880. srvlog2:lodsb                ; remote char
  881.     mov    ah,[di]            ; local char
  882.     inc    di
  883.     or    ax,2020h        ; lower case both
  884.     cmp    ah,al            ; same?
  885.     jne    srvlog8            ; ne = no, fail
  886.     loop    srvlog2            ; continue match
  887.     cmp    lpass,0            ; local password specified?
  888.     je    srclog6            ; e = no, don't check incoming p/w
  889.     mov    cl,decbuf+1        ; username length
  890.     sub    cl,' '
  891.     xor    ch,ch            ; clear high byte
  892.     mov    si,offset decbuf+2    ; skip over username field
  893.     add    si,cx            ; password length byte
  894.     mov    cl,[si]            ; ascii count of password bytes
  895.     sub    cl,' '            ; to binary
  896.     jc    srvlog8            ; carry means no field
  897.     inc    si            ; start of password text
  898.     mov    di,offset lpass        ; local password text, case sensitive
  899.     push    cx
  900.     mov    ax,cx            ; external password length
  901.     mov    dx,di
  902.     call    strlen            ; length of local password
  903.     cmp    ax,cx            ; same?
  904.     pop    cx
  905.     je    srvlog5            ; e = yes
  906.     mov    byte ptr [si],20h    ; corrupt external password
  907.     jmp    short srvlog8        ; fail
  908. srvlog5:lodsb                ; remote char
  909.     mov    ah,[di]            ; local char
  910.     inc    di
  911.     cmp    ah,al            ; same?
  912.     jne    srvlog8            ; ne = no, fail
  913.     loop    srvlog5            ; do all chars
  914. srclog6:mov    slogin,1        ; declare user logged-in
  915.     jmp    short srvlog9        ; ACK with brief message
  916.  
  917. srvlog8:mov    si,offset remms2    ; say invalid login information
  918.     jmp    short srvlog10
  919.  
  920. srvlog9:mov    si,offset remms3    ; welcome aboard message
  921.     mov    slogin,1        ; say logged in successfully
  922. srvlog10:mov    di,offset encbuf    ; copy to here
  923.     call    strcpy
  924.     mov    dx,di            ; where command lies
  925.     call    strlen            ; length to cx
  926.     push    si
  927.     mov    si,offset rpacket    ; packet to use for reply
  928.     call    doenc            ; encode reply
  929.     pop    si
  930.     mov    trans.chklen,1        ; reply with 1 char checksum
  931.     call    ackpak
  932.     clc
  933.     ret
  934. srvlogin endp
  935.  
  936. ; srvspc - handle other side's request of Remote Space
  937. srvspc    proc    near
  938.     test    denyflg,spcflg        ; is command enabled?
  939.     jz    srspc1            ; z = yes
  940.     mov    dx,offset remms9    ; else give a message
  941.     mov    trans.chklen,1        ; reply with 1 char checksum
  942.     call    ermsg
  943.     mov    bx,dx
  944.     call    errpack            ; back to local kermit
  945.     clc
  946.     ret
  947. srspc1:    xor    cl,cl            ; use current drive
  948.     cmp    decbuf+1,0        ; any data?
  949.     je    srspc2            ; e = no
  950.     mov    cl,decbuf+2        ; get the drive letter
  951. srspc2:    call    dskspace        ; calculate space, get letter into CL
  952.     jnc    srspc3            ; nc = success
  953.     mov    spcmsg3,cl        ; insert drive letter
  954.     mov    di,offset encbuf    ; encoder buffer
  955.     mov    si,offset spcmsg2    ; give Drive not ready message
  956.     call    strcpy
  957.     jmp    short srspc4        ; send it
  958. srspc3:    mov    spcmsg1,cl        ; insert drive letter
  959.     mov    di,offset encbuf    ; destination
  960.     mov    word ptr[di],'  '    ; space space
  961.     add    di,2            ; start number here
  962.     call    lnout            ; convert number to asciiz in [di]
  963.     mov    si,offset spcmsg    ; trailer of message
  964.     call    strcat            ; tack onto end of number part
  965. srspc4:    mov    trans.chklen,1        ; reply with 1 char checksum
  966.     mov    dx,offset encbuf
  967.     call    strlen            ; get data size into cx for doenc
  968.     mov    si,offset rpacket
  969.     call    doenc            ; encode
  970.     call    pktsize            ; report packet size
  971.     call    ackpak
  972.     clc
  973.     ret
  974. srvspc    endp
  975.  
  976. ; srvwho - respond to remote host's WHO command.
  977. srvwho    proc    near
  978.     mov    si,offset whomsg    ; add brief msg of just us chickens
  979.     mov    di,offset encbuf    ; encoder source field
  980.     call    strcpy            ; copy msg to pkt
  981.     mov    dx,si            ; strlen works on dx
  982.     call    strlen
  983.     mov    si,offset rpacket
  984.     call    doenc            ; encode reply, size is in cx
  985.     mov    trans.chklen,1        ; reply with 1 char checksum
  986.     call    ackpak
  987.     clc
  988.     ret
  989. srvwho    endp
  990.  
  991. ; srvmsg - respond to remote host's Message (Send) command
  992. ;  show message on our screen.
  993. srvmsg    proc    near
  994.     cmp    decbuf,0        ; any data in the packet?
  995.     jbe    srvmsg2            ; e = no, just ack the message 
  996.     cmp    decbuf,'M'        ; Message packet?
  997.     jne    srvmsg2            ; ne = no, ack and forget
  998.     test    flags.remflg,dquiet+dserial ; quiet or serial display?
  999.     jnz    srvmsg1            ; nz = yes
  1000.     mov    dx,scrmsg        ; move cursor to Last message area
  1001.     call    poscur
  1002.     call    clearl            ; and clear the line
  1003. srvmsg1:xor    ch,ch
  1004.     mov    cl,decbuf+1        ; data length
  1005.     sub    cl,' '            ; remove ascii bias
  1006.     jle    srvmsg2            ; le = nothing
  1007.     mov    di,offset decbuf+2    ; main part of message
  1008.     call    prtscr            ; display cx chars on the screen
  1009. srvmsg2:mov    rpacket.datlen,0    ; length
  1010.     mov    trans.chklen,1        ; reply with 1 char checksum
  1011.     call    ackpak
  1012.     clc
  1013.     ret
  1014. srvmsg    endp
  1015.  
  1016.  
  1017. ; srvhos - handle other side's request of REM Host command-line. [jrd]
  1018. ; We execute the command with STDOUT redirected to $kermit$.tmp and then
  1019. ; read and transmit that file to the other end. No such file results in
  1020. ; returning just an error msg ACK packet
  1021. srvhos    proc    near
  1022.     call    logchk            ; check login status
  1023.     jc    srvhos1            ; c = ok
  1024.     ret                ; else have sent error packet
  1025. srvhos1:test    denyflg,hostflg        ; command enabled?
  1026.     jz    srvhos2            ; z = yes
  1027.     mov    trans.chklen,1        ; reply with 1 char checksum
  1028.     mov    dx,offset remms9    ; else give a message
  1029.     call    ermsg
  1030.     mov    bx,dx
  1031.     call    errpack            ; back to local kermit
  1032.     clc
  1033.     ret
  1034.  
  1035. srvhos2:mov    si,offset decbuf    ; received filename, asciiz from dodec
  1036.     mov    di,offset srvbuf    ; destination
  1037.     call    strcpy            ; copy data to srvbuf
  1038.     jmp    SRDIR6            ; do common completion code
  1039. srvhos    endp
  1040.  
  1041. ; Respond to other side's request of Remote Help. Write & read $kermit$.tmp
  1042. srvhlp    proc    near
  1043.     mov    dl,curdsk
  1044.     add    dl,'A'-1        ; change to letter
  1045.     mov    srvtmp+2,dl        ; insert current disk drive
  1046.     mov    dx,offset srvtmp+2    ; use filename of d:$kermit$.tmp
  1047.     mov    ah,creat2        ; create the file
  1048.     xor    cx,cx            ; attributes r/w
  1049.     int    dos
  1050.     jc    srvhlp1            ; c = could not open
  1051.     mov    dx,offset hlprem    ; data to be sent, strlen uses dx
  1052.     call    strlen            ; put string length in cx
  1053.     mov    bx,ax            ; handle
  1054.     mov    ah,write2        ; write to file
  1055.     int    dos            ; write the info
  1056.     mov    ah,close2    ; close the file so we can reread it below
  1057.     int    dos
  1058. srvhlp1:mov    si,offset infms4    ; pseudo filename
  1059.     mov    di,offset auxfile    ; send-as name
  1060.     call    strcpy            ; copy it there
  1061.     jmp    srvtail            ; send temporary file to remote screen
  1062. srvhlp    endp
  1063.  
  1064. ; srvker - handle other side's request of REM Kermit command-line.
  1065. srvker    proc    near
  1066.     call    logchk            ; check login status
  1067.     jc    srvker8            ; c = ok
  1068.     ret                ; else have sent error packet
  1069. srvker8:test    denyflg,kerflg        ; command enabled?
  1070.     jz    srvker1            ; z = yes
  1071.     mov    trans.chklen,1        ; reply with 1 char checksum
  1072.     mov    dx,offset remms9    ; else give a message
  1073.     call    ermsg
  1074.     mov    bx,dx
  1075.     call    errpack            ; back to local kermit
  1076.     clc
  1077.     ret
  1078.  
  1079. srvker1:call    takopen            ; open a Take file
  1080.     jc    srvker3            ; c = failed to obtain Take space
  1081.     mov    dx,prmptr        ; get prompt
  1082.     call    prompt              ; prompt user, set reparse address
  1083.     mov    bx,takadr        ; pointer to Take structure
  1084.     mov    skertmp,bx        ; remember it here for cleanup
  1085.     mov    [bx].taktyp,0ffh    ; mark as a macro
  1086.     mov    dx,offset decbuf    ; received command, asciiz
  1087.     call    strlen            ; get length into cx
  1088.     mov    si,dx
  1089. srvker6:cmp    byte ptr [si],' '    ; strip leading white space
  1090.     ja    srvker7            ; a = non-white
  1091.     loop    srvker6            ; continue
  1092. srvker7:cmp    cx,8            ; need at least 8 chars "SET xx y"
  1093.     jb    srvker2            ; b = too few, bad command
  1094.     mov    ax,[si]            ; get first two characters
  1095.     or    ax,2020h        ; lower case them
  1096.     cmp    ax,'es'            ; start of "SET"?
  1097.     jne    srvker2            ; ne = no, bad command
  1098.     mov    ax,[si+2]        ; next two
  1099.     or    ax,2020h
  1100.     cmp    ax,' t'            ; rest of "SET "?
  1101.     jne    srvker2            ; ne = no, bad command
  1102.     add    si,4            ; move to end of "SET "
  1103.     sub    cx,4
  1104.     mov    [bx].takcnt,cx        ; number of bytes in command
  1105.     push    es
  1106.     mov    ax,[bx].takbuf        ; segment of Take buffer
  1107.     mov    es,ax
  1108.     mov    di,1            ; place here (skip buf length byte)
  1109.     cld
  1110.     rep    movsb
  1111.     pop    es
  1112.     call    setcom
  1113.     jnc    srvker3            ; nc = success
  1114. srvker2:mov    si,offset remms6    ; "Command failed"
  1115.     jmp    short srvker4
  1116. srvker3:mov    si,offset remms8    ; "Command succeeded"
  1117. srvker4:mov    di,offset encbuf    ; destination for message
  1118.     call    strcpy            ; move the message
  1119.     mov    dx,di
  1120.     call    strlen            ; length to cx
  1121.     mov    si,offset rpacket    ; use this packet for reply
  1122.     call    doenc            ; encode
  1123.     mov    trans.chklen,1        ; reply with 1 char checksum
  1124.     call    ackpak            ; send ACK with message
  1125.     mov    ax,skertmp        ; get old take address
  1126.     cmp    ax,takadr        ; same (still in current Take)?
  1127.     jne    srvker5            ; ne = no
  1128.     call    takclos            ; close the Take file
  1129. srvker5:clc
  1130.     ret
  1131. srvker    endp
  1132.  
  1133. ;  Command                                Code   Values
  1134. ;  REMOTE SET ATTRIBUTES IN ALL            132   0 = OFF, 1 = ON
  1135. ;  REMOTE SET ATTRIBUTES IN LENGTH         133   0 = OFF, 1 = ON
  1136. ;  REMOTE SET ATTRIBUTES IN TYPE           134   0 = OFF, 1 = ON
  1137. ;  REMOTE SET ATTRIBUTES IN DATE           135   0 = OFF, 1 = ON
  1138. ;X  REMOTE SET ATTRIBUTES IN CREATOR        136   0 = OFF, 1 = ON
  1139. ;X  REMOTE SET ATTRIBUTES IN ACCOUNT        137   0 = OFF, 1 = ON
  1140. ;X  REMOTE SET ATTRIBUTES IN AREA           138   0 = OFF, 1 = ON
  1141. ;X  REMOTE SET ATTRIBUTES IN BLOCK-SIZE     139   0 = OFF, 1 = ON
  1142. ;X  REMOTE SET ATTRIBUTES IN ACCESS         140   0 = OFF, 1 = ON
  1143. ;X  REMOTE SET ATTRIBUTES IN ENCODING       141   0 = OFF, 1 = ON
  1144. ;X  REMOTE SET ATTRIBUTES IN DISPOSITION    142   0 = OFF, 1 = ON
  1145. ;X  REMOTE SET ATTRIBUTES IN PROTECTION     143   0 = OFF, 1 = ON
  1146. ;X  REMOTE SET ATTRIBUTES IN GPROTECTION    144   0 = OFF, 1 = ON
  1147. ;X  REMOTE SET ATTRIBUTES IN SYSTEM-ID      145   0 = OFF, 1 = ON
  1148. ;X  REMOTE SET ATTRIBUTES IN FORMAT         146   0 = OFF, 1 = ON
  1149. ;X  REMOTE SET ATTRIBUTES IN SYS-INFO       147   0 = OFF, 1 = ON
  1150. ;X  REMOTE SET ATTRIBUTES IN BYTE-COUNT     148   0 = OFF, 1 = ON
  1151. ;
  1152. ;  REMOTE SET ATTRIBUTES OUT ALL           232   0 = OFF, 1 = ON
  1153. ;  REMOTE SET ATTRIBUTES OUT LENGTH        233   0 = OFF, 1 = ON
  1154. ;  REMOTE SET ATTRIBUTES OUT TYPE          234   0 = OFF, 1 = ON
  1155. ;  REMOTE SET ATTRIBUTES OUT DATE          235   0 = OFF, 1 = ON
  1156. ;X  REMOTE SET ATTRIBUTES OUT CREATOR       236   0 = OFF, 1 = ON
  1157. ;X  REMOTE SET ATTRIBUTES OUT ACCOUNT       237   0 = OFF, 1 = ON
  1158. ;X  REMOTE SET ATTRIBUTES OUT AREA          238   0 = OFF, 1 = ON
  1159. ;X  REMOTE SET ATTRIBUTES OUT BLOCK-SIZE    239   0 = OFF, 1 = ON
  1160. ;X  REMOTE SET ATTRIBUTES OUT ACCESS        240   0 = OFF, 1 = ON
  1161. ;X  REMOTE SET ATTRIBUTES OUT ENCODING      241   0 = OFF, 1 = ON
  1162. ;X  REMOTE SET ATTRIBUTES OUT DISPOSITION   242   0 = OFF, 1 = ON
  1163. ;X  REMOTE SET ATTRIBUTES OUT PROTECTION    243   0 = OFF, 1 = ON
  1164. ;X  REMOTE SET ATTRIBUTES OUT GPROTECTION   244   0 = OFF, 1 = ON
  1165. ;X  REMOTE SET ATTRIBUTES OUT SYSTEM-ID     245   0 = OFF, 1 = ON
  1166. ;X  REMOTE SET ATTRIBUTES OUT FORMAT        246   0 = OFF, 1 = ON
  1167. ;X  REMOTE SET ATTRIBUTES OUT SYS-INFO      247   0 = OFF, 1 = ON
  1168. ;X  REMOTE SET ATTRIBUTES OUT BYTE-COUNT    248   0 = OFF, 1 = ON
  1169. ;
  1170. ;  REMOTE SET FILE TYPE                    300   0 = TEXT, 1 = BINARY
  1171. ;X  REMOTE SET FILE NAMES                   301   0 = CONVERTED, 1 = LITERAL
  1172. ;  REMOTE SET FILE COLLISION               302   0 = RENAME,  1 = REPLACE,
  1173. ;                                                X 2 = BACKUP,  X 3 = APPEND,
  1174. ;                                                4 = DISCARD, X  5 = ASK
  1175. ;X  REMOTE SET FILE REPLACE                 303   0 = PRESERVE, 1 = DEFAULT
  1176. ;  REMOTE SET INCOMPLETE                   310   0 = DISCARD, 1 = KEEP
  1177. ;
  1178. ;  REMOTE SET BLOCK-CHECK                  400   number (1, 2, or 3)
  1179. ;  REMOTE SET RECEIVE PACKET-LENGTH        401   number (10-9024)
  1180. ;  REMOTE SET RECEIVE TIMEOUT              402   number (any, 0 = no timeout)
  1181. ;  REMOTE SET RETRY                        403   number (any, 0 = no limit)
  1182. ;  REMOTE SET SERVER TIMEOUT               404   number (any, 0 = no timeout)
  1183. ;  REMOTE SET TRANSFER CHARACTER-SET       405   Character Set Designator
  1184. ;  REMOTE SET WINDOW-SLOTS                 406   number (1-31)
  1185. ;
  1186. ; Items marked with "X" are ignored by this server
  1187.  
  1188. ; srvset - manage incoming REMOTE SET commands
  1189. ; decode buffer looks like S<len1><value1><len2><value2>
  1190. srvset    proc    near
  1191.     mov    bufptr,offset decbuf+1    ; received command data, asciiz
  1192.     call    srvswk            ; worker to convert first value to ax
  1193.     jc    srvset3            ; c = failure
  1194.     mov    temp,ax            ; save first value here
  1195.     cmp    ax,132            ; before known set?
  1196.     jb    srvset3            ; b = yes, bad
  1197.     mov    di,offset sattr        ; assume SET ATTRIBUTES
  1198.     cmp    ax,148            ; still in range?
  1199.     jbe    srvset2            ; be = yes
  1200.     cmp    ax,232            ; before next range?
  1201.     jb    srvset1            ; b = yes
  1202.     cmp    ax,248            ; still in range?
  1203.     jbe    srvset2            ; be = yes, get final value
  1204. srvset1:push    es            ; do table lookup on other values
  1205.     push    ds
  1206.     pop    es
  1207.     mov    di,offset setval    ; look up other codes in table
  1208.     mov    cx,setvlen
  1209.     cld
  1210.     repne    scasw
  1211.     pop    es
  1212.     mov    bx,offset remms1    ; "Unknown server command", if needed
  1213.     jne    srvset3            ; ne = no match, unknown command
  1214.     sub    di,offset setval+2    ; get displacement
  1215.     mov    di,setvec[di]
  1216. srvset2:call    di            ; call the action routine
  1217.     mov    bx,offset remms6    ; "Command failed", if needed
  1218.     jc    srvset3            ; c = failure
  1219.     mov    si,offset remms8    ; "Command succeeded"
  1220.     mov    di,offset encbuf    ; destination for message
  1221.     call    strcpy            ; move the message
  1222.     mov    dx,di
  1223.     call    strlen            ; length to cx
  1224.     mov    si,offset rpacket    ; use this packet for reply
  1225.     call    doenc            ; encode
  1226.     mov    trans.chklen,1        ; reply with 1 char checksum
  1227.     call    ackpak            ; send ACK with message
  1228.     clc
  1229.     ret
  1230. srvset3:mov    trans.chklen,1        ; reply with 1 char checksum
  1231.     call    errpack            ; send error message in ptr bx
  1232.     clc
  1233.     ret
  1234. srvset    endp
  1235.  
  1236. sattr    proc    near            ; SET ATTRIBUTES IN/OUT ITEM ON/OFF
  1237.     mov    ax,temp            ; get kind of attribute
  1238.     cmp    ax,200            ; the OUT kind?
  1239.     jb    sattr1            ; b = no, IN kind
  1240.     sub    ax,100            ; merge to same thing
  1241. sattr1:    cmp    ax,132            ; ALL?
  1242.     jne    sattr2            ; be = ok
  1243.     mov    bl,0ffh            ; all bits
  1244.     jmp    short sattr6
  1245. sattr2:    cmp    al,133            ; Length?
  1246.     jne    sattr3            ; ne = no
  1247.     mov    bl,attlen
  1248.     jmp    short sattr6
  1249. sattr3:    cmp    al,134            ; Type
  1250.     jne    sattr4            ; ne = no
  1251.     mov    bl,atttype
  1252.     jmp    short sattr6
  1253. sattr4:    cmp    bl,135            ; Date?
  1254.     jne    sattr5            ; ne = no, fail
  1255.     mov    bl,attdate
  1256.     jmp    short sattr6
  1257. sattr5:    stc                ; fail
  1258.     ret
  1259. sattr6:    call    srvswk            ; get second value to ax, 1 = on
  1260.     jc    sattr5            ; c = failure
  1261.     or    ax,ax            ; off?
  1262.     jnz    sattr7            ; nz = no, on
  1263.     mov    al,flags.attflg        ; current flags
  1264.     not    bl            ; invert selected items
  1265.     and    al,bl            ; turn off selected items
  1266.     mov    flags.attflg,al        ; store the flags
  1267.     clc
  1268.     ret
  1269. sattr7:    cmp    ax,1            ; on?
  1270.     jne    sattr5            ; ne = no, fail
  1271.     or    flags.attflg,bl        ; insert ON selected bits
  1272.     clc    
  1273.     ret
  1274. sattr    endp
  1275.  
  1276. sftype    proc    near            ; SET FILE TYPE
  1277.     call    srvswk            ; get second value to ax
  1278.     jc    sftypb            ; c = failure
  1279.     cmp    al,1
  1280.     ja    sftypb            ; a = bad
  1281.     mov    trans.xtype,al        ; store transfer type
  1282.     mov    dtrans.xtype,al        ; store transfer type
  1283.     clc
  1284.     ret
  1285. sftypb:    stc                ; bad command
  1286.     ret
  1287. sftype    endp
  1288.  
  1289. sfcoll    proc    near            ; SET FILE COLLISION
  1290.     call    srvswk            ; get second value to ax
  1291.     jc    sfcollb            ; c = failure
  1292.     cmp    ax,4
  1293.     ja    sfcollb            ; a = bad
  1294.     cmp    ax,2            ; backup?
  1295.     je    sfcollb            ; e = yes, bad command
  1296.     cmp    ax,3            ; append?
  1297.     je    sfcollb            ; e = yes, bad command
  1298.     mov    flags.flwflg,al        ; set file collison state
  1299.     clc
  1300.     ret
  1301. sfcollb:stc                ; bad command
  1302.     ret
  1303. sfcoll    endp
  1304.  
  1305. sfinc    proc    near             ; SET INCOMPLETE, SET FILE INCOMPLETE
  1306.     call    srvswk            ; get second value to ax
  1307.     jc    sfincb            ; c = failure
  1308.     cmp    ax,1
  1309.     ja    sfincb            ; a = bad
  1310.     mov    flags.abfflg,al        ; discard incomplete files if al = 1
  1311.     clc
  1312.     ret
  1313. sfincb:    stc                ; bad command
  1314.     ret
  1315. sfinc    endp
  1316.  
  1317. srtmo    proc    near            ; SET RECEIVE TIMEOUT
  1318.     call    srvswk            ; get second value to ax
  1319.     jnc    srtmo1            ; nc = success
  1320.     ret
  1321. srtmo1:    cmp    ax,94            ; above limit?
  1322.     jbe    srtmo2            ; be = no
  1323.     mov    al,94
  1324. srtmo2:    mov    trans.rtime,al
  1325.     clc
  1326.     ret
  1327. srtmo    endp
  1328.  
  1329. sblkck    proc    near            ; SET BLOCK-CHECK
  1330.     call    srvswk            ; get second value to ax
  1331.     jnc    sblkck1            ; nc = success
  1332.     ret                ; fail
  1333. sblkck1:cmp    ax,3            ; our limit
  1334.     jbe    sblkck2            ; be = safe
  1335.     mov    ax,3            ; set to max
  1336. sblkck2:or    ax,ax            ; too small?
  1337.     jnz    sblkck3            ; z = no
  1338.     inc    ax
  1339. sblkck3:mov    dtrans.chklen,al    ; use this char as initial checksum
  1340.     clc
  1341.     ret
  1342. sblkck    endp
  1343.  
  1344. srpkt    proc    near             ; SET RECEIVE PACKET-LENGTH
  1345.     call    srvswk            ; get second value to ax
  1346.     jnc    srpkt1            ; nc = success
  1347.     ret
  1348. srpkt1:    cmp    ax,9024            ; above limit?
  1349.     jbe    srpkt2            ; be = no
  1350.     mov    ax,9024
  1351. srpkt2:    cmp    ax,20            ; too small?
  1352.     jae    srpkt3            ; ae = no
  1353.     mov    ax,20            ; set minimum
  1354. srpkt3:    mov    dtrans.rlong,ax        ; set long packet size
  1355.     mov    bl,dtrans.rpsiz        ; regular packet size
  1356.     xor    bh,bh
  1357.     cmp    ax,bx            ; is long packet shorter
  1358.     jae    srpkt4            ; ae = no
  1359.     mov    dtrans.rpsiz,al        ; set regular pkt length too
  1360. srpkt4:    clc
  1361.     ret
  1362. srpkt    endp
  1363.  
  1364. sretry    proc    near            ; REMOTE SET RETRY
  1365.     call    srvswk            ; get second value to ax
  1366.     jnc    sretry1            ; nc = success
  1367.     ret                ; fail
  1368. sretry1:cmp    ax,63            ; our limit
  1369.     jbe    sretry2            ; be = safe
  1370.     mov    ax,63            ; set to max
  1371. sretry2:mov    maxtry,al        ; set packet retry limit
  1372.     clc
  1373.     ret
  1374. sretry    endp
  1375.  
  1376. sstmo    proc    near            ; SET SERVER TIMEOUT
  1377.     call    srvswk            ; get second value to ax
  1378.     jnc    sstmo1            ; nc = success
  1379.     ret
  1380. sstmo1:    cmp    ax,255
  1381.     jbe    sstmo2            ; be = in range
  1382.     mov    al,255            ; limit to max
  1383. sstmo2:    mov    srvtmo,al        ; store timeout value
  1384.     clc
  1385.     ret
  1386. sstmo    endp
  1387.  
  1388. sxfrch    proc    near            ; SET TRANSFER CHARACTER-SET string
  1389.     mov    bx,bufptr
  1390.     xor    ch,ch
  1391.     mov    cl,[bx]            ; byte count of next field, if any
  1392.     sub    cl,' '            ; remove ascii bias
  1393.     jnc    sxfrch1            ; nc = is ok
  1394.     ret
  1395. sxfrch1:inc    bx            ; look at character string
  1396.     cmp    byte ptr[bx],'A'    ; A for Transparent?
  1397.     jne    sxfrch2
  1398.     cmp    cx,1            ; just that char?
  1399.     jne    sxfrchb            ; ne = no, fail
  1400.     mov    trans.xchset,0        ; set transfer char set to Transparent
  1401.     clc
  1402.     ret
  1403. sxfrch2:cmp    cx,6            ; "I2/100"?
  1404.     jne    sxfrchb            ; ne = no, fail
  1405.     cmp    word ptr [bx],'2I'    ; length is ok, check spelling
  1406.     jne    sxfrchb            ; ne = failure
  1407.     cmp    word ptr [bx+2],'1/'
  1408.     jne    sxfrchb
  1409.     cmp    word ptr [bx+4],'00'
  1410.     jne    sxfrchb
  1411.     mov    trans.xchset,1        ; set transfer char set to Latin1
  1412.     clc
  1413.     ret
  1414. sxfrchb:stc                ; fail
  1415.     ret
  1416. sxfrch    endp
  1417.  
  1418. swind    proc    near            ; SET WINDOW-SLOTS
  1419.     call    srvswk            ; get second value to ax
  1420.     jnc    swind1            ; nc = success
  1421.     ret
  1422. swind1:    cmp    ax,31            ; max legal
  1423.     jbe    swind2            ; be = in range
  1424.     mov    al,31            ; limit to max
  1425. swind2:    or    ax,ax            ; no windowing?
  1426.     jnz    swind3            ; nz = no, not that way
  1427.     mov    ax,1            ; local min size for no windowing
  1428. swind3:    mov    dtrans.windo,al        ; store default window size
  1429.     clc
  1430.     ret
  1431. swind    endp
  1432.  
  1433. ; Worker for srvset. Reads buffer pointed at by bufptr looking for 
  1434. ; construction <length><numbers>. Returns carry clear and binary number
  1435. ; in AX, else carry set and AX = -1. Bufptr is always updated.
  1436. srvswk    proc    near
  1437.     push    bx
  1438.     push    cx
  1439.     push    dx
  1440.     push    si
  1441.     mov    bx,bufptr
  1442.     xor    ch,ch
  1443.     mov    cl,[bx]            ; byte count of next field, if any
  1444.     sub    cl,' '            ; remove ascii bias
  1445.     jnc    srvswk1            ; nc = is ok
  1446.     mov    ax,-1            ; else say value is -1
  1447.     jmp    short srvswkx
  1448. srvswk1:inc    bx
  1449.     xor    si,si            ; accumulated value
  1450.     mov    dl,10
  1451. srvswk2:mov    ax,si            ; accumulated value
  1452.     mul    dl            ; times 10
  1453.     mov    si,ax            ; store
  1454.     xor    ah,ah
  1455.     mov    al,[bx]            ; get a digit
  1456.     inc    bx
  1457.     sub    al,'0'            ; remove ascii bias
  1458.     jnc    srvswk3            ; nc = no
  1459.     mov    ax,-1            ; say bad value
  1460.     jmp    short srvswkx        ; and quit
  1461. srvswk3:add    si,ax            ; accumulate new digit
  1462.     loop    srvswk2            ; do all digits
  1463.     mov    ax,si            ; return results in ax
  1464.     clc
  1465. srvswkx:mov    bufptr,bx        ; remember where we read from decbuf
  1466.     pop    si
  1467.     pop    dx
  1468.     pop    cx
  1469.     pop    bx
  1470.     ret
  1471. srvswk    endp
  1472.  
  1473. ; srvini - init parms based on 'I' init packet
  1474. srvini    proc    near
  1475.     call    spar            ; parse info
  1476.     call    packlen
  1477.     mov    cx,trans.rlong        ; max receiving pkt length to report
  1478.     call    makebuf            ; remake buffers for new windowing
  1479.     push    si
  1480.     mov    si,offset rpacket
  1481.     call    rpar            ; setup info about our reception
  1482.     pop    si
  1483.     mov    al,trans.chklen        ; checksum length negotiated
  1484.     push    ax            ; save around reply
  1485.     mov    trans.chklen,1        ; reply with 1 char checksum
  1486.     call    ackpak
  1487.     pop    ax            ; restore checksum length
  1488.     mov    dtrans.chklen,al    ;  to negotiation value
  1489.     clc                ; success
  1490.     ret
  1491. srvini    endp
  1492.  
  1493.  
  1494. ; BYE command - tell remote KERSRV to logout & exit to DOS  
  1495.  
  1496. BYE    PROC    NEAR
  1497.     mov    ah,cmeol        ; get a confirm
  1498.     call    comnd
  1499.     jnc    bye1            ; nc = success
  1500.     ret                ; failure
  1501. bye1:    mov    remcmd,'L'        ; Logout command letter
  1502.     call    logo            ; tell the host Kermit to logout
  1503.      jc    bye2            ; c = failed, do not exit
  1504. ;;;    mov    flags.extflg,1        ; set this Kermit's exit flag
  1505.     call    serhng            ; hangup the phone
  1506. bye2:    clc
  1507.     ret
  1508. BYE    ENDP
  1509.  
  1510. ; FINISH - tell    remote KERSRV to exit
  1511.  
  1512. FINISH    PROC    NEAR
  1513.     mov    ah,cmeol        ; get a confirm
  1514.     call    comnd
  1515.     jnc    finish1            ; nc = success
  1516.     ret                ; failure
  1517. finish1:mov    remcmd,'F'        ; Finish command letter
  1518.     call    logo
  1519.     clc
  1520.     ret
  1521. FINISH    ENDP
  1522.  
  1523. ; Common routine for BYE, FINISH, REMOTE LOGOUT. Avoids sending I packet.
  1524. ; Return carry clear for success, else carry set
  1525. LOGO    PROC    NEAR
  1526.     call    serini            ; Initialize port
  1527.     jnc    logo1            ; nc = success
  1528.     ret                ; c = failure
  1529. logo1:    call    clrbuf            ; clear serial port buffer
  1530.     call    ihostr            ; initialize the host
  1531.     mov    trans.windo,1        ; one window slot before negotiations
  1532.     mov    cx,dspsiz        ; default send pkt length (94)
  1533.     call    makebuf            ; set up packet buffers
  1534.     xor    ax,ax
  1535.     mov    diskio.string,al    ; clear local filename for stats
  1536.     mov    pktnum,al        ; packet number to be used
  1537.     mov    windlow,al        ; reset windowing
  1538.     call    packlen            ; get max packet length
  1539.     call    getbuf            ; get buffer for sending
  1540.     mov    trans.chklen,1        ; use one char for server functions
  1541.     mov    ah,remcmd        ; get command letter ('L' or 'F')
  1542.     mov    encbuf,ah        ; encode the command
  1543.     mov    cx,1            ; one piece of data
  1544.     call    doenc            ; do encoding
  1545.     mov    [si].pktype,'G'        ; Generic command packet type
  1546.     mov    flags.xflg,1        ; say receiving to screen
  1547.     call    sndpak            ;  to suppress # pkts msg
  1548.     jc    logo3            ; c = failure
  1549.     mov    al,[si].seqnum        ; get response for this sequence num
  1550.     mov    ah,maxtry        ; retry threshold
  1551.     call    response        ; get response
  1552.     pushf
  1553.     mov    si,offset rpacket    ; packet to look at
  1554.     cmp    [si].pktype,'E'        ; Error packet?
  1555.     je    logo2            ; e = yes, contents displayed already
  1556.     call    msgmsg            ; show any message
  1557. logo2:    popf
  1558. logo3:    mov    flags.cxzflg,0        ; clear these flags
  1559.     mov    flags.xflg,0
  1560.     ret                ; exit with carry flag from response
  1561. LOGO    ENDP
  1562.  
  1563. ; GET command. Ask remote server to send the specified file(s)
  1564. ; Queries for remote filename and optional local override path/filename
  1565. GET    PROC    NEAR
  1566.     mov    auxfile,0        ; clear, for safety
  1567.     mov    encbuf,0        ; ditto
  1568.     mov    flags.cxzflg,0        ; no Control-C typed yet
  1569.     mov    bx,offset encbuf    ; where to put text
  1570.     mov    dx,offset filmsg    ; help
  1571.     mov    ah,cmline        ; filenames with embedded whitespace
  1572.     call    comnd            ; get text or confirm
  1573.     jnc    get1            ; nc = success
  1574.     ret                ; failure 
  1575. get1:    mov    cnt,ax            ; remember number of chars we read
  1576.     or    ax,ax            ; read in any chars?
  1577.     jnz    get7            ; nz = yes, analyze
  1578.                     ; if empty line, ask for file names
  1579. get2:    mov    dx,offset remfnm    ; ask for remote name first
  1580.     call    prompt
  1581.     mov    bx,offset encbuf    ; place for remote filename
  1582.         mov    dx,offset frem        ; help message
  1583.     mov    ah,cmline        ; use this for embedded spaces
  1584.     call    comnd            ; get a filename
  1585.     jnc    get3            ; nc = success
  1586.     ret                ; failure
  1587. get3:    mov    cnt,ax            ; remember number of chars read
  1588.     or    ax,ax            ; count of entered chars
  1589.     jz    get2            ; z = none, try again
  1590.     mov    dx,offset lclfnm    ; prompt for local filename
  1591.     call    prompt
  1592.     mov    bx,offset filhlp
  1593.     mov    dx,offset auxfile    ; complete local filename
  1594.     mov    auxfile,0        ; clear, for safety
  1595.     mov    ah,cmword        ; get a word
  1596.     call    comnd
  1597.     jnc    get5            ; nc = success
  1598.     ret                ; failure
  1599. get5:    mov    ah,cmeol        ; get confirmation
  1600.     call    comnd
  1601.     jnc    get6            ; nc = success
  1602.     ret                ; failure
  1603. get6:    cmp    auxfile,'#'        ; is first char a replacement for '?'
  1604.     jne    get7            ; ne = no
  1605.     mov    auxfile,'?'        ; replace '#' by '?'
  1606. get7:    cmp    encbuf,'#'        ; is first char a replacement for '?' ?
  1607.     jne    get8            ; ne = no
  1608.     mov    encbuf,'?'        ; replace '#' by '?'
  1609.  
  1610. get8:    call    rrinit            ; get & clear buffers and counters
  1611.     mov    flags.xflg,1        ; assume writing to screen
  1612.     cmp    flags.destflg,2        ; receiving to screen?
  1613.     je    get8a            ; e = yes, skip screen stuff
  1614.     mov    flags.xflg,0        ; not writing to screen, yet
  1615.     call    init            ; init (formatted) screen
  1616. get8a:    mov    kstatus,kssuc        ; global status, success
  1617.     call    ipack            ; Send Initialize, 'I', packet
  1618.     jnc    get8b            ; nc = success, ok to fail 'I' pkt
  1619.     jmp    short get10        ; failure
  1620.  
  1621. get8b:    mov    si,offset encbuf    ; copy from here
  1622.     mov    di,offset fsta.xname    ; to statistics remote name field
  1623.     call    strcpy
  1624.     mov    si,offset rpacket    ; packet for response
  1625.     mov    cx,cnt            ; get back remote filename size
  1626.     call    doenc            ; encode data already in encbuf
  1627.     jnc    get9            ; nc = success
  1628.     mov    dx,offset ermes6        ; filename is too long for pkt
  1629.     call    ermsg
  1630.     mov    bx,dx            ; point to message, for errpack
  1631.     call    errpack            ; tell the host we are quiting
  1632.     jmp    short get10        ; data could not all fit into packet
  1633.  
  1634. get9:    mov    trans.chklen,1        ; use one char for server functions
  1635.     mov    rpacket.pktype,'R'    ; Receive init packet
  1636.     mov    si,offset rpacket
  1637.     call    sndpak            ; send the packet, no ACK expected
  1638.     jc    get10            ; c = failure to send packet
  1639.     mov    rstate,'R'        ; Set the state to receive initiate
  1640.     jmp    READ2            ; go join read code
  1641.  
  1642. get10:    call    bufclr            ; total failures come here
  1643.     call    rprpos            ; reset cursor for prompt
  1644.     or    errlev,ksrecv        ; set DOS error level to cannot rcv
  1645.     or    fsta.xstatus,ksrecv    ; set status
  1646.     mov    kstatus,ksrecv        ; global status
  1647.     mov    flags.cxzflg,0        ; clear flag for next command
  1648.     mov    auxfile,0        ; clear send-as filename buffer
  1649.     mov    flags.xflg,0        ; clear to-screen flag
  1650.     mov    al,1            ; underline cursor
  1651.     call    fcsrtype        ; set IBM-PC cursor to underline
  1652.     clc
  1653.     ret
  1654. GET    ENDP
  1655.  
  1656. ;    This is the REMOTE command
  1657.  
  1658. REMOTE    PROC    NEAR
  1659.     mov    dx,offset remtab    ; Parse keyword from the REMOTE table
  1660.     mov    bx,offset remhlp
  1661.     mov    ah,cmkey
  1662.     call    comnd
  1663.     jnc    remote1            ; nc = success
  1664.     ret                ; failure
  1665. remote1:jmp    bx            ; do the appropriate routine
  1666. REMOTE    ENDP
  1667.  
  1668. ; REMSET - Execute a REMOTE SET command
  1669.  
  1670. REMSET    PROC    NEAR
  1671.     mov    rempac,'G'        ; Packet type = generic
  1672.     mov    encbuf,'S'        ; command type = Set
  1673.     mov    bufptr,offset encbuf+1    ; place more pkt material here
  1674.     mov    ah,cmkey        ; get keyword
  1675.     mov    dx,offset remstt1    ; table of keywords
  1676.     xor    bx,bx            ; help
  1677.     call    comnd
  1678.     jnc    remset1            ; nc = success
  1679.     ret
  1680. remset1:cmp    bx,1            ; Attributes?
  1681.     jne    remset5            ; ne = no
  1682.     mov    dx,offset remsat1    ; Attributes IN, OUT table
  1683.     xor    bx,bx            ; help
  1684.     mov    ah,cmkey
  1685.     call    comnd
  1686.     jnc    remset2
  1687.     ret
  1688. remset2:mov    temp,bx            ; save in out
  1689.     mov    dx,offset remsat2    ; next attributes keyword table
  1690.     xor    bx,bx            ; help
  1691.     mov    ah,cmkey
  1692.     call    comnd
  1693.     jnc    remset3
  1694.     ret
  1695. remset3:add    bx,temp            ; save final value
  1696.     call    remwork
  1697.     mov    dx,offset onoff        ; ON, OFF table
  1698.     xor    bx,bx            ; help
  1699.     mov    ah,cmkey        ; get on,off
  1700.     call    comnd
  1701.     jnc    remset4
  1702.     ret
  1703. remset4:jmp    remset17
  1704.  
  1705. remset5:cmp    bx,2            ; REMOTE SET FILE?
  1706.     jne    remset14        ; ne = no
  1707.     mov    dx,offset remsfit    ; REM SET FILE table
  1708.     xor    bx,bx            ; help
  1709.     mov    ah,cmkey
  1710.     call    comnd
  1711.     jnc    remset6
  1712.     ret
  1713. remset6:push    bx
  1714.     call    remwork            ; write kind to buffer
  1715.     pop    bx
  1716.     cmp    bx,300            ; TYPE?
  1717.     jne    remset8
  1718.     mov    dx,offset remsfty    ; TYPE table
  1719.     xor    bx,bx
  1720.     mov    ah,cmkey
  1721.     call    comnd
  1722.     jnc    remset17
  1723.     ret
  1724.  
  1725. remset8:cmp    bx,301            ; NAME?
  1726.     jne    remset10        ; ne = no
  1727.     mov    dx,offset remsfna    ; NAME table
  1728.     xor    bx,bx
  1729.     mov    ah,cmkey
  1730.     call    comnd
  1731.     jnc    remset17
  1732.     ret
  1733.  
  1734. remset10:cmp    bx,302            ; COLLISION?
  1735.     jne    remset12        ; ne = no
  1736.     mov    dx,offset remsfco    ; COLLISION table
  1737.     xor    bx,bx
  1738.     mov    ah,cmkey
  1739.     call    comnd
  1740.     jnc    remset17
  1741.     ret
  1742.  
  1743. remset12:cmp    bx,303            ; REPLACE?
  1744.     jne    remset13        ; ne = no
  1745.     mov    dx,offset remsfre    ; REPLACE table
  1746.     xor    bx,bx
  1747.     mov    ah,cmkey
  1748.     call    comnd
  1749.     jnc    remset17
  1750.     ret
  1751.  
  1752. remset13:cmp    bx,310            ; INCOMPLETE?
  1753.     jne    remset13a        ; ne = no
  1754.     mov    dx,offset remsfin    ; INCOMPLETE table
  1755.     xor    bx,bx
  1756.     mov    ah,cmkey
  1757.     call    comnd
  1758.     jnc    remset17
  1759. remset13a:stc
  1760.     ret
  1761.  
  1762. remset14:cmp    bx,310            ; REMOTE SET INCOMPLETE?
  1763.     jne    remset15        ; ne = no
  1764.     push    bx
  1765.     call    remwork            ; write main command
  1766.     pop    bx
  1767.     jmp    short remset13        ; use above to complete the command
  1768.  
  1769. remset15:cmp    bx,3            ; REMOTE SET RECEIVE?
  1770.     jne    remset18        ; ne = no
  1771.     mov    dx,offset remsrcv    ; RECEIVE table
  1772.     xor    bx,bx
  1773.     mov    ah,cmkey
  1774.     call    comnd
  1775.     jnc    remset19        ; get value as text
  1776. remset16:stc
  1777.     ret
  1778.  
  1779. remset17:call    remwork            ; write to buffer
  1780.     jmp    short remset22
  1781.                     ; text as last item commands
  1782. remset18:mov    temp,bx
  1783.     cmp    bx,405            ; Transfer?
  1784.     jne    remset19        ; ne = no
  1785.     mov    dx,offset remsxfr    ; TRANSFER table
  1786.     xor    bx,bx
  1787.     mov    ah,cmkey
  1788.     call    comnd
  1789.     jnc    remset19
  1790.     ret
  1791. remset19:call    remwork            ; store command type
  1792.     mov    dx,bufptr        ; store response as text
  1793.     inc    dx            ; skip count byte
  1794.     mov    bx,offset numhlp
  1795.     cmp    temp,405        ; Transfer character set needs string
  1796.     jne    remset20        ; ne = not string
  1797.     mov    bx,offset xfrhlp    ; use this help
  1798. remset20:mov    ah,cmword
  1799.     call    comnd
  1800.     jnc    remset21
  1801.     ret
  1802. remset21:mov    dx,bufptr        ; field pointer
  1803.     inc    dx            ; look at text
  1804.     call    strlen            ; length to cx
  1805.     add    cx,' '            ; compute byte count field
  1806.     mov    bx,bufptr
  1807.     mov    [bx],cl            ; store byte count
  1808.  
  1809. remset22:mov    ah,cmeol        ; get a confirmation
  1810.     call    comnd
  1811.     jnc    remset23
  1812.     ret
  1813. remset23:mov    dx,offset encbuf
  1814.     call    strlen            ; get length
  1815.     mov    cnt,cx            ; length for generic
  1816.     mov    flags.xflg,1        ; response coming to screen
  1817.     jmp    genr9            ; do the operation
  1818. REMSET    ENDP
  1819.  
  1820. ; Remote Set worker. Enter with new numerical value in BX. Writes length
  1821. ; and asciiz value to encbuf and increments buffer pointer bufptr.
  1822. remwork    proc    near
  1823.     mov    di,offset tmpbuf    ; temp buffer
  1824.     mov    byte ptr [di],0        ; clear it
  1825.     mov    ax,bx
  1826.     call    dec2di            ; convert value to asciiz
  1827.     mov    dx,offset tmpbuf    ; get length to cx
  1828.     mov    si,dx            ; asciiz data source
  1829.     call    strlen
  1830.     push    cx            ; save length
  1831.     mov    di,bufptr        ; byte count field
  1832.     add    cl,' '            ; to ascii
  1833.     mov    [di],cl            ; store count byte
  1834.     inc    di
  1835.     pop    cx
  1836.     push    es
  1837.     push    ds
  1838.     pop    es
  1839.     cld
  1840.     rep    movsb            ; copy asciiz data value
  1841.     pop    es
  1842.     mov    byte ptr [di],0        ; insert null terminator
  1843.     mov    bufptr,di
  1844.     ret
  1845. remwork    endp
  1846.  
  1847. ; In REM commands below, al = remcmd, ah = rempac, cl = remlen
  1848. ; REMCWD - Change remote working directory
  1849.  
  1850. REMCWD    PROC    NEAR
  1851.     mov    ax,'GC'            ; Packet type = generic
  1852.     xor    cl,cl            ; no text required
  1853.     jmp    genric
  1854. REMCWD    ENDP
  1855.  
  1856. ; REMDEL - Delete a remote file
  1857.  
  1858. REMDEL    PROC    NEAR
  1859.     mov    ax,'GE'            ; Packet type = generic
  1860.     mov    cl,1            ; text required
  1861.     jmp    genric
  1862. REMDEL    ENDP
  1863.  
  1864. ; REMDIR - Do a directory
  1865.  
  1866. REMDIR    PROC    NEAR
  1867.     mov    ax,'GD'            ; Packet type = generic
  1868.     xor    cl,cl            ; no text required
  1869.     jmp    genric
  1870. REMDIR    ENDP
  1871.  
  1872. ; REMDIS - Get disk usage on remote system
  1873.  
  1874. REMDIS    PROC    NEAR
  1875.     mov    ax,'GU'            ; Packet type = generic, disk usage
  1876.     xor    cl,cl            ; optional text permitted
  1877.     jmp    genric            ; Execute generic Kermit command
  1878. REMDIS    ENDP
  1879.  
  1880.  
  1881. ; REMHEL - Get help about remote commands
  1882.  
  1883. REMHEL    PROC    NEAR
  1884.     mov    ax,'GH'            ; Packet type = generic, Help
  1885.     xor    cl,cl            ; no text required
  1886.     jmp    genric            ; Execute generic Kermit command
  1887. REMHEL    ENDP
  1888.  
  1889. ; REMHOS - Execute a remote host command
  1890.  
  1891. REMHOS    PROC    NEAR
  1892.     mov    ax,'C '            ; Packet type = remote command
  1893.     mov    cl,1            ; text required
  1894.     jmp    genric
  1895. REMHOS    ENDP
  1896.  
  1897. ; REMKER - Execute a remote Kermit command
  1898.  
  1899. REMKER    PROC    NEAR
  1900.     mov    ax,'K '            ; Packet type = remote Kermit command
  1901.     mov    cl,1            ; text required
  1902.     jmp    short genric
  1903. REMKER    ENDP
  1904.  
  1905. ; REMLOGIN - LOGIN [username [password [account]]]
  1906.  
  1907. REMLOGIN PROC    NEAR
  1908.     mov    ax,'GI'            ; Packet type = generic
  1909.     xor    cl,cl            ; no text required
  1910.     jmp    short genric
  1911. REMLOGIN ENDP
  1912.  
  1913. ; REMOTE LOGOUT - Logout of remote server and host, stay in this Kermit
  1914. REMLOGOUT PROC    NEAR
  1915.     mov    remcmd,'L'        ; Logout command letter
  1916.     call    logo            ; perform without I packet
  1917.     clc
  1918.     ret
  1919. REMLOGOUT ENDP
  1920.  
  1921. ; REMMSG - Send one line short message to remote screen.
  1922.  
  1923. REMMSG    proc    near
  1924.     mov    ax,'GM'
  1925.     mov    cl,1            ; text required
  1926.     jmp    short genric
  1927. REMMSG    endp
  1928.  
  1929. ; REMTYP - Type a remote file
  1930.  
  1931. REMTYP    PROC    NEAR
  1932.     mov    ax,'GT'            ; Packet type = generic, Type file
  1933.     mov    cl,1            ; text required
  1934.     jmp    short genric
  1935. REMTYP    ENDP
  1936.  
  1937. ; REMWHO - ask for list of remote logged on users
  1938.  
  1939. REMWHO    proc    near
  1940.     mov    ax,'GW'
  1941.     xor    cl,cl            ; optional text permitted
  1942.     jmp    short genric
  1943. REMWHO    endp
  1944.  
  1945. ; GENRIC - Send a generic command to a remote Kermit server
  1946. ; remlen = 0: no additional text, or additional text is optional
  1947. ; remlen = 1: additional text is required
  1948. GENRIC    PROC    NEAR
  1949.     mov    remcmd,al        ; stash cmd info in real memory
  1950.     mov    rempac,ah        ; packet type
  1951.     mov    remlen,cl        ; text required flag
  1952.     mov    si,offset infms3    ; dummy filename for transaction log
  1953.     mov    di,offset diskio.string    ; where such names go
  1954.     call    strcpy            ; move the name
  1955.     mov    bx,offset encbuf    ; where to put text
  1956.     mov    temp,bx            ; where field starts
  1957.     cmp    rempac,'C'        ; Remote Host command? 
  1958.     je    genr2            ; e = yes, no counted string(s)
  1959.     cmp    rempac,'K'        ; Remote Kermit command?
  1960.     je    genr2            ; e = yes, no counted string(s)
  1961. genr1:    mov    ah,remcmd        ; get command letter
  1962.     mov    [bx],ah            ; store in buffer
  1963.     add    bx,2            ; leave room for count byte
  1964.     mov    temp,bx            ; point at data field
  1965. genr2:    mov    ah,cmline        ; get a line text
  1966.     mov    dx,offset genmsg    ; help message
  1967.     call    comnd
  1968.     jnc    genr3            ; nc = success
  1969.     ret                ; failure
  1970. genr3:    mov    cnt,ax            ; size
  1971.     call    genredir        ; act on any ">filespec" redirection
  1972.     add    temp,ax            ; point to next field
  1973.     cmp    rempac,'C'        ; Remote Host command?
  1974.     je    genr4            ; e = yes, no counted string(s)
  1975.     cmp    rempac,'K'        ; Remote Kermit command?
  1976.     je    genr4            ; e = yes, no counted string(s)
  1977.     mov    encbuf+1,al        ; size of first field
  1978.     add    encbuf+1,32        ; do tochar function
  1979.     inc    temp            ; include count byte
  1980. genr4:    cmp    al,remlen        ; got necessary command text?
  1981.     jae    genr5            ; ae = yes
  1982.     cmp    remlen,0        ; is text optional?
  1983.     je    genr5            ; e = yes, continue without it
  1984. genr4a:    mov    dx,offset infms2    ; say need more info
  1985.     mov    ah,prstr
  1986.     int    dos
  1987.     or    errlev,ksgen        ; say cannot receive
  1988.     or    fsta.xstatus,ksgen    ; set status failed
  1989.     mov    kstatus,ksgen        ; global status
  1990.     clc
  1991.     ret
  1992.  
  1993. genr5:    mov    flags.xflg,1        ; output coming to screen
  1994.     cmp    remcmd,'I'        ; Remote Login command?
  1995.     je    genr6            ; e = yes
  1996.     cmp    remcmd,'C'        ; Remote Change Working Directory?
  1997.     je    genr7a            ; e = yes, get optional password
  1998.     jmp    short genr8        ; neither so no extra prompts here
  1999.  
  2000. genr6:    cmp    cnt,0            ; have username etc already?
  2001.     je    genr6a            ; e = no
  2002.     call    genupwd            ; parse username etc
  2003.     jmp    short genr8        ; send formatted contents
  2004. genr6a:    mov    dx,offset user        ; prompt for username
  2005.      call    prompt
  2006.     mov    bx,offset encbuf+1    ; skip command letter
  2007.     mov    temp,bx            ; start of field
  2008.     call    input            ; read text
  2009.     jc    genr8            ; c = none
  2010.     mov    temp,bx            ; point to next data field
  2011.  
  2012. genr7:    mov    dx,offset password    ; get optional password
  2013.     call    prompt
  2014. genr7a:    mov    bx,temp            ; where to put the password
  2015.     cmp    byte ptr [bx-1],0    ; extra null?
  2016.     jne    genr7b            ; ne = no
  2017.     dec    bx            ; backup to overwrite it
  2018.     dec    temp
  2019. genr7b:    mov    comand.cmquiet,1    ; turn on quiet mode
  2020.     call    input            ; read in the password
  2021.     mov    comand.cmquiet,0    ; turn off quiet mode
  2022.     jc    genr8            ; c = no text, do not add field
  2023.     mov    temp,bx            ; point to next data field
  2024.                     ;
  2025.     cmp    remcmd,'I'        ; Remote Login command?
  2026.     jne    genr8            ; ne = no
  2027.     mov    dx,offset account    ; get optional account ident
  2028.     call    prompt
  2029.     mov    bx,temp            ; where this field starts
  2030.     call    input            ; read text
  2031. genr8:    cmp    flags.cxzflg,'C'    ; Control-C entered?
  2032.     jne    genr9            ; ne = no
  2033.     stc
  2034.     ret                ; return failure
  2035.  
  2036. GENR9:    mov    kstatus,kssuc        ; global status
  2037.     call    ipack            ; Send Init parameters
  2038.     jc    genr11            ; c = failure
  2039.     mov    trans.chklen,1        ; use 1 char for server functions
  2040.     mov    fsta.pretry,0        ; no retries yet
  2041.     mov    pktnum,0
  2042.     cmp    flags.cxzflg,'C'    ; did the user type a ^C?
  2043.     jne    genr10            ; ne = no
  2044.     stc
  2045.     ret                ; return in error state
  2046.  
  2047. genr10:    push    si
  2048.     mov    si,offset rpacket    ; use this packet for reply
  2049.     mov    dx,offset encbuf
  2050.     call    strlen            ; length of data
  2051.     call    doenc            ; encode data
  2052.     mov    trans.chklen,1        ; use block check 1 to server
  2053.     mov    ah,rempac        ; packet type
  2054.     mov    rpacket.pktype,ah
  2055.     call    sndpak            ; send the Generic command packet
  2056.     pop    si
  2057.     jc    genr11            ; c = failure
  2058.     mov    rstate,'R'        ; next state is Receive Initiate
  2059.     jmp    READ2            ; file receiver does the rest
  2060.  
  2061. genr11:    mov    flags.xflg,0        ; reset screen output flag
  2062.     xor    ax,ax            ; tell statistics this was a read
  2063.     or    errlev,ksrem         ; DOS error level, failure of REMote cmd
  2064.     mov    fsta.xstatus,ksrem    ; set status
  2065.     mov    kstatus,ksrem        ; global status
  2066.     clc
  2067.     ret
  2068. GENRIC    ENDP
  2069.  
  2070. ; Extract ">filespec" redirection at end of command line. If found put
  2071. ; filespec in auxfile as new output name.
  2072. genredir proc    near
  2073.     mov    cx,cnt            ; chars on command line
  2074.     jcxz    genred3            ; z = none
  2075.     mov    di,temp            ; buffer, after prologue
  2076.     add    di,cx            ; end of buffer+1
  2077.     dec    di
  2078.     push    ax
  2079.     push    es
  2080.     mov    ax,ds
  2081.     mov    es,ax
  2082.     mov    al,'>'            ; redirection symbol
  2083.     std                ; scan backward
  2084.     repne    scasb            ; found '>'?
  2085.     cld
  2086.     pop    es
  2087.     pop    ax
  2088.     jne    genred3            ; ne = no
  2089.     inc    di            ; look at '>'
  2090.     mov    byte ptr[di],0        ; insert terminator
  2091.     mov    ax,cx            ; new count length
  2092.     mov    cnt,cx            ; remember here too
  2093. genred1:inc    di            ; look at optional filename
  2094.     or    di,di            ; terminator?
  2095.     jz    genred2            ; z = yes
  2096.     cmp    byte ptr [di],' '    ; remove lead-in puncutation
  2097.     jbe    genred1            ; be = punctuation, go until text
  2098. genred2:mov    si,di
  2099.     mov    di,offset auxfile    ; new output name goes here
  2100.     call    strcpy
  2101. genred3:ret
  2102. genredir endp
  2103.  
  2104. ; Parse a single command line into username, password, account in counted
  2105. ; string style, for REM LOGIN. Enter with BX pointing at the next new
  2106. ; byte to store a command character and CNT holding the current line length.
  2107. ; Returns a completely formatted line, asciiz. Use {..} to surround items
  2108. ; with embedded spaces.
  2109. genupwd    proc    near
  2110.     push    ax
  2111.     push    bx
  2112.     push    es
  2113.     mov    ax,ds
  2114.     mov    es,ax
  2115.     sub    bx,cnt            ; next item minus count of items
  2116.     mov    si,bx            ; where text starts
  2117.     dec    bx            ; point at count byte
  2118.     mov    cx,3            ; three fields possible
  2119. genupw1:push    cx
  2120.     mov    cx,cnt            ; number of text chars to examine
  2121.     call    genup10            ; get first field
  2122.     mov    cnt,cx            ; update remaining count
  2123.     or    cx,cx            ; get remaining count
  2124.     pop    cx            ; recover loop counter
  2125.     jz    genupw2            ; z means empty remainder
  2126.     loop    genupw1            ; try to do three fields
  2127. genupw2:pop    es
  2128.     pop    bx
  2129.     pop    ax
  2130.     ret
  2131.  
  2132. ; Worker. Enter with bx=offset of count byte, si=offset of start of text,
  2133. ;  cx=chars remaining in input string.
  2134. ; Exit with bx=offset of next count byte, si=offset of where new text is
  2135. ; to be read, cx=chars remaining in input string.
  2136. genup10:mov    byte ptr [bx],' '    ; clear count byte to zero + space
  2137.     mov    di,si            ; work on text part
  2138.     mov    al,' '            ; skip whitespace
  2139.     cld
  2140.     repe    scasb
  2141.     je    genup12            ; e = nothing present
  2142.     dec    di            ; back up to non-white char
  2143.     inc    cx            ; correct count
  2144.     mov    si,di            ; si = where non-white text starts
  2145.     mov    di,bx            ; count byte
  2146.     inc    di            ; where text goes
  2147.     mov    ah,' '            ; assume this is the break char
  2148.     cmp    byte ptr [si],'{'    ; field starts with brace?
  2149.     jne    genup11            ; ne = no
  2150.     mov    ah,'}'            ; use this break char
  2151.     inc    si            ; skip over leading brace
  2152.     dec    cx            ; one less char to consider
  2153. genup11:lodsb                ; get a char
  2154.     cmp    al,ah            ; break char yet?
  2155.     je    genup12            ; e = yes
  2156.     or    al,al            ; end of text?
  2157.     jz    genup12            ; z = yes
  2158.     stosb                ; store char without leading padding
  2159.     inc    byte ptr [bx]        ; count chars stored in this field
  2160.     loop    genup11            ; continue
  2161. genup12:mov    bx,di            ; where to store next count byte
  2162.     mov    byte ptr [di],0        ; null terminator
  2163.     ret
  2164. genupwd    endp
  2165.     
  2166. ; Send    "I" packet with transmission parameters
  2167.  
  2168. IPACK    PROC    NEAR
  2169.     call    serini            ; initialize serial port
  2170.     jnc    ipack1
  2171.     ret                ; c = failure
  2172. ipack1:    call    ihostr            ; initialize the host
  2173.     call    clrbuf            ; clear serial port buffer
  2174.     call    sparmax            ; set up our maximum capabilites
  2175.     mov    trans.windo,1        ; no windows yet
  2176.     mov    cx,dspsiz        ; default send pkt length (94)
  2177.     call    makebuf            ; remake buffers
  2178.     xor    ax,ax
  2179.     mov    rpacket.numtry,al    ; number of receive retries
  2180.     mov    fsta.pretry,ax        ; no retries
  2181.     mov    pktnum,al        ; packet number 0
  2182.     mov    windlow,al        ; reset windowing
  2183.     call    packlen            ; compute packet length
  2184.     call    getbuf            ; get buffer for sending
  2185.     call    rpar            ; store them in the packet
  2186.     mov    trans.chklen,1        ; one char for server function
  2187.     mov    [si].pktype,'I'        ; "I" packet
  2188.     call    sndpak            ; send the packet
  2189.     jnc    ipack2            ; nc = success
  2190.     ret                ; return failure
  2191. ipack2:    mov    al,[si].seqnum
  2192.     mov    ah,maxtry        ; retry threshold
  2193.     add    ah,ah
  2194.     add    ah,maxtry        ; triple the normal retries
  2195.     mov    chkparflg,1        ; check for unexpected parity
  2196.     call    response        ; get response
  2197.     jnc    ipack3            ; nc = success
  2198.     call    bufclr            ; clear all
  2199.     cmp    rpacket.pktype,'E'    ; was it an Error pkt response?
  2200.     je    ipack4            ; e = yes, this is forgivable
  2201.     stc                ; carry set for failure
  2202.     ret                ; return failure
  2203.  
  2204. ipack3:    cmp    rpacket.pktype,'Y'    ; ACK response?
  2205.     jne    ipack4            ; ne = no
  2206.     push    si
  2207.     mov    si,offset rpacket    ; packet address
  2208.     call    spar            ; read in the data
  2209.     pop    si
  2210.     call    packlen            ; get max send packet size
  2211.     mov    cx,trans.rlong        ; max receiving pkt length to report
  2212.     call    makebuf            ; remake buffers for new windowing
  2213. ipack4:    cmp    rpacket.pktype,'E'    ; was it an Error pkt response?
  2214.     jne    ipack5            ; ne = no
  2215.     mov    dx,offset emptymsg    ; clear last error line
  2216.     call    ermsg            ; do it
  2217. ipack5:    clc
  2218.     ret                ; return success
  2219. IPACK    ENDP
  2220.  
  2221. ; Returns BX the updated pointer to the input buffer
  2222. ;      input buffer = <ascii data length count byte>textstring
  2223. ; return carry clear if have text, else carry set for none
  2224. INPUT    PROC    NEAR
  2225.     mov    temp2,bx        ; where to put byte count
  2226.     inc    bx            ; start text after count byte
  2227.     xor    dx,dx            ; help, none
  2228.     mov    ah,cmline        ; get text with embedded whitespace
  2229.     call    comnd
  2230.     jnc    input1            ; nc = success
  2231.     mov    bx,temp2        ; empty field, restore pointer
  2232.     ret                ; failure
  2233. input1:    push    bx
  2234.     mov    bx,temp2
  2235.     add    al,' '            ; convert byte count to ascii
  2236.     mov    [bx],al            ; store count byte
  2237.     pop    bx            ; return pointer to next free byte
  2238.     clc                ; say have bytes
  2239.     ret
  2240. INPUT    ENDP
  2241.  
  2242. code    ends
  2243.     end
  2244.