!********************************************************** !* * !* RCO ITP to GEC Network Management Module * !* * !* Gecgrab * !* * !* Version 9.3 11 Apr 1983 * !* * !********************************************************** #options !* Prep options !* b - output binary file, else packed hex+compression !* !* %control 1 ;!No record checking. !* #if ~i %include "deimosperm" #else %include "b_deimosspecs" %control x'4001' #fi %begin !* !************************** !* * !* Declarations * !* * !************************** !****** Constintegers ****** !* !States %constinteger estb = 2 %constinteger wait data = 1 %constinteger disconnected = 0 !* modes %constinteger idle = 0 %constinteger sft sent = 1 !estb = 2 %constinteger go sent = 3 %constinteger expect data = 4 %constinteger interact = 0 %constinteger dump = 1 %constinteger hex = 1 %constinteger interp = 2 %include "b_ygatecalls" %constinteger gatex ser = 24 %constinteger buffer manager = 17 !Various useful consts etc %CONSTINTEGER REQUEST BUFFER = 0 %CONSTINTEGER RELEASE BUFFER = 1 %constinteger data = 5 %constinteger ack = 4 !Reasons for grabbing buffers %constinteger send go = 1 %constinteger send er = 2 %constinteger send ms = 3 %constinteger send sft = 0 %constinteger send connect = 4 !Monitor Calls %constinteger grotted 2 = 2 %constinteger grotted 4 = 6 !* !****** End of Constintegers ****** !* !* !****** Recordformats ****** !* %recordformat qf(%record (qf) %name link, %integer count) %recordformat ts29f(%string (255) s %or %byte octet1 %or %bytearray a(0:255)) %recordformat itpf(%byte cnsl, hb2, hb3, (%string(252) s %or %bytearray a(0:252))) %recordformat mef(%record (mef) %name link, %byte l,type, %c (%bytearray a(0:251) %c %or (%string(4) padding, %byte octet1, lcn, fn ,(%bytearray data(0:243) %or %record (itpf) itp %or %record (ts29f) ts29 %or %string (243) ds)) %c %or %string(250) s )) %recordformat pf( %c (%byte ser, reply, fn, s1, %record (mef) %name m, %byte gate port, task port) %c %or (%integer address, d5, %string (3) facility) %c %or (%byte d6, d7, a1, a2, b1, b2, c1, c2) %c %or (%integer type, a, b, c)) %recordformat sidef(%byte proc, state, inputs, outputs, %record (qf) outq) %ownbyte param, cnsl, mode %owninteger blocks in !* !****** Names ****** !* %ownrecord (sidef) gec !* !****** Records and Recordarrays ****** !* %constrecord (*) %name null == 0 %ownrecord (pf) p = 0 %owninteger i,logopt, dataopt,buffers held = 0 %ownstring (255) itpbuff %ownstring (63) address = "" !* !****** Routine Specs ****** !* %routinespec ask for buffer(%record (mef) %name mes, %byte reason) %routinespec free buffer(%record (mef) %name mes) ;!EXT %routinespec to gatex(%integer type, flag) %routinespec do connect(%record (mef) %name mes) %routinespec handle gec data(%record (pf) %name p) %routinespec handle ts packet(%byte ser) #if ~f %routinespec monitor(%record (pf) %name p, %integer type) ;!EXT #fi %routinespec read string(%string (*) %name s) %routinespec query process %routinespec send(%record (mef) %name mes, %c %integer fn) %routinespec stop(%integer reason) !* !****** Others ****** !* %ownstring(1) snil = "" %ownstring (4) stopit = "STOP" %ownstring (3) marker = "* " !************************ !* * !* Main Program * !* * !************************ !* %on 9 %start; ! disc full etc. selectoutput(0) printstring("Disc/directory is full! ") -> abo %finish printstring("Gecgrab Running ") prompt("Address?"); readstring(address) %if address = "" %then address = "18888888888803" i = map virt(buffer manager, 6, 5) i = map virt(buffer manager, 5, 4) ask for buffer(null, send connect) %cycle p_ser = 0 poff(p) %if 'M' <= int <= 'O' %start logopt = int-'O'; int = 0 %finish %if int = 'A' %then to gatex(Disconnect, 1) %if int = '?' %start query process #if ~f monitor(null, query) #fi %finish int = 0 buffers held = buffers held + 1 %unless p_m == null handle ts packet(p_reply) %continue abo: to gatex(disconnect, 1) %repeat !********************* !* * !* Routines * !* * !********************* %routine ask for buffer(%record (mef) %name mes, %byte reason) !This routine fires off a buffer request to Buffer Manager %record (pf) p %if mes == null %start p_ser = buffer manager ;p_reply = own id p_fn = request buffer p_c = 0 ponoff(p) buffers held = buffers held+1 mes == p_m %finish #if m %if logopt < 0 %start printstring("ask for buffer, call ="); write(reason, 1); newline %finish #fi %if reason = send sft %start mes_l = 5 mes_data(0) = x'84' ;mes_data(1) = 3 ;mes_data(2) = 0 mes_data(3) = param >>8 ;mes_data(4) = param & 255 %elseif reason = send go mes_l = 3 mes_data(0) = x'82' ;mes_data(1) = 2 ;mes_data(2) = 0 %elseif reason = send er mes_l = 3 mes_data(0) = 0 ;mes_data(1) = 4 ;mes_data(2) = 0 %elseif reason = send ms mes_l = 3 mes_data(0) = 0 ;mes_data(1) = 3 ;mes_data(2) = param %else %if reason = send connect do connect(mes); %return %finish send(mes, data) %return %end ;!of Buffer Arrived %routine free buffer(%record (mef) %name mes) %record (pf) p %if mes == null %then %return ;!No buffer to free p_ser = buffer manager ;p_reply = own id p_fn = release buffer p_m == mes buffers held = buffers held - 1 stop(grotted 2) %if 0 # mes_type # 64 pon(p) %end ;!of Free Buffer %routine mon mes(%record (mef) %name mes) %integer i, j, k, n k = mes_l write(k, 1); space; space j = 0 %cycle i = 0, 1, k-1 write(mes_data(i), 1) j = j+1; %if j = 20 %then j = 0 %and newline %repeat newline; select output(0) %end %routine to gatex(%integer fn, flag) p_ser = gatex ser; p_reply = id p_fn = fn; p_s1 = flag p_gate port = gec_proc; p_task port = 1 p_m == null pon(p) #if m %if logopt < 0 %start printstring("To Gatex, call ="); write(fn, 1) printstring(", flag ="); write(flag, 1) newline %finish #fi %end %routine pack(%record(mef) %name mes, %string (*) %name s) string(addr(mes_a(mes_l))) = s mes_l = mes_l+length(s)+1 %end %routine do connect(%record (mef) %name mes) %string (3) facn %ownstring (5) wind = "W=4/4" p_ser = gatex ser; p_reply = id p_fn = Connect p_s1 = 0 p_gate port = 0; p_task port = 1 p_m == mes mes_l = 0 pack(mes, address) pack(mes, snil) pack(mes, wind) pack(mes, snil) %if logopt # 0 %start printstring("Connect to "); printstring(address) newline %finish pon(p) %end #if ~b %routine squeeze(%string (*) %name s) %integer i, j, n, c %owninteger last = 0, pos = 0 n = length(s) %for i = 1, 1, n %cycle c = charno(s, i) %if c = '0' %start last = last+1 %else select output(1) %if last # 0 %start %if last < 5 %start %for j = 1, 1, last %cycle printsymbol('0') %repeat pos = pos+last %else printsymbol('('); write(last, 1) printsymbol(')') pos = pos+5 %finish last = 0 %finish printsymbol(c); pos = pos+1 %if pos > 100 %then newline %and pos = 0 select output(0) %finish %repeat %end #fi %routine handle gec data(%record (pf) %name p) %routinespec pack(%byte char) %routinespec packhex(%integer n, places) %integer i, m, n, q, l %record (mef) %name mes mes == p_m to gatex(ack, 1); ! ack the block: NB: Disturbs P %if logopt < 0 %then printstring("From Gate ") %and mon mes(mes) %if mes_l = 0 %then free buffer(mes) %and %return %if mode = sft sent %start %if mes_data(1) = 0 %and mes_data(2) = 0 %start !Rpos rec'd ok ask for buffer(mes, send go) ;mes == null printstring("Rpos ") mode = go sent %else printstring("Rneg ") mes == null mode = idle to gatex(Disconnect, 1) %finish %elseif mode = go sent %if logopt # 0 %then printstring("SS ") mode = expect data %elseif mes_data(0) = 0 %and (mode = estb %or mode = expect data) blocks in = blocks in+1 %if mes_data(1) = 1 %start %if blocks in = 6000 %start printstring("File too large, stopping ") to Gatex(Disconnect, 0) mode = idle free buffer(mes) %return %finish param = mes_data(2) ask for buffer(mes, send ms) ;mes == null %if logopt # 0 %start printstring("MR"); write(param, 1); newline %finish #if ~b squeeze(marker) #fi mode = expect data %elseif mes_data(1) = 2 ask for buffer(mes, send er) ;mes == null printstring("ES ") mode = idle to gatex(Disconnect, 1) %else printstring("Unkn ?") write(mes_data(0), 1) ;write(mes_data(1), 1) ;write(mes_data(2), 1) ;newline %finish %elseif mode = expect data %if mes_data(0) > 127 %then mode = estb %and mes_data(0) = mes_data(0) & 127 %if dataopt = hex %start itpbuff = "" q = 1 %if length(mes_ds) # 0 %start l = length(mes_ds) back: select output(1) %for i = 1, 1, l %cycle #if ~b packhex(mes_data(q), 2) #else printsymbol(mes_data(q)) #fi q = q +1 %repeat select output(0) %if mes_l > q %then l = mes_data(q) %and q = q+1 %and -> back %finish %else itpbuff = mes_ds %finish #if ~b squeeze(itpbuff) #fi %if logopt < 0 %start %if length(itpbuff) > 70 %start %cycle i = 1, 1, length(itpbuff) printsymbol(charno(itpbuff, i)) newline %if i&63 = 0 %repeat %finish %else printstring(itpbuff) newline %finish %finish free buffer(mes) %return %routine pack(%byte char) length(itpbuff) = length(itpbuff) + 1 ;charno(itpbuff, length(itpbuff)) = char %end ;!of pack %routine packhex(%integer val, d) %integer i,j,mask %constintegerarray k(0:15) = '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' i = val>>4&15; j = val&15 pack(k(i)); pack(k(j)) %end ;!of packhex %end ;!of Handle GEC Data %routine handle ts packet(%byte ser) %record (mef) %name mes %integer gate port, task port mes == p_m task port = p_task port gate port = p_gate port #if m %if logopt < 0 %start printstring("From Gate; Fn ="); write(p_fn, 1) printstring(" flag ="); write(p_s1, 1) newline %finish #fi %if p_fn = accept call %start free buffer(mes) %unless mes == null cnsl = 0 ;mode = 0 ;gec = 0 dataopt = hex param = 0 gec_proc = gate port ask for buffer(null, send sft) mode = sft sent %elseif p_fn = data %or p_fn = control data gec_inputs = gec_inputs + 1 handle gec data(p) %elseif p_fn = disconnect free buffer(mes) %unless mes == null gec_proc = gate port %if gec_proc = 0 free buffer(pop(gec_outq)) %while gec_outq_count # 0 gec_outputs = 0 printstring("Call Disconnected "); write(p_s1, 1) newline #if ~b squeeze(stopit); select output(1); newline #else select output(1); newline #fi %stop %elseif p_fn = ack gec_outputs = gec_outputs - p_s1 %if gec_outputs > 250 %then gec_outputs = 0 %finish %return %end ;!of Handle TS packet %routine read string(%string (*) %name s) %integer i,j s = "" %cycle readsymbol(i) %return %if i = nl s = s.tostring(i) %repeat %end %routine query process %integer i,j %routinespec monside(%record (sidef) %name side) printstring("BH=") ;write(buffers held, 1) ;newline printstring("CL,IQ:") write(cnsl, 1) ;write(mode, 1) printstring(" GEC:") ;monside(gec) newline printstring("Blocks In ="); write(blocks in, 1) newline %routine monside(%record (sidef) %name side) write(side_proc, 2) write(side_state, 1) write(side_inputs, 1) write(side_outputs, 1) write(side_outq_count, 1) %end ;!of Monside (in Query Processes) %end ;!of Query Process %routine send(%record (mef) %name mes, %integer fn) %byte q %if fn = data %or fn = control data %then gec_outputs = gec_outputs + 1 p_reply = id p_fn = fn p_m == mes p_gate port = gec_proc p_task port = 1 p_ser = gatex ser %unless p_m == null %start buffers held = buffers held - 1 stop(grotted 4) %if 0 # p_m_type # 64 %finish pon(p) %return %end ;!of Send %routine stop(%integer reason) printstring("Gecgrab Stopped") ;write(reason, 1) #if ~f monitor(null, query) #fi %cycle %repeat %end ;!of Stop %endofprogram