home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msvp98b1.lzh / MSSSER.ASM < prev    next >
Assembly Source File  |  1993-05-14  |  70KB  |  2,238 lines

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