home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / mssser.asm < prev    next >
Assembly Source File  |  2020-01-01  |  87KB  |  2,792 lines

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