|
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: 241152 (0x3ae00) Types: TextFile Names: »tctxt «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer └─⟦39138f30b⟧ └─⟦this⟧ »tctxt «
<****************************************************************************> <* SW8110 Terminal Access System *> <* Catalog and Operator Program 'tascat' *> <* *> <* Henning Godske 890818 *> <* A/S Regnecentralen *> <* *> <* Compiler call :tc=algol connect.no fp.yes spill.no *> <****************************************************************************> begin <****************************************************************************> <* Vedligeholdelse af katalogerne, operatør kommunikation *> <* og initialisering af systemet. *> <* *> <* Program skitse: *> <* a) Læsning af intialiserings parametre fra init fil. *> <* b) Åbning af test output filen. *> <* c) Evt. oprettelse af nye katalogfiler ud fra catalog tekst fil *> <* d) Synkronisering med menu processen herunder overførsel af init *> <* data til menu. *> <* e) Opstart af korutiner: 1) Katalog vedligeholdelse og modtagelse af *> <* message fra Menu og bruger processer. *> <* 2) Timecheck rutinen til evt. automatisk *> <* udlogning af brugerer. *> <* 3) Kontrol af afsendelse af tekster til *> <* terminaler via menu processen. *> <* 4) Operatør korutinerne. En for hver operatør *> <* der skal kunne 'køre' samtidig, dog altid *> <* en til brug for hovedkonsollen. *> <* f) Start af kerne. *> <* Besvarelse af message fra menu-processen. *> <* Besvarelse af message fra bruger-processer. *> <* Opstart af operatør rutiner. *> <****************************************************************************> <****************************************************************************> <* Revision history: *> <* *> <* 87.05.06 tascat release 1.0 *> <* 87.08.14 tascat release 1.1 ingen ændringer *> <* 88.02.25 mode parameter in type catalog added *> <* udvidet test på "Removed " (tidligere "No Connect") *> <* System start tid i displ system *> <* Nye MENU message: terminal_removed og terminal restart *> <* Terminal PDA negativ = Midlertidigt fjernet *> <* Release 1.2 OBS. Skal oversættes med algol rel. 3 *> <* 88.08.30 Tascat Release 2.0 ingen ændringer *> <* 89.02.22 NOLOGIN terminals added. Release 2.1 *> <****************************************************************************> <*******************************> <* Globale variable for tascat *> <*******************************> integer reld; <* Release datoer *> integer relt; integer initver; integer tastermverd; integer tastermvert; integer array init_file_name(1:4); <* Navnet på init filen *> integer number_of_opera; <* Antal operatør korutiner Max. 5 *> integer array opera_terms(4:8,1:2); <* Beskrivelse af opr. rutiner *> integer language; <* Sprog benyttet ved bruger udskrift*> integer cps; <* Initialiserings parametre *> integer cls; integer max_sessions; integer max_sysmenu; integer max_terminals; integer corebufs; integer mclprogs; integer termtypes; integer max_users; boolean system_stop; <* Systemet er ved at stoppe *> integer login_stat; <* Aktuel login status for terminaler*> integer fp_maxterms; <* Maxterms angivet ved kald *> integer max_terms; <* Max. terminaler inlogget *> integer terms; <* Aktuel antal terminaler inlogget *> integer users; <* Aktuel antal brugerer inlogget *> integer sessions; <* Aktuel antal sessioner *> integer max_text_count; <* Max antal udestående 'sent text' *> integer max_user_block; <* Max. antal user block før alarm *> integer max_term_block; <* Max. antal term block før alarm *> integer array text_buf_reserved(1:3); <* Text buffer reserveret *> boolean timecheck_stat; <* Status for timecheck *> integer array log_txt(0:27); <* Logout tekst for timecheck *> integer array stop_txt(0:27); integer log_time; <* Logout vente tid *> integer array host_id(0:27); <* host navn signon tekst *> integer array signon_text(0:68); <* operator signon tekst *> zone head_term_zone(14,1,konsol_error);<* Hovedkonsol output zone *> integer array head_term_name(1:4); <* Hovedkonsollens navn *> integer head_term_pda; <* Hovedkonsol pda *> integer tasterm_pda; <* Tasterm processens pda *> integer array tasterm_name(1:4); <* Tasterm processens navn *> integer own_size; <* Egen proces størrelse *> integer own_pda; <* Egen proces pda *> integer array own_name(1:4); <* Eget proces navn *> integer array prog_name(1:4); <* Programmets navn *> integer struc_size; <* Antal blokke i login_struc *> integer user_list; <* Peger til user kæden i login_struc*> integer free_list; <* Peger til free kæden i login_struc*> boolean new_catalog; <* True = nyt katalog angivet *> integer array cattxt_name(1:4); <* Navnet på katalog tekst filen *> integer array cat_doc(1:4); <* Katalogernes dokument navn *> zone cat_file(128,1,stderror); <* Zone til læsning af katalog tekst *> integer array sys_bases(1:2); <* Base par for system baser *> integer array cmcl_bases(1:2); <* Base par for cmcl filer *> zone usercat(128,1,std_error); <* Zone til user kataloget *> zone termcat(128,1,std_error); <* Zone til terminal kataloget *> zone typecat(128,1,std_error); <* Zone til terminaltype kataloget *> integer usercat_size; <* Antal segmenter i user kataloget *> integer termcat_size; <* Antal segmenter i terminal kat. *> integer typecat_size; <* Antal segmenter i terminaltype kat*> integer array field user_entry; <* Aktuelt entry i user kat. segment *> integer array field term_entry; <* Aktuelt entry i term kat. segment *> integer array field type_entry; <* Aktuelt entry i type kat. segment *> integer user_seg; <* Aktuelt seg. i zone fra user kat. *> integer term_seg; <* aktuelt seg. i zone fra term kat. *> integer user_entry_length; <* Længden af et entry i user kat. *> integer term_entry_length; <* Længden af et entry i term kat. *> integer type_entry_length; <* Længden af et entry i type kat. *> integer array usercat_name(1:4); <* Bruger katalogets fil navn *> integer array termcat_name(1:4); <* Terminal katalogets fil navn *> integer array typecat_name(1:4); <* Terminaltype katalogets fil navn *> long array opr_keywords(0:20); <* Operatør keywords i tascat *> integer opr_num_keys; <* Antal keywords defineret *> long array cat_keywords(0:60); <* Katalog keywords i tascat *> integer cat_num_keys; <* Antal keywords defineret *> long array init_keywords(0:50); <* Init keywords i tascat *> integer init_num_keys; <* Antal keywords defineret *> integer array char_table(0:255); <* Tegn input tabel *> zone copy_buf(128,1,stderror); <* Buffer til general copy *> boolean killed; <* True = stoppet ved kill *> boolean test_on; <* Status for test output *> boolean sys_start; <* Korutine system startet *> zone test_out(128,1,test_out_error);<* Zone til output af test records *> integer array testout_name(1:4); <* Navnet på testout filen *> integer trace_type; <* Typen af den trace der foretages *> integer test_select; <* Typen af test fra aktiviteter *> integer run_alarm_cause; <* Cause ved alarm (trap) *> integer run_alarm_pos; <* procedure nr ved alarm *> integer free_sem; <* Semafor -4 *> integer delay_sem; <* Semafor -3 *> integer wait_answer_pool; <* Semafor -2 *> integer wait_message; <* Semafor -1 *> integer wait_message_pool; <* Semafor 0 *> integer message_buf_pool; <* Semafor 1 *> integer time_sem; <* Semafor 2 *> integer struc_sema; <* Semafor 3 *> integer text_write_sem; <* Semafor 4 *> real t_n_l,miss_par,u_n_l,ill_val, <* konstant tekster *> ill_par,long_text,ill_time, <* *> c_p ; integer array answer(1:9); <* Answer til modtaget mess *> integer array mess(1:1); <* Reference til message *> integer field sender_pda; <* Sender pda i mess *> integer field reciever_pda; <* Modtager pda i mess *> integer field buf_addr; <* Buffer adresse på mess *> integer array field mess_array; <* Message *> real start_time; <* Start time for Tas *> long array field laf; <* work *> integer array field iaf; <* work *> boolean array field baf; <* work *> integer i; <* work *> <*********************************************************> <* Procedure til afhjælpelse af fejl i externe procedure *> <*********************************************************> integer procedure put_ch(dest,pos,char,rep); long array dest; integer pos,char,rep; begin trap(local); put_ch:=putchar(dest,pos,char,rep); if false then local: put_ch:=-1; end; integer procedure put_txt(dest,pos,text,length); long array dest,text; integer pos,length; begin trap(local); put_txt:=puttext(dest,pos,text,length); if false then local: put_txt:=-1; end; <*******************************************> <* Generelle hjælpe procedure til TASCAT *> <*******************************************> procedure claim(words); <* 1 *> <*------------------------------------------------------*> <* Reserver et antal ord på stakken *> <* *> <* words (call) : Antal ord der reserveres på stakken *> <*------------------------------------------------------*> integer words; begin integer array x(1:words); end; integer procedure send_mess(z,mess); <* 4 *> <*--------------------------------------------------------------------*> <* z (call and return) : Zone åbnet med navnet på den proces der skal *> <* sendes til. Share 1 benyttes til message og *> <* sharestate skal være 0 el. 1. Ved retur er *> <* sharestate lig message buffer adresse. *> <* mess (call) : Integer array(1:8) indeholdede message *> <* Return : Message buffer adresse *> <* Der udføres TRAP hvis message buffer claim *> <* er overskredet *> <*--------------------------------------------------------------------*> zone z; integer array mess; begin integer array share(1:12); integer buf_addr,i; trap(alarm); getshare6(z,share,1); for i:=1 step 1 until 8 do share(i+3):=mess(i); setshare6(z,share,1); buf_addr:=monitor(16,z,1,share <* dummy ia *>); if buf_addr=0 then write_message(4,1,false,<:claims exceeded:>); send_mess:=buf_addr; if false then alarm: disable traped(4); end; boolean procedure wait_ans(z,mess_addr,time,wait_sem,regret); <* 5 *> <*---------------------------------------------------------------------*> <* z (call and return) : Zone der blev benyttet ved send_mess *> <* Ved retur er sharestate lig 0 *> <* mess_addr (call) : Adressen på message buffer fra send_mess. *> <* time (call) : Tiden der skal ventes inden message fortrydes *> <* sættes tiden 0 ventes uendeligt *> <* wait_sem (call) : Semafor der benyttes til at vente på answer *> <* regret (call) : True = regret message ved time-out *> <* Return : True= answer modtaget; False=Time out *> <* Ved time out fortrydes den sendte message *> <*---------------------------------------------------------------------*> zone z; integer mess_addr,time,wait_sem; boolean regret; begin integer array answer(1:1),ia(1:1); trap(alarm); initref(answer); wait_select:=6; wait(message_buf_pool,answer); answer(2):=mess_addr; answer(3):=wait_sem; signal(wait_answer_pool,answer); wait_ans:=true; wait_time:=time; if wait(wait_sem,answer)=0 then begin <* time out *> wait_ans:=false; wait_select:=mess_addr; wait(wait_answer_pool,answer); if regret then monitor(82<* regret message *>,z,1,ia<* dummy *>); end; answer(2):=6; signal(message_buf_pool,answer); if false then alarm: disable traped(5); end; procedure write_message(from,result,cont,mess); <* 6 *> <*------------------------------------------------------------*> <* Udskriver meddelelse på hovedkonsol og danner test-record *> <* *> <* from (call) : Angiver hvorfra meddelensen kommer *> <* result (call) : Angiver årsagen eller resultat til mes. *> <* cont (call) : True= returner efter udskrift *> <* False= Afbryd kørslen med trap(from) *> <* mess (call) : Selve meddelelsen *> <*------------------------------------------------------------*> integer from,result; boolean cont; string mess; begin real time; trap(alarm); if sys_start and test_on then begin prepare_test; test_out.iaf(1):=1030; <* message *> test_out.iaf(2):=abs from; test_out.iaf(3):=result; end; if (false add (trace_type shift (-1))) or from>=0 then begin open(head_term_zone,8,head_term_name,1 shift 9); write(head_term_zone,<:Tas message : :>); outdate(head_term_zone,round systime(5,0,time)); write(head_term_zone,<: :>); outdate(head_term_zone,round time); write(head_term_zone,<: :>,true,30,mess,<<-dddddd>, <: :>,result, <:.:>,<<zddddd>,abs from,<:<10>:>); close(head_term_zone,false); end; if not cont then trap(from); if false then alarm: disable traped(6); end; procedure traped(procedure_nr); <* 7 *> <*--------------------------------------------------------------------*> <* procedure_nr (call) : Nummeret på den procedure hvori kaldet står *> <* *> <* Der dannes test records til beskrivelse af *> <* årsagen til trap'et. Der efter fortsætte til *> <* de næste ydre trap niveau. På yderste niveau *> <* afbrydes programmet *> <*--------------------------------------------------------------------*> value procedure_nr; integer procedure_nr; begin integer i,cause; integer array ia(1:8); trap(alarm); cause:=alarmcause extract 24; if run_alarm_pos=0 and cause<>-13 then begin run_alarm_cause:=cause; run_alarm_pos:=procedure_nr; end; if cause=-9 and (alarmcause shift (-24))=8 then killed:=true; if sys_start and test_on then begin prepare_test; test_out.iaf(2):=procedure_nr; test_out.iaf(3):=alarmcause shift (-24) extract 24; test_out.iaf(4):=cause; if cause=-13 then test_out.iaf(1):=1028 <* Cont *> else if cause=-11 then begin <* Give up *> test_out.iaf(1):=1026; <* give up 1 *> test_out.iaf(5):=getalarm(ia); prepare_test; test_out.iaf(1):=1027; <* give up 2 *> for i:=2 step 1 until 5 do test_out.iaf(i):=ia(i+3); end else test_out.iaf(1):=1025;<* Trap *> end; if false then alarm: procedure_nr:=(alarmcause extract 24)-100; trap(0); trap(procedure_nr); end; procedure trace(p1,p2,p3,p4); <* 8 *> <*----------------------------------------------------------------------*> <* p1 til p4 (call) : Integer parametre der skrives i trace test record *> <*----------------------------------------------------------------------*> integer p1,p2,p3,p4; begin if sys_start and test_on then begin prepare_test; test_out.iaf(1):=1029; <* trace *> test_out.iaf(2):=p1; test_out.iaf(3):=p2; test_out.iaf(4):=p3; test_out.iaf(5):=p4; end; end; procedure close_test_out; <* 9 *> <*---------------------------------------*> <* Luk test_out filen hvis det er muligt *> <*---------------------------------------*> begin if sys_start and test_on then begin write_message(-9,select_test,true,<:Test output stopped:>); <* Udskriv stop record *> prepare_test; close(test_out,true); end; select_test:=0; test_on:=false; end; procedure open_test(name); <* 10 *> <*----------------------------------------------------------------------*> <* Åben test filen hvis det er muligt og tilladt. *> <* *> <* name (call) : Navnet på det dokument der skal benyttes som test out *> <* *> <*----------------------------------------------------------------------*> integer array name; begin integer array tail(1:10); integer i,stop_result; trap(alarm); stop_result:=0; if test_on then begin set_cat_bases(sys_bases); test_on:=false; open(test_out,4,name,1 shift 18 <* end document *>); if monitor(42<* lookup entry *>,test_out,0,tail)<>0 then stop_result:=1 else if tail(1)<2 then stop_result:=2 else begin tail(6):=systime(7,0,0.0); i:=monitor(44,test_out,0,tail); i:=monitor(52,test_out,0,tail)+i; i:=monitor(08,test_out,0,tail)+i; if i<>0 then stop_result:=3; end; if stop_result=0 then begin <* initialiser test_out segmenterne *> outrec6(test_out,512); for i:=1 step 1 until 128 do test_out(i):=real <::>; for i:=2 step 1 until tail(1) do outrec6(test_out,512); setposition(test_out,0,0); write_message(-10,tail(1),true,<:Test output started:>); test_on:=true; end else begin test_on:=false; write_message(10,stop_result,true,<:Error in test out file:>); end; end; if not test_on then close_test_out; if false then alarm: disable traped(10); end; procedure test_out_error(z,s,b); <* 11 *> <*-----------------------------------*> <* blok procedure for test_out zonen *> <*-----------------------------------*> zone z; integer s,b; begin integer array ia(1:20); trap(alarm); if false add (s shift (-18)) then begin <* EOF Skift tilbage til segment 1 *> getzone6(test_out,ia); ia(9):=2; setzone6(test_out,ia); getshare6(test_out,ia,1); ia(7):=1; setshare6(test_out,ia,1); monitor(16,test_out,1,ia); check(test_out); b:=512; end else close_test_out; if false then alarm: disable traped(11); end; boolean procedure set_cat_bases(bases); <* 12 *> <*--------------------------------------*> <* Sæt cat baserne til angivet base-par *> <* *> <* bases(1) : Nedre base værdi. *> <* bases(2) : Øvre base værdi. *> <* Return : True= baser sat *> <* False= baser IKKE sat *> <*--------------------------------------*> integer array bases; begin zone this_proc(1,1,stderror); trap(alarm); open(this_proc,0,<::>,0); set_cat_bases:= monitor(72<* set catalog base *>,this_proc,0,bases)=0; if false then alarm: disable traped(12); end; integer procedure get_pda(name); <* 13 *> <*-----------------------------------------------------------------*> <* Hent pda for angivet proces *> <* *> <* name (call) : Navnet på processen som pda skal findes for *> <* Return : pda for proces hvis den findes ellers 0 *> <*-----------------------------------------------------------------*> integer array name; begin integer array ia(1:20); integer i; zone proc(1,1,stderror); trap(open_trap); getzone6(proc,ia); for i:=1,2,3,4 do ia(i+1):=name(i); setzone6(proc,ia); get_pda:=monitor(4,proc,0,ia); if false then open_trap: get_pda:=0; end; boolean procedure get_proc_name(pda,name); <* 14 *> <*---------------------------------------------------------------------*> <* Hent navnet på processen udpeget af proces beskriver adressen i pda *> <* *> <* pda (call) : Proces beskriver adressen *> <* name (ret) : Navn på proces i integer array name(1:4) *> <* Return : True = navn fundet *> <* False = navn IKKE fundet *> <*---------------------------------------------------------------------*> integer pda; integer array name; begin integer array ia(1:20),bases(1:2); integer lt,i; boolean ok; zone proc(1,1,stderror); trap(alarm); lt:=trapmode; trapmode:=-1; ok:=system(5,pda+2,name)=1; trap(open_trap); getzone6(proc,ia); for i:=1,2,3,4 do ia(i+1):=name(i); setzone6(proc,ia); ok:=ok and monitor(4,proc,0,ia)=pda; if false then open_trap: ok:=false; get_proc_name:=ok; if not ok then begin if pda < 0 then movestring(name.laf,1,<:No Connect:>) else movestring(name.laf,1,<:Removed :>); end; trapmode:=lt; if false then alarm: disable traped(14); end; integer procedure cur_time; <* 15 *> <*-------------------------------------------*> <* Find den aktuelle tid *> <* *> <* Return : Aktuelle tid i hel time (0-23) *> <*-------------------------------------------*> begin real time; trap(alarm); systime(5,0,time); cur_time:=round(time)//10000; if false then alarm: disable traped(15); end; integer procedure date(text); <* 16 *> <*-----------------------------------------------------------------------*> <* Dan dags dato som tekst med følgende format: *> <* <dags navn> d.<dag>/<måned> 19<år> <time>.<minut> *> <* *> <* text (ret) : Long array indeholdende dags dato som tekst *> <* Array'ets første 6 longs benyttes (36 tegn) *> <* Return : Antal tegn sat i text *> <*-----------------------------------------------------------------------*> long array text; begin real time,year,hour; integer day,pos; trap(alarm); systime(1,0,time); day:=(round((time/86400)-0.5) mod 7)+1; pos:=1; text(5):=text(6):=0; case language of begin put_text(text,pos,case day of (<:Mandag :>,<:Tirsdag:>, <:Onsdag :>,<:Torsdag:>, <:Fredag :>,<:Lørdag :>, <:Søndag :>) ,7); put_text(text,pos,case day of (<:Monday :>,<:Tuesday :>, <:Wedensday:>,<:Thursday :>, <:Friday :>,<:Saturday :>, <:Sunday :>) ,9); end; put_text(text,pos,<: d.:>,3); year:=systime(4,time,hour); put_number(text,pos,<<zd>,round(year) mod 100); put_text(text,pos,<:/:>,1); put_number(text,pos,<<zd >,(round(year) mod 10000)//100); put_text(text,pos,<:19:>,2); put_number(text,pos,<<zd >,round(year)//10000); put_number(text,pos,<<dd>,round(hour)//10000); put_text(text,pos,<:.:>,1); put_number(text,pos,<<zd>,(round(hour) mod 10000)//100); date:=pos-1; if false then alarm: disable traped(16); end; integer procedure data_to_copy_buf(words,mess_addr,answer); <* 17 *> <*------------------------------------------------------------------------*> <* Kopier data fra anden proces til copy_buf. *> <* *> <* words (call) : Antal ord der kopieres (max. 256) *> <* mess_addr (call) : Adressen på message der udpeger område der skal *> <* kopieres fra (2 og 3 ord i message: first,last) *> <* answer (ret) : Resultatet af kopieringen: *> <* answer(1) : Udefineret. *> <* answer(2) : Antal HW overført *> <* answer(3) : Antal tegn overført *> <* answer(9) : Hvis returværdi lig 3 så 3 ellers 1 *> <* Return : 0 = Data kopieret til copy_buf. *> <* 2 = Anden proces stoppet. *> <* 3 = Fejl i kopieringen m.m *> <*------------------------------------------------------------------------*> integer mess_addr,words; integer array answer; begin trap(alarm); answer(1):=2 shift 1 + 0; answer(2):=2; answer(3):=2*words; answer(4):=0; data_to_copy_buf:=monitor(84,copy_buf,mess_addr,answer); answer(3):=3*(answer(2)//2); if false then begin alarm: answer(9):=3; data_to_copy_buf:=3; end; end; integer procedure data_from_copy_buf(words,mess_addr,answer); <* 18 *> <*------------------------------------------------------------------------*> <* Kopier data til anden proces fra copy_buf. *> <* *> <* words (call) : Antal ord der kopieres (max. 256) *> <* mess_addr (call) : Adressen på message der udpeger område der skal *> <* kopieres til (2 og 3 ord i message: first,last) *> <* answer (ret) : Resultatet af kopieringen: *> <* answer(1) : Udefineret. *> <* answer(2) : Antal HW overført *> <* answer(3) : Antal tegn overført *> <* answer(9) : Hvis returværdi lig 3 så 3 ellers 1 *> <* Return : 0 = Data kopieret til anden proces *> <* 2 = Anden proces stoppet. *> <* 3 = Fejl i kopieringen m.m *> <*------------------------------------------------------------------------*> integer mess_addr,words; integer array answer; begin trap(alarm); answer(1):=2 shift 1 + 1; answer(2):=2; answer(3):=2*words; answer(4):=0; data_from_copy_buf:=monitor(84,copy_buf,mess_addr,answer); answer(3):=3*(answer(2)//2); if false then begin alarm: answer(9):=3; data_from_copy_buf:=3; end; end; procedure init_sem; <* 19 *> <*----------------------------------------------------*> <* initialiser semafor navnene med nummer *> <* Semafor 5 og frem benyttes af operatør korutinerne *> <*----------------------------------------------------*> begin free_sem:=-4; <* Semafor -4 *> delay_sem:=-3; <* Semafor -3 *> wait_answer_pool:=-2; <* Semafor -2 *> wait_message:=-1; <* Semafor -1 *> wait_message_pool:=0; <* Semafor 0 *> message_buf_pool:=1; <* Semafor 1 *> time_sem:=2; <* Semafor 2 *> struc_sema:=3; <* Semafor 3 *> text_write_sem:=4; <* Semafor 4 *> end; procedure konsol_error(z,s,b); <* 20 *> <*----------------------------------------------------*> <* Block procedure for hoved_konsollen *> <* Ignorer alle error og give up *> <*----------------------------------------------------*> zone z; integer s,b; begin end; procedure init_bases; <* 22 *> <*----------------------------------------------------*> <* Check om mcl baser og sys baser kan benyttes *> <* Sæt catalog baser til sys_bases *> <*----------------------------------------------------*> begin integer array bases(1:6); integer b; trap(alarm); own_pda:=system(6,0,own_name.laf); if system(5,own_pda+68,bases)<>1 then trap(2); b:=0; if not set_cat_bases(cmcl_bases) then b:=1; if not set_cat_bases(sys_bases) then b:=2; if b<>0 then write_message(22,b,false,<:Illegal base parameter:>); if false then alarm: disable traped(22); end; procedure keywords_init; <* 23 *> <*-------------------------------------------*> <* initialiser keywords *> <*-------------------------------------------*> begin integer i; opr_num_keys:=20; for i:=1 step 1 until opr_num_keys do begin opr_keywords(i):=0; opr_keywords(i):= long (case i of <* 1 *> (<:finis:>,<:displ:>,<:messa:>,<:remov:>,<:set:>, <* 6 *> <:start:>,<:stop:>,<:termi:>,<:user:>,<:on:>, <* 11 *> <:off:>,<:all:>,<:signo:>,<:sessi:>,<:syste:>, <* 16 *> <:login:>,<:timec:>,<:users:>,<:resou:>,<:check:>)); end; cat_num_keys:=51; for i:=1 step 1 until cat_num_keys do begin cat_keywords(i):=0; cat_keywords(i):= long (case i of <* 1 *> (<:end:>,<:size:>,<:user:>,<:passw:>,<:cpass:>, <* 6 *> <:monda:>,<:tuesd:>,<:wedne:>,<:thurs:>,<:frida:>, <* 11 *> <:satur:>,<:sunda:>,<:block:>,<:sessi:>,<:privi:>, <* 16 *> <:mclna:>,<:base:>,<:group:>,<:mclte:>,<:freet:>, <* 21 *> <:termi:>,<:termt:>,<:termg:>,<:bypas:>,<:type:>, <* 26 *> <:scree:>,<:colum:>,<:lines:>,<:sbup:>,<:sbdow:>, <* 31 *> <:sblef:>,<:sbrig:>,<:sbhom:>,<:sbdel:>,<:ceod:>, <* 36 *> <:ceol:>,<:invon:>,<:invof:>,<:hlon:>,<:hloff:>, <* 41 *> <:delet:>,<:inser:>,<:curso:>,<:up:>,<:down:>, <* 46 *> <:left:>,<:right:>,<:home:>,<:mode:>,<:init:>, <* 51 *> <:nolog:>)); end; init_num_keys:=46; for i:=1 step 1 until init_num_keys do begin init_keywords(i):=0; init_keywords(i):= long (case i of <* 1 *> (<:true:>,<:false:>,<:on:>,<:off:>,<:start:>, <* 6 *> <:stop:>,<:catal:>,<:termi:>,<:init:>,<:catdo:>, <* 11 *> <:userc:>,<:termc:>,<:typec:>,<:ctnam:>,<:spool:>, <* 16 *> <:ttnam:>,<:temna:>,<:login:>,<:userb:>,<:termb:>, <* 21 *> <:timec:>,<:logti:>,<:mclba:>,<:sysba:>,<:cpool:>, <* 26 *> <:clink:>,<:maxse:>,<:maxte:>,<:maxsy:>,<:coreb:>, <* 31 *> <:mclpr:>,<:maxty:>,<:tbufs:>,<:spseg:>,<:maxus:>, <* 36 *> <:maxop:>,<:timeo:>,<:hosti:>,<:signo:>,<:timet:>, <* 41 *> <:stopt:>,<:catte:>,<:trap:>,<:termt:>,<:initv:>, <* 46 *> <:reser:>)); end; end; integer procedure find_keyword_value(keyword,tabel); <* 24 *> <*----------------------------------------------------------------*> <* Find 'token' værdien for det angivne keyword *> <* *> <* keyword (call) : Long indeholdende op til 5 tegn af keyword *> <* tabel (call) : 1=opr 2=cat 3=init keword-tabel *> <* Return : Værdien for det angivne keyword eller *> <* 0 hvis keyword er ukendt *> <*----------------------------------------------------------------*> long keyword; integer tabel; begin integer i; trap(alarm); i:=case tabel of (opr_num_keys,cat_num_keys,init_num_keys)+1; keyword:=(keyword shift (-8)) shift 8; case tabel of begin for i:=i-1 while (not (keyword=opr_keywords(i)) and (i<>0)) do; <* nothing *> for i:=i-1 while (not (keyword=cat_keywords(i)) and (i<>0)) do; <* nothing *> for i:=i-1 while (not (keyword=init_keywords(i)) and (i<>0)) do; <* nothing *> end; find_keyword_value:=i; if false then alarm: disable traped(24); end; procedure init_opera_terms; <* 25 *> <*----------------------------------------------------*> <* init opera_terms array'et *> <*----------------------------------------------------*> begin integer i; trap(alarm); for i:=4 step 1 until number_of_opera+3 do begin opera_terms(i,1):=0; opera_terms(i,2):=i+2 end; if false then alarm: disable traped(25); end; procedure next_line(z,z_line_nr); <* 26 *> <*-------------------------------------------------------*> <* Læs til starten af næste linie i fil *> <* Linier der starter med ; eller er blanke overspringes *> <* Linie tæller optælles med 1 for hver linie *> <* *> <* z (call) : Fil der læses fra. *> <* z_line_nr (call and ret) : Linie tæller for fil, *> <*-------------------------------------------------------*> zone z; integer z_line_nr; begin integer i; trap(alarm); repeatchar(z); readchar(z,i); while (i<>'nl') and (i<>'em') do readchar(z,i); z_line_nr:=z_line_nr+1; readchar(z,i); if i<>'em' then begin while i=' ' do readchar(z,i); if i='nl' or i='em' or i=';' then begin next_line(z,z_line_nr); readchar(z,i); end; end; repeatchar(z); if false then alarm: disable traped(26); end; integer procedure read_start_key(z,t,z_line_nr); <* 27 *> <*-------------------------------------------------------------------*> <* Find værdien af nøgleordet i starten af tekst linien i fil *> <* *> <* z (call) : Filen der læses fra *> <* t (call) : Keyword tabel. 1=opr 2=cat 3=init *> <* Return : -1 = Sidste linie i fil er læst *> <* 0 = Nøgleord er ikke fundet *> <* >0 = Nøgleordets værdi *> <*-------------------------------------------------------------------*> zone z; integer t,z_line_nr; begin long array key(1:5); integer i; trap(alarm); readchar(z,i); if i<>'em' then begin while i=' ' do readchar(z,i); if i='nl' or i='em' or i=';' then begin next_line(z,z_line_nr); readchar(z,i); end; end; repeatchar(z); read_start_key:=if readstring(z,key,1)>0 then find_keyword_value(key(1),t) else -1; repeatchar(z); if false then alarm: disable traped(27); end; integer procedure read_text(z,text,max); <* 28 *> <*---------------------------------------------------------------------*> <* Læs tekst fra z filen til text til slutning af linie eller til *> <* maximalt antal tegn læst. Indledende blanktegn overspringes. *> <* *> <* z (call) : File der læses fra *> <* text (ret) : Den læste tekst *> <* max (call) : Det maximale antal tegn der læses *> <* Return : Antal tegn læst til text *> <* *> <* NB. Der læses altid et tegn mere fra z *> <*---------------------------------------------------------------------*> zone z; integer max; long array text; begin integer ch,pos; boolean first; trap(alarm); pos:=1; first:=true; repeatchar(z); readchar(z,ch); if (ch<>'nl') and (ch<>'em') then begin readchar(z,ch); while ch<>'nl' and ch<>'em' and pos<=max do begin if first and (ch<>' ') then first:=false; if not first then put_ch(text,pos,ch,1); readchar(z,ch); end; end; read_text:=pos-1; if pos<=max then put_ch(text,pos,0,1); repeatchar(z); if false then alarm: disable traped(28); end; boolean procedure read_nr(z,nr); <* 29 *> <*-----------------------------------------------------------------*> <* Læs et heltal fra fil z. Er der ikke flere tal på linien *> <* returneres -1 ellers det læste tal. Er der angivet ulovligt *> <* tal (eller andet end tal) sættes read_nr til false *> <* *> <* z (call) : Zonen der læses fra *> <* nr (ret) : Læst tal eller -1 hvis ikke flere tal *> <* Return : True = ok False = illegalt tal *> <*-----------------------------------------------------------------*> zone z; integer nr; begin integer ch,class; trap(alarm); read_nr:=true; repeat class:=readchar(z,ch); until class<>7 or ch=';' ; if ch=';' or class=8 then nr:=-1 else if class<2 or class>3 then begin nr:=-1; read_nr:=false; end else begin repeatchar(z); read(z,nr); end; repeatchar(z); if false then alarm: disable traped(29); end; boolean procedure read_name(z,name,ok); <* 30 *> <*---------------------------------------------------------------------*> <* Læs et navn fra filen z til name. Resterende tegn nulstilles *> <* Indledende blanktegn overspringes. Der stoppes ved kommentar *> <* *> <* z (call) : File der læses fra *> <* name (ret) : Det læste navn i integer array name(0:3) *> <* ok (ret) : True hvis første tegn er et bogstav *> <* NB. Der læses altid et tegn mere fra z *> <*---------------------------------------------------------------------*> zone z; integer array name; boolean ok; begin integer ch,pos; long array field laf; trap(alarm); for pos:=0,1,2,3 do name(pos):=0; pos:=1; laf:=-2; repeatchar(z); readchar(z,ch); while ch=' ' do readchar(z,ch); ok:=(ch>='a' and ch<='å'); while ((ch>='0' and ch<='9') or (ch>='a' and ch<='å')) and pos<=11 do begin put_ch(name.laf,pos,ch,1); readchar(z,ch); end; repeatchar(z); read_name:=not name(0)=0; if false then alarm: disable traped(30); end; procedure open_catalogs(usercat_name,termcat_name,typecat_name); <* 31 *> <*-----------------------------------------------------------------*> <* Åben kataloger og undersøg om disse er ok og kan bruges til i/o *> <* sæt size og length for hvert katalog *> <* Er newcat=true dannes nye kataloger ud fra teksten i cat_file. *> <* cat_doc angiver navnet på dokument hvorpå katalogerne lægges. *> <* *> <* usercat_name, *> <* termcat_name, *> <* typecat_name (call) : Navnene på katalogerne *> <*-----------------------------------------------------------------*> integer array usercat_name,termcat_name,typecat_name; begin integer array user_tail,term_tail,type_tail(1:10); integer reason,cat_line_nr; long array start_key(1:47); <*--------------------------------------------------------------------------*> <* ******************* Katalog indholds beskrivelse ********************** *> <* Bruger katalog (user catalog) : Indeholder i hver indgang oplysninger om en bruger, der har ad- gang til RC8000 via menu-systemet. Hvert segment pånær det første i user catalog indeholder 4 indgange. Indgangene sorteres i de enkelte segmenter efter deres hash nøgle således at nøglens værdi svarer til segmentets nummer. Segmentnummer = hash nøgle Første ord i hvert segment indeholder hash nøgle tælleren. Denne angiver den samlede antal indgange i hele kataloget, der har hash nøgle svarende til segments nummer. Format af første segment i bruger kataloget : +0 : 1 ; User catalog +2 : Catalog size (segments inc. segment 0) +4 : Entry length i hw's for a user entry. +8 : Generate date (short time) +10 : Not used +254: - - Bruger indgang format : +0 : Hash key (0 = empty entry) +2 : User id (key) +10 : Password +14 : Login time limits: Monday +15 : Tuesday +16 : Wednesday +17 : Thursday +18 : Friday +19 : Saturday +20 : Sunday +21 : User block count +22 : Max. user index +23 : Privilege +24 : MCL program name +32 : User MCL bases (lower, upper) +36 : Terminal group limit (bit map) +44 : MCL default variable text (mcl-text format) +100: Free text (30 char) +120: Time stamp +122: Not used +124: - - Et segment indeholder (bortset fra segment 0): +0 : Hash nøgle tæller +2 : Entry 0 +128: Entry 1 +254: Entry 2 +380: Entry 3 +506: not used +510: - - Hash nøgel : Hash nøglen beregnes ved: Summen af de 4 integer der indgår i user id teksten beregnes til S. Hash key = 1+((ABS S) mod (n-1)) hvor n er antallet af segmenter i kataloget (seg. 0 til seg. n-1). User id: Bruger navn. Fra 1 til 11 tegn afsluttet med nul-tegn. Kan kun indgå i en indgang i brugerkataloget. (Nøgle) Password: Kryptograferet løsen (metode se ??). Værdien nul angiver at der intet løsen er tilknyttet denne indgang. Login time limits: Angiver for hver dag i ugen det tidsrum, hvor indlogning for bru- geren er tilladt. Angives som første tidspunkt og sidste tidspunkt i hele timer (0- 24). Sidste tidspunkt er det klokkeslet, hvor brugeren bliver logget ud. Dagen og første tid er sammenhørende. Er aktuel tid (A) mindre end første tid (F) prøves med dagen før, der da skal være af type 2. Hvis aktuel tid her er mindre end sidste tid (S) gives adgang. Ellers skal gælde: ( F<S and A>=F and A<S ) or ( F>S and ( 24>A>=F or 0<=A<S )) og typen skal være 1, 2 eller 3. Hver dag beskrives i 1 HW ved: F<7 + S<2 + type Hvor type er: 0 = Ingen adgang denne dag. 1 = Første tid mindre end sidste tid. 2 = Første tid større end sidste tid. 3 = Adgang hele dagen (0 til 24). User block count: Angiver antal gange (i træk), der er førsøgt refereret til denne indgang med forkert password. Værdien nulstilles ved korrekt reference, hvis grænsen ikke er nået. Max. user index: Angiver det maximale antal sessioner en bruger må have samtidig (ved en eller flerer terminaler). Værdien skal ligge mellem 1 og 12 ink. Privilege: Brugerens privilegier er beskrevet i dette felt. Bit: 0 = Menu-system control 1 = Catalog update/list 2 = MCL control 3 = Message control 4 = List control MCL program name: Navnet på det oversatte MCL-program, der skal udføres ved start af en session. User MCL bases: Det base-interval, hvorpå der ledes efter et MCL-program, hvis det ikke er kendt af menu-systemet. Første værdi er nedre base, anden værdi er øvre base. Terminal group limit: Angiver hvilke terminalgrupper, der må benyttes af brugeren. En bruger kan benytte terminaler i en eller flerer af grupperne 0 til 95. Angivet som bitmap, hvor bit 0 sat angiver at bruger må benytte terminaler fra terminalgruppe 0, bit 1 fra terminalgruppe 1 o.s.v. MCL default variable text: Tekst der overføres til variabel (T) i MCL ved start af session. Format som ved CMCL-text. Free text: Fri tekst til f.eks at beskrive brugeren (Navn m.m). Der kan angives op til 30 tegn efterfulgt af nul-tegn. Time stamp: Tidsangivelse (access tæller ), der sættes når nyt indhold sættes i entry. Benyttes til at kontrolerer gyldigheden af læst data ved senere rettelse. Terminal katalog (terminal catalog) Indeholder i hver indgang en beskrivelse af en terminal, der er tilsluttet via menu-systemet. Hvert segment i terminal catalog pånær segment 0 indeholder 14 indgange. Indgangene sorteres i de enkelte segmenter efter deres hash nøglesåledes at nøglens værdi svarer til segmentets nummer. Segmentnummer = hash nøgle Første ord i hvert segment indeholder hash nøgle tælleren. Denne angiver den samlede antal indgange i hele kataloget der har hash key svarende til segments nummer. Format af første segment i terminal kataloget +0 : 2 ; Terminal catalog +2 : Catalog size (segments inc. segment 0) +4 : Entry length i hw's for a terminal entry. +8 : Generate date (short time) +10 : Not used +254: - - Terminal katalog format +0 : Hash key (0 = empty entry) +2 : Terminal name +10 : Terminal type +11 : Terminal block count +12 : Nologin < 1 + Bypass +13 : Terminal group +14 : Free text (30 char.) +34 : Time stamp Segment indhold: +0 : Hashnøgle tæller +2 : Entry 0 +38 : Entry 1 +74 : Entry 2 . . +470: Entry 13 +506: not used +510: - - Hash nøgle: Hash nøglen beregnes ved: Summen af de 4 integer der indgår i user id teksten beregnes til S. Hash key = 1+((ABS S) mod (n-1)) hvor n er antallet af segmenter i kataloget (seg. 0 til seg. n-1). Terminal name: Navnet på den externe proces, der er tilknyttet terminalen i samme format som proces beskriverens navnefelt. Terminal type: Tal der refererer til beskrivelsen af terminalens type i ter- minaltype kataloget. Typen skal ligge mellem 1 og antal af segmenter i terminaltype kataloget gange 4. Terminal block count: Angiver antal gange (i træk), der er forsøgt indlogning fra denne terminal uden at korrekt 'userid' er opgivet. Værdien nulstilles ved korrekt indlogning, hvis den ikke har nået grænsen. Bypass: Angiver om terminalen skal gå uden om menu systemet ved oprettelse af link. 0 = No bypass, 1 = Bypass. Nologin: Angiver om TAS skal oprette et link for terminalen ved opstart. 0 = No link, 1-99 = LAN number to use (lanmainxx) Terminal group: Angiver hvilken gruppe (en ud af grupperne 0 til 95) terminalen indgår i. Free text: Fri tekst til f.eks at beskrive terminalens fysiske placering. Der kan angives op til 30 tegn. Time stamp: Tidsangivelse der sættes når nyt indhold sættes i entry. Benyttes til at kontrolerer gyldigheden af læst data ved senere rettelse. Terminal type katalog Indeholder i hver indgang beskrivelse af en bestem type terminals funktioner. Kataloget indeholder 4 indgange per segment. En indgang findes ved at benytte typen som index. segment = ((type-1) div 4)+1. indgang i segment = 128*((type-1) mod 4) Format af første segment i terminaltype kataloget +0 : 3 ; Terminal type catalog +2 : Catalog size (segments inc. segment 0) +4 : Entry length i hw's for a type entry. +8 : Generate date (short time) +10 : Not used +254: - - Terminaltype indgang format +0 : Terminal type (0= empty entry) +2 : Screen type (set of values 0 to 11) +3 : Mode (set term. spec. mode) +4 : Number of colums on line +5 : Number of lines on display +6 : Send by CURSOR UP key +7 : Send by CURSOR DOWN key +8 : Send by CURSOR LEFT key +9 : Send by CURSOR RIGHT key +10 : Send by HOME key +11 : Send by DELETE key +12 : Clear to end of display seq. +16 : Clear to end of line seq. +20 : Invers on seq. +24 : Invers off seq. +28 : High light on seq. +32 : High light off seq. +36 : Delete line seq. (move succeeding lines up) +40 : Insert line seq. (move lines down) +44 : Cursor addressing seq. +50 : Cursor up char. +51 : Cursor down char. +52 : Cursor left char. +53 : Cursor right char. +54 : Cursor home char. +55 : +56 : Init. terminal (75 char.) +106: Free text (30 char.) +126: Time stamp Format af data. Send by (sb) værdierne angiver værdien af det tegn, der sendes af den pågældende tast. Sekvenserne (seq.) kan bestå af op til 6 tegn. Ikke benyttede tegn sættes til 0. Er første tegn et 0 er den pågældende funktion ikke tilgænglig på terminalen. Initialiserings sekvensen kan sendes til terminalen ved f.eks opstart. Sekevensen kan f.eks være initialisering af funktions tasterne. Der kan angives op til 30 tegn. Ikke benyttede tegn sættes til 0. Screen type Angiver hvilke karekteristika den enkelte skærmtype har. Bit: 0 = Terminal is a hardcopy (paper) terminal. 1 = Scroll when 'nl' on the last line 2 = Scroll when write in then last character on the screen 3 = . . 11 = Cursor addressing seq.: Sekvensen består af op til 7 skrivbare tegn samt to positions- tegn. Positions-tegnene står på de steder i sekvensen, hvor cursor-positions værdierne skal sendes. Positions tegnene er opbygget som: (pos. er positionsværdi ved adresseringen) bit: værdi: (bit 0 er MSB) 0 1 = Positionstegn markering sammen med bit 1 ellers kontroltegn med MSB sat. 0 = Andet tegn 1 1 = Positionstegn markering sammen med bit 0 ellers skrivbart tegn. 0 = Andet tegn. 2 1 = Brug pos. som colonne 0 = Brug pos. som linie 3 1 = Adder 1 til pos. 0 = intet 4 1 = Adder 32 til pos. 0 = intet 5 1 = Exclusive or pos med 140(octal) 0 = intet 6 1 = Udskriv pos. som et tegn (tegnværdi lig pos.) 0 = Udskriv pos. som 2 cifret decimal (2 tegn) 7 intet Free text Benyttes f.eks til at angive hvilken type terminal der er beskrevet i denne indgang i kataloget. Der kan angives op til 30 tegn. Time stamp: Tidsangivelse der sættes når nyt indhold sættes i entry. Benyttes til at kontrolerer gyldigheden af læst data ved senere rettelse. *> <*--------------------------------------------------------------------------*> integer procedure init_catalogs; <* 32 *> <*----------------------------------------------------------------------*> <* Initialiser de 3 kataloger til tomme ud fra størrelserne læst fra *> <* cat_file *> <* *> <* Return : Reason fra initialiseringen. reason=0 er OK *> <*----------------------------------------------------------------------*> begin integer reason,i; trap(alarm); reason:=0; open(cat_file,4,cattxt_name,0); i:=read_start_key(cat_file,2,cat_line_nr); while i=0 do begin next_line(cat_file,cat_line_nr); i:=read_start_key(cat_file,2,cat_line_nr); end; if i=2 then begin read_nr(cat_file,usercat_size); read_nr(cat_file,termcat_size); read_nr(cat_file,typecat_size); if usercat_size<1 or termcat_size<1 or typecat_size<1 then reason:=16 else begin next_line(cat_file,cat_line_nr); user_entry_length:=126; <************************> term_entry_length:=36; <* Antal hw i entry !!! *> type_entry_length:=128; <************************> usercat_size:=(usercat_size-1)//(512//user_entry_length)+2; termcat_size:=(termcat_size-1)//(512//term_entry_length)+2; typecat_size:=(typecat_size-1)//(512//type_entry_length)+2; user_tail(1):=usercat_size; user_tail(2):=cat_doc(1); user_tail(3):=cat_doc(2); user_tail(4):=cat_doc(3); user_tail(5):=cat_doc(4); user_tail(6):=systime(7,0,0.0); user_tail(7):=0; user_tail(8):=0; user_tail(9):=11 shift 12; user_tail(10):=0; end; if reason=0 then begin if monitor(40<* create entry *>,usercat,0,user_tail)<>0 then reason:=21 else if monitor(50<* permanent *>,usercat,3,user_tail)<>0 then reason:=22 else if monitor(52<* create area proc *>,usercat,0,user_tail)<>0 then reason:=23 else if monitor(8<* reserve proc *>,usercat,0,user_tail)<>0 then reason:=24; end; if reason=0 then begin term_tail(1):=termcat_size; term_tail(2):=cat_doc(1); term_tail(3):=cat_doc(2); term_tail(4):=cat_doc(3); term_tail(5):=cat_doc(4); term_tail(6):=systime(7,0,0.0); term_tail(7):=0; term_tail(8):=0; term_tail(9):=11 shift 12; term_tail(10):=0; if monitor(40<* create entry *>,termcat,0,term_tail)<>0 then reason:=31 else if monitor(50<* permanent *>,termcat,3,term_tail)<>0 then reason:=32 else if monitor(52<* create area proc *>,termcat,0,term_tail)<>0 then reason:=33 else if monitor(8<* reserve proc *>,termcat,0,term_tail)<>0 then reason:=34; end; if reason=0 then begin type_tail(1):=typecat_size; type_tail(2):=cat_doc(1); type_tail(3):=cat_doc(2); type_tail(4):=cat_doc(3); type_tail(5):=cat_doc(4); type_tail(6):=systime(7,0,0.0); type_tail(7):=0; type_tail(8):=0; type_tail(9):=11 shift 12; type_tail(10):=0; if monitor(40<* create entry *>,typecat,0,type_tail)<>0 then reason:=41 else if monitor(50<* permanent *>,typecat,3,type_tail)<>0 then reason:=42 else if monitor(52<* create area proc *>,typecat,0,type_tail)<>0 then reason:=43 else if monitor(8<* reserve proc *>,typecat,0,type_tail)<>0 then reason:=44; end; if reason=0 then begin <* initialiser katalog indholdet *> setposition(usercat,0,1); outrec6(usercat,512); for i:=1 step 1 until 128 do usercat(i):=real <::>; for i:=3 step 1 until usercat_size do outrec6(usercat,512); setposition(usercat,0,0); outrec6(usercat,512); usercat.iaf(1):=1; <* Bruger katalog = 1 *> usercat.iaf(2):=usercat_size; usercat.iaf(3):=user_entry_length; usercat.iaf(4):=systime(7,0,0.0); setposition(usercat,0,0); user_seg:=-1; setposition(termcat,0,1); outrec6(termcat,512); for i:=1 step 1 until 128 do termcat(i):=real <::>; for i:=3 step 1 until termcat_size do outrec6(termcat,512); setposition(termcat,0,0); term_seg:=-1; outrec6(termcat,512); termcat.iaf(1):=2; <* Terminal katalog = 2 *> termcat.iaf(2):=termcat_size; termcat.iaf(3):=term_entry_length; termcat.iaf(4):=systime(7,0,0.0); setposition(termcat,0,0); setposition(typecat,0,1); outrec6(typecat,512); for i:=1 step 1 until 128 do typecat(i):=real <::>; for i:=3 step 1 until typecat_size do outrec6(typecat,512); setposition(typecat,0,0); outrec6(typecat,512); typecat.iaf(1):=3; <* Type katalog = 3 *> typecat.iaf(2):=typecat_size; typecat.iaf(3):=type_entry_length; typecat.iaf(4):=systime(7,0,0.0); setposition(typecat,0,0); end; end else reason:=17; init_catalogs:=reason; if false then alarm: disable traped(32); end; integer procedure fill_catalogs; <* 33 *> <*-----------------------------------------------------*> <* Hent data fra cat_file og indsæt i relevant katalog *> <*-----------------------------------------------------*> begin integer reason,key,i,first,last,type,term_type,priv; integer array group,pgn,term_id,user_id(0:4); long array password(1:8); boolean ok; procedure clear_high(i); <* 32 *> integer i; begin i:=(i shift 12) shift (-12); end; procedure clear_low(i); <* 33 *> integer i; begin i:=(i shift (-12)) shift 12; end; trap(alarm); reason:=0; key:=read_start_key(cat_file,2,cat_line_nr); while (key<>1 <* end *>) and (key<>-1) and (reason=0) do begin if key=3 then begin <* user entry *> if not read_name(cat_file,user_id,ok) then goto ill_nr; if not ok then goto ill_nr; for i:=3,2,1,0 do user_id(i+1):=user_id(i); if not find_user(user_id) then begin if find_empty_user_entry(calc_hash(user_id,usercat_size)) then begin <* init entry *> for i:=2 step 1 until 5 do usercat.user_entry(i):=user_id(i-1); usercat.user_entry(12):=1 shift 12; <* max user index *> usercat.user_entry(23):=2 shift 12; <* mcl def. text *> usercat.user_entry(19):=1 shift 23; <* term. group 0 *> next_line(cat_file,cat_line_nr); key:=read_start_key(cat_file,2,cat_line_nr); while (key>=4) and (key<=20) do begin <* indsæt i entry *> if (key>=6) and (key<=12) then begin <* læs first og last for login tid *> if not (read_nr(cat_file,first) and read_nr(cat_file,last)) then goto ill_nr; if first<0 or first>24 or last<0 or last>24 then goto ill_nr; type:=if first<1 and last>23 then 3 else if first=last then 0 else if first<last then 1 else 2; end; begin case key-3 of begin begin <* password *> for i:=1 step 1 until 8 do password(i):=0; usercat.user_entry(6):=0; usercat.user_entry(7):=0; if read_text(cat_file,password,48)>0 then begin <* kod password *> for last:=1 step 1 until 31 do begin key:=password.baf(last) extract 12; for i:=last+1 step 1 until 32 do password.baf(i):=false add ((password.baf(i) extract 12) + key); end; for i:=1 step 1 until 16 do begin usercat.user_entry(6):=usercat.user_entry(6)+ password.iaf(i); usercat.user_entry(7):=usercat.user_entry(7)+ usercat.user_entry(6); end; end; end; begin <* kodet password *> read(cat_file,password(1)); usercat.user_entry(6):=password(1) shift (-24); usercat.user_entry(7):=password(1) extract 24; end; begin <* monday *> clear_high(usercat.user_entry(8)); usercat.user_entry(8):=usercat.user_entry(8)+ ((first shift 7)+(last shift 2) + type) shift 12; end; begin <* tuesday *> clear_low(usercat.user_entry(8)); usercat.user_entry(8):=usercat.user_entry(8)+ ((first shift 7)+(last shift 2) + type); end; begin <* wednesday *> clear_high(usercat.user_entry(9)); usercat.user_entry(9):=usercat.user_entry(9)+ ((first shift 7)+(last shift 2) + type) shift 12; end; begin <* thursday *> clear_low(usercat.user_entry(9)); usercat.user_entry(9):=usercat.user_entry(9)+ ((first shift 7)+(last shift 2) + type); end; begin <* friday *> clear_high(usercat.user_entry(10)); usercat.user_entry(10):=usercat.user_entry(10)+ ((first shift 7)+(last shift 2) + type) shift 12; end; begin <* saturday *> clear_low(usercat.user_entry(10)); usercat.user_entry(10):=usercat.user_entry(10)+ ((first shift 7)+(last shift 2) + type); end; begin <* sunday *> clear_high(usercat.user_entry(11)); usercat.user_entry(11):=usercat.user_entry(11)+ ((first shift 7)+(last shift 2) + type) shift 12; end; begin <* block *> clear_low(usercat.user_entry(11)); if not read_nr(cat_file,i) or i<0 then goto ill_nr; usercat.user_entry(11):=usercat.user_entry(12)+i; end; begin <* index *> clear_high(usercat.user_entry(12)); if not read_nr(cat_file,i) then goto ill_nr; if i>9 or i<1 then goto ill_nr; usercat.user_entry(12):=usercat.user_entry(12)+ (i shift 12); end; begin <* privilegier *> priv:=0; clear_low(usercat.user_entry(12)); if not read_nr(cat_file,i) then goto ill_nr; while i>=0 do begin if i>11 then goto ill_nr; priv:=priv+(1 shift (11-i)); if not read_nr(cat_file,i) then goto ill_nr; end; usercat.user_entry(12):=usercat.user_entry(12)+priv; end; begin <* mcl name *> if not read_name(cat_file,pgn,ok) then goto ill_nr; if not ok then goto ill_nr; for i:=0 step 1 until 3 do usercat.user_entry(i+13):=pgn(i); end; begin <* cmcl bases *> if not (read_nr(cat_file,first) and read_nr(cat_file,last)) then goto ill_nr; if first>last then goto ill_nr; usercat.user_entry(17):=first; usercat.user_entry(18):=last; end; begin <* groups *> for i:=1 step 1 until 4 do group(i):=0; if not read_nr(cat_file,i) then goto ill_nr; while (i>=0) and (i<=95) do begin first:=(i//24)+1; last:=23-(i mod 24); if not (false add (group(first) shift (-last))) then group(first):=group(first)+(1 shift last); if not read_nr(cat_file,i) then goto ill_nr; end; for i:=1 step 1 until 4 do usercat.user_entry(18+i):=group(i); end; begin <* mcl text *> laf:=46; i:=read_text(cat_file,usercat.user_entry.laf,80); usercat.user_entry(23):= ((((i+2)//3*2)+2) shift 12) + i; laf:=0; end; begin <* free text *> laf:=100; read_text(cat_file,usercat.user_entry.laf,30); laf:=0; end; end; end; next_line(cat_file,cat_line_nr); key:=read_start_key(cat_file,2,cat_line_nr); end; write_user_seg; end else reason:=101; <* Ikke flere entries *> end else reason:=102; <* Entry eksisterer *> end else if key=21 then begin <* terminal entry *> if not read_name(cat_file,term_id,ok) then goto ill_nr; for i:=3 step (-1) until 0 do term_id(i+1):=term_id(i); if not find_term(term_id) then begin if find_empty_term_entry(calc_hash(term_id,termcat_size)) then begin <* init entry *> for i:=2 step 1 until 5 do termcat.term_entry(i):=term_id(i-1); termcat.term_entry(6):=1 shift 12; <* terminal type *> next_line(cat_file,cat_line_nr); key:=read_start_key(cat_file,2,cat_line_nr); while key=13 or key=20 or key=51 or (key>=22 and key<=24) do begin <* indsæt i entry *> if key=22 then begin <* Terminal type *> if not read_nr(cat_file,i) or i<0 or i>2047 then goto ill_nr; clear_high(termcat.term_entry(6)); termcat.term_entry(6):=termcat.term_entry(6)+ i shift 12; end; if key=13 then begin <* Block *> if not read_nr(cat_file,i) or i<0 then goto ill_nr; clear_low(termcat.term_entry(6)); termcat.term_entry(6):=termcat.term_entry(6)+i; end; if key=23 then begin <* terminal group *> if not read_nr(cat_file,i) or i<0 or i>95 then goto ill_nr; clear_low(termcat.term_entry(7)); termcat.term_entry(7):=termcat.term_entry(7)+i; end; clear_high(termcat.term_entry(7)); if key=24 then begin <* bypass *> if (not read_nr(cat_file,i)) or i<>0 then termcat.term_entry(7):=termcat.term_entry(7)+(1 shift 12); end; if key=51 then begin <* nologin *> if not read_nr(cat_file,i) or i<0 or i>99 then goto ill_nr; termcat.term_entry(7):=termcat.term_entry(7)+(i shift 13); end; if key=20 then begin <* free text *> laf:=14; read_text(cat_file,termcat.term_entry.laf,30); laf:=0; end; next_line(cat_file,cat_line_nr); key:=read_start_key(cat_file,2,cat_line_nr); end; write_term_seg; end else reason:=105; <* Ikke flere entries *> end else reason:=106; <* Entry eksisterer *> end else if key=25 then begin <* type entry *> if not read_nr(cat_file,term_type) or term_type<1 then goto ill_nr; if find_type_entry(term_type) then begin if typecat.type_entry(1) = 0 then begin boolean array field baf; baf:=0; <* init entry *> typecat.type_entry(1):=term_type; <* terminal type *> typecat.type_entry(3):=(80 shift 12)+24; next_line(cat_file,cat_line_nr); key:=read_start_key(cat_file,2,cat_line_nr); while (key>=26) or (key=20) do begin <* indsæt i entry *> if key=26 then begin <* screen type *> priv:=0; if not read_nr(cat_file,i) or i>11 or i<0 then goto ill_nr; while i>=0 do begin if i>11 then goto ill_nr; priv:=priv+(1 shift (11-i)); if not read_nr(cat_file,i) then goto ill_nr; end; typecat.type_entry.baf(3):=false add (priv extract 12) end; if key=49 then begin <* mode *> if not read_nr(cat_file,i) or i>9 or i<0 then goto ill_nr; typecat.type_entry.baf(4):=false add (i extract 12) end; if (key>=27) and (key<=34) then begin <* 'send by' værdier *> if not read_nr(cat_file,i) or i>255 or i<0 then goto ill_nr; typecat.type_entry.baf(key-22):=if i>0 then false add i else false; end; if (key>=44) and (key<=48) then begin <* et tegns værdier *> if not read_nr(cat_file,i) or i>255 or i<0 then goto ill_nr; typecat.type_entry.baf(key+7):=if i>0 then false add i else false; end; if (key>=35) and (key<=42) then begin <* 6 tegns sekevnser *> if not read_nr(cat_file,i) or i>255 or i<0 then goto ill_nr; first:=1; laf:=case (key-34) of (12,16,20,24,28,32,36,40); typecat.type_entry.laf(1):=0; while (i<>-1) and (first<=6) do begin put_ch(typecat.type_entry.laf,first,i,1); if first<=6 then begin if not read_nr(cat_file,i) or i>255 or i<(-1) then goto ill_nr; end; end; laf:=0; end; if key=43 then begin <* cursor sekvens *> if not read_nr(cat_file,i) or i>255 or i<0 then goto ill_nr; first:=1; laf:=44; while (i<>-1) and (first<=9) do begin put_ch(typecat.type_entry.laf,first,i,1); if first<=9 then begin if not read_nr(cat_file,i) or i>255 or i<(-1) then goto ill_nr; end; end; laf:=0; end; if key=50 then begin <* initialiserings sekvens *> laf:=56; if not read_nr(cat_file,i) or i>255 or i<0 then goto ill_nr; first:=1; while (i<>-1) and (first<=75) do begin put_ch(typecat.type_entry.laf,first,i,1); if first<=75 then begin if not read_nr(cat_file,i) or i>255 or i<(-1) then goto ill_nr; end; end; laf:=0; end; if key=20 then begin <* free text *> laf:=106; read_text(cat_file,typecat.type_entry.laf,30); laf:=0; end; next_line(cat_file,cat_line_nr); key:=read_start_key(cat_file,2,cat_line_nr); end; write_type_seg; end else reason:=108; <* Entry eksisterer *> end else reason:=109; <* Illegal type *> end else if key<>65 then reason:=100; <* illegal entry key *> end; if false then ill_nr: reason:=110; fill_catalogs:=reason; if false then alarm: disable traped(33); end; <*****************************> <* Hoveddel af open_catalogs *> <*****************************> trap(alarm); cat_line_nr:=1; set_cat_bases(sys_bases); open(usercat,4,usercat_name,1 shift 9 <* passivate *> ); open(termcat,4,termcat_name,1 shift 9 <* passivate *> ); open(typecat,4,typecat_name,0 <* NO passivate *> ); reason:=0; if monitor(42<* lookup *>,usercat,0,user_tail)<>0 then reason:=1 else if new_catalog then monitor(48 <*remove entry*>,usercat,0,user_tail); if monitor(42<* lookup *>,termcat,0,term_tail)<>0 then reason:=2 else if new_catalog then monitor(48 <*remove entry*>,termcat,0,term_tail); if monitor(42<* lookup *>,typecat,0,type_tail)<>0 then reason:=3 else if new_catalog then monitor(48 <*remove entry*>,typecat,0,type_tail); if (not new_catalog) and (reason=0) then begin <* alle kataloger findes, test ydeligerer *> usercat_size:=user_tail(1); termcat_size:=term_tail(1); typecat_size:=type_tail(1); if monitor(92<* create area proc *>,usercat,0,user_tail)<>0 then reason:=4 else if monitor(8<* reserve proc *>,usercat,0,user_tail)<>0 then reason:=5 else begin user_seg:=-1; find_user_seg(0); user_entry:=0; if usercat.user_entry(1)<>1 then reason:=6 else if usercat.user_entry(2)<>usercat_size then reason:=7 else user_entry_length:=usercat.user_entry(3); end; if reason=0 then begin if monitor(92<* create area proc *>,termcat,0,term_tail)<>0 then reason:=8 else if monitor(8<* reserve proc *>,termcat,0,term_tail)<>0 then reason:=9 else begin term_seg:=-1; find_term_seg(0); term_entry:=0; if termcat.term_entry(1)<>2 then reason:=10 else if termcat.term_entry(2)<>termcat_size then reason:=11 else term_entry_length:=termcat.term_entry(3); end; end; if reason=0 then begin if monitor(92<* create area proc *>,typecat,0,type_tail)<>0 then reason:=12 else if monitor(8<* reserve proc *>,typecat,0,type_tail)<>0 then reason:=13 else begin setposition(typecat,0,0); inrec6(typecat,512); type_entry:=0; if typecat.type_entry(1)<>3 then reason:=14 else if typecat.type_entry(2)<>typecat_size then reason:=15 else type_entry_length:=typecat.user_entry(3); end; end; end else if new_catalog then begin <* ingen kataloger findes, opret nye *> write_message(31,0,true,<:Generating new catalog:>); reason:=init_catalogs; if reason=0 then reason:=fill_catalogs; close(cat_file,true); end; if reason<>0 then write_message(cat_line_nr,reason,false,<:Catalog error:>); if false then alarm: disable traped(31); end; integer procedure calc_hash(id,cat_size); <* 34 *> <*-----------------------------------------------------------*> <* Beregn hash key ud fra navnet i id og kataloget størrelse *> <* *> <* id (call) : Navnet som hash nøglen beregnes for *> <* navnet står i integer array id(1:4) *> <* cat_size (call) : Størrelsen af kataloget hvortil hash *> <* skal benyttes *> <* Return : Den beregnede hash nøgle. *> <*-----------------------------------------------------------*> integer array id; integer cat_size; begin calc_hash:=1+((abs(id(1)+id(2)+id(3)+id(4))) mod (cat_size-1)); end; procedure find_user_seg(seg_nr); <* 35 *> <*----------------------------------------------------------*> <* Find segment i usercat og indlæs dette. Udskriv aktuelt *> <* segment, hvis wflag er sat. *> <* *> <* seg_nr (call) : Nummeret på det segment der ønskes *> <*----------------------------------------------------------*> integer seg_nr; begin integer array ia(1:20); trap(alarm); if seg_nr>(usercat_size-1) or seg_nr<0 then write_message(35,seg_nr,false,<:Illegal seg_nr in cat.:>) else if seg_nr<>user_seg then begin setposition(usercat,0,seg_nr); inrec6(usercat,512); getzone6(usercat,ia); ia(9):=seg_nr; setzone6(usercat,ia); user_seg:=seg_nr; end; if false then alarm: disable traped(35); end; procedure write_user_seg; <* 36 *> <*----------------------------------------------------------*> <* Opdater aktuelt user segment på disken. Segmentet for- *> <* bliver i zone-bufferen med state: opend and positioned. *> <*----------------------------------------------------------*> begin integer array ia(1:20); trap(alarm); setstate(usercat,6); if (user_seg>usercat_size-1) or (user_seg<0) then write_message(36,user_seg,false,<:Illegal seg_nr in cat.:>); setposition(usercat,0,user_seg); inrec6(usercat,512); getzone6(usercat,ia); ia(9):=user_seg; setzone6(usercat,ia); if false then alarm: disable traped(36); end; procedure next_user_entry; <* 37 *> <*----------------------------------------------------------*> <* Find næste user_entry i katalog. Er aktuelt entry sidste *> <* i katalog sættes næste entry til det første i kataloget *> <*----------------------------------------------------------*> begin integer seg_nr; trap(alarm); user_entry:=user_entry+user_entry_length; if (511-user_entry)<user_entry_length then begin seg_nr:=if user_seg=usercat_size-1 then 1 <* Segment 0 benyttes til katalog information *> else user_seg+1; find_user_seg(seg_nr); user_entry:=2; end; if false then alarm: disable traped(37); end; boolean procedure find_user(user_id); <* 38 *> <*----------------------------------------------------------*> <* Find user_entry i katalog med key som angivet user_id *> <* *> <* user_id (call) : Bruger navn i integer array (1:4) *> <* Return : True=fundet, False=ikke fundet *> <*----------------------------------------------------------*> integer array user_id; begin integer field hash_count; integer i,hash; boolean found; trap(alarm); hash:=calc_hash(user_id,usercat_size); find_user_seg(hash); hash_count:=2; hash_count:=usercat.hash_count; user_entry:=2; if hash_count>0 then begin repeat if usercat.user_entry(1)=hash then begin found:=true; hash_count:=hash_count-1; for i:=2, i+1 while (i<=5 and found) do if usercat.user_entry(i)<>user_id(i-1) then found:=false; end else found:=false; if not found then next_user_entry; until found or hash_count=0 or (user_seg=hash and user_entry=2); if not found and hash_count>0 then write_message(38,1,true,<:Cyclic in catalog:>); end else found:=false; find_user:=found; if false then alarm: disable traped(38); end; boolean procedure find_empty_user_entry(hash_key); <* 39 *> <*----------------------------------------------------------*> <* Find første tomme user_entry hørende til hash_key *> <* Optæl hash key tæller i hash segmentet. Sæt user_entry *> <* til fundet entry. Hash_key indsættes i fundet segment. *> <* Entry SKAL udskrives på disken efter indsættelse af data *> <* *> <* hash_key (call) : Hash nøglen hørende til det segment *> <* hvorfra der søges efter tomt entry *> <* Return : True=Entry fundet. Sat i user_entry *> <* False=Ikke mere plads i katalog *> <*----------------------------------------------------------*> integer hash_key; begin boolean room; trap(alarm); find_user_seg(hash_key); user_entry:=0; usercat.user_entry(1):=usercat.user_entry(1)+1; setstate(usercat,6); user_entry:=2; room:=true; while usercat.user_entry(1)<>0 and room do begin next_user_entry; if (hash_key=user_seg) and (user_entry=2) then room:=false; end; if not room then begin find_empty_user_entry:=false; find_user_seg(hash_key); user_entry:=0; usercat.user_entry(1):=usercat.user_entry(1)-1; write_user_seg; end else begin find_empty_user_entry:=true; usercat.user_entry(1):=hash_key; end; if false then alarm: disable traped(39); end; procedure find_term_seg(seg_nr); <* 40 *> <*----------------------------------------------------------*> <* Find segment i termcat og indlæs dette. Udskriv aktuelt *> <* segment, hvis wflag er sat. *> <* *> <* seg_nr (call) : Nummeret på det segment der ønskes *> <*----------------------------------------------------------*> integer seg_nr; begin integer array ia(1:20); trap(alarm); if seg_nr>(termcat_size-1) or seg_nr<0 then write_message(40,seg_nr,false,<:Illegal seg_nr in cat.:>) else if seg_nr<>term_seg then begin setposition(termcat,0,seg_nr); inrec6(termcat,512); getzone6(termcat,ia); ia(9):=seg_nr; setzone6(termcat,ia); term_seg:=seg_nr; end; if false then alarm: disable traped(40); end; procedure write_term_seg; <* 41 *> <*----------------------------------------------------------*> <* Opdater aktuelt term segment på disken. Segmentet for- *> <* bliver i zone-bufferen med state: opend and positioned. *> <*----------------------------------------------------------*> begin integer array ia(1:20); trap(alarm); setstate(termcat,6); if (term_seg>termcat_size-1) or (term_seg<0) then write_message(41,term_seg,false,<:Illegal seg_nr in cat.:>); setposition(termcat,0,term_seg); inrec6(termcat,512); getzone6(termcat,ia); ia(9):=term_seg; setzone6(termcat,ia); if false then alarm: disable traped(41); end; procedure next_term_entry; <* 42 *> <*----------------------------------------------------------*> <* Find næste term_entry i katalog. Er aktuelt entry sidste *> <* i katalog sættes næste entry til det første i kataloget *> <*----------------------------------------------------------*> begin integer seg_nr; trap(alarm); term_entry:=term_entry+term_entry_length; if (511-term_entry)<term_entry_length then begin seg_nr:=if term_seg=termcat_size-1 then 1 <* Segment 0 benyttes til katalog information *> else term_seg+1; find_term_seg(seg_nr); term_entry:=2; end; if false then alarm: disable traped(42); end; boolean procedure find_term(term_id); <* 43 *> <*----------------------------------------------------------*> <* Find term_entry i katalog med key som angivet term_id *> <* *> <* term_id (call) : Terminal navn (integer array (1:4)) *> <* Return : True=fundet, False=ikke fundet *> <*----------------------------------------------------------*> integer array term_id; begin integer field hash_count; integer i,hash; boolean found; trap(alarm); hash:=calc_hash(term_id,termcat_size); find_term_seg(hash); hash_count:=2; hash_count:=termcat.hash_count; term_entry:=2; if hash_count>0 then begin repeat if termcat.term_entry(1)=hash then begin found:=true; hash_count:=hash_count-1; for i:=2, i+1 while (i<=5 and found) do if termcat.term_entry(i)<>term_id(i-1) then found:=false; end else found:=false; if not found then next_term_entry; until found or hash_count=0 or (term_seg=hash and term_entry=2); if not found and hash_count>0 then write_message(43,2,true,<:Cyclic in catalog:>); end else found:=false; find_term:=found; if false then alarm: disable traped(43); end; boolean procedure find_empty_term_entry(hash_key); <* 44 *> <*----------------------------------------------------------*> <* Find første tomme term_entry hørende til hash_key *> <* Optæl hash key tæller i hash segmentet. Sæt term_entry *> <* til fundet entry. Hash_key indsættes i fundet segment. *> <* Entry SKAL udskrives på disken efter indsættelse af data *> <* *> <* hash_key (call) : Hash nøglen hørende til det segment *> <* hvorfra der søges efter tomt entry *> <* Return : True=Entry fundet. Sat i term_entry *> <* False=Ikke mere plads i katalog *> <*----------------------------------------------------------*> integer hash_key; begin boolean room; trap(alarm); find_term_seg(hash_key); term_entry:=0; termcat.term_entry(1):=termcat.term_entry(1)+1; setstate(termcat,6); term_entry:=2; room:=true; while termcat.term_entry(1)<>0 and room do begin next_term_entry; if (hash_key=term_seg) and (term_entry=2) then room:=false; end; if not room then begin find_empty_term_entry:=false; find_term_seg(hash_key); term_entry:=0; termcat.term_entry(1):=termcat.term_entry(1)-1; write_term_seg; end else begin find_empty_term_entry:=true; termcat.term_entry(1):=hash_key; end; if false then alarm: disable traped(44); end; boolean procedure find_type_entry(type_nr); <* 45 *> <*----------------------------------------------------------*> <* Find entry hørende til angivet type. Sæt type_entry *> <* BEMÆRK: Benyttes parallelt i catalog, operatør og *> <* timecheck korutinerne *> <* *> <* type_nr (call) : typen af terminalen >0 *> <* Return : True=Entry fundet, False= IKKE fundet *> <* field type_entry sat til entry *> <*----------------------------------------------------------*> integer type_nr; begin integer seg; integer array ia(1:20); trap(alarm); seg:=(type_nr-1)//(512//type_entry_length)+1; if seg > typecat_size-1 or seg<1 or type_nr<1 then find_type_entry:=false else begin type_entry:=type_entry_length*((type_nr-1) mod (512//type_entry_length)); setposition(typecat,0,seg); inrec6(typecat,512); <* NO passivate *> getzone6(typecat,ia); ia(9):=seg; setzone6(typecat,ia); find_type_entry:=true; end; if false then alarm: disable traped(45); end; procedure write_type_seg; <* 46 *> <*----------------------------------------------------------*> <* Opdater aktuelt type segment på disken. Segmentet for- *> <* bliver i zone-bufferen med state: opend and positioned. *> <*----------------------------------------------------------*> begin integer seg; integer array ia(1:20); trap(alarm); getposition(typecat,0,seg); setstate(typecat,6); setposition(typecat,0,seg); inrec6(typecat,512); getzone6(typecat,ia); ia(9):=seg; setzone6(typecat,ia); if false then alarm: disable traped(46); end; procedure read_param_line; <* 47 *> <*---------------------------------------------------------------*> <* Læs parametre fra fp kaldet *> <* Sæt : new_catalog / cattxt_name *> <* init_file_name *> <* fp_maxterms *> <* *> <* init_file_name sættes default til: 'tasinit' men ændres *> <* hvis der angives init.<name> i kald *> <* maxterms sættes fra kald hvis der angives terminals.<antal> *> <* ellers sættes maxterms fra init_file. *> <* Angives catalog.<name> sættes <name> i cattxt_name og *> <* new_catalog sættes true *> <*---------------------------------------------------------------*> begin integer j,seperator,i,key; real array item(1:2); trap(alarm); new_catalog:=false; fp_maxterms:=0; init_file_name.laf(1):=init_file_name.laf(2):=0; put_text(init_file_name.laf,1,<:tasinit:>); <* Default init name *> i:=1; repeat seperator:=system(4,i,item); i:=i+1; if seperator=(4 shift 12) + 10 then begin key:=find_keyword_value(item.laf(1),3); seperator:=system(4,i,item); i:=i+1; if key=7 then begin if seperator=(8 shift 12) + 10 then begin new_catalog:=true; for j:=1,2 do cattxt_name.laf(j):=item.laf(j); end else write_message(47,i,false,<:Illegal call parameter:>); end else if key=9 then begin if seperator=(8 shift 12) + 10 then begin for j:=1,2 do init_file_name.laf(j):=item.laf(j); end else write_message(47,i,false,<:Illegal call parameter:>); end else if key=8 then begin if seperator=(8 shift 12) + 4 then fp_maxterms:=item(1) else write_message(47,i,false,<:Illegal call parameter:>); end else write_message(47,i,false,<:Unknown call parameter:>); end; until seperator=0; if false then alarm: disable traped(47); end; procedure init_tascat; <* 48 *> <*-------------------------------------------------------*> <* Initialiser tascat variable. *> <* Data hentes enten fra init fil eller der benyttes *> <* standard værdi. Beskrivelsen af data typer og *> <* standard værdier sættes i procedure init_param_arrays *> <*-------------------------------------------------------*> begin zone init_file(128,1,std_error); integer array val(0:45); integer array init_type,init_count(1:init_num_keys-9); integer array init_lim(1:init_num_keys-9,1:2); long array init_default(1:init_num_keys-9); integer array spoolname,ttname,temname(1:4); integer spseg,textbufsize,timeout,tbufsize,ttmask,reserve,i; procedure init_param_arrays; <* 49 *> <*-------------------------------------------------*> <* Initialiser arrays der beskriver data typer m.m *> <*-------------------------------------------------*> begin long f,t; integer i; integer max,min; <*********************************************************************> <* Følgende arrays initialiseres: *> <* integer array init_type(1:???) ; Beskriver typen af data : *> <* 0 = IKKE brugt *> <* 1 = cmcl-tekst *> <* 2 = navn *> <* 3 = heltal (integer) *> <* 4 = logisk (boolean) *> <* 5 = 2 heltal (integer) *> <* *> <* long array init_default(1:???) ; Standard værdi : *> <* For type 1 : 0 til 130 iso tegn *> <* 2 : 0 til 11 iso tegn *> <* 3 : Heltals værdi *> <* 4 : false add værdi (0=false , 1=true) *> <* 5 : Heltals værdi for begge værdier *> <* *> <* integer array init_lim(1:???,1:2) ; Grænser for angivet værdi *> <* For type 1 : (1) = Max. antal tegn *> <* (2) = ubrugt *> <* 2 : (1) = ubrugt *> <* (2) = ubrugt *> <* 3 : (1) = mindste værdi *> <* (2) = største værdi *> <* 4 : (1) = ubrugt *> <* (2) = ubrugt *> <* 5 : (1) = mindste værdi *> <* (2) = største værdi *> <* *> <* integer array init_count(1:???); Beskrivelse af gemning af værdi *> <* Angiver antallet af ord -1, der indgår i værdien. *> <* *> <* Navne på parametrerne i init_file sættes i : *> <* procedure keywords_init i array init_keywords. *> <* fra keyword 10 og frem. Keyword værdi benyttes som index til *> <* init array's. Lokale værdier sættes i set_local_data *> <*********************************************************************> trap(alarm); t:=1; f:=0; max:=8388605; min:=-8388607; for i:=1 step 1 until init_num_keys-9 do begin init_type(i):=case i of (2,2,2,2,2,2,2,2,4,3, 3,4,3,5,5,3,3,3,3,3, 3,3,3,3,3,3,3,3,1,1, 1,1,3,3,3,3,4); init_default(i):=case i of (long <:disc:>,long <:tasusercat:>,long <:tastermcat:>, long <:tastypecat:>,long <:tascattest:>,long <:tasspool:>, long <:tastermtest:>, long <:tem:>,t,3, 3,t,5,max,max,0,0,20,10,5, 25,5,2,170,3,10,2,30,long <::>,long <::>, long <:Afmeld !:>,long <:Afmeld !:>,412,-1,1365,0,t); init_count(i):=case i of (3,3,3,3,3,3,3,3,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,27,45, 27,27,0,0,0,0,0); init_lim(i,1):=case i of (0,0,0,0,0,0,0,0,0,0, 0,0,1,min,min,0,0,1,1,1, 3,1,1,70,1,1,1,1,80,80, 80,80,0,-1,0,0,0); init_lim(i,2):=case i of (0,0,0,0,0,0,0,0,0,4095, 4095,0,30,max,max,max,max,max,max,max, max,max,max,500,2047,max,5,max,0,0, 0,0,1024,0,4095,999999,0); end; if false then alarm: disable traped(49); end; procedure set_default; <* 50 *> <*------------------------------------------------------*> <* Sæt standard værdierne i lokale og globale variable *> <*------------------------------------------------------*> begin integer i,j; <*************************************************************************> <* integer array val benyttes til midlertidig opbevaring af læst værdi *> <* For type 1 : (0) = hw's shift 12 + char's *> <* (1:45) = Teksten *> <* 2 : (0:3) = Navnet (udfyldt med 0) *> <* 3 : (0) = Værdien *> <* 4 : (0) = (0=false , 1=true); *> <* 5 : (0),(1)= 2 værdier *> <*************************************************************************> trap(alarm); host_id(0):=signon_text(0):=logtxt(0):=stoptxt(0):=0; for i:=1 step 1 until init_num_keys-9 do begin if init_type(i)>0 then begin case init_type(i) of begin begin <* 1 *> val(0):=puttext(val.laf,1,string init_default(i),-init_lim(i,1)); val(0):=val(0)+1; put_ch(val.laf,val(0)+0,10,1); put_ch(val.laf,val(0)+1,0,6); val(0):=(((val(0)+2)//3+1)*2) shift 12 + val(0); end; begin <* 2 *> val.laf(1):=val.laf(2):=0; puttext(val.laf,1,string init_default(i),-11); for j:=1 step 1 until 4 do val(j-1):=val(j); end; begin <* 3 *> val(0):=init_default(i); end; begin <* 4 *> val(0):=init_default(i); end; begin <* 5 *> val(0):=init_default(i); val(1):=init_default(i); end; end; set_local_data(i); end; end; if false then alarm: disable traped(50); end; procedure read_init_param; <* 51 *> <*---------------------------------------------------*> <* Modifiser værdier med læste værdier fra init_file *> <*---------------------------------------------------*> begin integer i,j,init_line_nr; boolean ok; trap(alarm); init_line_nr:=1; i:=read_start_key(init_file,3,init_line_nr); while i=0 do begin next_line(init_file,init_line_nr); i:=read_start_key(init_file,3,init_line_nr); end; i:=i-9; while i>=1 do begin if init_type(i)>0 then begin case init_type(i) of begin begin <* 1 *> val(0):=read_text(init_file,val.laf,init_lim(i,1)); val(0):=val(0)+1; put_ch(val.laf,val(0)+0,10,1); put_ch(val.laf,val(0)+1,0,6); val(0):=(((val(0)+2)//3+1)*2) shift 12 + val(0); end; begin <* 2 *> read_name(init_file,val,ok); if not ok then write_message(51,init_line_nr,false,<:Illegal init. value:>); end; begin <* 3 *> if not read_nr(init_file,val(0)) or (val(0)<init_lim(i,1)) or (val(0)>init_lim(i,2)) then write_message(51,init_line_nr,false,<:Illegal init. value:>); end; begin <* 4 *> j:=read_start_key(init_file,3,init_line_nr); if j=1 <* true *> or j=3 <* on *> or j=5 <* start *> then val(0):=1 else if j=2 <* false *> or j=4 <* off *> or j=6 <* stop *> then val(0):=0 else write_message(51,init_line_nr,false,<:Illegal init. value:>); end; begin <* 5 *> if not read_nr(init_file,val(0)) or (val(0)<init_lim(i,1)) or (val(0)>init_lim(i,2)) then write_message(51,init_line_nr,false,<:Illegal init. value:>); if not read_nr(init_file,val(1)) or (val(1)<init_lim(i,1)) or (val(1)>init_lim(i,2)) then write_message(51,init_line_nr,false,<:Illegal init. value:>); end; end; set_local_data(i); end; next_line(init_file,init_line_nr); i:=read_start_key(init_file,3,init_line_nr)-9; end; if i=-9 then write_message(51,init_line_nr,false,<:Unknown init. param.:>); if false then alarm: disable traped(51); end; procedure set_local_data(key); <* 52 *> <*------------------------------------*> <* Sæt data fra val i lokale variable *> <* *> <* key (call) : Angiver den variable *> <* der skal initialiseres*> <*------------------------------------*> integer key; begin integer i; integer array st(0:68); for i:=0 step 1 until init_count(key) do begin case key of begin cat_doc(i+1):=val(i); usercat_name(i+1):=val(i); termcat_name(i+1):=val(i); typecat_name(i+1):=val(i); testout_name(i+1):=val(i); spoolname(i+1):=val(i); ttname(i+1):=val(i); temname(i+1):=val(i); login_stat:=if val(0)=0 then 0 else 96; max_user_block:=val(0); max_term_block:=val(0); timecheck_stat:=false add val(0); logtime:=val(0); begin cmclbases(1):=val(0); cmclbases(2):=val(1); end; begin sysbases(1):=val(0); sysbases(2):=val(1); end; cps:=val(0); cls:=val(0); max_sessions:=val(0); max_terminals:=val(0); max_sysmenu:=val(0); corebufs:=val(0); mclprogs:=val(0); term_types:=val(0); tbufsize:=val(0); spseg:=val(0); max_users:=val(0); number_of_opera:=val(0); timeout:=val(0); host_id(i):=val(i); st(i):=val(i); logtxt(i):=val(i); stoptxt(i):=val(i); begin testselect:=val(0) extract 8; tracetype:=val(0) shift (-8); end; trapmode:=val(0); ttmask:=val(0); initver:=val(0); reserve:=val(0); end; end; if key=30 then begin i:=signon_text(0) extract 12 + 1; put_txt(signon_text.laf,i,st.laf,st(0) extract 12); put_ch(signon_text.laf,i+0,0,6); signon_text(0):=(((i+1)//3)*2) shift 12 + (i-1); end; end; trap(alarm); open(init_file,4,init_file_name,0); if monitor(42,init_file,0,val)<>0 then write_message(48,1,false,<:No init. file:>); init_param_arrays; set_default; <* Set host id fra navn i monitor *> hostid(0):=22 shift 12 + 29; movestring(hostid.laf,1,<: Velkommen til :>); system(5,1192,val); for i:=1,2,3,4 do hostid(6+i):=val(i); read_init_param; text_buf_size:=148; max_text_count:=max_terminals//4; test_on:=true; language:=1; close(init_file,true); <* Sæt data i copy_buf *> copy_buf.iaf(1):=cps+cls+2*max_sessions+max_sysmenu; <* Antal cdescr *> copy_buf.iaf(2):=term_types; <* Antal terminal type beskrivelser *> copy_buf.iaf(3):=max_terminals; <* Antal terminal beskrivelser *> copy_buf.iaf(4):=mclprogs; <* Antal indgange i mcltable *> copy_buf.iaf(5):=spoolname(1); <* Navn på spool area *> copy_buf.iaf(6):=spoolname(2); copy_buf.iaf(7):=spoolname(3); copy_buf.iaf(8):=spoolname(4); copy_buf.iaf(9):=corebufs; <* Antal core buffere *> copy_buf.iaf(10):=max_sysmenu//2;<* Antal att event descr *> copy_buf.iaf(11):=reserve; <* reserver terminal ved create link *> copy_buf.iaf(12):=cmclbases(1); <* MCL database std baser *> copy_buf.iaf(13):=cmclbases(2); copy_buf.iaf(14):=cls+max_sessions+max_sysmenu; <* Antal termina buf *> copy_buf.iaf(15):=tbufsize; <* max tbuf size *> copy_buf.iaf(16):=spseg; <* std seg i link spool area *> copy_buf.iaf(17):=2*152; <* hw i signon buffer *> copy_buf.iaf(18):=sysbases(1); <* test/spool baser *> copy_buf.iaf(19):=sysbases(2); copy_buf.iaf(20):=temname(1); <* Navn på tem pseudo proces *> copy_buf.iaf(21):=temname(2); copy_buf.iaf(22):=temname(3); copy_buf.iaf(23):=temname(4); copy_buf.iaf(24):=ttname(1); <* Testområde navn *> copy_buf.iaf(25):=ttname(2); copy_buf.iaf(26):=ttname(3); copy_buf.iaf(27):=ttname(4); copy_buf.iaf(28):=timeout; <* Antal timeout på term i mcl *> copy_buf.iaf(29):=textbufsize; <* Antal hw til txt i systxt buf *> copy_buf.iaf(30):=max_text_count;<* Antal udestående systxt mess. *> copy_buf.iaf(31):=ttmask; <* testmaske *> copy_buf.iaf(32):=cps; <* max pools efter create pool mess. *> copy_buf.iaf(33):=max_sessions; <* Max sessioner *> copy_buf.iaf(34):=cls; <* Max create links *> if false then alarm: disable traped(48); end; procedure wait_tasterm(error); <* 53 *> <*----------------------------------------------*> <* Vent på init message fra tasterm *> <* Når denne kommer sendes init data til tasterm*> <*----------------------------------------------*> boolean error; begin zone z(1,1,stderror), tasterm(1,1,std_error); integer array ia(1:8); long array la(1:10); integer buf, lan; trap(alarm); write_message(-53,0,true,if error then <:Stop menu:> else <:Synchronizing:>); repeat <* sæt tasterm_pda ud fra denne message *> tasterm_pda:=monitor(20,z,buf,answer); <* sæt tasterm_name ud fra pda *> if not get_proc_name(tasterm_pda,tasterm_name) then write_message(53,1,false,<:Sync. error:>); if answer(1)<>(9 shift 12 + 1) then begin write_message(53,answer(1),true,<:System not running yet:>); answer(9):=3; monitor(22,z,buf,answer); end; until answer(1)=(9 shift 12 + 1); tastermverd:=answer(4); tastermvert:=answer(5); write_message(answer(5),answer(4),true,<:Tasterm release:>); write_message(relt,reld,true,<:Tascat release:>); write_message(0,initver,true,<:Init. version:>); <* retur init data til tasterm *> if data_from_copy_buf(256,buf,answer)<>0 then write_message(53,2,false,<:Sync. error:>); answer(9):=1; answer(1):=if error then 1 else 0; monitor(22,z,buf,answer); <* Find alle 'nologin' terminaler og beskriv dem for menu *> open(tasterm,0,tasterm_name,1 shift 9); term_entry := 2; term_seg := 0; find_term_seg(1); repeat if termcat.term_entry(1) <> 0 then begin <* Check entry for nologin *> lan := termcat.term_entry(7) shift (-13); if lan <> 0 then begin <* Nologin terminal *> ia(1) := 20 shift 12 + 0; ia(2) := termcat.term_entry(2); ia(3) := termcat.term_entry(3); ia(4) := termcat.term_entry(4); ia(5) := termcat.term_entry(5); ia(6) := <:lan:> shift (-24) extract 24; ia(7) := <:mai:> shift (-24) extract 24; ia(8) := <:n:> shift (-24) extract 24; laf := 0; put_number(ia.laf,23,<<d>,lan); send_mess(tasterm,ia); if monitor(18,tasterm,1,ia) <> 1 then write_message(53,3,false,<:Sync. Error:>); i := 1; if ia(1) <> 0 then put_text(la,i,<:Make link error : :>,18) else put_text(la,i,<:Link : :>,7); laf := 2; put_text(la,i,termcat.term_entry.laf,12); i := 1; write_message(lan,ia(1),true,string la(increase(i))); end; end; next_term_entry; until (term_seg = 1) and (term_entry = 2); <* Tilbage ved start ! *> laf := 0; ia(1) := 20 shift 12 + 0; ia(2) := 0; send_mess(tasterm,ia); if monitor(18,tasterm,1,ia) <> 1 then write_message(53,3,false,<:Sync. Error:>); if false then alarm: disable traped(53); end; procedure tascat; <* 00 *> <*------------------------------------------*> <*------------------------------------------*> <* Hoved procedure for TASCAT *> <*------------------------------------------*> <*------------------------------------------*> begin integer array login_struc(1:4*struc_size); <*---------------------------------------------------------------------*> <* login_struc indeholder beskrivelse af alle tilmeldte brugere *> <* *> <* ! *> <* bruger ----> terminal ---- session *> <* ! ! ! *> <* ! ! V *> <* ! ! session *> <* ! ! . *> <* ! V . *> <* ! terminal ... *> <* V . *> <* bruger ... . *> <* . *> <* . *> <* *> <* login_struc er opdelt i blokke af 4 integer. *> <* brugerbeskrivelse = 2 blokke *> <* terminalbeskrivelse = 1 blok *> <* sessionsbeskrivelse = 1 blok *> <* *> <* brugerbeskrivelse: *> <* *> <* (0) - (3) : user id *> <* (4) : userindex map < 12 + last login time *> <* (5) : user privilege < 12 + user status *> <* (6) : terminal pointer *> <* (7) : next user pointer *> <* *> <* terminalbeskrivelse: *> <* *> <* (0) : terminal pda (Negative = terminal removed) *> <* (1) : mess < 21 + session map < 12 + terminal type *> <* (2) : session pointer *> <* (3) : next terminal pointer *> <* *> <* sessionbeskriver *> <* *> <* (0) : terminal handler cda (tasterm) *> <* (1) : session nr < 12 + user index *> <* (2) : session status *> <* (3) : next session *> <* *> <* free block beskriver *> <* *> <* (0) : 0 *> <* (1) : 0 *> <* (2) : prev. free block pointer *> <* (3) : next free block pointer *> <* *> <* pointer er index på første integer i blok. pointer lig 0 er tom. *> <* *> <* mess : 0 = ingen message *> <* bit sat angiver text buffer nr: *> <* lsb = 1, msb = 3 *> <* user index map : bit sat for hver user index benyttet *> <* index 0 lig lsb. *> <* session map : bit sat for hver session i brug *> <* session 1 lig 1 shift 1. *> <* last login time : sidste tilmeldingstid (0 til 24) *> <* 25 = ingen begrænsning (NON) *> <* 26 = under afmelding (NOW) *> <* 27 = remove mess. sendt *> <* >100 lig næste dag. *> <* user privilege : privilegiebit fra katalog *> <* user status : bit 11 sat lig tilmelding stoppet for bruger *> <* session status : bit 23 sat lig removing session *> <* *> <*---------------------------------------------------------------------*> procedure init_login_struc; <* 54 *> <*----------------------------------------------------*> <* Initialiser login_struc *> <*----------------------------------------------------*> begin integer size,pos; trap(alarm); system(3,size,login_struc); free_list:=1; userlist:=0; login_struc(1):=login_struc(2):=login_struc(3):=0; login_struc(4):=5; for pos:=5 step 4 until size-4 do begin login_struc(pos):=login_struc(pos+1):=0; login_struc(pos+2):=pos-4; login_struc(pos+3):=pos+4; end; login_struc(pos):=login_struc(pos+1):=login_struc(pos+3):=0; login_struc(pos+2):=pos-4; if false then alarm: disable traped(54); end; integer procedure get_free_login(numbers); <* 55 *> <*--------------------------------------------------------------*> <* Reserver et antal sammenhængende blokke i login strukturen. *> <* *> <* numbers (call) : Det antal blokke der ønskes reserveret *> <* Return : Peger til første blok der er reserveret *> <* eller nul (0) hvis det ikke var muligt *> <*--------------------------------------------------------------*> integer numbers; begin boolean found; integer free,cur,next,prev; trap(alarm); get_free_login:=0; found:=false; cur:=free_list; while not found and cur>0 do begin found:=true; free:=cur; while free <= cur+(numbers-2)*4 and found do if login_struc(free+3)=free+4 then free:=free+4 else found:=false; if not found then cur:=login_struc(free+3); end; if found then begin get_free_login:=cur; next:=login_struc(free+3); prev:=login_struc(cur+2); if prev=0 then free_list:=next else login_struc(prev+3):=next; if next>0 then login_struc(next+2):=prev; end; if false then alarm: disable traped(55); end; procedure release_block(addr); <* 56 *> <*---------------------------------------------------------------*> <* Indsæt blokken angivet ved addr i free listen direkte efter *> <* den forrige frie blok. *> <* *> <* addr (call) : Adressen på den blok der skal indsættes i free *> <* listen (listen udpeget af free_list) *> <*---------------------------------------------------------------*> integer addr; begin integer prev,next; trap(alarm); prev:=0; next:=free_list; while not (next > addr) and next>0 do begin prev:=next; next:=login_struc(prev+3); end; login_struc(addr):=0; login_struc(addr+1):=0; login_struc(addr+2):=prev; login_struc(addr+3):=next; if prev=0 then free_list:=addr else login_struc(prev+3):=addr; if next>0 then login_struc(next+2):=addr; if false then alarm: disable traped(56); end; integer procedure find_login_user(id,start); <* 57 *> <*-------------------------------------------------------------*> <* Find bruger beskrivelse i login struktur ud fra id *> <* Start søgningen med beskrivelsen udpeget af start *> <* *> <* id (call) : Navnet på brugeren der skal søges efter *> <* start (call) : Peger til første beskrivelse der søges i *> <* Return : Peger til fundet beskrivelse eller nul hvis *> <* beskrivelsen ikke blev fundet *> <*-------------------------------------------------------------*> value start; integer start; integer array id; begin integer i; boolean found; trap(alarm); find_login_user:=0; while start>0 do begin found:=true; for i:=1, i+1 while (i<=4 and found) do if login_struc(start+i-1)<>id(i) then found:=false; if found then begin find_login_user:=start; start:=0; end else start:=login_struc(start+7); end; if false then alarm: disable traped(57); end; integer procedure find_login_terminal(name,user_index); <* 58 *> <*-----------------------------------------------------------*> <* Find terminal beskrivelse i login_struc ud fra navn *> <* *> <* name (call) : Navnet på terminalen *> <* user_index (ret) : Index i login_struc på terminal bruger *> <* Return : Index i login_struc hvis fundet ellers 0 *> <*-----------------------------------------------------------*> integer array name; integer user_index; begin integer pda,term_index; boolean found; trap(alarm); pda:=get_pda(name); found:=false; term_index:=0; while user_index>0 and not found do begin term_index:=find_user_terminal(pda,login_struc(user_index+6)); if term_index>0 then found:=true else user_index:=login_struc(user_index+7); end; find_login_terminal:=term_index; if false then alarm: disable traped(58); end; integer procedure find_user_terminal(pda,start); <* 59 *> <*-------------------------------------------------------------*> <* Find terminal beskrivelse i login struktur ud fra pda *> <* Start søgningen med beskrivelsen udpeget af start *> <* *> <* pda (call) : PDA for den terminal der ledes efter *> <* start (call) : Peger til første beskrivelse der søges i *> <* Return : Peger til fundet beskrivelse eller nul hvis *> <* beskrivelsen ikke blev fundet *> <*-------------------------------------------------------------*> value start; integer pda,start; begin trap(alarm); find_user_terminal:=0; while start>0 do begin if login_struc(start)=pda then begin find_user_terminal:=start; start:=0; end else start:=login_struc(start+3); end; if false then alarm: disable traped(59); end; boolean procedure check_term(term_id); <* 60 *> <*--------------------------------------------------------------------*> <* Undersøg om terminal er indlogget *> <* *> <* term_id (call) : Navnet på terminalen (integer array (1:4) *> <* Return : True = terminal indlogget *> <* False = terminal ikke indlogget *> <*--------------------------------------------------------------------*> integer array term_id; begin integer pda,next; integer array dummy(1:1); boolean found; trap(alarm); found:=false; pda:=get_pda(term_id); if pda<>0 then begin next:=user_list; while (next<>0) and not found do begin found:=find_user_terminal(pda,login_struc(next+6))>0; next:=login_struc(next+7); end; end; check_term:=found; if false then alarm: disable traped(60); end; boolean procedure check_type(type_nr); <* 61 *> <*--------------------------------------------------------------------*> <* Undersøg om terminal med givet type nummer er indlogget *> <* *> <* type_nr (call) : nummeret på den type der checkes *> <* Return : True = type benyttet *> <* False = type ikke benyttet *> <*--------------------------------------------------------------------*> integer type_nr; begin integer next_user,next_term; boolean found; trap(alarm); found:=false; next_user:=user_list; while (next_user<>0) and not found do begin next_term:=login_struc(next_user+6); while (next_term<>0) and not found do begin found:=(login_struc(next_term+1) extract 12)=type_nr; next_term:=login_struc(next_term+3); end; next_user:=login_struc(next_user+7); end; check_type:=found; if false then alarm: disable traped(61); end; boolean procedure remove_sess(sess_index); <* 62 *> <*-----------------------------------------------------------------*> <* Send remove message til tasterm for angivet session *> <* Sæt remove-status i session hvis message er sendt ok *> <* *> <* sess_index (call) : Index i login_struc til session *> <* Return : True = Message sendt og/eller status sat *> <* False = Message ikke sendt eller ikke ok *> <* Status ikke sat af denne procedure *> <*-----------------------------------------------------------------*> integer sess_index; begin integer array ia(1:8); integer i; zone tasterm(1,1,std_error); trap(alarm); remove_sess:=true; if not (false add login_struc(sess_index+2)) then begin login_struc(sess_index+2):=login_struc(sess_index+2)+1; ia(1):=10 shift 12 + 0; ia(2):=login_struc(sess_index); open(tasterm,0,tasterm_name,1 shift 9); <* Imp. passivate *> send_mess(tasterm,ia); i:=monitor(18,tasterm,1,ia); if i<>1 or ia(1)<>0 then begin remove_sess:=false; login_struc(sess_index+2):=login_struc(sess_index+2)-1 end; end; if false then alarm: disable traped(62); end; integer procedure check_user(login_user,last_time, user_id,term_id,password1,password2); <* 63 *> <*--------------------------------------------------------------------------*> <* Check om bruger kan tilmeldes login strukturen *> <* *> <* last_time (ret) : Sidste indlognings tid for bruger (hvis bruger ok) *> <* login_user (ret) : Index til fundet bruger i login_struc eller *> <* hvis bruger er ny er login_user lig 0 *> <* user_id (call) : Navn på bruger der skal checkes (fra inlogning) *> <* term_id (call) : Navn på terminal hvorfra inlogning foretages. *> <* password1 (call) : Første ord i kodet password (fra inlogning) *> <* password2 (call) : Andet ord i kodet password *> <* Return : 0 hvis check af bruger er OK ellers fejlårsag *> <* *> <* Fejlårsag: *> <* *> <* 0 = User ok *> <* 1 = inlogning stopped *> <* 2 = max terminals inloged *> <* 3 = unknown user id *> <* 4 = wrong password *> <* 5 = terminal limit (illegal terminal group) *> <* 6 = user blocked *> <* 7 = terminal blocked *> <* 8 = max sessions exceeded *> <* 9 = login time exceeded *> <* 10 = no resources *> <* 11 = unknown terminal *> <* 12 = main consol *> <* *> <*--------------------------------------------------------------------------*> integer login_user,last_time; integer array user_id,term_id; integer password1,password2; begin integer check,group,i,count; real time; integer array id(1:8); trap(alarm); check:=0; <* Bruger OK *> if not find_term(term_id) then begin <* Find default terminal *> integer array default(1:4); default(1):=<:def:> shift (-24) extract 24; default(2):=<:aul:> shift (-24) extract 24; default(3):=<:t:> shift (-24) extract 24; default(4):=0; if not find_term(default) then check:=11; end; if sessions>=max_sessions then check:=8; if check=0 then begin group:=termcat.term_entry(7) extract 12; if group>=login_stat then check:=1 else if max_terms<=terms then check:=2 else if not find_user(user_id) then begin if max_term_block>0 then termcat.term_entry(6):=termcat.term_entry(6)+1; check:=3; end else if not ((usercat.user_entry(6)=password1) and (usercat.user_entry(7)=password2)) then begin check:=4; if ((password1<>0) or (password2<>0)) and (max_user_block>0) then usercat.user_entry(11):=usercat.user_entry(11)+1; end else if (usercat.user_entry(11) extract 12)<max_user_block or max_user_block=0 then usercat.user_entry(11):= (usercat.user_entry(11) shift (-12)) shift 12; end; if check=0 then begin i:=group//24; group:=23-(group mod 24); if not (false add (usercat.user_entry(19+i) shift (-group))) then begin check:=5; if max_term_block>0 then termcat.term_entry(6):=termcat.term_entry(6)+1; end else if (termcat.term_entry(6) extract 12)<max_term_block or max_term_block=0 then termcat.term_entry(6):= (termcat.term_entry(6) shift (-12)) shift 12; end; if check=0 then begin login_user:=find_login_user(user_id,user_list); if login_user>0 then begin if false add (login_struc(login_user+5) extract 1) then check:=1 else begin group:=login_struc(login_user+4); count:=0; for i:=-12 step (-1) until (-21) do if false add (group shift i) then count:=count+1; if count>=(usercat.user_entry(12) shift (-12)) then check:=8; end; end; end; if check=0 then begin <* test inlognings tid *> if login_user>0 then begin <* test i login_struc *> last_time:=login_struc(login_user+4) extract 12; if timecheck_stat and (last_time=26 or last_time=27 or last_time=0) then check:=9; end else <* test i katalog *> if not check_time(last_time) then check:=9 end; for i:=1 step 1 until 4 do id(i):=logor((32 shift 16 + 32 shift 8 + 32),user_id(i)); for i:=5 step 1 until 8 do id(i):=term_id(i-4); i:=1; if ((usercat.user_entry(11) extract 12)>=max_user_block) and (max_user_block>0) then begin check:=6; if ((usercat.user_entry(11) extract 12) mod 5=max_user_block) then begin write_message(63,1,true,<:Max. user block reached:>); write_message(63,usercat.user_entry(11) extract 12,true, string id.laf(increase(i))); end; end else if ((termcat.term_entry(6) extract 12)>=max_term_block) and (max_term_block>0) then begin check:=7; if ((termcat.term_entry(6) extract 12) mod 5=max_term_block) then begin write_message(63,2,true,<:Max. terminal block reached:>); write_message(63,termcat.term_entry(6) extract 12,true, string id.laf(increase(i))); end; end; write_user_seg; write_term_seg; check_user:=check; if false then alarm: disable traped(63); end; boolean procedure check_time(time_last); <* 64 *> <*----------------------------------------------------------------------*> <* Check inlognings tidspunktet for bruger angivet i aktuelt user_entry *> <* *> <* time_last (ret) : sidste indlognings tid for bruger eller 25 hvis *> <* der ikke er sat grænse *> <* Return : True hvis ok, False hvis ikke ok *> <*----------------------------------------------------------------------*> integer time_last; begin boolean field day; integer time_type,time_first,time_cur,new_time_last; real time; trap(alarm); systime(1,0,time); day:=(round((time/86400)-0.5) mod 7)+15; time_type:=usercat.user_entry.day extract 2; time_first:=(usercat.user_entry.day shift (-7)) extract 5; time_last:=(usercat.user_entry.day shift (-2)) extract 5; check_time:=false; time_cur:=cur_time; if time_type<>0 then begin if time_cur<time_first then begin day:=day-1; if day<15 then day:=21; new_time_last:=(usercat.user_entry.day shift (-2)) extract 5; if (usercat.user_entry.day extract 2 = 2) and (time_cur<new_time_last) then begin if new_time_last<time_first then time_last:=new_time_last; check_time:=true; end; end else if (time_type=3) or (time_last>24) or (time_first=0 and time_last=24) then begin time_last:=25; check_time:=true; end else if (time_type=2) then begin time_last:=time_last+100; check_time:=true; end else if (time_type=1) and (time_cur>=time_first) and (time_cur<time_last) then check_time:=true; end else time_last:=0; if not timecheck_stat then check_time:=true; if false then alarm: disable traped(64); end; procedure mess_to_term(term_index,text_buf); <* 65 *> <*--------------------------------------------------------------------------*> <* Sæt markering i login structure at tekst skal udskrives *> <* Ved kald skal struc_sema være 'sat' *> <* *> <* term_index (call): Index i login_struc på terminal *> <* text_buf (call) : Nummeret på tekst buffer der skal skrives fra *> <*--------------------------------------------------------------------------*> integer term_index; integer text_buf; begin trap(alarm); login_struc(term_index+1):=logor(loginstruc(term_index+1), 1 shift (text_buf+20) ); if false then alarm: disable traped(65); end; integer procedure set_text_buf(text); <* 65.1 *> <*--------------------------------------------------------------------------*> <* Sæt text i buffer i tasterm. *> <* *> <* text (call) : Teksten der skal sættes *> <* Return : Nummeret på den buffer teksten er sat i eller 0 hvis *> <* der ingen ledig buffer er *> <*--------------------------------------------------------------------------*> integer array text; begin zone tasterm(40,1,stderror); integer array ia(1:20),term_id(1:4); integer i,hw,term_type,nr; trap(alarm); hw:=text(0) shift (-12)+4; nr:=0; for i:=1,2,3 do if text_buf_reserved(i)=0 then nr:=i; if hw<=148 and nr>0 then begin tasterm.iaf(1):=(7 shift 16) + (7 shift 8) +7; tasterm.iaf(2):=10; for i:=3 step 1 until (hw//2) do tasterm.iaf(i):=text(i-2); text_buf_reserved(nr):=-1; open(tasterm,0,tasterm_name,1 shift 9); <* Imp. passivate *> getzone6(tasterm,ia); ia(1):=11 shift 12 +0; ia(2):=ia(19)+1; ia(3):=ia(2)+hw-2; ia(4):=nr; send_mess(tasterm,ia); i:=monitor(18,tasterm,1,ia); if i<>1 then begin text_buf_reserved(nr):=0; nr:=0; end; end; set_text_buf:=nr; if false then alarm: disable traped(651); end; procedure send_message_text(nr); <* 65.2 *> <*------------------------------------------*> <* Signalerer til write_term_text korutinen *> <* at der er tekst til udskrift *> <*------------------------------------------*> integer nr; begin integer array ref(1:1); trap(alarm); initref(ref); wait_select:=8; wait(message_buf_pool,ref); ref(3):=nr; signal(text_write_sem,ref); if false then alarm: disable traped(652); end; boolean procedure check_user_priv(priv,result); <* 66 *> <*-------------------------------------------------------------------*> <* Test om bruger givet i copy_buf er kendt, har korrekt password og *> <* har det angivne privilegie *> <* *> <* priv (call) : Privilegie der testes for (0 til 4) *> <* result (ret) : 0 = Ok *> <* 1 = Ukendt bruger *> <* 2 = Forkert password *> <* 3 = Privilegie ikke opfyldt *> <* Return : True hvis result=0 ellers false *> <* Er result=0 er user_entry sat til fundet bruger *> <*-------------------------------------------------------------------*> integer priv,result; begin trap(alarm); result:=1; if find_user(copy_buf.iaf) then begin <* Bruger fundet *> result:=2; if (copy_buf.iaf(5)=usercat.user_entry(6)) and (copy_buf.iaf(6)=usercat.user_entry(7)) then begin <* password ok *> result:=if false add (usercat.user_entry(12) shift (priv-11)) then 0 <* privilegie ok *> else 3; <* Privilegie ikke sat *> end; end; check_user_priv:=result=0; if false then alarm: disable traped(66); end; procedure catco; <* 67 *> <*---------------------------------------*> <* Hoved procedure for catalog korutinen *> <*---------------------------------------*> begin zone dummy_zone(1,1,stderror); integer operation, mode, i; <***********************************> <* Procedure til katalog korutinen *> <***********************************> procedure attention; <* 68 *> <*---------------------------------------------------------------------*> <* Start en ny operatør korutine hvis der er attention fra ny terminal *> <*---------------------------------------------------------------------*> begin integer i,head_consol; integer array ref(1:1); boolean found; integer array sender_name(1:4); trap(alarm); i:=4; answer(9):=1; found:=false; while (not found) and (i<(number_of_opera+4)) do begin found:=opera_terms(i,1)=mess.sender_pda; i:=i+1; end; system(5,mess.sender_pda,sender_name); if sender_name(1)=0 then begin answer(9):=2; found:=true; end; if not found then begin <* Ny terminal *> get_proc_name(mess.sender_pda,sender_name); i:=if (sender_name.laf(1)=head_term_name.laf(1)) and (sender_name.laf(2)=head_term_name.laf(2)) then 4 else 5; head_consol:=i-4; while (not found) and (i<(number_of_opera+4)) do begin found:=opera_terms(i,1)=0; i:=i+1; end; if found then begin <* Ventende operatør korutine er fundet *> opera_terms(i-1,1):=mess.sender_pda; initref(ref); wait_select:=6; wait(message_buf_pool,ref); ref(3):=head_consol; signal(opera_terms(i-1,2),ref); answer(9):=1; <* Operatør er startet *> end else begin answer(9):=2; <* Ikke flere operatør rutiner *> end; end; if false then alarm: disable traped(68); end; procedure get_segments; <* 69 *> <*--------------------------------------------------*> <* Hent segmenter fra katalogerne til bruger proces *> <*--------------------------------------------------*> begin integer seg,cat,i,size; trap(alarm); seg:=mess.mess_array(4); cat:=mess.mess_array(5); if (cat<1) or (cat>3) then answer(1):=1 shift 22 <* error; illegal katalog type *> else begin if data_to_copy_buf(6,mess.buf_addr,answer)=0 then begin <* data kopieret *> if check_user_priv(1,answer(1)) then begin <* operatør ok *> case cat of begin begin <* bruger katalog *> if usercat_size>seg then begin size:=usercat_size; find_user_seg(seg); for i:=1 step 1 until 128 do copy_buf(i):=usercat(i); end else answer(1):=1 shift 18; <* end of catalog *> end; begin <* terminal katalog *> if termcat_size>seg then begin size:=termcat_size; find_term_seg(seg); for i:=1 step 1 until 128 do copy_buf(i):=termcat(i); end else answer(1):=1 shift 18; <* end of catalog *> end; begin <* type katalog *> if typecat_size>seg then begin size:=typecat_size; setposition(typecat,0,seg); write_type_seg; for i:=1 step 1 until 128 do copy_buf(i):=typecat(i); end else answer(1):=1 shift 18; <* end of catalog *> end; end; <* case *> if answer(1)=0 then begin answer(1):=if data_from_copy_buf(256,mess.buf_addr,answer)<>0 then 1 shift 23 <* fejl i kopiering *> else 0; <* alt ok *> answer(4):=size; end; end else if answer(1)=3 then answer(1):=1 shift 11 <* ingen privilegie *> else answer(1):=1 shift 10; <* illegal bruger (operatør) *> end else answer(1):=1 shift 23; <* bruger proces stoppet *> end; answer(9):=1; if false then alarm: disable traped(69); end; procedure tasterm_mess; <* 70 *> <*-------------------------------*> <* Behandling af message fra TAS *> <*-------------------------------*> begin <******************************> <* Procedure til tasterm_mess *> <******************************> procedure sign_on; <* 71 *> <*------------------------------------------------*> <* Undersøg inlognings muligheden og hvis ok *> <* dan signon tekst til brug for TAS *> <*------------------------------------------------*> begin integer term_type,width,pos,date_width; integer array term_id(1:4); long array date_text(1:6); boolean term_found,def; trap(alarm); def:=false; get_proc_name(mess.mess_array(4),term_id); if (term_id.laf(1)=head_term_name.laf(1)) and (term_id.laf(2)=head_term_name.laf(2)) then <* Hovedkonsollen *> answer(1):=12 else if terms<max_terms then begin <* Ikke maximalt antal terminaler tilmeldt *> answer(1):=11; if get_proc_name(mess.mess_array(4),term_id) then begin <* terminal id fundet *> term_found:=find_term(term_id); if not term_found then begin <* Find default terminal *> integer array default(1:4); default(1):=<:def:> shift (-24) extract 24; default(2):=<:aul:> shift (-24) extract 24; default(3):=<:t:> shift (-24) extract 24; default(4):=0; def:=true; term_found:=find_term(default); end; if term_found then begin <* Terminal kendt i katalog *> if (termcat.term_entry(7) extract 12)>=login_stat then answer(1):=1; term_type:=termcat.term_entry(6) shift (-12); if answer(1)<>1 and find_type_entry(term_type) then begin if typecat.type_entry(1)>0 then begin <* Term type fundet i katalog *> width:=typecat.type_entry(3) shift (-12); date_width:=date(date_text); copy_buf.iaf(1):=((termcat.term_entry(7) shift (-12)) shift 12)+term_type; <* sæt signon text i copy_buf *> pos:=7; <* Første tegn i copy_buf i position 7 *> laf:=56; <* Sæt init data i tekst *> put_text(copy_buf,pos,char_table,typecat.type_entry.laf,-75); laf:=0; <* Sæt signon tekst *> put_char(copy_buf,pos,10,2); put_char(copy_buf,pos,32,(width-(host_id(0) extract 12))//2); put_text(copy_buf,pos,host_id.laf,host_id(0) extract 12); put_char(copy_buf,pos,10,2); put_char(copy_buf,pos,32,(width-date_width)//2); put_text(copy_buf,pos,date_text,date_width); put_char(copy_buf,pos,10,2); put_text(copy_buf,pos,signon_text.laf, signon_text(0) extract 12); put_char(copy_buf,pos,10,2); if def then begin puttext(copy_buf,pos,<:<10>Terminal :>,10); puttext(copy_buf,pos,term_id.laf,-12); puttext(copy_buf,pos,<: er ikke i katalog<10>:>,19); end; copy_buf.iaf(2):=(2*((pos-5)//3+1) shift 12) + (pos-7); put_char(copy_buf,pos,0,3); <* Kopier data til TAS *> if data_from_copy_buf(152,mess.buf_addr,answer)<>0 then write_message(71,1,true,string c_p ); answer(1):=0; end; end; end; end; end else answer(1):=2; if false then alarm: disable traped(71); end; procedure include_user; <* 72 *> <*---------------------------------*> <* Inkluder ny bruger og terminal *> <*---------------------------------*> begin integer user_index,term_index,sess_index,last_time,i,ui; integer array user_id,term_id(1:4); integer array struc_ref(1:1); boolean term_found; procedure init_term; <* 73 *> <* initialiser term i login_struc *> begin login_struc(term_index):=copy_buf.iaf(1); <* bemærk: term_entry sat af find_term *> login_struc(term_index+1):= (1 shift 13)+(termcat.term_entry(6) shift (-12)); login_struc(term_index+2):=sess_index; login_struc(term_index+3):=login_struc(user_index+6); login_struc(user_index+6):=term_index; terms:=terms+1; end; procedure init_sess; <* 74 *> <* initialiser sess i login_struc *> begin login_struc(sess_index):=copy_buf.iaf(2); ui:=0; while false add (login_struc(user_index+4) shift (-ui-12)) do ui:=ui+1; <* Sæt ny userindex bit *> login_struc(user_index+4):=login_struc(user_index+4)+(1 shift (12+ui)); login_struc(sess_index+1):=(1 shift 12)+ui; <* session 1, user-index ui *> login_struc(sess_index+2):=0; login_struc(sess_index+3):=0; sessions:=sessions+1; end; trap(alarm); initref(struc_ref); wait(struc_sema,struc_ref); answer(1):=0; user_index:=term_index:=sess_index:=0; if data_to_copy_buf(8,mess.buf_addr,answer)=0 then begin <* Data kopieret *> if answer(2)=16 then begin <* alt kopieret *> answer(1):=0; for i:=1 step 1 until 4 do user_id(i):=copy_buf.iaf(i+2); if get_proc_name(copy_buf.iaf(1),term_id) then begin <* Terminal navn fundet *> term_found:=find_term(term_id); if not term_found then begin <* Find default terminal *> integer array default(1:4); default(1):=<:def:> shift (-24) extract 24; default(2):=<:aul:> shift (-24) extract 24; default(3):=<:t:> shift (-24) extract 24; default(4):=0; term_found:=find_term(default); end; if term_found then begin <* Terminal fundet i katalog *> answer(1):=check_user(user_index,last_time, user_id,term_id,copy_buf.iaf(7),copy_buf.iaf(8)); if answer(1)=0 then begin <* user ok *> if user_index=0 then begin <* Ny bruger *> term_index:=sess_index:=0; user_index:=get_free_login(4); if user_index>0 then begin term_index:=user_index+8; sess_index:=user_index+12; end else begin user_index:=get_free_login(2); if user_index>0 then begin term_index:=get_free_login(2); if term_index>0 then sess_index:=term_index+4 else begin term_index:=get_free_login(1); if term_index>0 then sess_index:=get_free_login(1); end; end; end; if term_index=0 then begin release_block(user_index); release_block(user_index+4); user_index:=0; end else if sess_index=0 then begin release_block(user_index); release_block(user_index+4); release_block(term_index); user_index:=term_index:=0; end; if user_index>0 then begin <* Initialiser ny user, term og sess *> for i:=1 step 1 until 4 do login_struc(user_index+i-1):=user_id(i); login_struc(user_index+4):=last_time; <* bemærk: user_entry sat af check_user *> login_struc(user_index+5):=usercat.user_entry(12) shift 12; login_struc(user_index+6):=0; <* indsæt ny user først i user liste *> login_struc(user_index+7):=user_list; user_list:=user_index; init_term; init_sess; users:=users+1; end; end <* Ny bruger indsat, hvis user_index>0 *> else begin <* Bruger kendt, ny terminal og session *> term_index:=get_free_login(2); if term_index>0 then sess_index:=term_index+4 else begin term_index:=get_free_login(1); if term_index>0 then sess_index:=get_free_login(1); end; if sess_index=0 then begin release_block(term_index); term_index:=0; end; if term_index>0 then begin <* Initialiser term og sess *> init_term; init_sess; end; end; <* Ny terminal og session indsat, hvis term_index>0 *> end; <* user ok *> end <* terminal navn fundet *> else <* pda ukendt *> answer(1):=11; end else <* terminal ukendt *> answer(1):=11; if answer(1)=0 then begin if (user_index>0) and (term_index>0) then begin copy_buf.iaf(1):=user_index; for i:=2 step 1 until 7 do copy_buf.iaf(i):=usercat.user_entry(i+11); copy_buf.iaf(8):=1; copy_buf.iaf(9):=(4 shift 12)+1; copy_buf.iaf(10):=(ui+48) shift 16; copy_buf.iaf(11):=(4 shift 12)+1; copy_buf.iaf(12):=49 shift 16; for i:=13 step 1 until 40 do copy_buf.iaf(i):=usercat.user_entry(i+10); if data_from_copy_buf(40,mess.buf_addr,answer)<>0 then write_message(74,1,true,string c_p ); answer(1):=0; end else answer(1):=10; end; end <* alt kopiret *> else answer(9):=3; end <* data kopieret *> else write_message(74,2,true,string c_p ); signal(struc_sema,struc_ref); if false then alarm: disable traped(74); end; procedure start_sess; <* 75 *> <*--------------------------------------------------*> <* Start en ny session hos kendt bruger og terminal *> <*--------------------------------------------------*> begin integer user_index,term_index,sess_index,i,ui,sess_nr,map,count; integer array user_id(1:4); integer array struc_ref(1:1); trap(alarm); initref(struc_ref); wait(struc_sema,struc_ref); user_index:=term_index:=sess_index:=0; if data_to_copy_buf(3,mess.buf_addr,answer)=0 then begin <* data kopieret *> if answer(2)=6 then begin answer(1):=0; user_index:=copy_buf.iaf(3); if (user_index>0) and (user_index<=(4*struc_size-7)) then begin for i:=1 step 1 until 4 do user_id(i):=login_struc(user_index+i-1); if find_user(user_id) then begin <* bruger kendt *> if (login_stat>0) and not (false add login_struc(user_index+5)) then begin <* bruger login ok *> map:=login_struc(user_index+4) shift (-12); count:=0; for i:=0 step (-1) until (-9) do if false add (map shift i) then count:=count+1; if (count<(usercat.user_entry(12) shift (-12))) and (sessions<max_sessions) then begin <* ledige sessioner *> if cur_time<(login_struc(user_index+4) extract 12) then begin <* tid ok *> term_index:=find_user_terminal(copy_buf.iaf(1), login_struc(user_index+6)); if term_index>0 then begin <* terminal kendt *> sess_index:=get_free_login(1); if sess_index>0 then begin <* resourcer ok *> login_struc(sess_index+3):=login_struc(term_index+2); login_struc(term_index+2):=sess_index; login_struc(sess_index):=copy_buf.iaf(2); login_struc(sess_index+2):=0; ui:=0; while false add (login_struc(user_index+4) shift (-ui-12)) do ui:=ui+1; <* Sæt ny userindex bit *> login_struc(user_index+4):= login_struc(user_index+4)+(1 shift (12+ui)); sess_nr:=1; sessions:=sessions+1; while false add (login_struc(term_index+1) shift (-sess_nr-12)) do sess_nr:=sess_nr+1; <* Sæt ny sessions nummer bit *> login_struc(term_index+1):= login_struc(term_index+1)+(1 shift (12+sess_nr)); login_struc(sess_index+1):= (sess_nr shift 12)+ui; <* session nr, user-index *> end <* initialiser *> else answer(1):=10; end else answer(1):=11; end else answer(1):=9; end else answer(1):=8; end else answer(1):=1; end else answer(1):=3; end else answer(1):=3; if answer(1)=0 then begin <* sæt returdata i copy_buf *> copy_buf.iaf(1):=user_index; for i:=2 step 1 until 7 do copy_buf.iaf(i):=usercat.user_entry(i+11); copy_buf.iaf(8):=sess_nr; copy_buf.iaf(9):=(4 shift 12)+1; copy_buf.iaf(10):=(ui+48) shift 16; copy_buf.iaf(11):=(4 shift 12)+1; copy_buf.iaf(12):=(sess_nr+48) shift 16; for i:=13 step 1 until 40 do copy_buf.iaf(i):=usercat.user_entry(i+10); if data_from_copy_buf(40,mess.buf_addr,answer)<>0 then write_message(75,1,true,string c_p ); answer(1):=0; end; end else answer(9):=3; end else write_message(75,2,true,string c_p ); signal(struc_sema,struc_ref); if false then alarm: disable traped(75); end; procedure end_sess; <* 76 *> <*-------------------------------------------------------------------------*> <* Nedlæg en sessions beskrivelse *> <* Er det sidste session på terminalen, nedlægges terminal beskrivelsen *> <* Er det sidste terminal på bruger, nedlægges bruger beskrivelsen *> <*-------------------------------------------------------------------------*> begin integer user_index,term_index,sess_index; integer prev_user_index,prev_term_index,prev_sess_index; integer next_user_index; integer array struc_ref(1:1); boolean found; trap(alarm); initref(struc_ref); wait(struc_sema,struc_ref); user_index:=mess.mess_array(4); if (user_index>0) and (user_index<=(4*struc_size-7)) then begin found:=false; prev_term_index:=0; term_index:=login_struc(user_index+6); while term_index>0 and not found do begin <* find terminal beskrivelse *> if abs login_struc(term_index)=mess.mess_array(2) then found:=true else begin prev_term_index:=term_index; term_index:=login_struc(term_index+3); end; end; if found then begin <* terminal fundet *> found:=false; prev_sess_index:=0; sess_index:=login_struc(term_index+2); while sess_index>0 and not found do begin <* find sessions beskrivelse *> if login_struc(sess_index)=mess.mess_array(3) then found:=true else begin prev_sess_index:=sess_index; sess_index:=login_struc(sess_index+3); end; end; if found then begin <* session fundet *> if (prev_sess_index=0) and (login_struc(sess_index+3)=0) then begin <* sidste session på denne terminal *> if (prev_term_index=0) and (login_struc(term_index+3)=0) then begin <* sidste terminal for denne bruger *> <* nedlæg bruger *> prev_user_index:=0; next_user_index:=user_list; while user_index<>next_user_index do begin prev_user_index:=next_user_index; next_user_index:=login_struc(next_user_index+7); end; if prev_user_index=0 then user_list:=login_struc(user_index+7) else login_struc(prev_user_index+7):=login_struc(user_index+7); release_block(user_index); release_block(user_index+4); release_block(term_index); release_block(sess_index); terms:=terms-1; users:=users-1; sessions:=sessions-1; answer(1):=2; end else begin <* nedlæg terminal *> <* nulstil userindex bit for session i map *> login_struc(user_index+4):=login_struc(user_index+4) - (1 shift ((login_struc(sess_index+1) extract 12)+12)); if prev_term_index=0 then login_struc(user_index+6):=login_struc(term_index+3) else login_struc(prev_term_index+3):=login_struc(term_index+3); release_block(term_index); release_block(sess_index); terms:=terms-1; sessions:=sessions-1; answer(1):=1; end; end else begin <* nedlæg session *> <* nulstil userindex bit for session i map *> login_struc(user_index+4):=login_struc(user_index+4) - (1 shift ((login_struc(sess_index+1) extract 12)+12)); <* nulstil sessions nr bit for session i map *> login_struc(term_index+1):=login_struc(term_index+1) - (1 shift ((login_struc(sess_index+1) shift (-12))+12)); if prev_sess_index=0 then login_struc(term_index+2):=login_struc(sess_index+3) else login_struc(prev_sess_index+3):=login_struc(sess_index+3); release_block(sess_index); sessions:=sessions-1; answer(1):=0; end; end else answer(1):=3; <* session ikke fundet *> end else answer(1):=3; <* terminal ikke fundet *> end else answer(1):=3; <* Ukendt bruger *> signal(struc_sema,struc_ref); if false then alarm: disable traped(76); end; procedure modify_pass; <* 77 *> <*--------------------------------------*> <* Sæt nyt password for inlogget bruger *> <*--------------------------------------*> begin integer user_index; integer array field user_id; integer array struc_ref(1:1); trap(alarm); initref(struc_ref); wait(struc_sema,struc_ref); if data_to_copy_buf(5,mess.buf_addr,answer)=0 then begin <* data læst *> if answer(2)=10 then begin <* al data læst *> answer(1):=1; user_index:=copy_buf.iaf(1); if (user_index>0) and (user_index<=(4*struc_size-7)) then begin <* User ident ok *> user_id:=(user_index-1)*2; if find_user(login_struc.user_id) then begin <* bruger fundet i katalog *> if (usercat.user_entry(6)=copy_buf.iaf(2)) and (usercat.user_entry(7)=copy_buf.iaf(3)) then begin <* old password ok *> usercat.user_entry(6):=copy_buf.iaf(4); usercat.user_entry(7):=copy_buf.iaf(5); usercat.user_entry(61):=usercat.user_entry(61)+1; write_user_seg; answer(1):=0; end; end; end; end else answer(9):=3; end else write_message(77,3,true,string c_p ); signal(struc_sema,struc_ref); if false then alarm: disable traped(77); end; procedure get_term_data; <* 78 *> <*---------------------------------*> <* Hent terminal type data til TAS *> <*---------------------------------*> begin integer i; trap(alarm); answer(1):=1; if find_type_entry(mess.mess_array(4)) then begin if typecat.type_entry(1)>0 then begin <* type entry fundet *> for i:=1 step 1 until 53 do <* Kopier data *> copy_buf.iaf(i):=typecat.type_entry(i); if data_from_copy_buf(53,mess.buf_addr,answer)<>0 then write_message(78,1,true,string c_p ); answer(1):=0; end; end; if false then alarm: disable traped (78); end; procedure terminal_removed; <* 781 *> <*-------------------------------------------------------------------------*> <* Marker terminal som midlertidig fjernet. *> <*-------------------------------------------------------------------------*> begin integer user_index,term_index,sess_index; integer prev_user_index,prev_term_index,prev_sess_index; integer next_user_index; integer array struc_ref(1:1); boolean found; trap(alarm); initref(struc_ref); wait(struc_sema,struc_ref); user_index:=mess.mess_array(4); if (user_index>0) and (user_index<=(4*struc_size-7)) then begin found:=false; prev_term_index:=0; term_index:=login_struc(user_index+6); while term_index>0 and not found do begin <* find terminal beskrivelse *> if abs login_struc(term_index)=mess.mess_array(2) then found:=true else begin prev_term_index:=term_index; term_index:=login_struc(term_index+3); end; end; if found then begin <* terminal fundet *> login_struc(term_index) := -login_struc(term_index); end else answer(1):=3; <* terminal ikke fundet *> end else answer(1):=3; <* Ukendt bruger *> signal(struc_sema,struc_ref); if false then alarm: disable traped(781); end; procedure terminal_restart; <* 782 *> <*-------------------------------------------------------------------------*> <* Marker terminal som genstartet *> <*-------------------------------------------------------------------------*> begin integer user_index,term_index,sess_index; integer prev_user_index,prev_term_index,prev_sess_index; integer next_user_index; integer array struc_ref(1:1); boolean found; trap(alarm); initref(struc_ref); wait(struc_sema,struc_ref); user_index:=mess.mess_array(4); if (user_index>0) and (user_index<=(4*struc_size-7)) then begin found:=false; prev_term_index:=0; term_index:=login_struc(user_index+6); while term_index>0 and not found do begin <* find terminal beskrivelse *> if abs login_struc(term_index)=mess.mess_array(2) then found:=true else begin prev_term_index:=term_index; term_index:=login_struc(term_index+3); end; end; if found then begin <* terminal fundet. Sæt ny PDA *> login_struc(term_index) := mess.mess_array(3); end else answer(1):=3; <* terminal ikke fundet *> end else answer(1):=3; <* Ukendt bruger *> signal(struc_sema,struc_ref); if false then alarm: disable traped(782); end; <**************************************> <* Hoveddel af procedure tasterm_mess *> <**************************************> trap(alarm); if (mode<2) or (mode>9) or (mess.sender_pda<>tasterm_pda) then <* Ukendt mode i message eller illegal sender *> answer(9):=3 else begin answer(9):=1; case mode-1 of begin sign_on; include_user; start_sess; end_sess; modify_pass; get_term_data; terminal_removed; terminal_restart; end; end; if false then alarm: disable traped(70); end; procedure modify_entry; <* 79 *> <*-----------------------------------------------*> <* Behandling af modify_entry message fra bruger *> <*-----------------------------------------------*> begin procedure modify_user_entry; <* 80 *> <*------------------------------------------------*> <* Hent, sæt eller modifiser data i brugerkatalog *> <*------------------------------------------------*> begin integer array field user_id,liaf; boolean user_exist; integer func,i; trap(alarm); user_id:=12; func:=mess.mess_array(4)+1; if (func<1) or (func>4) then answer(9):=3 else begin if data_to_copy_buf((case func of (10,66,66,10)), mess.buf_addr,answer)=0 then begin <* data kopieret *> if check_user_priv(1,answer(1)) then begin <* operatør ok *> user_exist:=find_user(copy_buf.user_id); liaf:=10; case func of begin <* Get data *> if user_exist then begin for i:=2 step 1 until 61 do copy_buf.liaf(i):=usercat.user_entry(i); answer(1):=if data_from_copy_buf(66,mess.buf_addr,answer)=0 then 0 <* ok *> else 8; <* process stopped *> end else answer(1):=2; <* entry not found *> <* Modify data *> if user_exist then begin if find_login_user(copy_buf.user_id,user_list)=0 then begin <* bruger er ikke logget ind *> if copy_buf.liaf(61)=usercat.user_entry(61) then begin <* time stamp's ens *> for i:=2 step 1 until 60 do usercat.user_entry(i):=copy_buf.liaf(i); <* sæt ny time stamp *> usercat.user_entry(61):=usercat.user_entry(61)+1; write_user_seg; answer(1):=0; end else answer(1):=7; <* Data changed since last get-data *> end else answer(1):=1; <* entry in use *> end else answer(1):=2; <* entry not found *> <* Set new data *> if not user_exist then begin if find_empty_user_entry( calc_hash(copy_buf.user_id,usercat_size)) then begin <* tomt entry fundet *> for i:=2 step 1 until 60 do usercat.user_entry(i):=copy_buf.liaf(i); <* sæt ny time stamp *> usercat.user_entry(61):=0; write_user_seg; answer(1):=0; end else answer(1):=6; <* catalog full *> end else answer(1):=3; <* entry exist *> <* Delete data *> if user_exist then begin if find_login_user(copy_buf.user_id,user_list)=0 then begin <* bruger ikke logget ind *> usercat.user_entry(1):=0; setstate(usercat,6); find_user_seg(calc_hash(copy_buf.user_id,usercat_size)); user_entry:=0; <* nedtæl hash-nøgle tæller *> usercat.user_entry(1):=usercat.user_entry(1)-1; write_user_seg; answer(1):=0; end else answer(1):=1; <* entry in use *> end else answer(1):=2; <* entry not found *> end; end else answer(1):=if answer(1)=3 then 4 <* ingen privilegie *> else 13; <* illegal bruger (operatør) *> end else answer(1):=8; <* bruger proces stoppet *> end; if false then alarm: disable traped(80); end; procedure modify_term_entry; <* 81 *> <*--------------------------------------------------*> <* Hent, sæt eller modificer data i terminalkatalog *> <*--------------------------------------------------*> begin integer array field term_id,liaf; boolean term_exist; integer func,i; trap(alarm); term_id:=12; func:=mess.mess_array(4)+1; if (func<1) or (func>4) then answer(9):=3 else begin if data_to_copy_buf((case func of (10,23,23,10)), mess.buf_addr,answer)=0 then begin <* data kopieret *> if check_user_priv(1,answer(1)) then begin <* operatør ok *> term_exist:=find_term(copy_buf.term_id); liaf:=10; case func of begin <* Get data *> if term_exist then begin for i:=2 step 1 until 18 do copy_buf.liaf(i):=termcat.term_entry(i); answer(1):=if data_from_copy_buf(23,mess.buf_addr,answer)=0 then 0 <* ok *> else 8; <* process stopped *> end else answer(1):=2; <* entry not found *> <* Modify data *> if term_exist then begin if not check_term(copy_buf.term_id) then begin <* terminal ikke logget ind *> if copy_buf.liaf(18)=termcat.term_entry(18) then begin <* time stamp's ens *> for i:=2 step 1 until 17 do termcat.term_entry(i):=copy_buf.liaf(i); <* sæt ny time stamp *> termcat.term_entry(18):=termcat.term_entry(18)+1; write_term_seg; answer(1):=0; end else answer(1):=7; <* Data changed since last get-data *> end else answer(1):=1; <* entry in use *> end else answer(1):=2; <* entry not found *> <* Set new data *> if not term_exist then begin if find_empty_term_entry( calc_hash(copy_buf.term_id,termcat_size)) then begin <* tomt entry fundet *> for i:=2 step 1 until 17 do termcat.term_entry(i):=copy_buf.liaf(i); <* sæt ny time stamp *> termcat.term_entry(18):=0; write_term_seg; answer(1):=0; end else answer(1):=6; <* catalog full *> end else answer(1):=3; <* entry exist *> <* Delete data *> if term_exist then begin if not check_term(copy_buf.term_id) then begin <* terminal ikke logget ind *> termcat.term_entry(1):=0; setstate(termcat,6); find_term_seg(calc_hash(copy_buf.term_id,termcat_size)); term_entry:=0; <* nedtæl hash-nøgle tæller *> termcat.term_entry(1):=termcat.term_entry(1)-1; write_term_seg; answer(1):=0; end else answer(1):=1; <* entry in use *> end else answer(1):=2; <* entry not found *> end; end else answer(1):=if answer(1)=3 then 4 <* ingen privilegie *> else 13; <* illegal bruger (operatør) *> end else answer(1):=8; <* bruger proces stoppet *> end; if false then alarm: disable traped(81); end; procedure modify_type_entry; <* 82 *> <*----------------------------------------------*> <* Hent, sæt eller modificer data i typekatalog *> <*----------------------------------------------*> begin integer array field liaf; boolean type_exist; integer func,i; integer field type_nr; trap(alarm); type_nr:=14; func:=mess.mess_array(4)+1; if (func<1) or (func>4) then answer(9):=3 else begin if data_to_copy_buf((case func of (7,70,70,7)), mess.buf_addr,answer)=0 then begin <* data kopieret *> if check_user_priv(1,answer(1)) then begin <* operatør ok *> type_exist:=false; if find_type_entry(copy_buf.type_nr) then type_exist:=typecat.type_entry(1)<>0; liaf:=12; case func of begin <* Get data *> if type_exist then begin for i:=1 step 1 until 64 do copy_buf.liaf(i):=typecat.type_entry(i); answer(1):=if data_from_copy_buf(70,mess.buf_addr,answer)=0 then 0 <* ok *> else 8; <* process stopped *> end else answer(1):=2; <* entry not found *> <* Modify data *> if type_exist then begin if not check_type(copy_buf.type_nr) then begin <* type er ikke i login terminaler *> if copy_buf.liaf(64)=typecat.type_entry(64) then begin <* time stamp's ens *> for i:=1 step 1 until 63 do typecat.type_entry(i):=copy_buf.liaf(i); <* sæt ny time stamp *> typecat.type_entry(64):=typecat.type_entry(64)+1; write_type_seg; answer(1):=0; end else answer(1):=7; <* Data changed since last get-data *> end else answer(1):=1; <* entry in use *> end else answer(1):=2; <* entry not found *> <* Set new data *> if not type_exist then begin if find_type_entry(copy_buf.type_nr) then begin <* tomt entry fundet *> for i:=1 step 1 until 63 do typecat.type_entry(i):=copy_buf.liaf(i); <* sæt ny time stamp *> typecat.type_entry(64):=0; write_type_seg; answer(1):=0; end else answer(1):=6; <* illegal type *> end else answer(1):=3; <* entry exist *> <* Delete data *> if type_exist then begin if not check_type(copy_buf.type_nr) then begin <* type benyttes ikke i indlogget terminal *> typecat.type_entry(1):=0; write_type_seg; answer(1):=0; end else answer(1):=1; <* entry in use *> end else answer(1):=2; <* entry not found *> end; answer(4):=(typecat_size-1)*(512//type_entry_length); end else answer(1):=if answer(1)=3 then 4 <* ingen privilegie *> else 13; <* illegal bruger (operatør) *> end else answer(1):=8; <* bruger proces stoppet *> end; if false then alarm: disable traped(82); end; <*****************************> <* Hoved del af modify_entry *> <*****************************> trap(alarm); if (mode<1) or (mode>3) then answer(9):=3 else begin answer(9):=1; case mode of begin modify_user_entry; modify_term_entry; modify_type_entry; end; end; if false then alarm: disable traped(79); end; procedure send_text; <* 83 *> <*--------------------------------------------------------------------*> <* Behandling af message fra bruger, med tekst til udskrift på anden *> <* terminal tilknyttet TAS *> <*--------------------------------------------------------------------*> begin integer array id(1:4); integer i,user_index,term_index,t,nr; integer array field liaf; integer array struc_ref(1:1); trap(alarm); initref(struc_ref); answer(9):=1; if data_to_copy_buf(256,mess.buf_addr,answer)=0 then begin <* data kopieret *> if check_user_priv(3,answer(1)) then begin <* operatør ok *> liaf:=14; t:=0; answer(1):=0; for i:=1 step 1 until 4 do id(i):=mess.mess_array(i+3); if id(1)<>0 then begin user_index:=find_login_user(id,user_list); if user_index>0 then begin nr:=set_text_buf(copy_buf.liaf); if nr>0 then begin term_index:=login_struc(user_index+6); wait(struc_sema,struc_ref); while term_index>0 do begin mess_to_term(term_index,nr); t:=t+1; term_index:=login_struc(term_index+3); end; signal(struc_sema,struc_ref); send_message_text(nr); end else answer(1):=4; end else answer(1):=1; end else begin nr:=set_text_buf(copy_buf.liaf); if nr>0 then begin wait(struc_sema,struc_ref); user_index:=user_list; while user_index>0 do begin term_index:=login_struc(user_index+6); while term_index>0 do begin mess_to_term(term_index,nr); t:=t+1; term_index:=login_struc(term_index+3); end; user_index:=login_struc(user_index+7); end; signal(struc_sema,struc_ref); send_message_text(nr); end else answer(1):=4; end; answer(4):=t; end else answer(1):=if answer(1)=3 then 2 else 13; end else answer(1):=3; if false then alarm: disable traped(83); end; procedure move_mcl; <* 84 *> <*-------------------------------------------------------*> <* Behandling af message til flytning af cmcl programmer *> <*-------------------------------------------------------*> begin integer array ia(1:17),name(1:4),user_bases(1:2); zone z(1,1,stderror); integer i,result; trap(alarm); if (mode<0) or (mode>2) then answer(9):=3 <* error; illegal mode *> else begin answer(9):=1; if data_to_copy_buf(12,mess.buf_addr,answer)=0 then begin <* data kopieret *> if check_user_priv(2,result) then begin <* operatør ok *> result:=0; for i:=1 step 1 until 4 do name(i):=copy_buf.iaf(i+6); open(z,0,name,0); user_bases(1):=copy_buf.iaf(11); user_bases(2):=copy_buf.iaf(12); if mode=0 then begin <* Lookup file *> set_cat_bases(cmcl_bases); if monitor(42,z,0,ia)<>0 or ia(9)<>(29 shift 12) then result:=1 else begin for i:=2,3,4,5 do copy_buf.iaf(i+5):=ia(i); copy_buf.iaf(11):=ia(6); copy_buf.iaf(12):=ia(10); result:=if data_from_copy_buf(12,mess.buf_addr,answer)=0 then result else 8; end; end else if mode=1 then begin <* move to tascat *> set_cat_bases(user_bases); i:=monitor(76,z,0,ia); if monitor(76,z,0,ia)=0 then begin if (ia(8)>0) and (ia(16) shift (-12) = 29) and (ia(1) extract 3 = 3) then begin result:=monitor(74,z,0,cmcl_bases); if result=7 then result:=2; end else result:=9; end else result:=1; end else if mode=2 then begin <* move to user *> set_cat_bases(cmcl_bases); if monitor(42,z,0,ia)=0 then begin result:=monitor(74,z,0,user_bases); if result=7 then result:=2; end else result:=1; end; answer(1):=result; answer(4):=cmcl_bases(1); answer(5):=cmcl_bases(2); set_cat_bases(sys_bases); end else answer(1):=if result=3 then 7 <* ingen privilegie *> else 13; <* illegal bruger (operatør) *> end else answer(1):=8; <* bruger proces stoppet *> end; if false then alarm: disable traped(84); end; <**********************************> <* Hoved del af catalog korutinen *> <**********************************> trap(alarm); claim(600); <* Reserver plads på stakken *> <* Hent buffer til message *> initref(mess); wait_select:=22; wait(message_buf_pool,mess); <* sæt den i wait message pool *> signal(wait_message_pool,mess); while true do begin <* vent på næste message til TASCAT *> <* Der behandles kun 1 mess af gangen *> wait_time:=0; wait_select:=0; wait(wait_message,mess); for i:=1 step 1 until 8 do answer(i):=0; answer(9):=3; operation:=mess.mess_array(1) shift (-12); mode:=mess.mess_array(1) extract 12; if false add trace_type then trace(31,1,operation,mode); if operation=0 then attention else if operation=3 then get_segments else if operation=9 then tasterm_mess else if operation=11 then modify_entry else if operation=13 then send_text else if operation=15 then move_mcl; <* send answer sat af procedure der behandlede message *> <* answer(9) er sat til answer-result, mens answer(1) *> <* til answer(8) indeholder svaret (hvis answer(9)=1) *> monitor(22,dummy_zone,mess.buf_addr,answer); <* sæt besked buffer i pool så der kan ventes på næste message *> signal(wait_message_pool,mess); end; if false then alarm: disable traped(67); end; <***********************************************> <***********************************************> <* Hoved procedurerne for operatør korutinerne *> <***********************************************> <***********************************************> procedure operator(cor_nr); <* 85 *> <*------------------------------------------*> <* Hoved procedure for operator korutinerne *> <* *> <* cor_nr (call) : Denne korutines nummer *> <*------------------------------------------*> value cor_nr; integer cor_nr; begin zone term_in(13,1,in_error), term_out(13,1,out_error); integer i, head_consol, buf, command_value, command_keyword, user_ident; boolean priv, break, finis, out_stop; integer array term_name(1:4), command_name(1:4), ref(1:1), ia(1:20), user_id(1:4); long password; <**************************************> <**************************************> <* Operatør korutine hjælpe procedure *> <**************************************> <**************************************> boolean procedure read_param(term_in,text_param,num_param); <* 86 *> <*--------------------------------------------------------------------------*> <* Læs en parameter fra input fra terminal *> <* *> <* text_param (ret) : Den læste parameter (max 11 tegn) konverteret til *> <* små bogstaver og efterstillet med nul *> <* num_par (ret) : Den læste parameter omregnet til integer *> <* Return : True = parameter læst til text_param og num_param *> <* False = ikke flere parametre (retur param. nulstillet)*> <*--------------------------------------------------------------------------*> zone term_in; integer num_param; integer array text_param; begin integer text_pos,char_class,ch; long array field laf; boolean neg; trap(alarm); neg:=false; char_class:=7; while char_class=7 do char_class:=readchar(term_in,ch); laf:=0; text_pos:=1; num_param:=0; text_param.laf(1):=text_param.laf(2):=0; if (ch=0) or (char_class>=8) then read_param:=false else begin read_param:=true; if ch='-' then neg:=true; while char_class<7 do begin num_param:=if char_class=2 then (num_param*10)+(ch-48) else 0; if (text_pos<12) and (char_class>1) then put_char(text_param.laf,text_pos,ch); char_class:=readchar(term_in,ch); end; end; if neg then num_param:= -num_param; repeatchar(term_in); if false then alarm: disable traped(86); end; procedure out_error(z,s,b); <* 87 *> <*--------------------------------------------------------------*> <* Blok procedure for zonen term_out *> <* Sæt out_stop true hvis der sættes attention status på output *> <* Sæt break ved fejl *> <*--------------------------------------------------------------*> zone z; integer s,b; begin out_stop:=true; if not (false add (s shift (-16))) then begin <* Ikke attention status men give_up eller error *> break:=true; b:=0; end; end; procedure in_error(z,s,b); <* 88 *> <*-------------------------------------*> <* Blok procedure for zonen term_in *> <* Sæt break ved fejl og returner da *> <* 'em' i input *> <*-------------------------------------*> zone z; integer s,b; begin <* Give_up eller error *> break:=true; b:=2; z(1):= real <:<'em'><'em'><'em'>:>; end; procedure show_sess(sess_index); <* 89 *> <*---------------------------------------------------------------------*> <* Udskriv en linie på skærmen indeholde data for den angivne sesseion *> <* *> <* sess_index (call) : Index i login_struc for sessionen *> <*---------------------------------------------------------------------*> integer sess_index; begin begin zone tasterm(1,1,stderror); integer array ia(1:8),name(1:4); integer buf; boolean ok; trap(alarm); ok:=false; open(tasterm,0,tasterm_name,1 shift 9); ia(1):=12 shift 12 + 0; ia(2):=login_struc(sess_index); buf:=send_mess(tasterm,ia); if wait_ans(tasterm,buf,100,opera_terms(cor_nr,2),true) then begin if monitor(18,tasterm,1,ia)=1 then begin if ia(1)=0 then begin name(1):=ia(5); name(2):=ia(6); name(3):=name(4):=0; write(term_out,<:Id =:>,true,6,name.laf, <: Index=:>,<<d>, login_struc(sess_index+1) extract 12); if ia(2)>0 then begin get_proc_name(ia(2),name); write(term_out,<: Sess.Term=:>,true,11,name.laf); end else write(term_out," ",23); if ia(3)>0 then begin get_proc_name(ia(3),name); write(term_out,<: User=:>,true,11,name.laf); end else write(term_out," ",18); if false add login_struc(sess_index+2) then write(term_out,<: Removing:>) else begin write(term_out,if false add (ia(4) shift (-1)) then <: :> else <: Active:>); write(term_out,if false add ia(4) then <: Direct:> else <::>); end; ok:=true; end; end; end; if not ok then write(term_out,string c_p ,<:<10>:>); if false then alarm: disable traped(89); end; end; procedure show_term(user_index,term_index); <* 90 *> <*---------------------------------------------------------------*> <* Udskriv oplysninger om en inlogget terminal og dens sessioner *> <* *> <* user_index (call) : Index i login_struc til den user *> <* der benytter terminalen *> <* term_index (call) : Index i login_struc til ønsket terminal *> <*---------------------------------------------------------------*> integer user_index,term_index; begin begin integer array user_id,term_id(1:4); integer i,sess_index; trap(alarm); for i:=1 step 1 until 4 do user_id(i):=login_struc(user_index-1+i); if get_proc_name(login_struc(term_index),term_id) then begin if find_login_terminal(term_id,login_struc(user_index+7))>0 then movestring(term_id.laf,1,<:Removed :>); <* Optaget af anden terminal *> end; i:=login_struc(user_index+4) extract 12; write(term_out,<:<10>User=:>,true,11,user_id.laf, <: Terminal =:>,true,11,term_id.laf, <: Logout :>); if i>=100 then i:=i-100; if i=25 then write(term_out,<:disabled for user:>) else if timecheck_stat then begin write(term_out,if i>25 or i=0 then <:now:> else <:time :>); if i<25 and i>0 then write(term_out,<<dd>,i); end else begin write(term_out,<:disabled (:>); if i>25 or i=0 then write(term_out,<:now):>) else write(term_out,<<dd>,i,<:):>); end; write(term_out,<:<10>:>); sess_index:=login_struc(term_index+2); while sess_index>0 do begin show_sess(sess_index); write(term_out,<:<10>:>); sess_index:=login_struc(sess_index+3); end; if false then alarm: disable traped(90); end; end; boolean procedure check_priv(priv_nr); <* 91 *> <*--------------------------------------------------------*> <* Check privilegie for bruger, udskriv fejl hvis ikke ok *> <* *> <* priv_nr (call) : Privilegie nummeret der checkes *> <*--------------------------------------------------------*> integer priv_nr; begin trap(alarm); if false add ((priv extract 12) shift (priv_nr-11)) then check_priv:=true else begin check_priv:=false; write(term_out,<:*** no privilege<10>:>); end; if false then alarm: disable traped(91); end; procedure opr_finis; <* 92 *> <*-------------------------------------------*> <* Stop udførelsen af operatør kommandoer og *> <* send continue message til terminal hvis *> <* denne ikke er hovedterminalen *> <*-------------------------------------------*> begin trap(alarm); write(term_out,<:Operator finish<10>:>); finis:=true; setposition(term_out,0,0); if cor_nr<>4 then begin <* Send continue message til terminal *> ia(1):=128 shift 12 + 0; ia(2):=0; ia(3):=8 shift 12 + 8; ia(4):=<:ope:> shift (-24) extract 24; ia(5):=<:rat:> shift (-24) extract 24; ia(6):=<:or:> shift (-24) extract 24; buf:=send_mess(term_in,ia); wait_ans(term_in,buf,100,opera_terms(cor_nr,2),true); end; if false then alarm: disable traped(92); end; procedure opr_disp; <* 93 *> <*---------------------------------------------------*> <* Udskriv oplysninger om bruger / terminal / system *> <*---------------------------------------------------*> begin zone tasterm(1,1,stderror); long array text(1:6); integer user_index,term_index; integer array ia(1:8); integer array struc_ref(1:1); real r; boolean ok; trap(alarm); initref(struc_ref); if read_param(term_in,command_name,0) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=8 then begin <* terminal *> if check_priv(4) then begin wait(struc_sema,struc_ref); if read_param(term_in,command_name,0) then begin user_index:=user_list; term_index:=find_login_terminal(command_name,user_index); if term_index>0 then show_term(user_index,term_index) else write(term_out,string t_n_l); end else opr_terminal; signal(struc_sema,struc_ref); end; end else if command_keyword=9 or command_keyword=18 then begin <* user *> if check_priv(4) then begin wait(struc_sema,struc_ref); if read_param(term_in,command_name,0) then begin user_index:=find_login_user(command_name,user_list); if user_index>0 then begin term_index:=login_struc(user_index+6); while term_index>0 and not out_stop do begin show_term(user_index,term_index); term_index:=login_struc(term_index+3); end; end else write(term_out,string u_n_l); end else opr_user; signal(struc_sema,struc_ref); end; end else if command_keyword=15 then begin <* system *> write(term_out,<:<10>System start at: :>); write(term_out,<<zddddd >,systime(4,start_time,r),r); if system_stop then write(term_out,<:<10>System is stopping:>); write(term_out,<:<10><10>--- Sign on ---:>); write(term_out,<:<10>:>,host_id.laf); date(text); write(term_out,<:<10>:>,text); write(term_out,<:<10>:>,signon_text.laf); write(term_out,<:<10>--- Status ---:>); write(term_out,<< dddd >,<:<10>Users : :>,users, <:Free::>,maxterminals-terms); write(term_out,<< dddd >,<:<10>Terminals : :>,terms, <:Max ::>,max_terms); write(term_out,<< dddd >,<:<10>Sessions : :>,sessions); write(term_out,<:<10>Timecheck : :>,if timecheck_stat then <:activ:> else <:passiv:>, <:<10>Login : :>); if login_stat=96 then write(term_out,<:enabled:>) else if login_stat=0 then write(term_out,<:disabled:>) else write(term_out,<:disabled from terminal group :>,login_stat); write(term_out,<:<10><10>--- Release dates ---:>); write(term_out,<:<10>Tasterm : :>,<<zddddd >, tastermverd,tastermvert); write(term_out,<:<10>Tascat : :>,<<zddddd >,reld,relt); write(term_out,<:<10>Init. : :>,<<dddddd >,initver); end else if command_keyword=19 then begin <* Resources *> ok:=false; open(tasterm,0,tasterm_name,1 shift 9); ia(1):=18 shift 12; if wait_ans(tasterm,send_mess(tasterm,ia), 100,operaterms(cor_nr,2),true) then begin if monitor(18,tasterm,1,ia)=1 then begin ok:=true; write(term_out,<:<10>Resource Maximum:>, <: Used % Used<10>:>, <:<10>Create pools :>, <<dddd >,cps,cps-ia(1), <<ddd>,if cps=0 then 0 else (cps-ia(1))/cps*100, <:<10>Create links :>, <<dddd >,cls,ia(2), <<ddd>,if cls=0 then 0 else ia(2)/cls*100, <:<10>Sessions :>, <<dddd >,maxsessions,sessions, <<ddd>,sessions/maxsessions*100, <:<10>Terminals :>, <<dddd >,maxterminals,terms, <<ddd>,terms/maxterminals*100, <:<10>Users :>, <<dddd >,maxusers,users, <<ddd>,users/maxusers*100, <:<10>System menues :>, <<dddd >,maxsysmenu,ia(3), <<ddd>,ia(3)/maxsysmenu*100, <:<10>Terminal types :>, <<dddd >,termtypes,termtypes-ia(6), <<ddd>,(termtypes-ia(6))/termtypes*100, <:<10>MCL programs :>, <<dddd >,mclprogs,mclprogs-ia(5), <<ddd>,(mclprogs-ia(5))/mclprogs*100, <:<10>Core buffers :>, <<dddd >,corebufs,corebufs-ia(4), <<ddd>,(corebufs-ia(4))/corebufs*100, <:<10>Spool segments :>, <<dddd >,ia(7),ia(7)-ia(8), <<ddd>,(ia(7)-ia(8))/ia(7)*100); end; end; if not ok then write(term_out,string c_p,<:<10>:>); end else write(term_out,string ill_par,command_name.laf); end else write(term_out,string miss_par); write(term_out,<:<10>:>); if false then alarm: disable traped(93); end; procedure opr_message; <* 94 *> <*---------------------------------------------------*> <* Send meddelelser til bruger og terminal *> <*---------------------------------------------------*> begin long array text(0:34); integer i,t,user_index,term_index,nr; integer array struc_ref(1:1); boolean procedure read_term_text(text); <* 95 *> <*--------------------------------------------------------------*> <* Læs tekst fra terminal til text i mcl-format *> <* prompt for hver linie. Afslut ved '.' først på linie *> <* *> <* text (ret) : Den læste tekst i mcl-format *> <* Return : True = Tekst læst, False = Fejl ved læsning *> <*--------------------------------------------------------------*> long array text; begin long array line(1:14); integer i,pos; trap(alarm); pos:=1; repeat i:=read_line(line); if i>0 then i:=put_txt(text,pos,line,i); until i<1; if i=0 then begin put_ch(text,pos,0,3); put_ch(text,200,0,3); pos:=pos-4; text(0):=((((pos+2)//3)*2+1) shift 12) + pos; read_term_text:=true; end else read_term_text:=false; if false then alarm: disable traped(95); end; integer procedure read_line(line); <* 96 *> <*--------------------------------------------------------------------*> <* Læs en linie fra terminal *> <* *> <* line (ret) : Den læste linie *> <* Return : Antal tegn læst ink. 'nl' (0 = '.' først på linie) *> <*--------------------------------------------------------------------*> long array line; begin integer ch,i,pos; trap(alarm); write(term_out,<:>:>); setposition(term_out,0,0); setposition(term_in,0,0); pos:=1; repeat readchar(term_in,ch); i:=put_ch(line,pos,ch,1); until (ch='nl') or (i<1) or (((ch='.') or (ch='/')) and (pos=2)); if ch='nl' then read_line:=pos-1 else if ch='/' then read_line:=-1 else read_line:=pos-2; if false then alarm: disable traped(96); end; trap(alarm); initref(struc_ref); if read_param(term_in,command_name,0) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=16 then begin <* login *> if check_priv(0) then begin t:=0; if read_term_text(text) then begin nr:=set_text_buf(text.iaf); if nr>0 then begin wait(struc_sema,struc_ref); user_index:=user_list; while user_index>0 do begin term_index:=login_struc(user_index+6); while term_index>0 do begin mess_to_term(term_index,nr); t:=t+1; term_index:=login_struc(term_index+3); end; user_index:=login_struc(user_index+7); end; signal(struc_sema,struc_ref); send_message_text(nr); end else write(term_out,<:No free text buffer<10>:>); end else write(term_out,string long_text); write(term_out,<<d>,<:Message sent to :>,t,<: terminal:>, if t<>1 then <:s:> else <::>); end; end else if command_keyword=13 then begin <* sign on *> if check_priv(0) then begin if read_term_text(text) then begin signon_text(0):=text(0) extract 24; for i:=1 step 1 until 34 do signon_text.laf(i):=text(i); end else write(term_out,string long_text); end; end else if command_keyword=12 then begin <* all *> if check_priv(0) then begin t:=0; if read_term_text(text) then begin signon_text(0):=text(0) extract 24; for i:=1 step 1 until 34 do signon_text.laf(i):=text(i); nr:=set_text_buf(text.iaf); if nr>0 then begin wait(struc_sema,struc_ref); user_index:=user_list; while user_index>0 do begin term_index:=login_struc(user_index+6); while term_index>0 do begin mess_to_term(term_index,nr); t:=t+1; term_index:=login_struc(term_index+3); end; user_index:=login_struc(user_index+7); end; signal(struc_sema,struc_ref); send_message_text(nr); end else write(term_out,<:No free text buffer<10>:>); end else write(term_out,string long_text); write(term_out,<<d>,<:Message sent to :>,t,<: terminal:>, if t<>1 then <:s:> else <::>); end; end else if command_keyword=9 then begin <* user *> if read_param(term_in,command_name,0) then begin if check_priv(3) then begin t:=0; user_index:=find_login_user(command_name,user_list); if user_index>0 then begin if read_term_text(text) then begin nr:=set_text_buf(text.iaf); if nr>0 then begin wait(struc_sema,struc_ref); user_index:=find_login_user(command_name,user_list); if user_index>0 then term_index:=login_struc(user_index+6) else term_index:=0; while term_index>0 do begin mess_to_term(term_index,nr); t:=t+1; term_index:=login_struc(term_index+3); end; signal(struc_sema,struc_ref); send_message_text(nr); end else write(term_out,<:No free text buffer<10>:>); write(term_out,<<d>,<:Message sent to :>,t,<: terminal:>, if t<>1 then <:s:> else <::>); end else write(term_out,string long_text); end else write(term_out,string u_n_l); end; end else write(term_out, string miss_par); end else if command_keyword=8 then begin <* terminal *> if read_param(term_in,command_name,0) then begin if check_priv(3) then begin term_index:=find_login_terminal(command_name,user_list); if term_index>0 then begin if read_term_text(text) then begin nr:=set_text_buf(text.iaf); if nr>0 then begin wait(struc_sema,struc_ref); term_index:=find_login_terminal(command_name,user_list); if term_index>0 then mess_to_term(term_index,nr); signal(struc_sema,struc_ref); send_message_text(nr); end else write(term_out,<:No free text buffer<10>:>); end else write(term_out,string long_text); end else write(term_out,string t_n_l); end; end else write(term_out, string miss_par); end else write(term_out,string ill_par,command_name.laf); end else write(term_out,string miss_par); write(term_out,<:<10>:>); if false then alarm: disable traped(94); end; procedure opr_remove; <* 97 *> <*---------------------------------------------------*> <* Nedlæg session, terminal eller bruger *> <*---------------------------------------------------*> begin integer array user_id,term_id(1:4); integer index,user_index,term_index,sess_index,t; integer array struc_ref(1:1); boolean found; trap(alarm); initref(struc_ref); if read_param(term_in,command_name,0) then begin if check_priv(0) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=14 then begin <* session *> if read_param(term_in,user_id,0) and read_param(term_in,command_name,index) then begin wait(struc_sema,struc_ref); user_index:=find_login_user(user_id,user_list); if user_index>0 then begin if false add (login_struc(user_index+4) shift (-12-index)) then begin found:=false; term_index:=login_struc(user_index+6); while not found and term_index>0 do begin sess_index:=login_struc(term_index+2); while not found and sess_index>0 do begin if (login_struc(sess_index+1) extract 12)=index then found:=true else sess_index:=login_struc(sess_index+3); end; term_index:=login_struc(term_index+3); end; if not remove_sess(sess_index) then write(term_out,<:*** session not removed:>); end else write(term_out,<:*** unknow user index:>); end else write(term_out,string u_n_l); signal(struc_sema,struc_ref); end else write(term_out,string miss_par); end else if command_keyword=9 then begin <* user *> if read_param(term_in,user_id,0) then begin t:=0; wait(struc_sema,struc_ref); user_index:=find_login_user(user_id,user_list); if user_index>0 then begin term_index:=login_struc(user_index+6); while term_index>0 do begin sess_index:=login_struc(term_index+2); while sess_index>0 do begin if remove_sess(sess_index) then t:=t+1; sess_index:=login_struc(sess_index+3); end; term_index:=login_struc(term_index+3); end; end else write(term_out,string u_n_l); signal(struc_sema,struc_ref); write(term_out,<<dd >,t,<:session:>,if t<>1 then <:s:> else <::>, <: removed:>); end else write(term_out,string miss_par); end else if command_keyword=8 then begin <* terminal *> if read_param(term_in,term_id,0) then begin t:=0; wait(struc_sema,struc_ref); term_index:=find_login_terminal(term_id,user_list); if term_index>0 then begin sess_index:=login_struc(term_index+2); while sess_index>0 do begin if remove_sess(sess_index) then t:=t+1; sess_index:=login_struc(sess_index+3); end; term_index:=login_struc(term_index+3); end else write(term_out,string t_n_l); signal(struc_sema,struc_ref); write(term_out,<<dd >,t,<:session:>,if t<>1 then <:s:> else <::>, <: removed:>); end else write(term_out,string miss_par); end else write(term_out,string ill_par,command_name.laf); end; end else write(term_out,string miss_par); write(term_out,<:<10>:>); if false then alarm: disable traped(97); end; procedure opr_set; <* 98 *> <*---------------------------------------------------*> <* Sæt værdi for timecheck eller antal terminaler *> <*---------------------------------------------------*> begin integer user_index; integer array user_id(1:4),ref(1:1),struc_ref(1:1); trap(alarm); initref(struc_ref); if read_param(term_in,command_name,0) then begin if check_priv(0) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=8 then begin <* terminal *> if read_param(term_in,command_name,command_value) then begin if command_value<=maxterminals then max_terms:=command_value else write(term_out,<:*** not enough resources<10>:>); end else write(term_out,string miss_par); end else if command_keyword=17 then begin <* timecheck *> if read_param(term_in,command_name,0) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=10 or command_keyword=11 then begin <* on/off *> timecheck_stat:=if command_keyword=10 then true else false; end else if command_keyword=9 then begin <* user *> if read_param(term_in,user_id,0) then begin if read_param(term_in,command_name,command_value) then begin if find_keyword_value(command_name.laf(1),1)=11 then command_value:=25; if command_value<=25 and command_value>=0 then begin wait(struc_sema,struc_ref); user_index:=find_login_user(user_id,user_list); if user_index>0 then login_struc(user_index+4):= ((login_struc(user_index+4) shift (-12)) shift 12)+ command_value else write(term_out,string u_n_l); signal(struc_sema,struc_ref); end else write(term_out,string ill_time); end else write(term_out, string miss_par); end else write(term_out,string miss_par); end else write(term_out,string ill_par,command_name.laf,<:<10>:>); end; <* start time check *> initref(ref); wait_select:=6; wait(message_buf_pool,ref); signal(time_sem,ref); end else write(term_out,string ill_par,command_name.laf,<:<10>:>); end; end else write(term_out,string miss_par); if false then alarm: disable traped(98); end; procedure opr_start; <* 99 *> <*---------------------------------------------------*> <* Start inlogning til systemet *> <*---------------------------------------------------*> begin integer array ref(1:1); trap(alarm); if read_param(term_in,command_name,0) then begin if check_priv(0) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=16 then begin <* login *> login_stat:=96; end else if command_keyword=15 then begin <* system *> if system_stop then begin initref(ref); wait_select:=6; wait(message_buf_pool,ref); signal(free_sem,ref); write(term_out,<:System restarted<10>:>); end else write(term_out,<:*** System not stopped<10>:>); end else write(term_out,string ill_par,command_name.laf,<:<10>:>); end; end else write(term_out,string miss_par); if false then alarm: disable traped(99); end; procedure opr_stop; <* 100 *> <*---------------------------------------------------*> <* Stop inlogning eller hele systemet *> <*---------------------------------------------------*> begin zone z(4,1,stderror); integer array ia(1:8); integer array dummy(1:1); integer user_index,i,stop_time; trap(alarm); initref(dummy); if read_param(term_in,command_name,0) then begin if check_priv(4) then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=15 then begin <* system *> if read_param(term_in,command_name,stop_time) then begin if stop_time=0 then begin command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword=20 then begin <* check *> stop_time:=8388606; write(term_out,<:System stopping after last logout<10>:>); end else if command_name.laf(1)<> long <:0:> then begin write(term_out,string ill_par,command_name.laf,<:<10>:>); goto start; end; end else write(term_out,<:System stopping<10>:>); setposition(term_out,0,0); opera_terms(cor_nr,1):=1; login_stat:=0; system_stop:=true; timecheck_stat:=false; write_message(-100,if stop_time<>8388606 then stop_time else -1,true,<:Operator system stop:>); for i:=1 step 1 until stop_time do begin if (stop_time=8388606) and (sessions=0) then goto stop_sys; notis_users(stop_txt); if i<stop_time then begin wait(struc_sema,dummy); user_index:=user_list; while user_index>0 do begin if login_struc(user_index+4) extract 12 = 26 then login_struc(user_index+4):= (login_struc(user_index+4) shift (-12)) shift 12 ; user_index:=login_struc(user_index+7); end; signal(struc_sema,dummy); end; wait_time:=600; if wait(free_sem,dummy)>0 then begin signal(message_buf_pool,dummy); system_stop:=false; finis:=true; if head_consol=1 then write(term_out,<:System restarted<10>:>); head_consol:=1; wait(struc_sema,dummy); user_index:=user_list; while user_index>0 do begin login_struc(user_index+4):= ((login_struc(user_index+4) shift (-12)) shift 12) + 25; user_index:=login_struc(user_index+7); end; signal(struc_sema,dummy); goto start; end; end; stop_sys: <* Send stop message til tasterm *> ia(1):=14 shift 12 + 0; ia(2):=0; open(z,0,tasterm_name,0); send_mess(z,ia); monitor(18,z,1,ia); goto stop; end else write(term_out,string miss_par); end else if command_keyword=16 then begin <* login *> read_param(term_in,command_name,i); if i<0 or i>95 then write(term_out,string ill_val) else login_stat:=i; end else write(term_out,string ill_par,command_name.laf,<:<10>:>); end; end else write(term_out,string miss_par); start: if false then alarm: disable traped(100); end; procedure opr_terminal; <* 101 *> <*---------------------------------------------------*> <* Udskriv alle terminaler der er inlogget *> <*---------------------------------------------------*> begin integer user_index,term_index,t,i; integer array term_id,user_id(1:4); trap(alarm); t:=0; user_index:=user_list; while user_index>0 and not out_stop do begin for i:=0 step 1 until 3 do user_id(i+1):=login_struc(user_index+i); term_index:=login_struc(user_index+6); while term_index>0 and not out_stop do begin get_proc_name(login_struc(term_index),term_id); write(term_out,<:<10>:>,true,20,term_id.laf,true,11,user_id.laf); term_index:=login_struc(term_index+3); t:=t+1; end; user_index:=login_struc(user_index+7); end; write(term_out,<:<10><10>Terminals = :>,t); if false then alarm: disable traped(101); end; procedure opr_user; <* 102 *> <*---------------------------------------------------*> <* Udskriv alle brugerer der er tilmeldt *> <*---------------------------------------------------*> begin integer user_index,t,i; integer array user_id(1:4); trap(alarm); t:=0; user_index:=user_list; while user_index>0 and not out_stop do begin for i:=0 step 1 until 3 do user_id(i+1):=login_struc(user_index+i); write(term_out,<:<10>:>,true,11,user_id.laf); t:=t+1; user_index:=login_struc(user_index+7); end; write(term_out,<:<10><10>Users = :>,t); if false then alarm: disable traped(102); end; <****************************************> <* Hoved rutinen for operatør korutinen *> <****************************************> trap(alarm); claim(600); <* Reserver plads på stakken *> initref(ref); wait_time:=0; wait_select:=0; while true do begin break:=false; finis:=false; wait(opera_terms(cor_nr,2),ref); head_consol:=ref(3); <* sæt uændret besked buffer tilbage i pool *> signal(message_buf_pool,ref); if get_proc_name(opera_terms(cor_nr,1),term_name) then begin open(term_out,8,term_name,1 shift 16 + 1 shift 9); open(term_in,8,term_name,1 shift 9); if head_consol=1 then begin <* Ikke hoved terminalen *> <* Hent user id fra terminal *> getzone6(term_in,ia); ia(1):=131 shift 12 + 0; <* get user id *> ia(2):=ia(19)+1; <* first address *> ia(3):=ia(19)+11; <* last address *> buf:=send_mess(term_in,ia); if buf=0 then break:=true else begin if not wait_ans(term_in,buf,100,opera_terms(cor_nr,2),false) then break:=true <* Der blev ikke svaret inden 10 sek. *> else begin if monitor(18,term_in,1,ia)<>1 then break:=true else if ia(1)<>0 then break:=true else begin close(term_in,false); for i:=1,2 do user_id.laf(i):=term_in.laf(i); password:=term_in.laf(3); open(term_in,8,term_name,1 shift 9); <* Find privilegier i login_struc *> user_ident:=find_login_user(user_id,user_list); if user_ident=0 then break:=true <* Bruger ikke login *> else priv:=false add (login_struc(user_ident+5) shift (-12)); end; end; end; end else priv:=true; <* alle privilegier *> if not break then write(term_out,<:<10>Operator ready<10>:>) else begin write(term_out, <:Operatøradgang ikke tilladt fra denne terminal<10>:>); setposition(term_out,0,0); monitor(64,term_out,0,command_name <*dummy*>); end; while not (finis or break) do begin <* Udfør operatør kommunikation *> setposition(term_out,0,0); write(term_out,<:$ :>);<* Prompt *> setposition(term_out,0,0); setposition(term_in,0,0); <* Slet input buffer *> if read_param(term_in,command_name,0) then begin if not break then <* break evt. sat af write el. read_param *> begin <* fortolk kommando i commandline *> command_keyword:=find_keyword_value(command_name.laf(1),1); if command_keyword>7 or command_keyword=0 then begin write(term_out,<:*** unknown command: :>, command_name.laf,<:<10>:>); setposition(term_out,0,0); end else begin out_stop:=false; case command_keyword of begin <* Udfør kommando *> <* Test for out_stop ved hver setposition på output *> <* er denne true stoppes evt ydeligerer udskrift *> <* Test for break efter hver i/o, er denne true *> <* stoppes udførelsen af kommandoen *> opr_finis; opr_disp; opr_message; opr_remove; opr_set; opr_start; opr_stop; end; end; end; end; if head_consol=0 then begin write(term_out,<:ok<10>:>); finis:=true; <* Hoved terminal *> end; end; <* session *> end; close(term_in,true); close(term_out,true); opera_terms(cor_nr,1):=0; end; <* while true *> stop: if false then alarm: disable traped(85); end; <* Operatør korutine *> <**************************************> <**************************************> <* Procedure til time ckeck korutinen *> <**************************************> <**************************************> integer procedure next_hour; <* 103 *> <*------------------------------------------------------------*> <* Beregn ventetiden til næste hele klokkeslet i *> <* 0.1 sek enheder *> <* *> <* Return : Tiden til næste hele klokkeslet i 0.1 sek enheder *> <*------------------------------------------------------------*> begin real r; long t; integer nh; systime(1,0,r); t:=r; nh:=round(3600-t+t//3600*3600)*10; if false add trace_type then trace(103,nh,0,0); next_hour:=nh; end; procedure notis_users(txt); <* 104 *> <*--------------------------------------------------------------------*> <* Find bruger der har overskredet tiden eller alle hvis stop *> <* Send log_txt og mærk tiden med 26 *> <* Gentag for alle brugere *> <*--------------------------------------------------------------------*> integer array txt; begin integer user_index,term_index,map,ut,nr; boolean found; integer array ref(1:1),struc_ref(1:1); trap(alarm); initref(ref); initref(struc_ref); found:=true; repeat nr:=set_text_buf(txt); if nr=0 then begin wait_time:=100; wait(delay_sem,ref); end; until nr>0; while found do begin wait(struc_sema,struc_ref); found:=false; user_index:=user_list; while user_index>0 and not found do begin ut:=login_struc(user_index+4) extract 12; found:=(ut<=cur_time) or (system_stop and (ut<>26)); if not found then user_index:=login_struc(user_index+7); end; if found then begin map:=login_struc(user_index+4) shift (-12); login_struc(user_index+4):=(map shift 12)+26; term_index:=login_struc(user_index+6); while term_index>0 do begin mess_to_term(term_index,nr); term_index:=login_struc(term_index+3); end; end; signal(struc_sema,struc_ref); send_message_text(nr); end; if false then alarm: disable traped(104); end; procedure remove_users; <* 105 *> <*--------------------------------------------------------------------*> <* Find første bruger der har 26 sat i tid *> <* Send remove session message til TAS og sæt tid 27 *> <* Gentag for alle *> <*--------------------------------------------------------------------*> begin integer user_index,term_index,sess_index,map; boolean found; integer array struc_ref(1:1); trap(alarm); initref(struc_ref); found:=true; while found do begin wait(struc_sema,struc_ref); found:=false; user_index:=user_list; while user_index>0 and not found do begin found:=(login_struc(user_index+4) extract 12)=26; if not found then user_index:=login_struc(user_index+7); end; if found then begin map:=login_struc(user_index+4) shift (-12); login_struc(user_index+4):=(map shift 12)+27; term_index:=login_struc(user_index+6); while term_index>0 do begin sess_index:=login_struc(term_index+2); while sess_index>0 do begin remove_sess(sess_index); sess_index:=login_struc(sess_index+3); end; term_index:=login_struc(term_index+3); end; end; signal(struc_sema,struc_ref); end; if false then alarm: disable traped(105); end; procedure timeco; <* 106 *> <*--------------------------------------------*> <* Hoved procedure for check time korutinen *> <*--------------------------------------------*> begin integer array dummy(1:1); integer user_index,i,last_time; integer array id(1:4); trap(alarm); claim(500); initref(dummy); while true do begin wait_time:=next_hour; if wait(time_sem,dummy)>0 then signal(message_buf_pool,dummy); if cur_time=0 then begin wait(struc_sema,dummy); user_index:=user_list; while user_index>0 do begin for i:=0,1,2,3 do id(i+1):=login_struc(user_index+i); find_user(id); last_time:=if check_time(last_time) then last_time else 0; login_struc(user_index+4):= ((login_struc(user_index+4) shift (-12)) shift 12) + last_time; user_index:=login_struc(user_index+7); end; signal(struc_sema,dummy); end; for i:=1 step 1 until log_time do begin if timecheck_stat then begin notis_users(log_txt); if i<log_time then begin wait(struc_sema,dummy); user_index:=user_list; while user_index>0 do begin if login_struc(user_index+4) extract 12 = 26 then login_struc(user_index+4):= (login_struc(user_index+4) shift (-12)) shift 12 ; user_index:=login_struc(user_index+7); end; signal(struc_sema,dummy); end; wait_time:=600; if wait(time_sem,dummy)>0 then signal(message_buf_pool,dummy); end; end; if timecheck_stat then remove_users; end; if false then alarm: disable traped(106); end; procedure write_term_text; <* Korutine *> <* 107 *> <*---------------------------------------------------------------*> <* Gemmenløb alle terminaler for at udskrive en evt tekst der er *> <* markeret i login_struc. Start gennemløb ved signalering fra *> <* send_text proceduren. Efter udskrift frigives text-buffer *> <* *> <* Formater af sem-message: *> <* *> <* Ved send_text: (1) buf nr. *> <* (2) message_buf_addr *> <* (3) text_write_sem *> <* (4) zone array index *> <* *> <* Ved signal : (1) 0 *> <* (2) 8 *> <* (3) text buf. nr. *> <* (4) 0 *> <* *> <*---------------------------------------------------------------*> begin integer array ref(1:1),answer(1:8); integer out_count,i,buf_nr; boolean finis; zone array z(max_text_count,1,1,stderror); boolean procedure write_next_term; <* 108 *> <*-----------------------------------------------------*> <* Udskriv text på en terminal (den første der findes) *> <*-----------------------------------------------------*> begin integer array ref(1:1),share(1:12); integer user_index,term_index,bufs,nr,i,buf_addr; integer array struc_ref(1:1); boolean found; trap(alarm); initref(ref); initref(struc_ref); wait(struc_sema,struc_ref); found:=false; user_index:=user_list; while (user_index>0) and (not found) do begin term_index:=login_struc(user_index+6); while term_index>0 and not found do begin bufs:=login_struc(term_index+1) shift (-21); if bufs<>0 then begin found:=true; nr:=0; while not (false add (bufs shift (-nr))) do nr:=nr+1; nr:=nr+1; login_struc(term_index+1):=login_struc(term_index+1)- (1 shift (20+nr)); i:=1; repeat getshare6(z(i),share,1); i:=i+1; until share(1)<2; i:=i-1; share(4):=16 shift 12; share(5):=nr; share(6):=login_struc(term_index); setshare6(z(i),share,1); buf_addr:=monitor(16,z(i),1,share); if buf_addr=0 then write_message(998,1,false,<:claims exceeded:>); text_buf_reserved(nr):=if text_buf_reserved(nr)=-1 then 1 else text_buf_reserved(nr)+1; wait_select:=8; wait(message_buf_pool,ref); ref(1):=nr; ref(2):=buf_addr; ref(3):=text_write_sem; ref(4):=i; signal(wait_answer_pool,ref); end else term_index:=login_struc(term_index+3); end; user_index:=login_struc(user_index+7); end; write_next_term:=not found; signal(struc_sema,struc_ref); if false then alarm: disable traped(108); end; <* write_next_text *> trap(alarm); <* main write_term_text *> claim(500); initref(ref); out_count:=0; for i:=1,2,3 do text_buf_reserved(i):=0; for i:=1 step 1 until max_text_count do open(z(i),0,tasterm_name,1 shift 9); while true do begin wait(text_write_sem,ref); if ref(1)<>0 then begin <* answer *> monitor(18,z(ref(4)),1,answer); text_buf_reserved(ref(1)):=text_buf_reserved(ref(1))-1; ref(1):=0; ref(2):=8; signal(message_buf_pool,ref); out_count:=out_count-1; end else begin <* Ny tekst *> buf_nr:=ref(3); signal(message_buf_pool,ref); finis:=false; while not finis do begin if out_count=max_text_count then begin wait_select:=-1; wait(text_write_sem,ref); monitor(18,z(ref(4)),1,answer); text_buf_reserved(ref(1)):=text_buf_reserved(ref(1))-1; ref(1):=0; ref(2):=8; signal(message_buf_pool,ref); out_count:=out_count-1; end; finis:=write_next_term; if not finis then out_count:=out_count+1; end; if text_buf_reserved(buf_nr)=-1 then text_buf_reserved(buf_nr):=0; end; end; if false then alarm: disable traped(107); end; <*************************************************> <* Start af tascat og initialisering af korutiner*> <*************************************************> trap(alarm); <* Initialiser login_struc *> init_login_struc; <* Opret korutinerne og semafor beskrivelserne *> activity(3+number_of_opera); coroutines(5+number_of_opera,test_out); sys_start:=true; <***********************************************************> <* Alloker alle besked buffere på stakken og signaler dem *> <* til semaforen message_buf_pool *> <* En buffer kan hentes fra poolen på følgende måde: *> <* wait_selct:= 'besked buffer størrelse'; *> <* wait(message_buf_pool,ref); *> <* *> <* Når bufferen ikke skal benyttes mere sættes den tilbage *> <* ref(1):=0; *> <* ref(2):='besked buffer størrelse'; *> <* signal(message_buf_pool,ref); *> <***********************************************************> for i:=1 step 1 until (2*number_of_opera) do allocate(message_buf_pool,6,0); for i:=1 step 1 until (3 + max_text_count) do allocate(message_buf_pool,8,0); allocate(message_buf_pool,22,0); allocate(struc_sema,6,0); select_test:=test_select; systime(1,0,start_time); <* Vent på synkronisering med tasterm *> wait_tasterm(false); <* Start korutinerne *> new_activity(1,0,catco); <* Katalog hovedrutinen *> new_activity(2,0,timeco); <* Time check rutinen *> new_activity(3,0,write_term_text); for i:=4 step 1 until number_of_opera+3 do new_activity(i,0,operator,i); <* Operatør rutinerne *> <* Udskriv version, Start kerne og system *> write_message(struc_size,number_of_opera,true,<:Tas release 2.1 Ready:>); i:=kernel(traped); answer(4):= <:ok :> shift (-24) extract 24; answer(5):= <: :> shift (-24) extract 24; if not system_stop then begin alarm:traped(0); write_message(run_alarm_pos,run_alarm_cause,true,<:Run error:>); answer(4):= <:err:> shift (-24) extract 24; answer(5):= <:or :> shift (-24) extract 24; end else trapmode := -1; close(usercat,true); close(termcat,true); close(typecat,true); close_test_out; sys_start:=false; end; <* TASCAT *> <******************************************> <* Program start og initialisering *> <******************************************> <* Sæt global trap lable *> trap(init_alarm); <* sæt fields *> sender_pda:=2; reciever_pda:=4; buf_addr:=6; mess_array:=6; laf:=iaf:=baf:=0; <* sæt status *> trap_mode:=0; sys_start:=false; system_stop:=false; test_on:=false; killed:=false; users:= sessions:= terms:=0; run_alarm_pos:= run_alarm_cause:=0; <* initialiser konstant tekster *> ill_par:= real <:*** illegal parameter: :>; miss_par:= real <:*** missing parameter<10>:>; ill_val:= real <:*** illegal value<10>:>; long_text:= real <:*** text too long or input terminated by /<10>:>; t_n_l:= real <:*** terminal not login<10>:>; u_n_l:= real <:*** user not login<10>:>; ill_time:= real <:*** illegal login time<10>:>; c_p := real <:*** menu communication problems<10>:>; <* Fjern fp area proces og in zonen *> open(test_out,4,<:fp:>,0); close(test_out,true); close(in,true); <* Fjern c og v entry *> open(copy_buf,0,<:c:>,0); monitor(48,copy_buf,i,log_txt); close(copy_buf,true); open(copy_buf,0,<:v:>,0); monitor(48,copy_buf,i,log_txt); close(copy_buf,true); isotable(char_table); for i:=0 step 1 until 127 do char_table(i+128):=char_table(i)+128; char_table(46):=7 shift 12 + 46; intable(char_table); <* Initialiser hovedterminalen *> head_term_pda:=system(7,i,head_term_name.laf); <* initialiser keywords *> keywords_init; <* Læs fp parametre *> read_param_line; <* Sæt konstant værdier m.m fra init fil *> init_tascat; <* Åben test output filen *> open_test(testout_name); <* initialiser semafor navnene med nummer *> init_sem; <* Test og initialiser baserne for processen *> init_bases; <* init opera_terms array'et *> init_opera_terms; <* Beregn struc_size og test processens størrelse *> struc_size:=2*max_users+max_terminals+max_sessions; max_terms:=if fp_maxterms>0 then fp_maxterms else max_terminals; system(2,own_size,prog_name.laf); <* Hent oversættelses dato og tid for tascat (algol rel. 3) *> begin integer segm,rel; integer array tail(1:10); zone z(128,1,stderror); open(z,4,prog_name,0); monitor(42,z,0,tail); segm:=tail(7) shift (-12); rel:=tail(7) extract 12; setposition(z,0,segm); inrec6(z,rel+16); inrec6(z,4); segm:=z(1) shift (-12) extract 12; rel:=z(1) extract 12; setposition(z,0,segm); inrec6(z,rel-4); inrec6(z,4); reld:=z(1) shift (-24) extract 24; relt:=z(1) extract 24; close(z,true); end; if struc_size>(own_size-5000-number_of_opera*1500)//8 then write_message(own_size,25000+number_of_opera*1500+struc_size*8, false,<:Tas process too small:>) else begin <* Åben katalogerne *> open_catalogs(usercat_name,termcat_name,typecat_name); <* test buffer claims *> system(5,own_pda+26,testout_name <* work array *>); if (testout_name(1) shift (-12))<(max_text_count+3+ number_of_opera) then write_message(testout_name(1) shift (-12)+2, max_text_count+5+number_of_opera, false,<:Not enough buffers:>); if false then begin <* trap i initialiseringen *> init_alarm: traped(0); write_message(run_alarm_pos,run_alarm_cause,true,<:Initiation error:>); wait_tasterm(true); answer(4):= <:err:> shift (-24) extract 24; answer(5):= <:or :> shift (-24) extract 24; end else <* start hovedproceduren *> tascat; if killed then write_message(0,3,true,<:System breaked:>) else write_message(0,4,true,<:System stopped:>); system(11,i,log_txt); sys_bases(1):=log_txt(1); sys_bases(2):=log_txt(2); set_cat_bases(sys_bases); if trapmode = (-1) then answer(1):=2 shift 12 + 1 else answer(1):=16 shift 12 + 1; answer(2):= <: st:> shift (-24) extract 24; answer(3):= <:op :> shift (-24) extract 24; for i:=6,7,8 do answer(i):=0; system(10,0,answer); end; end; ▶EOF◀