|
|
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: 223488 (0x36900)
Types: TextFile
Names: »tctxtb «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer
└─⟦f546e193b⟧
└─⟦this⟧ »tctxtb «
<****************************************************************************>
<* SW8110 Terminal Access System *>
<* Catalog and Operator Program 'tascat' *>
<* *>
<* Henning Godske 870105 *>
<* 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 Tas processen herunder overførsel af init *>
<* data til Tas. *>
<* e) Opstart af korutiner: 1) Katalog vedligeholdelse og modtagelse af *>
<* message fra Tas og bruger processer. *>
<* 2) Timecheck rutinen til evt. automatisk *>
<* udlogning af brugerer. *>
<* 3) Kontrol af afsendelse af tekster til *>
<* terminaler via tasterm. *>
<* 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 tasterm-processen. *>
<* Besvarelse af message fra bruger-processer. *>
<* Opstart af operatør rutiner. *>
<****************************************************************************>
<****************************************************************************>
<* Revision history: *>
<* *>
<* 87.02.01 tascat release 1.0 *>
<****************************************************************************>
<*******************************>
<* 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 'send 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 *>
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,<:message Tas : :>);
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 -,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 -,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
name.laf(1):=long <:No connect:>;
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 -,set_cat_bases(cmcl_bases) then
b:=1;
if -,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:=50;
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:>,<:xxxxx:>,<:init:>));
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);
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>=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;
if key=24 then
begin <* bypass *>
clear_high(termcat.term_entry(7));
termcat.term_entry(7):=termcat.term_entry(7)+(1 shift 12);
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
<* 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>23 then
goto ill_nr;
while i>=0 do
begin
if i>23 then
goto ill_nr;
priv:=priv+(1 shift (23-i));
if not read_nr(cat_file,i) then
goto ill_nr;
end;
typecat.type_entry(2):=priv;
end;
if (key>=27) and (key<=34) then
begin <* 'send by' værdier *>
boolean array field baf;
baf:=0;
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<=49) then
begin <* et tegns værdier *>
boolean array field baf;
baf:=0;
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;
hostid.laf(1):=long <: V:> add 'e';
hostid.laf(2):=long <:lkomm:> add 'e';
hostid.laf(3):=long <:n til:> add ' ';
system(5,1192,val);
for i:=0,1,2,3 do
hostid(7+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 *>
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);
integer buf;
trap(alarm);
write_message(-53,0,true,if error then <:Stop tas:> 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);
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 *>
<* (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;
user_index:=user_list;
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 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;
<**************************************>
<* Hoveddel af procedure tasterm_mess *>
<**************************************>
trap(alarm);
if (mode<2) or (mode>7) 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;
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(61,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);
get_proc_name(login_struc(term_index),term_id);
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 finis<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);
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
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 *>
if system_stop then
write(term_out,<:<10>System is stopping:>);
write(term_out,<:<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 : :>,<<dddddd >,
tastermverd,tastermvert);
write(term_out,<:<10>Tascat : :>,<<dddddd >,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,0);
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,0);
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,0);
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 stoped<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 check<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,
<:Tas operatør-adgang 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;
systime(1,0,r);
t:=r;
next_hour:=round(3600-t+t//3600*3600)*10;
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;
<* 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 *>
<* Start kerne, Udskriv version *>
write_message(struc_size,number_of_opera,true,<:Tas version 1.0 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;
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:=-1;
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 <:*** 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 *>
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-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,<: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);
answer(1):=2 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◀