|
|
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◀