dispat MSG$COMMAND ,serv.c ; a host command dispat MSG$ERROR ,sernop ; ignore 'E' packets from remote dispat global global .sbttl routines for server serv.$: strlen #notimp spack #MSG$ERROR,paknum,r0,#notimp ; ignore unrecognized packet type clr r0 ; not done yet return serv$$: call serchk ; timeout, send a NAK please sernop: clr r0 ; not yet done return ; ignore timeouts, ACKS and NAKS serchk: mov r3 ,paknum ; nak checksum errors spack #MSG$NAK,paknum ; send the NAK out please clr r0 ; we are not done return serv.i: mov r3 ,paknum ; we got an init packet. respond in calls rpar ,<#packet,r2> ; kind please calls spar ,<#packet> ; get our parameters and send them to spack #MSG$ACK,paknum,sparsz,#packet; the other kermit call inirepeat ; clr r0 ; not done return ; bye global serv.s: mov pauset ,oldpau ; save the old pause time please call throtl ; and throttle the line speed mov r3 ,paknum ; got a SINIT, initialize packet number calls rpar ,<#packet,r2> ; store there send init info away calls spar ,<#packet> ; and send them ours for the ACK spack #MSG$ACK,paknum,sparsz,#packet call inirepeat ; do repeat initialization mov numtry ,oldtry ; save the retry count clr numtry ; retrycount := 0 incm64 paknum ; paknum := ( paknum+1 ) mod 64 calls rec.sw ,<#STA.FIL> ; and get set to receive a filename clr r0 ; not done mov oldpau ,pauset ; restore old pause time return ; next server command please serv.r: calls bufunp ,<#packet,#srcnam> ; /53/ clrb srcnam(r1) ; /53/ calls fixwild ,<#srcnam> ; change % to ? clr index ; first file in directory please call getnxt ; get the first filename please tst r0 ; did it work ? bne 100$ ; no. Getnxt will send the error pak calls sen.sw ,<#STA.SIN> 100$: clr r0 ; not done return .enabl lsb serv.c: call cretmp ; create the temp file please bcs 100$ ; oops calls sercmd ,<#packet,#lun.ou>; it worked cmpb r0 ,#377 ; normal exit on KMON wait? beq 10$ ; yes tst r0 ; zero (?) beq 10$ ; yes calls syserr , ; no, send the error over strlen #errtxt ; the length spack #MSG$ERROR,paknum,r0,#errtxt ; ignore unrecognized packet type call clotmp ; no, send error over br 100$ ; bye 10$: call clotmp ; close it and send the file over mov #kertmp ,r0 ; as a text reply call xreply 100$: clr r0 return .save .psect $PDATA ,D 200$: .asciz /Spawned job failed due to timeout or TT read wait/ .even .restore .dsabl lsb serv.g: sub #200 ,sp ; /53/ Make a temp copy of data mov sp ,r2 ; /53/ Point to it STRCPY r2 ,#packet ; /53/ Copy it calls bufunp , ; /53/ Undo it (with repeats) add #200 ,sp ; /53/ Pop buffer movb packet+0,r2 ; get the first data byte which scan r2,#gencom ; is the generic command type asl r0 ; index into dispatch table jsr pc ,@gendsp(r0) ; simple return dispat basedsp=gendsp ,baseval=gencom ,default=gen.$ dispat GN$LOGIN ,gen.i dispat GN$EXIT ,gen.f dispat GN$CONNECT ,gen.c dispat GN$BYE ,gen.l dispat GN$DIRECTORY ,gen.d dispat GN$DISK ,gen.u dispat GN$DELETE ,gen.e dispat GN$SUBMIT ,gen.$ dispat GN$WHO ,gen.w dispat GN$SEND ,gen.$ dispat GN$HELP ,gen.h dispat GN$QUERY ,gen.$ dispat GN$RENAME ,gen.r dispat GN$COPY ,gen.k dispat GN$PRINT ,gen.$ dispat GN$PROGRAM ,gen.$ dispat GN$JOURNAL ,gen.$ dispat GN$VARIABLE ,gen.$ dispat GN$TYPE ,gen.t dispat global global .sbttl generic kermit routines gen.$: strlen #notgen ; NO-OP for unimplemented generic spack #MSG$ERROR,paknum,r0,#notgen ; send an error packet back please clr r0 ; not done return gen.f: spack #MSG$ACK,paknum ; send a simple ACK clr r0 ; /45/ May want to stay in server tst srvprot K11SERMAC[.050032]K11SER.MAC[.050032]    X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>?\\\\\\\\\`:#@'="\abcdefghi\\\\\\\jklmnopqr\\\\\\\~stuvwxyz\\\\\\\\\\\\\\\\\\\\\\{ABCDEFGHI\\\\\\}JKLMNOPQR\\\\\\\\STUVWXYZ\\\\\\0123456789\\\\\  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~@ggh<i|o<m<4p<p<k|Zn<l fr rwx<x<x<x޺<w@]@@fjnr]Ze@@|> | |v<H|  |  |xz|  |zt f r   < &^ @&@'*/V,"?Lh:hmBmz|z{x`y~|fN|@@|@͂|@ ݃ƃ<ns<|Ŏ |️|ep|u|-@率|<ᄇ2ֻr||ZRM | ntB|xyvZw|J=|R>|J? nnaa|bddfst r0 ; /38/ preload sdodir's buffer. beq 10$ ; /38/ Send error packet on any error call generr ; /38/ Makes interfacing to BUFFIL br 100$ ; /38/ a bit simpler 10$: mov #sdodir ,getcroutine ; /38/ Stuff address of get_nextchar mov #null ,r0 ; /38/ and flag we are NOT using a file call xreply ; /38/ Do the extended reply now 100$: clr r0 ; /38/ cleared return ; /38/ and exit ; mov #packet+1,r1 ; get the packet address ; unchar (r1)+ ,r2 ; get the arguement length ; bne 5$ ; something was there ; clrb @r1 ; nothing was there, insure .asciz ;5$: call cretmp ; create the temp file please ; bcs 100$ ; oops ; calls fixwild , ; change % to ? ; calls dodir , ; it worked ; call clotmp ; close it and send the file over ; mov #kertmp ,r0 ; as a text reply ; call xreply ;100$: clr r0 ; return .sbttl do remote help command gen.h: textsrc #htxt ; /38/ use memory resident mov #null ,r0 ; /38/ for this extended response call xreply ; /38/ clr r0 ; /38/ success return ; /38/ exit .save .psect $Pdata ,D htxt: .ascii /The following commands are available for the Kermit-11/ .ascii /server. To avoid ambiguity with local Kermit commands/ .ascii /some of the server commands will need to be prefixed/ .ascii /with the REMOTE keyword./ .byte cr,lf .ascii /BYE Logout Kermit-11/ .ascii /REMOTE COPY Copy one file to another/ .ascii /REMOTE CWD Change default directory/ .ascii /REMOTE DIR Prints the directory out/ .ascii /REMOTE DISK Prints available space/ .ascii /REMOTE ERASE Deletes the filename(s)/ .ascii /FINISH Exits a Kermit-11 server/ .ascii /GET Sends the filename(s)/ .ascii /REMOTE HELP Prints this help text/ .ascii /REMOTE HOST Execute a host command/ .ascii /REMOTE LOGIN Login. RSTS V9.x only/ .ascii /REMOTE RENAME Rename old file to new/ .ascii /REMOTE SPACE Prints the disk space/ .ascii /REMOTE TYPE Prints the filename(s)/ .ascii /REMOTE WHO Shows users logged in/ .byte cr,lf,0 .even .restore global global .sbttl the remote type command and who commands .enabl lsb gen.t: mov #packet+1,r1 ; get the packet address tstb @r1 ; anything there ? beq 5$ ; no, thats an error unchar (r1)+ ,r2 ; get the arguement length bne 10$ ; something was there 5$: calls error ,<#1,#200$> ; have to have something to type br 100$ ; bye 10$: mov r1 ,r0 ; send the file over now call xreply ; simple to do 100$: clr r0 ; not done yet return .save .psect $Pdata,d 200$: .asciz /I need a filename to TYPE/ .even .restore .dsabl lsb .enabl lsb gen.w: call cretmp ; get the temp file created first bcs 100$ ; oops calls systat ,<#lun.ou> ; dump the systat out to disk now. tst r0 ; did it work ? beq 10$ ; yes calls error ,<#1,#200$> ; no, send an error packet over call clotmp ; insure temp file is closed br 100$ ; bye 10$: call clotmp ; close the temp file now mov #kertmp ,r0 ; and send an extended reply call xreply ; simple to do 100$: clr r0 ; not done yet return ; bye .save .psect $Pdata,d 200$: .asciz /SYSTAT failed/ .even .restore .dsabl lsb .sbttl do the server copy and rename functions .enabl lsb gen.i: sub #120 ,sp mov #120$ ,r3 call get2ar bcs 90$ mov sp ,r3 calls login , ; 1=uic,2=password,3=addr(msgtext) tst r0 ; did this one work ? bne 90$ ; no strlen #110$ ; an ack message spack #MSG$ACK,paknum,r0,#110$; send it back br 100$ ; and exit please 90$: calls error ,<#1,r3> ; invalid arguments 100$: clr r0 ; no errros add #120 ,sp ; pop stack and exit return ; exit .save .psect $Pdata,d 110$: .asciz /Login successful/ 120$: .asciz /Missing password or UIC (PPN)/ .even .rK11SERMAC[.050032]K11SER.MAC[.050032]    X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>?\\\\\\\\\`:#@'="\abcdefghi\\\\\\\jklmnopqr\\\\\\\~stuvwxyz\\\\\\\\\\\\\\\\\\\\\\{ABCDEFGHI\\\\\\}JKLMNOPQR\\\\\\\\STUVWXYZ\\\\\\0123456789\\\\\  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~@ggh<i|o<m<4p<p<k|Zn<l fr rwx<x<x<x޺<w@]@@fjnr]Ze@@|> | |v<H|  |  |xz|  |zt f r   < &^ @&@'*/V,"?Lh:hmBmz|z{x`y~|fN|@@|@͂|@ ݃ƃ<ns<|Ŏ |️|ep|u|-@率|<ᄇ2ֻr||ZRM | ntB|xyvZw|J=|R>|J? nnaa|bddflease 90$: sec ; failure, to try again someday 100$: unsave ; pop the registers we used and exit return ; good bye .sbttl talk to a remote server .enabl lsb remfin::clr paknum ; packetnumber := 0 call seropn ; get the link line intialzied spack #MSG$GENERIC,paknum,#1,#200$ ; send a generic F command rpack r2,r3,#packet ; get an ack for it please cmpb r1 ,#MSG$ACK ; did the server like it beq 100$ ; yes calls error ,<#1,#210$> ; no, say so 100$: call clostt ; close up the remote link now return ; and back please .save .psect $Pdata,d 200$: .byte GN$EXIT,0 210$: .asciz /Can't get the remote KERMIT to FINISH/ .even .restore .dsabl lsb .enabl lsb rembye::clr paknum ; packetnumber := 0 call seropn ; get the link line intialzied spack #MSG$GENERIC,paknum,#1,#200$ ; send a generic L command rpack r2,r3,#packet ; get an ack for it please cmpb r1 ,#MSG$ACK ; did the server like it beq 100$ ; yes cmpb r1 ,#MSG$ERROR ; what about an error packet bne 10$ ; no calls error ,<#1,#packet> ; yes, print the response br 100$ ; exit 10$: calls error ,<#1,#210$> ; other error 100$: call clostt ; close up the remote link now return .save .psect $Pdata,d 200$: .byte GN$BYE ,0 210$: .asciz /Can't get the remote KERMIT to LOGOUT/ .even .restore .dsabl lsb remget::call seropn ; get the link line intialzied call sinfo ; exchange information please clr paknum ; packet_number := 0 strlen argbuf ; get the length of the filename spack #MSG$RCV,paknum,r0,argbuf ; get the server to send this file calls recsw ,<#STA.RIN> ; and call the receiver 10$: call clostt ; close up the remote link now return ; bye remhos::call seropn ; get the link line intialzied call sinfo ; exchange information please clr paknum ; packet_number := 0 strlen argbuf ; get the length of the filename spack #MSG$COMMAND,paknum,r0,argbuf ; get the server to execute call getres ; off to common code ;- call clostt ; insure closed return .sbttl the remote space, dir, erase and help commands remspa::calls doremo ,<#GN$DISK,#1,#null> clr r0 return remdir::calls doremo ,<#GN$DIRECTORY,#1,@r5> clr r0 return remtyp::calls doremo ,<#GN$TYPE,#1,@r5> clr r0 return remwho::calls doremo ,<#GN$WHO,#1,#null> clr r0 return remera::calls doremo ,<#GN$DELETE,#1,@r5> clr r0 return remhlp::calls doremo ,<#GN$HELP,#1,#null> clr r0 return remren::calls doremo ,<#GN$RENAME,#2,@r5,2(r5)> clr r0 return remcop::calls doremo ,<#GN$COPY,#2,@r5,2(r5)> clr r0 return remcwd::mov 2(r5) ,r0 ; get address of second (password) arg tstb @r0 ; is there anything there (not likely) beq 10$ ; no calls doremo ,<#GN$CONNECT,#2,@r5,2(r5)> ; insert password also br 100$ ; 10$: calls doremo ,<#GN$CONNECT,#1,@r5> ; no password today 100$: clr r0 return remlgi::mov 2(r5) ,r0 ; get address of second (password) arg tstb @r0 ; is there anything there (not likely) beq 10$ ; no calls doremo ,<#GN$LOGIN,#2,@r5,2(r5)> ; insert password also br 100$ ; 10$: calls doremo ,<#GN$LOGIN,#1,@r5> ; no password today 100$: clr r0 return global .sbttl carry out the remote command please ; DOREMOTE handles most generic commands that may have ; a variable response, such as a simple ACK ("Y") with ; the response in the data packet, an SINIT or an "X" ; packet. doremo: clr paknum ; generic command sub #130 ,sp ; allocate a buffer please mov sp ,r2 ; point to it movb @r5 ,@r2 ; the generic command to execute bicb #40 ,(r2)+ ; insure command is upper case mov 4(r5) ,r1 ; get the first command argument strlen r1 ; get the length of it please tochar r0 ,(r2)+ ; followed by len of first arg copyz r1 ,r2,#40 ; copy the arglist over please cmp 2(r5) ,#1 ; one or two arguments passed ? beq 30$ ; only one 10$: tstb (r2)+ ; two, so find the end so far bne 10$ ;K11SERMAC[.050032]K11SER.MAC[.050032]    X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>?\\\\\\\\\`:#@'="\abcdefghi\\\\\\\jklmnopqr\\\\\\\~stuvwxyz\\\\\\\\\\\\\\\\\\\\\\{ABCDEFGHI\\\\\\}JKLMNOPQR\\\\\\\\STUVWXYZ\\\\\\0123456789\\\\\  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~@ggh<i|o<m<4p<p<k|Zn<l fr rwx<x<x<x޺<w@]@@fjnr]Ze@@|> | |v<H|  |  |xz|  |zt f r   < &^ @&@'*/V,"?Lh:hmBmz|z{x`y~|fN|@@|@͂|@ ݃ƃ<ns<|Ŏ |️|ep|u|-@率|<ᄇ2ֻr||ZRM | ntB|xyvZw|J=|R>|J? nnaa|bddfem.x .word rem.t ,rem.ck .restore .sbttl routines for doremote rem.t: inc numtry ; timeout error cmp numtry ,#10 ; been trying too hard ? bhi 10$ ; yes, abort please mov #1 ,r0 ; no, return code to do rpack again return 10$: message ,cr clr r0 ; ok return rem.n: inc numtry ; got a NAK back from remote cmp numtry ,#5 ; been trying too hard ? bhi 10$ ; yes, abort please spack #MSG$GENERIC,paknum,r5,cmdbuf ; send command again please mov #1 ,r0 ; no, return code to do rpack again return 10$: message ,cr clr r0 ; ok return rem.ck: inc numtry ; got a NAK back from remote cmp numtry ,#5 ; been trying too hard ? bhi 10$ ; yes, abort please spack #MSG$GENERIC,paknum,r5,cmdbuf ; send command again please mov #1 ,r0 ; no, return code to do rpack again return 10$: message ,cr clr r0 ; ok return rem.x: mov sp ,xmode ; set a global flag for this mov sp ,xgottn ; we already have the x packet message ,cr calls rec.sw ,<#STA.FIL> ; yes, switch to receive DATA clr xmode ; no longer want output to TI: clr xgottn ; we don't have any X packets message ; a cr/lf tst r0 ; did the receive succeed ? beq rxend ; yes message ,cr; no, please say so then rxend: clr r0 ; all done return rem.s: calls rpar ,<#packet,r2> ; yes, handle the SINIT now calls spar ,<#packet> ; and send my init things over spack #MSG$ACK,paknum,sparsz,#packet incm64 paknum ; bump the packet number up mod 64 calls rec.sw ,<#STA.FIL> ; switch to get fileheader state message clr r0 ; all done return rem.y: strlen #packet ; any data in the field ? tst r0 ; if so, simply print it out bne 10$ ; no, just exit return 10$: message print #packet ; yes, print the text out please print #crlf ; a cr/lf perhaps ? clr r0 ; all done return rem.e: calls error ,<#1,#packet> ; yes, print the error text out clr r0 ; all done return ; and exit please rem.$: calls error ,<#1,#nores> ; otherwise say they did not respond clr r0 return ; and exit please .save .psect $Pdata,d nores: .asciz /Can't get the remote KERMIT to respond/ .even .restore global global .sbttl initialize for a long (X) response for generic command ; Here is where we send an X packet back to the requesting Kermit ; to say that we are going to send an extended reply to it. This ; reply takes the form of a normal file transfer but we will want ; it to be printed on the user's terminal rather than go to a disk ; file. Thus the use of the 'X' packet to start things off. xreply: copyz r0 ,#srcnam ; copy the filename to be sent clrb filnam ; /38/ insure cleared out clr index ; wildcard filenumber := 0 tstb srcnam ; /38/ is there really a file? beq 20$ ; /38/ no, ignore lookup then. call getnxt ; go do a directory lookup please tst r0 ; well, did the lookup work out ? beq 20$ 5$: call generr ; no, send the error text over br 100$ ; and abort 20$: mov sp ,xmode calls sen.sw ,<#STA.FIL> ; and switch to senddata state clr xmode ; no longer XTENDED reply mode clr xgottn ; we don't have any X packets (?) clr r0 ; success (?) 100$: textsrc ; /38/ reset to normal file i/o return ; bye global .enabl lsb seropn: save call opentt ; open the link for a server command tst r0 ; did it work ? beq 10$ ; yes strlen #200$ ; no spack #MSG$ERROR,paknum,r0,#200$ ; try to send an error packet clr r0 ; no errors now 10$: calls cantyp ,<#ttname,#lun.ti>; flush any accumulated NAKS unsave return ; bye .save .psect $Pdata,d 200$: .asciz /Init failed for link/ .even .restore .dsabl lsb global .end K11SERMAC[.050032]K11SER.MAC[.050032]R   X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>