|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 24576 (0x6000) Types: TextFile Names: »trkermit «
└─⟦cde9d517b⟧ Bits:30007477 RC8000 Backup tape fra HT's bus-radio system └─⟦6a563b143⟧ └─⟦this⟧ »trkermit «
kermit=algol begin integer i, p, mk, state, abort, breakstate, retrycount, retry_limit, incount, inseq, inpackettype, checksum, crc, outcount, outseq, outpackettype, indatacount, outdatacount, packetsize, timeout, numpad, padchar, endchar, startchar, cntrlquote, bit8quote, checktype, repchar, state_ri, state_rf, state_rd, state_si, state_sf, state_sd, state_sz, state_sb, state_c, state_a, state_t, xon, xoff; boolean localecho, series1, xonxoff, waitxon, running, logging, forprinter, activecommandfile, gotsoh, dtrcheck, binary; integer array tail(1:10), alfa(0:255), saveattr(1:8), shd(1:12); real array recvdata, senddata, msgtext(1:43), filename(1:2); long array primary_device(1:2); integer array field iaf; long array field laf; real array field raf; procedure init_kermit; begin integer i; i:= 1; state_ri := increase(i); state_rf := increase(i); state_rd := increase(i); state_si := increase(i); state_sf := increase(i); state_sd := increase(i); state_sz := increase(i); state_sb := increase(i); state_c := increase(i); state_a := increase(i); state_t := increase(i); xon:= 'dc1'; xoff:= 'dc3'; retry_limit := 2; packetsize:= 94; timeout := 60; numpad := 0; padchar := 0; endchar := 'cr'; startchar := 'soh'; cntrlquote := '#'; bit8quote := '&'; checktype := '1'; repchar := 'nul'; <* default settings *> gotsoh := false; running := true; end; integer procedure tochar(x); value x; integer x; begin tochar:= x+' '; end; integer procedure unchar(x); value x; integer x; begin unchar:= x-' '; end; integer procedure ctrl(x); value x; integer x; begin ctrl:= (if x>='@' then (x-'@') else (x+'@')); end; integer procedure unshift(x); value x; integer x; begin unshift:= (if 'A'<= x and x<='Å' then (x-'A'+'a') else x); end; procedure crc_check(c); value c; integer c; begin integer q; c:= c extract 7; q:= exor(crc,c) extract 4; crc:= exor(crc shift (-4),q * 4225); q:= exor(crc,c shift (-4)) extract 4; crc:= exor(crc shift (-4),q * 4225); end; procedure timer(z,s,b); zone z; integer s,b; begin if (s extract 1) = 1 then stderror(z,s,b) else begin z(1):= real<:<'em'>:>; b:= 2; end; end; zone zin(32,1,timer), zout(32,1,stderror), zf, zl, zh(128,1,stderror); boolean procedure readch(c); integer c; begin readchar(zin,c); readch:= c<>'em'; end; procedure printchar(z,c); zone z; integer c; begin if c<' ' or c='del' then write(z,"^",1,false add ctrl(c),1) else outchar(z,c); end;\f message kermit - packet procedures, page 1; <*********************> <* packet procedures *> <*********************> procedure send_packet; begin integer i, sum, checkbytes, achar, ochar; boolean soh_echo; soh_echo:= false; achar:= 0; <* if waitxon then while achar<>xon do if -,readch(achar) then achar:=xon; waitxon:= xonxoff; *> setposition(zin,0,0); <* throw away all previous incomming data *> sum:= crc:= 0; checkbytes:= 1; if testbit(0) then write(zl,<:S(:>,<<d>,state,<:): :>); if (outpackettype='S') or (outpackettype='I') or ( inpackettype='S') or ( inpackettype='I') or ( inpackettype='R') then <* leave checkbytes = 1 *> else if checktype='2' then checkbytes:= 2 else if checktype='3' then checkbytes:= 3 ; write(zout,false add (startchar+128),1); if testbit(0) then printchar(zl,startchar); if soh_echo then <* wait for soh to be echoed back *> while achar<>startchar do if -,readch(achar) then achar:=startchar; outcount:= outdatacount + 2 + checkbytes; ochar:= tochar(outcount); <* COUNT *> outchar(zout,ochar); sum:= sum+ochar; crc_check(ochar); if testbit(0) then outchar(zl,ochar); ochar:= tochar(outseq); <* SEQ *> outchar(zout,ochar); sum:= sum+ochar; crc_check(ochar); if testbit(0) then outchar(zl,ochar); ochar:= outpackettype; <* TYPE *> outchar(zout,ochar); sum:= sum+ochar; crc_check(ochar); if testbit(0) then outchar(zl,ochar); if outdatacount > 0 then for i:= 1 step 1 until outdatacount do begin getchar(senddata,i+0,ochar); <* DATA *> outchar(zout,ochar); sum:= sum+ochar; crc_check(ochar); if testbit(0) then outchar(zl,ochar); end; if checkbytes = 1 then begin checksum:= (sum + (sum shift (-6) extract 2)) extract 6; ochar:= tochar(checksum); outchar(zout,ochar); if testbit(0) then outchar(zl,ochar); end else if checkbytes = 2 then begin checksum:= sum shift (-6) extract 6; ochar:= tochar(checksum); outchar(zout,ochar); if testbit(0) then outchar(zl,ochar); checksum:= sum extract 6; ochar:= tochar(checksum); outchar(zout,ochar); if testbit(0) then outchar(zl,ochar); end else if checkbytes = 3 then begin outchar(zout,tochar(crc shift (-12) extract 4)); outchar(zout,tochar(crc shift (-6) extract 6)); outchar(zout,tochar(crc extract 6)); if testbit(0) then outchar(zl,tochar(crc shift (-12) extract 4)); if testbit(0) then outchar(zl,tochar(crc shift (-6) extract 6)); if testbit(0) then outchar(zl,tochar(crc extract 6)); end; outchar(zout,endchar); if testbit(0) then outchar(zl,'nl'); if numpad > 0 then for i:= 1 step 1 until numpad do outchar(zout,padchar); setposition(zout,0,0); end; <* procedure send_packet *> boolean procedure recv_packet; begin integer i, sum, resends, inchar, checkbytes; boolean dummy; recvpacket:= false; <* if got_soh then begin inchar:= startchar; got_soh:= false; end else *> inchar:= ' '; if testbit(0) then write(zl,<:R(:>,<<d>,state,<:): :>); while inchar<>startchar do <* SOH *> begin if -, readch(inchar) then goto exit; if testbit(0) then printchar(zl,inchar); end; sum:= crc:= 0; if -, readch(inchar) then goto exit; <* COUNT *> if testbit(0) then outchar(zl,inchar); sum:= sum+inchar; crc_check(inchar); incount:= unchar(inchar); if -, readch(inchar) then goto exit; <* SEQ *> if testbit(0) then outchar(zl,inchar); sum:= sum+inchar; crc_check(inchar); inseq:= unchar(inchar); if -, readch(inchar) then goto exit; <* TYPE *> if testbit(0) then outchar(zl,inchar); sum:= sum+inchar; crc_check(inchar); inpackettype:= inchar; checkbytes:= 1; if (outpackettype='S') or ( inpackettype='S') or ( inpackettype='I') or ( inpackettype='R') then else if checktype='2' then checkbytes:= 2 else if checktype='3' then checkbytes:= 3 ; indatacount:= incount - 2 - checkbytes; if indatacount > 0 then for i:= 1 step 1 until indatacount do begin if -, readch(inchar) then goto exit; <* DATA *> if testbit(0) then outchar(zl,inchar); sum:= sum+inchar; crc_check(inchar); putchar(recvdata,i+0,inchar); end; recv_packet:= true; if checkbytes = 1 then begin checksum:= (sum + (sum shift (-6) extract 2)) extract 6; if -,readch(inchar) then recv_packet:= false else if inchar<>tochar(checksum) then begin if testbit(0) then write(zl,<: bad checksum ; expected/read :>, false add tochar(checksum),1,"/",1); recv_packet:= false; end; if testbit(0) then printchar(zl,inchar); end else if checkbytes = 2 then begin checksum:= sum shift (-6) extract 6; if -,readch(inchar) then else if inchar<>tochar(checksum) then recv_packet:= false; if testbit(0) then outchar(zl,inchar); checksum:= sum extract 6; if -,readch(inchar) then else if inchar<>tochar(checksum) then recv_packet:= false; if testbit(0) then outchar(zl,inchar); end else if checkbytes = 3 then begin checksum:= crc shift (-12) extract 4; if -,readch(inchar) then else if inchar<>tochar(checksum) then recv_packet:= false; if testbit(0) then outchar(zl,inchar); checksum:= crc shift (-6) extract 6; if -,readch(inchar) then else if inchar<>tochar(checksum) then recv_packet:= false; if testbit(0) then outchar(zl,inchar); checksum:= crc extract 6; if -,readch(inchar) then else if inchar<>tochar(checksum) then recv_packet:= false; if testbit(0) then outchar(zl,inchar); end; exit: if testbit(0) then outchar(zl,'nl'); end; <* procedure recv_packet *> procedure decode_file(z); zone z; begin integer pos, ch, repcount, bit8; pos:= 1; while pos <= indatacount do begin getchar(recvdata,pos,ch); if ch=repchar then begin getchar(recvdata,pos,ch); repcount:= unchar(ch); getchar(recvdata,pos,ch); end else repcount:= 1; if ch=bit8quote then begin bit8:= 128; getchar(recvdata,pos,ch); end else bit8:= 0; if ch=cntrlquote then begin getchar(recvdata,pos,ch); ch:= ctrl(ch); end; ch:= (ch mod 128) + bit8; for i:= 1 step 1 until repcount do if ch<>'cr' then outchar(z,ch); end; end; <* procedure decode_file *> integer procedure decode_data(buf); real array buf; begin integer pos, p, ch, repcount, bit8; pos:= 1; p:=1; while pos <= indatacount do begin getchar(recvdata,pos,ch); if ch=repchar then begin getchar(recvdata,pos,ch); repcount:= unchar(ch); getchar(recvdata,pos,ch); end else repcount:= 1; if ch=bit8quote then begin bit8:= 128; getchar(recvdata,pos,ch); end else bit8:= 0; if ch=cntrlquote then begin getchar(recvdata,pos,ch); ch:= ctrl(ch); end; ch:= (ch mod 128) + bit8; for i:= 1 step 1 until repcount do putchar(buf,p,ch); end; decode_data:= p-1; repeat putchar(buf,p,0) until (p mod 6)=1; end; <* procedure decode_data *> procedure decode_filename(name); real array name; begin real array buf(1:32); integer p,pos,ch,i; p:=pos:=1; decode_data(buf); while getchar(buf,pos,ch)<>0 do begin ch:=unshift(ch); if ch<>'.' and p<12 then begin if ('a'<=ch and ch<='å') or ('0'<=ch and ch<='9') then putchar(name,p,ch) else putchar(name,p,'ø'); end; end; while p<13 do putchar(name,p,0); end; procedure encode_data(buf); real array buf; begin integer i, pos, p, ch; pos:= 1; p:=1; while ((p-1)<packetsize-3-4) and (getchar(buf,pos,ch) extract 12 <> 0) do begin if ch >= 128 then putchar(senddata,p,bit8quote); ch:= ch mod 128; if ch<' ' or ch='del' then begin putchar(senddata,p,cntrlquote); putchar(senddata,p,ctrl(ch)); end else if ch=bit8quote or ch=cntrlquote then begin putchar(senddata,p,cntrlquote); putchar(senddata,p,ch); end else putchar(senddata,p,ch); end; outdatacount:= p-1; end; <* procedure encode_data *> procedure resendit(retries); value retries; integer retries; begin retry_count:= retrycount+1; if retries > 0 then begin send_packet; if recv_packet then begin if inpackettype='Y' then else if inpackettype='N' then resendit(retries-1) else state:= state_a; <* Abort *> end else state:= state_a; <* Abort *> end else state:= state_a; <* Abort *> end; <* procedure resendit *> procedure send_packettype(packettype,seq); value packettype; integer packettype, seq; begin integer saveseq; <* send Ack or Nak or B or Z *> saveseq:= outseq; outseq:= seq; outdatacount:= 0; outpackettype:= packettype; sendpacket; outseq:= saveseq; end; <* procedure send_packettype *> procedure send_msg_packet(packettype,msg,seq); value packettype, seq; integer packettype, seq; real array msg; begin outpackettype:= packettype; outseq:= seq; encode_data(msg); sendpacket; end; <* procedure send_msg_packet *> procedure putinitpacket; begin <* put parameters into initpacket *> outdatacount:= 9; outseq:= 0; putchar(senddata,1,tochar(64)); putchar(senddata,2,tochar(timeout)); putchar(senddata,3,tochar(numpad)); putchar(senddata,4,tochar(padchar)); putchar(senddata,5,tochar(endchar)); putchar(senddata,6,cntrlquote); putchar(senddata,7,bit8quote); putchar(senddata,8,checktype); putchar(senddata,9,repchar); if bit8quote=0 then outdatacount:= 6 else if checktype=0 then outdatacount:= 7 else if repchar=0 then outdatacount:= 8 ; end; <* procedure putinitpacket *> procedure getinitpacket; begin <* get init parameters *> integer ch; if indatacount >=1 then getchar(recvdata,1,ch); packetsize:= unchar(ch); if indatacount >=2 then getchar(recvdata,2,ch); timeout:= unchar(ch); if indatacount >=3 then getchar(recvdata,3,ch); numpad:= unchar(ch); if indatacount >=4 then getchar(recvdata,4,ch); padchar:= unchar(ch); if indatacount >=5 then getchar(recvdata,5,ch); endchar:= unchar(ch); if indatacount >=6 then getchar(recvdata,6,cntrlquote); if indatacount >=7 then begin getchar(recvdata,7,bit8quote); if bit8quote='Y' then bit8quote:= '&'; if (bit8quote < '!') or ('ü' < bit8quote) or ('?' < bit8quote and bit8quote < '`') then bit8quote:= 0; end else bit8quote:= 0; if indatacount >=8 then begin getchar(recvdata,8,checktype); if -,('1' <= checktype and checktype <= '3') then checktype:= '1'; end else checktype:= '1'; if indatacount >=9 then begin getchar(recvdata,9,repchar); if (repchar < '!') or ('ü' < repchar) or ('?' < repchar and repchar < '`') then repchar:= 0; end else repchar:= 0; end; <* procedure getinitpacket *> <*--------------- end of packet procedures ---------------*>\f message kermit - mabody, page 1; <**************** start of main program body ****************> trap(exit); if testbit(0) then open(zl,4,<:kermitlog:>,0); raf:=laf:=iaf:= 0; for i:= 0 step 1 until 255 do alfa(i):= 6 shift 12 + i; alfa(0):= 0; for i:= 10,13,25 do alfa(i):= 8 shift 12 + i; system(7,mk,primary_device); open(zin,8,primary_device,1 shift 21); open(zout,2 shift 12 + 8,primary_device,0); intable(alfa); <* lookup termial attributes *> open(zh,0,primary_device,0); getshare6(zh,shd,1); shd(1):= 1; shd(4):= 134 shift 12; for i:= 5 step 1 until 11 do shd(i):= 0; setshare6(zh,shd,1); monitor(16)send_message:(zh,1,shd); monitor(18)wait_answer:(zh,1,saveattr); <* set tiomeoutvalue and echo off *> getshare6(zh,shd,1); shd(1):= 1; shd(4):= 132 shift 12; for i:= 5 step 1 until 11 do shd(i):= saveattr(i-3); shd(5):= 3; shd(7):= 0; shd(10):= 10 shift 8; setshare6(zh,shd,1); monitor(16)send_message:(zh,1,shd); monitor(18)wait_answer:(zh,1,shd); close(zh,false); init_kermit; state:= state_ri; retry_count:= 0; outseq:= 0; <* main loop *> while running do case state of begin <* 1 : Recv_Init *> begin if -, recv_packet then begin increase(retry_count); if retry_count > retry_limit then begin p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,0); goto exit; end else send_packettype('N',0); end else if (inpackettype='I' or inpackettype='S') and inseq=0 then begin getinitpacket; outpackettype:= 'Y'; putinitpacket; sendpacket; if inpackettype='S' then begin outseq:= (outseq+1) mod 64; retry_count:= 0; state:= state_rf; end; end else if inpackettype='R' then begin decode_data(filename); state:= state_si; end else if inpackettype='G' and inseq=0 then begin if indatacount > 0 then begin getchar(recvdata,1,i); if i='L' or i='F' then begin state:= state_t; end else begin movestring(msgtext,1,<:Not Implemented:>); send_msg_packet('E',msgtext,0); end; end else begin movestring(msgtext,1,<:Protocol Error:>); send_msg_packet('E',msgtext,0); end; end else begin p:= 1; movestring(msgtext.raf,p,<:Packettype error:>); send_msg_packet('E',msgtext,0); end; end; <* state_ri *> <* 2 : Recv_File *> begin if -, recv_packet then begin increase(retry_count); if retry_count > retry_limit then begin p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,0); goto exit; end else send_packettype('Y',(out_seq+63) mod 64); end else if inpackettype='F' and inseq=outseq then begin decode_filename(filename); open(zf,4,<::>,0); for i:= 1 step 1 until 10 do tail(i):= 0; tail(1):= 1; if monitor(40,zf,0,tail)=0 and monitor(52,zf,0,tail)=0 then begin send_packettype('Y',outseq); outseq:= (outseq+1) mod 64; retry_count:= 0; state:= state_rd; end else begin close(zf,true); p:= 1; movestring(msgtext.raf,p,<:Cannot create file:>); send_msg_packet('E',msgtext,outseq); state:= state_a; end; end else if inpackettype='B' and inseq=outseq then begin send_packettype('Y',outseq); state:= state_c; end else if inpackettype='S' and ((inseq+1) mod 64)=outseq then begin increase(retry_count); if retry_count > retry_limit then begin p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,0); goto exit; end else begin putinitpacket; outpackettype:='Y'; outseq:= inseq; sendpacket; outseq:= (outseq+1) mod 64; end; end else if inpackettype='Z' and ((inseq+1) mod 64)=outseq then begin increase(retry_count); if retry_count > retry_limit then begin p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,0); goto exit; end else send_packettype('Y',inseq); end else begin p:= 1; movestring(msgtext.raf,p,<:Protocol error:>); send_msg_packet('E',msgtext,outseq); state:= state_a; end; end; <* state_RF *> <* 3 : Recv_Data *> begin if -, recv_packet then begin increase(retry_count); if retry_count > retry_limit then begin close(zf,true); monitor(48)remove_entry:(zf,0,tail); p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,outseq); state:= state_a; end else send_packettype('Y',(out_seq+63) mod 64); end else if inpackettype='D' and inseq=outseq then begin decode_file(zf); send_packettype('Y',outseq); outseq:= (outseq+1) mod 64; retry_count:= 0; end else if inpackettype='D' and ((inseq+1) mod 64)=outseq then begin increase(retry_count); if retry_count > retry_limit then begin close(zf,true); monitor(48)remove_entry:(zf,0,tail); p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,0); state:= state_a; end else send_packettype('Y',inseq); end else if inpackettype='Z' and inseq=outseq and indatacount=0 then begin outchar(zf,'em'); close(zf,true); i:= monitor(46)rename_entry:(zf,0,filename.iaf); if i=3 then begin open(zh,4,filename,0); close(zh,true); i:= monitor(48)remove_entry:(zh,0,tail); if i=0 then i:=monitor(46)rename_entry:(zf,0,filename.iaf); end; if i=0 then begin open(zh,4,filename,0); close(zh,true); i:=monitor(50)permanent_entry:(zh,3,tail); end; if i=0 then begin send_packettype('Y',outseq); outseq:= (outseq+1) mod 64; retry_count:= 0; state:= state_rf; end else begin close(zf,true); monitor(48)remove_entry:(zf,0,tail); p:= 1; movestring(msgtext.raf,p,<:File Receive Error:>); send_msg_packet('E',msgtext,outseq); state:= state_a; end; end else if inpackettype='Z' and inseq=outseq and indatacount > 0 and getchar(recvdata,1,i) extract 12 = 'D' then begin close(zf,true); monitor(48)remove_entry:(zf,0,tail); send_packettype('Y',outseq); outseq:= (outseq+1) mod 64; retry_count:= 0; state:= state_rf; end else if inpackettype='F' and ((inseq+1) mod 64)=outseq then begin increase(retry_count); if retry_count > retry_limit then begin close(zf,true); monitor(48)remove_entry:(zf,0,tail); p:= 1; movestring(msgtext.raf,p,<:Retrylimit exeeded:>); send_msg_packet('E',msgtext,0); goto exit; end else send_packettype('Y',inseq); end else begin close(zf,true); monitor(48)remove_entry:(zf,0,tail); p:= 1; movestring(msgtext.raf,p,<:Protocol error:>); send_msg_packet('E',msgtext,outseq); state:= state_a; end; end; <* state_RD *> <* 4 : state Send_Init *> begin end; <* state_SI *> <* 5 : state Send_File *> begin end; <* state_SF *> <* 6 : state Send_Data *> begin end; <* state_SD *> <* 7 : state Send_EOF *> begin end; <* state_SZ *> <* 8 : state Send_Break *> begin end; <* state_SB *> <* 9 : state Complete *> begin init_kermit; retry_count:= outseq:= 0; state:= state_ri; end; <* state_C *> <* 10 : state Abort *> begin init_kermit; retry_count:= outseq:= 0; state:= state_ri; end; <* state_A *> <* 11 : state Terminate *> begin running:= false; end; end; <* case state - main loop *> exit: <* reset terminal attributes *> close(zin,false); close(zout,false); if testbit(0) then begin outchar(zl,'em'); setposition(zl,0,0); close(zl,true); end; open(zh,8,primary_device,0); getshare6(zh,shd,1); shd(1):= 1; for i:= 1 step 1 until 8 do shd(3+i):= saveattr(i); shd(4):= 132 shift 12; setshare6(zh,shd,1); monitor(16)send_message:(zh,1,shd); monitor(18)wait_answer:(zh,1,shd); close(zh,false); end ▶EOF◀