|
|
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: 155904 (0x26100)
Types: TextFile
Names: »packtxt«
└─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ.
└─⟦4334b4c0b⟧
└─⟦this⟧ »packtxt«
(
mode 0.yes
if 2.yes
algol connect.no bossline.yes xref.yes stop.2
if 2.no
pack=algol connect.no bossline.yes
if warning.yes
mode 0.no
if ok.no
mode 0.no
if 0.yes
(
if 3.no
(
unpack=assign pack
searchpack=assign pack
clearpack=assign pack
repack=assign pack
pointpack=assign pack
purgepack=assign pack
)
)
end)
\f
pack - system : projectno. - 80 10 01
dokumentation : version 1 - 81 09 01/1, brugervejledning
last alteration : eja - 81 12 18
begin
<* her indkopieres globale library procedurer *>
comment algol copy.connecttxt;
comment algol copy.printareax;
comment algol copy.breaktxt;
comment algol copy.monerrtxt;
comment algol copy.getclaimtxt;
comment algol copy.resotxt; algol copy.librarytxt;
message end copy library procedures;
message algolline in source = errorline - this line + 10;
\f
comment
programname (object-code) pack
. (entry) unpack
. ( - ) searchpack
. ( - ) clearpack
. ( - ) repack
. ( - ) pointpack
. ( - ) purgepack
. ( - ) convertpack (not implemented)
programtext (algol8) packtext
version (documentation release) 800701, version 1, testversion
projectleader arne balslev, keld christensen
programmer ejlert andersen (eja)
resources needed std. proces + perm resources for library
. optimal size = 25000 bytes
externals used except algollibrary fpscan
programcall see users manual
tests:
0: filhovede, kataloger ved afslutning af kørsel
1: synlige entries i packfile
2: funktion af forskellige procedurer
3: bloktransporter til/fra kataloger
4: synlige entries i main catalog
5: tidsforbrug
;
\f
comment o v e r s i g t o v e r p r o g r a m s t r u k t u r
.
.begin <* blok 0, pack-programmet *>
.
. <* indkopiering af globale library procedurer *>
.
. connect
. printarea
. break
. monitor_error
. get_claim
. ressource_check
.
. <* globale konstanter *>
. <* dimensioneringsvariable *>
.
. <* globale styrevariable *>
.
. <* field-variable for packfilehead og catalogs *>
.
. <* initialisering af alle de globale variable *>
.
. begin <* blok 1, global programblok *>
.
. <* globale procedurer *>
.
. read_program_call
. begin <* blok 2, indlæsning og test af programkaldet *>
.
. <* hjælpeprocedurer for aflæsning af programkaldet *>
.
. fp_call_error
. print_optionlist
. check_leftside
. check_function
. check_filelist
. getnextparam
. check_param
. check_valuelist
. check_date
.
. <* aflæsning af programkaldet og test af parameterlisten *>
. <* initialisering af funktionsafhængige defaultværdier *>
.
. end <* blok 2, procedure read_program_call *>
.
. quicksort
. discsort
. get_permkit_name
. compute_hashtable_size
.
. initialize_packfile_head(head)
. begin <* blok 2, proceduren åbner til eller opretter en packfile *>
. delay
. init_packfile
. gen_packname
. get_packfile
.
. <* kald af get_packfile *>
.
. gat_packfile(head,pack_tail,
. if program_function = packsym then <* opret *> else <* ikke opret *>)
.
. end <* blok 2, procedure initialize_packfile_head *>
.
.
. main(ud,head)
. begin <* blok 2, procedure main indeholder hovedprogrammet *>
.
. <* centrale programdel *>
.
. empty_out
. recompute_hashkeys
. check_packfile_head
. check_catalogs
. begin
. check_packcat
. check_gapcat
. check_crossref
. end <* check catalogs *>
.
. lookup_auxdoc
. lookup_entry
. search_catalogentry
. lookup_error
. print_date
. print_head_and_tail
. print_modekind
. print_entry
. print_heading
. print_packhead
. print_packcat
. print_gapcat
. print_tables
. testblok
.
. entry_scope
. open_special
. change_scope
. create_entry
. newposition
. next_record
. find_record
. swop_cat
. set_packtail
. movearea
.
. compute_hashkey
. initialize_hashtables
. insert_tableentry
. delete_tableentry
. search_tableentry
. lookup_tableentry
.
. subcompare
. get_nextentryspec
. scan_packentry
. next_packentry
. search_gap
. delete_packentry
. insert_packentry
. reorganize_gapcat
. compute_last_date
. purge
.
. pack
. unpack
. searchpack
. clearpack
. repack
. pointpack
. purgepack
. convertpack
.
. <* buffere for hoved og kataloger *>
.
. packcat(128*1,1)
. gapcat(128*1,1)
.
. <* tabeller til hashing-funktionen *>
.
. boolean array hashtable(1:head.hashtable_size),
. linktable(1:head.packentries)
.
.
. <* hoved program *>
.
. case program_function of
. begin
. -
. -
. end case
.
. end <* blok 2, procedure main *>
.
. <* buffer til packfilens hovede, samt array til programkald *>
.
. zone pack_head(128*1,1)
.
. long array optionlist(1:maxindex)
.
.
. <* starttidspunkt og dato beregnes *>
.
. <* kald af read_program_call *>
.
. read_program_call
.
. <* initialisering af processbaser *>
.
. <* test af processressourcer *>
.
. <* åbning til eller oprettelse af packfile *>
.
. initialize_packfile_head(pack_head)
.
. <* hovedprogrammet afvikles *>
.
. if current_output then
. main(out,pack_head)
. else
. begin
. zone overs(128*1,1)
.
. main(overs,pack_head)
. end
.
. end <* blok 1, global programblok *>
.
.end <* blok 0, pack-program *>
.
;
\f
<* globale konstanter *>
<**********************>
long
_ empty;
integer
_ pack_entry_length,
_ max_pack_entries,
_ max_gap_entries,
_ max_function,
_ max_index,
_ max_params,
_ maxint,
_ nil,
_ free,
_ temp,
_ login,
_ user,
_ project,
_ systemscope,
_ normlist,
_ ownerlist,
_ statlist,
_ packsym,
_ unpacksym,
_ searchpacksym,
_ clearpacksym,
_ repacksym,
_ pointpacksym,
_ purgepacksym,
_ convertpacksym,
_ undefined,
_ maxwaittime,
_ max_timeinterval,
_ maxbsdevices;
\f
<* globale variable for programmet *>
<***********************************>
long array
_ program_name, <* programfunktionsnavnet *>
_ outfile, <* navnet på filen til kørselrapport *>
_ newkit, <* navnet på nye device ved unpack *>
_ ownerid, <* ownerid-navnet for ønskede filer *>
_ packkit, <* navnet på device hvor packfile opret. *>
_ packfile(1:2); <* navnet på pack-filen *>
integer array
_ process_bases(1:8), <* indeholder de aktuelle processbaser *>
_ intern_bases(1:8), <* interne processbaser for packfile *>
_ viewbases(1:2), <* alternative interne processbaser *>
_ pack_tail(1:10); <* indeholder packfilens entrytail *>
boolean array
_ scopelist(0:4); <* markering for bestilte scope's *>
real
_ timebase, <* base for tidsberegninger *>
_ cputime, <* måler cpu-tidsforbruget *>
_ realtime; <* måler real-tidsforbruget *>
integer
_ program_function, <* kode for programfunktionen *>
_ no_of_files, <* antal af filnavne i programkald *>
_ no_of_subtext, <* antal subtext angivelser *>
_ scope, <* scope tæller *>
_ newscope, <* husker nyt scope for unpack-filer *>
_ retention, <* antal dage pakkede filer overlever *>
_ dim_retention, <* do., anvendes ved repackdimensionering*>
_ dim_packentries, <* max. antal indgange i packkatalog *>
_ dim_gapentries, <* max. antal huller i packfilen *>
_ lastdate, <* skæringsdato ved sletning af filer *>
_ deletetype, <* slettedato type ved purgepack *>
_ listtype, <* udskriftstype ved searchpack *>
_ date, <* kørselsdato *>
_ lower_catbase, <* processens nederste katalogbase *>
_ upper_catbase, <* processens øverste katalogbase *>
_ max_bufsegm; <* max. antal segm. i buffer ved flytning*>
boolean
_ convert, <* kørselsrapport udskrives på printer *>
_ current_output, <* kørselsrapport udskrives i zone out *>
_ allowner, <* alle filer med ownerid listes *>
_ allpackfile, <* alle filer listes uden undtagelse *>
_ security, <* security ved repack (user fil) *>
_ remove, <* angiver om pakkede entries slettes *>
_ scopeboo, <* angiver at scopeliste er indlæst *>
_ gapcat_used, <* angiver at hulkataloget anvendes *>
_ hashing_used, <* angiver at hashtabellen initialiseres *>
_ system_packfile, <* packfilen ligger på systemniveau *>
_ viewbase_set; <* alternative internbaser er angivet *>
long array field
_ filelist_adr, <* pointer til listen af filnavne *>
_ subtext_adr; <* pointer til subtext-liste *>
<*+2*>
<* testfaciliteter kan skippes efter ønske med programmet cleaner *>
boolean test;
<*-2*>
\f
<* fieldvariable for catalog/pack entry *>
long array field
_ entryname,
_ documentname,
_ password,
_ auxdocname;
integer array field
_ entry_baseadr,
_ entry_tail;
integer field
_ key,
_ lowerbase,
_ upperbase,
_ areasize,
_ storeaddress,
_ packdate,
_ last_accessdate,
_ no_of_read,
_ no_of_point,
_ entryindex,
_ hashkey,
<* field variable for packfile_head *>
_ entrylength,
_ packentries,
_ gapentries,
_ gapcat_adr,
_ first_areasegm,
_ no_of_entries,
_ no_of_segm,
_ no_of_gaps,
_ no_of_gapsegm,
_ retentiondays,
_ last_update,
_ packfile_size,
_ creation_date,
_ update_mark,
_ hashtable_size,
_ last_function,
_ extend_mark,
<* fieldvariable for gapcat_entry *>
_ first_emptysegm,
_ no_of_emptysegm;
\f
<* initialisering af globale konstanter *>
<****************************************>
pack_entry_length := 64; <* længde af pack_entry i bytes *>
max_pack_entries := 50; <* max antal indgange i packcatalog *>
max_gap_entries := 128; <* max antal huller i packfilen *>
max_function := 7; <* antal program-funktioner *>
max_index := 500; <* max længde for programkald *>
max_params := 16+1; <* antallet af kendte fpparametre *>
maxbsdevices := 10; <* max ant. disckit i ressource besk.*>
maxwaittime := 50; <* ventid for packfile i cpusec. *>
max_timeinterval := 5; <* ventetid mel. reserve af packfile *>
maxint :=8388607; <* max. positiv heltal *>
temp := 0; <* kode for scope.temp *>
login := 1; <* kode for scope.login *>
user := 2; <* kode for scope.user *>
project := 3; <* kode for scope.project *>
systemscope := 4; <* kode for scope.system *>
undefined := 5; <* kode for udefineret scope *>
normlist := 1; <* kode for normal listning af entry *>
ownerlist := 2; <* kode for ydeligere list af owner *>
statlist := 3; <* kode for listning af statistikker *>
packsym := 1;
unpacksym := 2;
searchpacksym := 3;
clearpacksym := 4;
repacksym := 5;
pointpacksym := 6;
purgepacksym := 7;
convertpacksym := 8;
empty :=long <::>; <* tomt tekstelement *>
\f
<* initialisering af fieldvariable for catalog/pack entry *>
entry_baseadr := 0;
key := 2;
lowerbase := 4;
upperbase := 6;
entryname := 6;
areasize := 16;
documentname := 16;
entrytail := 24;
storeaddress := 36;
password := 36;
packdate := 46;
last_accessdate := 48;
no_of_read := 50;
no_of_point := 52;
auxdocname := 52;
entryindex := 62;
hashkey := 64;
<* initialisering af fieldvariable for packfile_head *>
entrylength := 2;
packentries := 4;
gapentries := 8;
gapcat_adr := 12;
first_areasegm := 14;
no_of_entries := 16;
no_of_segm := 18;
no_of_gaps := 20;
no_of_gapsegm := 22;
retentiondays := 24;
last_update := 26;
packfile_size := 28;
creation_date := 30;
update_mark := 32;
hashtable_size := 34;
last_function := 36;
extend_mark := 38;
<* initialisering af fieldvariable for gapcat *>
first_emptysegm := 2;
no_of_emptysegm := 4;
\f
<* styrevariable initialiseres *>
no_of_subtext := 0;
newscope := undefined;
retention := maxint;
dim_retention :=
dimpackentries:=
dim_gapentries:=
lastdate := 0;
listtype :=
deletetype := 1;
current_output:=
security := true;
convert :=
scopeboo :=
allowner :=
allpackfile :=
systempackfile:=
remove :=
viewbase_set := false;
<*+2*>
test := false;
<*-2*>
outfile(1) :=
outfile(2) :=
packfile(1) :=
packfile(2) :=
packkit(1) :=
packkit(2) :=
newkit(1) :=
newkit(2) :=
ownerid(1) :=
ownerid(2) := empty;
viewbases(2) := maxint;
for scope:=temp step 1 until systemscope do
scopelist(scope):=false;
\f
<* globale programblok *>
<* ------------------- *>
begin
procedure read_program_call;
<**************************>
<* indlæser programkaldet og den tilhørende parameterliste *>
<* herefter testes og analyseres indholdet for fejlelementer *>
begin
procedure fp_call_error(no,index);
<********************************>
value no,index ;
integer no,index ;
<*
udskriver programkaldet og giver en fejlmeddelelse
ved fejl i programkaldets parametre
*>
begin
integer
_ place_of_error;
place_of_error:=printoptionlist(1,index-1,0);
write(out,<: -->> :>);
printoptionlist(index,max_index,place_of_error);
write(out,"nl",2,<:*** error in parameter list, :>,
case no of (
<* 1 *> <:parameter list too long:>,
<* 2 *> <:seperator between parameter and value not ".":>,
<* 3 *> <:parameter name not text:>,
<* 4 *> <:parameter name unknown:>,
<* 5 *> <:parameter not allowed with this program function:>,
<* 6 *> <:valuelist of mixed type not allowed:>,
<* 7 *> <:number of elements in valuelist exceeds maximum:>,
<* 8 *> <:valuelist of type integer, should be of type text:>,
<* 9 *> <:valuelist of type text, should be of type integer:>,
<* 10 *> <:parameter value element unknown or of illegal value:>,
<* 11 *> <:parameter name read twice:>,
<* 12 *> <:valuelist not complete:>,
<* 13 *> <:program function unknown:>,
<::>));
break(<::>,0,true);
end fp_call_error;
\f
integer procedure printoptionlist(firstel,lastel,lastpos);
<********************************************************>
value firstel,lastel,lastpos ;
integer firstel,lastel,lastpos ;
<*
udskriver programkaldet på current output
*>
begin
long array
_ textel(1:2);
integer
_ i,
_ spaces;
textel(2):=long <::>;
if firstel = 1 then
begin
spaces:=1;
outchar(out,'nl');
outchar(out,'*');
end
else spaces:=lastpos;
for i:=firstel step 1 until lastel do
begin
case kind(i) of
begin
<* seperator *>
begin
outchar(out,optionlist(i) extract 12);
spaces:=spaces+1;
end;
<* integer number *>
spaces:=spaces + write(out,<<d>,optionlist(i));
<* textparameter *>
begin
textel(1):=optionlist(i);
spaces:=spaces+write(out,textel);
end;
end case kind(i);
if spaces > 50 and kind(i) = seperator then
begin
outchar(out,'nl');
spaces:=0;
end;
end elements;
printoptionlist:=spaces;
end printoptionlist;
\f
boolean procedure check_leftside(name);
<*************************************>
long array name ;
<*
undersøger om venstreside er angivet i programkaldet
returværdi:
true : udfil angivet - name indeholder navnet hvis ikke "convert"
false: udfil ikke angivet
*>
begin
if optionlist(3) = '=' then
begin
check_leftside:=true ;
current_output:=false;
if optionlist(1) = long <:c:>
or optionlist(1) = long <:conve:> add 'r'
then convert:=true
else
begin
name(1):=optionlist(1);
name(2):=optionlist(2);
end;
end
else
begin
check_leftside:= false;
name(1) := long <:c:>;
end;
end check_leftside;
\f
integer procedure check_function(index);
<**************************************>
integer index ;
<*
returnerer programfunktionen
0 : ukendt
1 : pack
2 : unpack
3 : searchpack
4 : clearpack
5 : repack
6 : pointpack
7 : purgepack
*>
begin
long
_ pname;
pname:=optionlist(index);
index:=index + 2;
check_function:=
if pname = long <:pack:> then 1 else
if pname = long <:unpac:> add 'k' then 2 else
if pname = long <:searc:> add 'h' then 3 else
if pname = long <:clear:> add 'p' then 4 else
if pname = long <:repac:> add 'k' then 5 else
if pname = long <:point:> add 'p' then 6 else
if pname = long <:purge:> add 'p' then 7 else
if pname = long <:conve:> add 'r' then 8 else
_ 0 ;
end check_function;
\f
integer procedure check_filelist(index,adr);
<******************************************>
integer index,adr ;
<*
returnerer antallet af filnavne i fillisten
og adressen på første filnavn i parameterlisten
*>
begin
integer
_ namecount;
boolean
_ more;
namecount:=0; adr:=index*4; more:=true;
while optionlist(index) = 'sp' and kind(index) = seperator and more do
if index + 3 <= max_index + 1 then
begin
if (optionlist(index+3) = 'sp' or kind(index+3) = 0) and kind(index+1) = text then
begin
index:=index+3;
namecount:=namecount+1;
end
else
if optionlist(index+3) = '.' and kind(index+1) = text then
begin
if index + 9 <= maxindex + 1 then
begin
if optionlist(index+6) = '.' and kind(index+4) = text and kind(index+7) = text then
begin
if optionlist(index+4) = long <:scope:>
and optionlist(index+5) = long <::>
and (optionlist(index+7) = long <:temp:>
or optionlist(index+7) = long <:login:>
or optionlist(index+7) = long <:user:>
or optionlist(index+7) = long <:proje:> add 'c'
)
then
begin
index:= index + 9;
namecount:= namecount + 1;
end
else more:=false;
end
else more:=false;
end
else more:=false;
end
else more:=false;
end
else more:=false;
check_filelist:=namecount;
end check_filelist;
\f
integer procedure getnextparam(index,no_of_values,adrix,listtype);
<****************************************************************>
integer index,no_of_values,adrix,listtype ;
<*
returnerer parameternummeret og antallet af værdielementer
for næste parameter i programkaldet
returnvalue:
- 5 : værdiliste af blandet type
- 4 : parameter ikke tilladt
- 3 : skilletegn ikke '.'
- 2 : integer
- 1 : parameter ukendt
0 : slut på parameterlisten
ellers nummeret på parameteren i navne kataloget
*>
begin
integer
_ return,
_ ccount;
boolean
_ firstel,
_ found,
_ more;
no_of_values:=listtype:=0; found:=false;
if index+1 > max_index then return:= 0 else
if kind(index+1) = number then return:=-2 else
if optionlist(index+3) <> '.' then return:=-3 else
begin
for ccount:=1, ccount+1 while ccount <= max_params and -,found do
if namecat(ccount) = optionlist(index+1) then
begin
found:= true;
return:= if check_param(if program_function = convertpacksym then
_ repacksym else program_function,ccount)
then ccount else (-4);
end;
if -,found then return:=-1;
index:=index+3;
adrix:=index+1;
more :=true; firstel:=true;
while more and index <= max_index do
if optionlist(index) = '.' then
begin
if firstel then
begin
firstel :=false;
listtype:=kind(index+1);
end
else
if listtype <> kind(index+1) then
begin
listtype:= 0;
if found then
return :=-5;
end;
no_of_values:=no_of_values + 1;
index :=index + (if kind(index+1) = text then 3 else 2);
end
else more:=false;
end;
getnextparam:=return;
end getnextparam;
\f
boolean procedure check_param(function,paramno);
<**********************************************>
value function,paramno ;
integer function,paramno ;
<*
undersøger om parameteren er tilladt ved programfunktionen
*>
check_param:=case (paramno-1)*max_function + function of (
<* function 1 2 3 4 5 6 7 *>
<* - - - - - - - pack unpack search clear repack point purge *>
<* parameter-no *>
<* 1,subtext *> true, true, true, false, false, true, false,
<* 2,scope *> true, true, true, false, false, true, false,
<* 3,packfile *> true, true, true, true, true, true, true,
<* 4,owner *> true, true, true, true, false, true, false,
<* 5,newscope *> true, true, false, false, false, true, false,
<* 6,retention *> true, false, false, false, true, false, false,
<* 7,all *> false, false, true, false, false, false, false,
<* 8,lastdate *> false, false, false, false, false, false, true,
<* 9,maxentries *> true, false, false, false, true, false, false,
<*10,security *> false, false, false, false, true, false, false,
<*11,maxgaps *> true, false, false, false, true, false, false,
<*12,changekit *> true, true, false, false, false, true, false,
<*13,list *> false, false, true, false, false, false, false,
<*14,deletetype *> false, false, false, false, false, false, true,
<*15,remove *> true, false, false, false, false, false, false,
<*16,base *> false, true, false, true, false, true, false,
<*xx,test *> true, true, true, true, true, true, true);
\f
integer procedure check_valuelist(paramno,type,no_of_values);
<***********************************************************>
value paramno,type,no_of_values ;
integer paramno,type,no_of_values ;
<*
undersøger typen og elementantallet for
værdilisten for en given parameter
*>
begin
integer array
_ param(1:2);
integer
_ no;
for no:=1,2 do
param(no):=case (paramno-1)*2 + no of (
<* parameter_no. type max. antal *>
<* 1,subtext *> text, maxint,
<* 2,scope *> text, 4,
<* 3,packfile *> text, 2,
<* 4,owner *> text, 1,
<* 5,newscope *> text, 1,
<* 6,retention *> number, 1,
<* 7,all *> text, 1,
<* 8,lastdate *> number, 1,
<* 9,maxentries *> number, 1,
<*10,security *> text, 1,
<*11,maxgaps *> number, 1,
<*12,changekit *> text, 1,
<*13,list *> text, 1,
<*14,deletetype *> text, 1,
<*15,remove *> text, 1,
<*16,base *> number, 2,
<* x,test *> number, 12 );
check_valuelist:=
if type <> param(1) then type else
if no_of_values > param(2) then 1 else 0;
end check_valuelist;
\f
boolean procedure check_date(first,last,date);
<********************************************>
value first,last,date ;
integer first,last,date ;
<* tester lovligheden af en datoangivelse *>
begin
boolean
_ ok;
integer
_ yy,
_ mm,
_ dd;
yy:= date // 10000;
mm:= date // 100 mod 100;
dd:= date mod 100;
ok:=
date >= first and
date <= last and
mm >= 1 and
mm <= 12 and
dd >= 1 ;
if ok then
ok:= dd <= (case mm of (31, if yy mod 4 = 0 then 29 else 28,
_ 31, 30, 31, 30, 31, 31, 30, 31, 30, 31));
check_date:= ok;
end check_date;
\f
long array
_ namecat(1:maxparams);
integer array
_ kind(1:max_index);
boolean array
_ param_read(1:max_params);
integer
_ parameter_type, <* kode for aktuel parameter i listen *>
_ parameter_values, <* antal læste værdier for en given parameter *>
_ valuelist_type, <* typen for en parameters værdiliste *>
_ valuelist_adr, <* index til værdiliste for given parameter *>
_ fp_index, <* løbende index til parameterlisten *>
_ old_index, <* husker tidligere index i parameterlisten *>
_ count, <* hjælpe variabel *>
_ seperator, <* kind for skilletegn i parameterliste *>
_ number, <* kind for heltal i parameterliste *>
_ text; <* kind for text i programkald *>
seperator := 1;
number := 2;
text := 3;
\f
<* initialisering af kendte parameternavne *>
for count:=1 step 1 until max_params do
begin
param_read(count):= false;
namecat(count):=long (case count of(
<* 1 *> <:subte:> add 'x',
<* 2 *> <:scope:> ,
<* 3 *> <:packf:> add 'i',
<* 4 *> <:owner:> ,
<* 5 *> <:newsc:> add 'o',
<* 6 *> <:reten:> add 't',
<* 7 *> <:all:> ,
<* 8 *> <:lastd:> add 'a',
<* 9 *> <:maxen:> add 't',
<* 10 *> <:secur:> add 'i',
<* 11 *> <:maxga:> add 'p',
<* 12 *> <:chang:> add 'e',
<* 13 *> <:list:> ,
<* 14 *> <:delet:> add 'e',
<* 15 *> <:remov:> add 'e',
<* 16 *> <:base:> ,
<* xx *> <:test:> ));
end;
<* parameterlisten indlæses i <optionlist> typerne i <kind> *>
max_index:=fp_scan(optionlist,kind);
if max_index < 0 then fp_call_error(1,abs max_index);
<* venstreside, programnavn og filnavneliste undersøges *>
fp_index:=if check_leftside(outfile) then 4 else 1;
program_name(1):=optionlist(fp_index);
program_name(2):=optionlist(fp_index+1);
program_function:=check_function(fp_index);
if program_function = 0 then fp_call_error(13,fp_index - 2);
no_of_files:=check_filelist(fp_index,filelist_adr);
\f
<* nu læses resten af parameterlisten *>
old_index:=fp_index;
for parameter_type:=getnextparam(fp_index,parameter_values,valuelist_adr,valuelist_type)
while parameter_type <> 0 do
begin
<*+1*>
if test shift(-2) then <* aktiveres først efter læsning af testparameter *>
write(out,<:<'nl'>paramtype, index, values, valueadr :>,<<ddddd>,
parameter_type,fp_index,parameter_values,valuelist_adr);
<*-1*>
if parameter_type > 0 then
begin
if -,param_read(parameter_type)
then param_read(parameter_type):= true
else fp_call_error(11,old_index);
count:=check_valuelist(parameter_type,valuelist_type,parameter_values);
if count > 0 then fp_call_error(6+count,valuelist_adr);
end;
case parameter_type + 6 of
begin
<* -5, valuelist of mixed type *>
fp_call_error(6,valuelist_adr);
<* -4, parameter not allowed *>
fp_call_error(5,old_index);
<* -3, seperator not '.' *>
fp_call_error(2,fp_index);
<* -2, integer - not text *>
fp_call_error(3,fp_index);
<* -1, parameter unknown *>
fp_call_error(4,old_index);
<* 0, not used ! *> ;
<* subtext *>
begin
no_of_subtext:=parametervalues;
subtext_adr :=(valuelist_adr-1)*4;
end;
<* scope *>
begin
scopeboo:=true;
for count:=valuelist_adr step 3 until valuelist_adr + (parameter_values - 1) * 3 do
begin
scope:=
if optionlist(count) = long <:temp:> then temp else
if optionlist(count) = long <:login:> then login else
if optionlist(count) = long <:user:> then user else
if optionlist(count) = long <:proje:> add 'c' then project else -1;
if scope > -1
then scopelist(scope):=true
else fp_call_error(10,count);
end;
end;
<* packfile *>
begin
packfile(1):=optionlist(valuelist_adr );
packfile(2):=optionlist(valuelist_adr+1);
if parametervalues > 1 then
begin
packkit(1):=optionlist(valuelist_adr+3);
packkit(2):=optionlist(valuelist_adr+4);
end;
end;
<* owner *>
begin
ownerid(1):=optionlist(valuelist_adr );
ownerid(2):=optionlist(valuelist_adr+1);
end;
<* newscope *>
begin
for count:=valuelist_adr step 3 until valuelist_adr+(parameter_values - 1) * 3 do
begin
scope:=
if optionlist(count) = long <:temp:> then temp else
if optionlist(count) = long <:login:> then login else
if optionlist(count) = long <:user:> then user else
if optionlist(count) = long <:proje:> add 'c' then project else -1;
if scope <> -1 and newscope = undefined then
newscope:= scope else fp_call_error(10,count);
end;
end;
<* retention *>
retention:=dim_retention:=optionlist(valuelist_adr);
<* all *>
if optionlist(valuelist_adr) = long <:owner:> then allowner:=true else
if optionlist(valuelist_adr) = long <:packf:> add 'i' then allpackfile:=true else
fp_call_error(10,valuelist_adr);
<* lastdate *>
begin
lastdate:=optionlist(valuelist_adr);
if -,check_date(700101,date,lastdate) then fp_call_error(10,valuelist_adr);
end;
<* maxentries *>
if optionlist(valuelist_adr) >= 15 and optionlist(valuelist_adr) < 4095 then
dim_packentries :=
max_pack_entries:= optionlist(valuelist_adr)
else fp_call_error(10,valuelist_adr);
<* security *>
if optionlist(valuelist_adr) = long <:no:> then security:=false else
if optionlist(valuelist_adr) <> long <:yes:> then fp_call_error(10,valuelist_adr);
<* maxgaps *>
if optionlist(valuelist_adr) >= 15 and optionlist(valuelist_adr) < 4095 then
dim_gapentries :=
max_gap_entries:= optionlist(valuelist_adr)
else fp_call_error(10,valuelist_adr);
<* changekit *>
if newkit(1) = empty then
begin
newkit(1):= optionlist(valuelist_adr );
newkit(2):= optionlist(valuelist_adr+1);
end
else fp_call_error(10,valuelist_adr);
<* list *>
if optionlist(valuelist_adr) = long <:norma:> add 'l' then listtype:= 1 else
if optionlist(valuelist_adr) = long <:stati:> add 's' then listtype:= 2 else
if optionlist(valuelist_adr) = long <:entry:> then listtype:= 3 else
fp_call_error(10,valuelist_adr);
<* deletetype *>
if optionlist(valuelist_adr) = long <:entry:> add 'd' then deletetype:= 1 else
if optionlist(valuelist_adr) = long <:packd:> add 'a' then deletetype:= 2 else
if optionlist(valuelist_adr) = long <:acces:> add 's' then deletetype:= 3 else
fp_call_error(10,valuelist_adr);
<* remove *>
if optionlist(valuelist_adr) = long <:yes:> then remove:= true else
if optionlist(valuelist_adr) = long <:no:> then remove:= false else
fp_call_error(10,valuelist_adr);
<* base *>
begin
viewbase_set:= true;
viewbases(1):= optionlist(valuelist_adr);
if parametervalues > 1 then
begin
if optionlist(valuelist_adr + 2) >= viewbases(1) then
viewbases(2):= optionlist(valuelist_adr + 2) else
fp_call_error(10,valuelist_adr + 2);
end
else fp_call_error(12,valuelist_adr);
end;
<* her indsættes nye parametre *>
<* test *>
begin
<*+2*>
boolean array testbits(0:11);
for count:= 0 step 1 until 11 do testbits(count):= false;
for count:=valuelist_adr step 2 until valuelist_adr+(parameter_values - 1) * 2 do
if optionlist(count) <= 11 then testbits(optionlist(count)):=true
else fp_call_error(10,count);
<* pakning af testbits *>
for count:=0 step 1 until 11 do
test:=test shift 1 add (testbits(11-count) extract 1);
<*-2*>
<*+1*>
if false then
<*-1*>
<*+2*>
begin
if test shift(-1) or test shift(-2) or test shift(-4) then
write(out,<:<10>*** only test.0.3.5 can be activated !:>);
end;
if false then
<*-2*>
write(out,<:<10>*** testfacilities are missing !:>);
end;
end case parameter_type;
old_index:=fp_index;
end while parameter_type <> 0;
<* initialisering af nogle styrevariable *>
gapcat_used:= case program_function of (
<* pack *> true,
<* unpack *> false,
<* searchpack *> false,
<* clearpack *> true,
<* repack *> true,
<* pointpack *> false,
<* purgepack *> true,
<* convertpack *> false);
hashing_used:=
<*+2*>
program_function = convertpacksym or
<*-2*>
program_function = packsym or
program_function = unpacksym and no_of_files > 0 or
program_function = pointpacksym and no_of_files > 0 or
program_function = clearpacksym;
<* initialisering af specielle defaultværdier *>
if newscope = undefined then
newscope:=
if program_function = unpacksym then login else
if program_function = pointpacksym then temp else
newscope;
if -,scopeboo
and no_of_files = 0
and no_of_subtext = 0
and (program_function = packsym
or program_function = unpacksym
or program_function = pointpacksym
)
then scopeboo:= scopelist(login):= true;
<*+1*>
if test shift(-2) then
begin
printoptionlist(1,max_index,0);
write(out,"nl",2,<<dddddddd>,
<:<10>antal filer i fillisten :>,no_of_files,
<:<10>antal subtext angivelser :>,no_of_subtext,
"nl",1);
if scopeboo then
for scope:=temp step 1 until project do
if scopelist(scope) then
write(out,<:<10>scope = :>,
_ case scope + 1 of (<:temp:>,<:login:>,<:user:>,<:project:>));
write(out,"nl",1);
end test;
<*-1*>
end procedure read_program_call;
\f
procedure quicksort(a,n,s,ix);
<****************************>
value n,s,ix ;
integer array a ;
integer n,s,ix ;
<*
sorterer array 'a' v.h.a. quicksort algoritmen.
n = antal rækker, s = antal søjler,
ix = søjlenr, hvorefter der skal sorteres.
kilde: niklaus wirth, algorithms + data structures = programs,
_ p. 80. new jersey 1976.
*>
begin
real array
_ stack(1:entier(ln(n)/ln(2)) + 1);
integer
_ x,
_ w; <* x, w of same type as 'a' *>
integer
_ i,
_ j,
_ k,
_ l,
_ r;
real array field
_ top;
integer field
_ left,
_ right;
left := 2;
right:= 4;
top:= 0;
stack.top.left := 1;
stack.top.right:= n;
repeat <* take top request from stack *>
l:= stack.top.left;
r:= stack.top.right;
top:= top - 4;
repeat <* split a(l) ... a(r) *>
i:= l;
j:= r;
x:= a((l+r)//2, ix);
repeat
while a(i,ix) < x do i:= i + 1;
while x < a(j,ix) do j:= j - 1;
if i <= j then
begin <* exchange *>
for k:=1 step 1 until s do
begin
w := a(i,k);
a(i,k):= a(j,k);
a(j,k):= w;
end;
i := i + 1;
j := j - 1;
end;
until i > j;
if j - l < r - i then
begin
if i < r then
begin <* stack request for sorting the right partition *>
top:= top + 4;
stack.top.left := i;
stack.top.right:= r;
end;
r:= j; <* continue sorting left partition *>
end
else
begin
if l < j then
begin <* stack request for sorting the left partition *>
top:= top + 4;
stack.top.left := l;
stack.top.right:= j;
end;
l:= i; <* continue sorting the right partition *>
end;
until l >= r;
until top < 0;
end quicksort;
\f
procedure discsort(filnavn,læ,antalindiv,segmprblok,startsegm,
_ k1,k2,k3,k4,k5);
<************************************************************>
value segmprblok ;
string filnavn ;
integer læ,antalindiv,segmprblok,startsegm,
_ k1,k2,k3,k4,k5;
begin
comment
sortering ved søren lauesens 'sldisksort'.
proceduren modificeret mht:
1) sorteringen starter først i <startsegm>.
2) der sorteres efter 5 nøgler, 4 longs og 1 integer
bjj 790222
eja 810927, udvidet til 5 nøgler
;
integer fysisksubbloklængde, fysiskbloklængde, b;
integer array ia(1:20);
array ra(1:2);
fysisksubbloklængde := 512 * segmprblok;
b:= (system(2,b,ra)-8*512)//(2*fysisksubbloklængde);
fysiskbloklængde := b * fysisksubbloklængde;
segmprblok := b * segmprblok;
begin
integer diff, fa, indivlæ2, logiskbloklængde, start,
logisksubbloklængde, nedbasis, nedplads, nedslut, opbasis,
opplads, opslut, slut2, start2, subblokstart, transporter;
integer field indivlæ;
real r;
real field i;
array field m, ned, op;
integer array nuvblok(0:1);
zone z(fysiskbloklængde//2,1,blproc);
long mid1, mid2, mid3, mid4, prim1, prim2, prim3, prim4;
integer mid5;
long field nøgle1, nøgle2, nøgle3, nøgle4;
integer field nøgle5;
procedure blproc(z,s,b);
zone z;
integer s, b;
if s extract 19 < 1 shift 18 or ia(4)<>5 shift 12 then
stderror(z,s,b);
procedure io(plads,operation);
integer plads, operation;
begin
b:=nuvblok(plads)*segmprblok;
if b>=0 then
begin
ia(4):= operation shift 12;
ia(7):= b+start;
ia(5):= b:= fa + plads*fysiskbloklængde;
ia(6):= b + fysiskbloklængde - 2;
setshare(z,ia,1);
monitor(16,z,1,ia);
check(z);
end
end io;
procedure quicksort(start,slut,enblok);
value start, slut, enblok;
integer start, slut;
boolean enblok;
begin
for m:=start+(slut-start)//indivlæ2*indivlæ while start<slut-indivlæ2 do
begin
op:= start-opbasis;
ned:= slut-nedbasis;
if enblok then m:= m - opbasis else
begin
transporter:=0;
transport(m,0,opplads,nedplads);
nedslut:=ned;
opslut:=op;
end;
mid1:= z.m.nøgle1;
mid2:= z.m.nøgle2;
mid3:= z.m.nøgle3;
mid4:= z.m.nøgle4;
mid5:= z.m.nøgle5;
søgned:
ned:= ned-indivlæ;
if ned < nedslut then
begin
transport(ned,nedbasis,nedplads,opplads);
nedslut:= subblokstart;
end;
prim1:= z.ned.nøgle1 - mid1;
prim2:= z.ned.nøgle2 - mid2;
prim3:= z.ned.nøgle3 - mid3;
prim4:= z.ned.nøgle4 - mid4;
if
(if prim1 = 0 then
(if prim2 = 0 then
(if prim3 = 0 then
(if prim4 = 0 then z.ned.nøgle5 > mid5 else prim4 > 0)
_ else prim3 > 0)
_ else prim2 > 0)
_ else prim1 > 0)
then goto søgned;
søgop:
op:= op+indivlæ;
if op >= opslut then
begin
transport(op,opbasis,opplads,nedplads);
opslut:= subblokstart + logisksubbloklængde;
if transporter=3 then enblok:= nedslut=subblokstart;
end;
prim1:= z.op.nøgle1 - mid1;
prim2:= z.op.nøgle2 - mid2;
prim3:= z.op.nøgle3 - mid3;
prim4:= z.op.nøgle4 - mid4;
if
(if prim1 = 0 then
(if prim2 = 0 then
(if prim3 = 0 then
(if prim4 = 0 then z.op.nøgle5 < mid5 else prim4 < 0)
_ else prim3 < 0)
_ else prim2 < 0)
_ else prim1 < 0)
then goto søgop;
if op+opbasis < ned+nedbasis then
begin
for i:=4 step 4 until indivlæ do
begin
r:=z.op.i;
z.op.i:=z.ned.i;
z.ned.i:=r
end;
if indivlæ extract 2 > 0 then
begin
i:= z.op.indivlæ;
z.op.indivlæ:=z.ned.indivlæ;
z.ned.indivlæ:=i;
end;
goto søgned;
end;
slut2:= op+opbasis;
start2:= start;
start:= ned+nedbasis;
if slut-start < slut2-start2 then
begin
i:=slut;
slut:=slut2;
slut2:=i;
i:=start;
start:=start2;
start2:=i;
end;
if start2<slut2-indivlæ2 then quicksort(start2,slut2,enblok);
end for m;
end quicksort;
procedure transport(fysisk,basis,plads,andenplads);
integer fysisk, basis, plads, andenplads;
begin
integer logisk, blok, blokrel, subbloknr, blokbasis;
logisk:= fysisk+basis;
blok:= logisk//logiskbloklængde;
blokrel:= logisk mod logiskbloklængde;
if blok = nuvblok(0) then plads := 0 else
if blok = nuvblok(1) then plads := 1 else
begin
plads := 1-andenplads;
io(plads,5);
nuvblok(plads):= blok;
io(plads,3);
end;
subbloknr := blokrel//logisksubbloklængde;
blokbasis := plads * fysiskbloklængde;
fysisk := blokrel + subbloknr * diff + blokbasis;
subblokstart := subbloknr * fysisksubbloklængde + blokbasis;
basis := logisk - fysisk;
transporter := transporter + 1;
end transport;
open(z,4,filnavn,1 shift 18);
close(z,false);
getzone(z,ia);
fa:=ia(19)+1;
getshare(z,ia,1);
start:=startsegm;
nøgle1:= k1;
nøgle2:= k2;
nøgle3:= k3;
nøgle4:= k4;
nøgle5:= k5;
indivlæ:=læ;
indivlæ2:=2*indivlæ;
if nøgle1<2 or indivlæ<nøgle1 then system(9,nøgle1,<:<10>index :>);
diff:= fysisksubbloklængde mod indivlæ;
logisksubbloklængde := fysisksubbloklængde - diff;
logiskbloklængde := b * logisksubbloklængde;
nuvblok(0) := nuvblok(1) := -1;
opbasis:= nedbasis:= nedplads:= 0;
quicksort(-indivlæ,indivlæ*antalindiv, false);
io(0,5);
io(1,5);
end zone blok;
end disksort;
\f
boolean procedure get_permkit_name(packkit);
<******************************************>
long array packkit ;
<* finder et bsdevice, hvor der er permanente ressourcer *>
begin
integer array
_ claims(1:6 + 11*maxbsdevices); <* ressourcebeskr. for bl.a. bs-devices *>
integer
_ count,
_ segments,
_ slicelength;
integer array field
_ devbase;
long array field
_ dev;
slicelength:=0;
segments :=0;
dev :=0;
devbase :=12;
<* processens ressourcebeskrivelser hentes *>
if -,get_claim(claims) then
break(<:*** all resource descriptions cannot be stored, max. bsdevices:>,maxbsdevices,true);
for count:=1 step 1 until claims(6) do
begin
if claims.devbase(10) > 0 <* entries *>
and claims.devbase(11) > 0 <* segments *>
and (claims.devbase(11) > segments
or claims.devbase(11) = segments
and claims.devbase(5) > slicelength) then
begin
dev :=devbase;
segments :=claims.devbase(11);
slicelength:=claims.devbase(5);
end;
devbase:=devbase + 22;
end;
if dev > 0 then <* permanente ressourcer tilstæde *>
begin
get_permkit_name:= true;
for count:=1,2 do
packkit(count):=claims.dev(count);
end
else
begin
get_permkit_name:= false;
packkit(1):= extend 1 shift 24 ; <* prefering a disckit with temp resources *>
write(out,"nl",1,<:*** no permanent resources available on any bsdevice<10>:>);
end;
end get_permkit_name;
\f
integer procedure compute_hashtable_size(max_entries);
<****************************************************>
value max_entries ;
integer max_entries ;
<*
finder det mindste primtal, som er større end max_entries.
dette tal er således størrelsen på den anvendte hashtabel.
*>
begin
real
_ help_real;
integer
_ candidate,
_ div,
_ square_root;
boolean
_ found;
candidate:= if max_entries mod 2 = 0 then
_ max_entries + 1 else max_entries;
found:= false;
repeat
help_real := candidate;
square_root := sqrt(help_real);
div:= 1;
repeat div:= div + 2;
until candidate mod div = 0 or div > square_root;
if div > square_root
then found:= true
else candidate:= candidate + 2;
until found;
compute_hashtable_size:= candidate;
<*+1*>
if test shift(-2) then
write(out,<:<10>compute_hashtable_size =:>,candidate);
<*-1*>
end compute_hashtable_size;
\f
procedure initialize_packfile_head(head);
<***************************************>
zone head ;
<*
indlæser hovedet fra en packfil. hvis pack
oprettes en packfil hvis denne ikke findes
*>
begin
procedure delay(seconds);
<***********************>
integer seconds ;
<*
stopper programmets udførelse
i <seconds> antal sekunder
*>
begin
zone
_ clock(1,1,stderror);
integer array
_ sh_descr(1:12);
open(clock,2,<:clock:>,0);
getshare6(clock,sh_descr,1);
sh_descr(4):= 0;
sh_descr(5):= seconds;
setshare6(clock,sh_descr,1);
monitor(16)send_message:(clock,1,sh_descr);
monitor(18)wait_answer:(clock,1,sh_descr);
close(clock,true);
end delay;
\f
procedure init_packfile(z,tail);
<******************************>
zone z ;
integer array tail ;
<*
proceduren initialiserer
hovedet, og katalogerne
i den nyoprettede packfile
*>
begin
integer
_ catsegm,
_ gap_catsegm,
_ i;
integer array field
_ iaf;
gap_catsegm:=(max_gap_entries-1)//(512//4)+1;
cat_segm :=(max_pack_entries-1)//(512//pack_entry_length)+1;
<* nulstilling af packfile *>
setposition(z,0,0);
outrec6(z,512);
for i:=1 step 1 until 128 do z(i):= real <::>;
for i:=1 step 1 until cat_segm + gap_catsegm do outrec6(z,512);
setposition(z,0,0);
iaf:=0;
swoprec6(z,512);
for i:=1 step 1 until 17 do
z.iaf(i):=case i of (
<* 1 *> pack_entry_length,
<* 2 *> max_pack_entries,
<* 3 *> 0,
<* 4 *> max_gap_entries,
<* 5 *> 0,
<* 6 *> 1 + cat_segm,
<* 7 *> 1 + cat_segm + gap_cat_segm,
<* 8 *> 0,
<* 9 *> 0,
<* 10 *> 0,
<* 11 *> 0,
<* 12 *> retention,
<* 13 *> date,
<* 14 *> 1 + cat_segm + gap_cat_segm,
<* 15 *> date,
<* 16 *> 0,
<* 17 *> compute_hashtable_size(max_pack_entries));
monitor(44)cut_entry_size:(z,0,tail);
setposition(z,0,0);
end init_packfile;
\f
procedure gen_packname(la);
<*************************>
long array la ;
<*
genererer navn for packfile
ud fra procesnavnet på
formen: xxxpack, dog max.
11 karakter for filnavn.
*>
begin
long array
_ processname(1:2);
integer
_ i,
_ ix,
_ char,
_ pos;
boolean
_ more;
<* hent procesnavn *>
system(6,0,processname);
ix:=2; pos:=0; more:=true;
repeat
char:=processname(ix) extract 8;
more:=char = 'nul' or ('0' <= char and char <= '9');
if more then
begin
pos:=pos + 1;
processname(ix):=processname(ix) shift(-8);
end;
if pos = 6 then
begin
pos:=0;
ix :=ix - 1;
end;
until -,more;
if ix = 2 and pos < 5 then
begin
processname(ix):=processname(ix) shift(8*pos - 40);
pos:=5;
end;
i:=0;
repeat
if pos = 0 then
begin
pos:=6;
ix :=ix + 1;
end;
i:=i + 1; pos:=pos - 1;
processname(ix):=
processname(ix) shift 8 add (if i <= 4 then (case i of ('p','a','c','k')) else 'nul');
until pos = 0 and i >= 4;
<* navnet returneres *>
for ix:=1,2 do la(ix):=processname(ix);
end gen_packname;
\f
procedure get_packfile(z,tail,opret);
<***********************************>
zone z ;
integer array tail ;
boolean opret ;
<*
proceduren åbner til packfile,
hvis den ikke findes og opret
er 'true', oprettes en ny
packfile med navnet 'xxxpack'
komponeret ud fra brugernavnet
*>
begin
procedure error(s,i,b);
<*********************>
string s ;
integer i ;
boolean b ;
begin
write(out,<:<10>packfile.:>,packfile);
if tail.device(1) <> empty
and tail.device(1) <> extend 1 shift 24
then write(out,<:.:>,tail.device);
break(s,i,b);
end error;
boolean procedure open_pack(name);
<********************************>
long array name ;
begin
integer r;
close(z,true);
open(z,4,name,0);
r:= monitor(42,z,0,tail);
if r = 0 and tail(1) <= 0 then
begin
long array field
_ doc;
doc:= 2;
tofrom(name,tail.doc,8);
close(z,true);
open(z,4,name,0);
r:= monitor(42,z,0,tail);
end;
if r <> 0 and r <> 3 then
monitor_error(42,z,r,true);
if r = 0 then
begin
if tail(9) <> 10 shift 12 add 1 then
error(<:*** file is no packfile, content key =:>,tail(9) shift(-12),true);
end;
open_pack:=if r = 0 then true else false;
end open_pack;
long array
_ la_help(1:2);
integer array
_ head_tail(1:17);
integer
_ waittime,
_ return;
boolean
_ search,
_ found;
long array field
_ device;
integer array field
_ iaf;
iaf :=0;
device:=2;
tail.device(1):= empty;
if packfile(1) = empty then
begin
search:=true;
gen_packname(la_help);
end
else search:=false;
if search then
begin
found:=open_pack(la_help);
if -,found then
begin
packfile(1):=long <:publi:> add 'c';
packfile(2):=long <:pack:> ;
found:=open_pack(packfile);
if -,found then
begin
packfile(1):=la_help(1);
packfile(2):=la_help(2);
close(z,true);
open (z,4,packfile,0);
end;
end
else
begin
packfile(1):=la_help(1);
packfile(2):=la_help(2);
end;
end
else found:=open_pack(packfile);
if -,found and opret then
begin
if packkit(1) = empty then get_permkit_name(packkit);
<* nødvendige størrelse beregnes *>
tail(1):= 1 +
_ (max_pack_entries - 1)//(512//pack_entry_length) + 1 +
_ (max_gap_entries - 1)//(512//4) + 1;
tail.device(1):=packkit(1);
tail.device(2):=packkit(2);
tail(6):=systime(7,0,0.0);
tail(7):=0;
tail(8):=0;
tail(9):=10 shift 12 + 1;
tail(10):=0;
return:=monitor(40,z,0,tail);
if return <> 0 then
begin
if return <> 4 then
monitor_error(40,z,return,false);
error(<:*** packfile cannot be created of segments:>,tail(1),true);
end;
monitor(42,z,0,tail);
write(out,<:<10>packfile.:>,packfile,<:.:>,tail.device,
_ <:, created of:>,tail(1),<: segments<10>:>);
<* packfilen tildeles scope = user *>
return:= monitor(50)permanent_entry:(z,3,tail);
if return = 0 then
begin
head_tail(1):= process_bases(5);
head_tail(2):= process_bases(6);
return:= monitor(74)set_entry_base:(z,0,head_tail);
if return <> 0 and return <> 3 then
monitor_error(74,z,return,false);
if return <> 0 then
monitor(50)temp_entry:(z,0,tail);
end
else
if return <> 6 then
monitor_error(50,z,return,false);
if return <> 0 then
write(out,"nl",1,<:*** packfile temporary, no perm resources<10>:>);
init_packfile(z,tail);
found:=true;
end
else
if -,found then
error(<:*** packfile does not exist:>,0,true);
return:=monitor(52)create_areaprocess:(z,0,tail);
if return <> 0 then monitor_error(52,z,return,true);
<* det undersøges om packfilen er en system packfil *>
return:= monitor(76)lookup_head_and_tail:(z,0,head_tail);
if return <> 0 then monitor_error(76,z,return,true);
system_packfile:=
if head_tail.key extract 3 = 3
and (head_tail.lower_base < process_bases(7) and head_tail.upperbase >= process_bases(8)
or head_tail.lower_base <= process_bases(7) and head_tail.upperbase > process_bases(8))
then true else false;
if system_packfile
and program_function <> unpacksym
and program_function <> pointpacksym
and program_function <> searchpacksym
then error(<:*** program function not allowed on system packfile !:>,0,true);
if scopeboo and system_packfile then
scopelist(systemscope):= true;
<* reservation af packfile *>
if -,system_packfile then
begin
trap(wait);
waittime:= 0;
for return:=monitor(8,z,0,tail)
while return = 1 do
begin <* wait for release *>
delay(max_timeinterval <* seconds *>);
waittime:= waittime + max_timeinterval;
if waittime >= maxwaittime then
begin
trap(0);
close(z,true);
error(<:*** waiting time for release of packfile exceeded, max. wait time =:>,maxwaittime,true);
end;
end;
trap(0);
if false then
wait:
begin
trap(0);
close(z,true);
error(<:*** time exceeded or user kill while waiting for release of packfile:>,0,true);
end;
if return <> 0 then monitor_error(8,z,return,true);
<* hovedet indlæses *>
swoprec6(z,512);
end
else
inrec6(z,512);
if z.entrylength < pack_entry_length then
error(<:*** packfile wrong version !<10> creation date =:>,z.creation_date,true);
end get_packfile;
<* der åbnes til packfile, ved pack oprettes denne evt. *>
get_packfile(head,pack_tail,
if program_function = packsym then true else false);
end procedure initialize_packfile;
\f
procedure main(ud,head);
<**********************>
zone ud,head ;
<* proceduren indeholder hele hovedprogrammet *>
<* bufferen 'ud' anvendes til kørselsoversigt *>
begin
procedure empty_out(z);
<*********************>
zone z ;
<*
tømmer den igangværende
blok efter tegnvis ud-
skrivning
*>
begin
integer array
_ descr(1:20);
integer
_ leftch,
_ pw;
getzone6(z,descr);
if descr(14) + 4*descr(20)//descr(18) > descr(15) then
begin
leftch:=(descr(15) - descr(14)) // 2 * 3;
pw := descr(12);
leftch:= leftch -
_ (if pw shift(-16) = 1 then 2 else
_ if pw shift(-8) extract 8 = 1 then 1 else 0);
outchar(z,'nl');
leftch:= leftch - 1;
if leftch < 0 then
leftch:= 768 - leftch;
write(z,false,leftch);
end;
end empty_out;
\f
procedure recompute_hashkeys(list);
<********************************>
boolean list ;
<*
proceduren gennemløber packcat, og
nyberegner hashnøglerne, såfremt
disse ikke er korrekte
*>
begin
integer
_ no,
_ h_help;
newposition(packcat,1,packcat_updated,packcat_leftblock);
for no:=1 step 1 until head.packentries do
begin
nextrecord(packcat,head.entrylength,packcat_updated,packcat_leftblock);
if packcat.key <> 0 then
begin
h_help:= compute_hashkey(packcat.entryname,packcat.password);
if packcat.hashkey <> h_help then
begin
packcat.hashkey:= h_help;
packcat_updated:= true ;
if list then
begin
print_entry(out,packcat.entrybase_adr,intern_bases,undefined,ownerlist);
write(out,"sp",5,<:*** hashkey recomputed:>);
end;
end;
end;
end packentries;
newposition(packcat,0,packcat_updated,packcat_leftblock);
if -,system_packfile and head.extend_mark <> 0 then
begin
head.extend_mark:= 0;
setposition(head,0,0);
swoprec6(head,512);
end;
<*+1*>
if test shift(-2) then write(out,<:<10><10>recompute hashkeys<10>:>);
<*-1*>
end recompute_hahskeys;
\f
boolean procedure check_packfile_head(z,tail);
<********************************************>
zone z ;
integer array tail ;
<*
undersøger indholdet af packfilens hovede
og sammenligner med oplysninger i tail,
hvis der er uoverensstemmelser markeres
at en nærmere undersøgelse af packfilen
bør gennemføres, hvilket kan være aktuelt
efter programfejl, programafbrydelse
eller system breakdown
returværdi = true, hvis der fandtes fejl.
*>
begin
check_packfile_head:=
if tail(1) <> z.packfile_size
or tail(7) <> z.no_of_entries
or tail(10)<> z.no_of_gaps
or tail(1) <> z.first_areasegm + z.no_of_segm + z.no_of_gapsegm
then true else false;
<* test af om repack er påkrævet *>
if program_function <> repacksym then
begin
if z.packentries - z.no_of_entries < round(0.1 * z.packentries) then
write(out,<:<10>*** repack required, free packentries less than:>,round(0.1 * z.packentries));
if z.gapentries - z.no_of_gaps < 10 then
write(out,<:<10>*** repack required, free gapentries less than 10:>);
end;
end check_packfile_head;
\f
boolean procedure check_catalogs(head,tail);
<******************************************>
zone head ;
integer array tail ;
<*
undersøger om der er fejl i katalogerne, og
om der er inkonsistens mellem packcataloget
og hulkataloget. hvis alt findes i orden
initialiseres antallet af indgange i de to
kataloger svarende til de registrerede værdier
i packfilens tail - såfremt disse stemmer overens
med det faktiske antal indgange.
returværdi = true, hvis fejl.
*>
begin
integer array
_ entry_table(1:head.packentries,1:3),
_ gap_table(1:head.gapentries,1:3);
integer
_ not_reg,
_ entry_used,
_ gap_used,
_ entry_segm,
_ gap_segm,
_ total_size;
boolean
_ hashkey_error,
_ pack_error,
_ gap_error,
_ cross_error;
\f
boolean procedure check_packcat(tab,used,segm,key_error);
<*******************************************************>
integer array tab ;
integer used,segm ;
boolean key_error ;
<*
undersøger packcataloget for evt. at afsløre fejl
i dette.
returværdi = true, hvis fejl.
*>
begin
procedure overskrift;
<*******************>
begin
first:= false;
write(out,"nl",3,
_ <:- - - errors in packcatalog - - -:>,"nl",1,
_ <:*********************************:>,"nl",2);
end;
integer
_ h_help,
_ no;
boolean
_ first;
check_packcat:= false;
key_error := false;
first := true ;
used := 0;
segm := 0;
total_size := head.first_areasegm;
newposition(packcat,1,packcat_updated,packcat_leftblock);
for no:=1 step 1 until head.packentries do
begin
nextrecord(packcat,head.entrylength,packcat_updated,packcat_leftblock);
if packcat.key <> 0 then
begin
used:= used + 1;
if packcat.area_size > 0 then
segm:= segm + packcat.area_size;
if packcat.entryindex <> no then
begin
check_packcat:= true;
if first then overskrift;
print_entry(out,packcat.entrybase_adr,intern_bases,undefined,statlist);
write(out,"nl",1,"sp",5,<:*** entry in wrong place =:>,<<ddddd>,no,
_ <:, right place is = :>,packcat.entryindex);
end;
<* test af hashkey *>
h_help:= compute_hashkey(packcat.entry_name,packcat.password);
if packcat.hashkey <> h_help then
begin
key_error:= true;
if first then overskrift;
print_entry(out,packcat.entrybase_adr,intern_bases,undefined,statlist);
write(out,"nl",1,"sp",5,<:*** wrong hashkey =:>,<<-ddddddd>,packcat.hashkey,
_ <:, hashkey should be =:>,h_help);
end;
<* initialisering af tabel *>
tab(used,1):= packcat.store_address;
if packcat.store_address > 0 then
tab(used,2):= packcat.store_address + packcat.area_size - 1
else
tab(used,2):= 0;
tab(used,3):= no;
if total_size < tab(used,2) + 1
then total_size:= tab(used,2) + 1;
if tab(used,2) > tail(1) then
begin
if first then overskrift;
print_entry(out,packcat.entrybase_adr,intern_bases,undefined,statlist);
write(out,"nl",1,"sp",5,<:*** area outside last segment of packfile:>);
end;
end key <> 0;
end packentries;
<*+1*>
if test shift(-2) then write(out,<:<10>check packcat, used/ segm::>,used,segm);
<*-1*>
end check_packcat;
\f
boolean procedure check_gapcat(gapcat,tab,used,segm);
<***************************************************>
zone gapcat ;
integer array tab ;
integer used,segm ;
<*
undersøger hulkataloget for evt. at afsløre
fejl i dette.
returværdi = true, hvis fejl.
*>
begin
procedure print_error(z);
<***********************>
zone z ;
begin
if first then
begin
first:= false;
write(out,"nl",3,
_ <:- - - errors in gapcatalog - - -:>,"nl",1,
_ <:********************************:>,"nl",2);
end;
write(out,"nl",1,
_ <:wrong gapcatalog entry =:>,<<-ddddddd>,no,
_ <:, first segment =:>,z(1) shift(-24) extract 24,
_ <:, no of segments =:>,z(1) extract 24);
end print_error;
integer
_ no;
boolean
_ first;
check_gapcat:= false;
first := true ;
used := 0 ;
segm := 0 ;
newposition(gapcat,head.gapcat_adr,gapcat_updated,gapcat_leftblock);
for no:=1 step 1 until head.gapentries do
begin
nextrecord(gapcat,4,gapcat_updated,gapcat_leftblock);
if gapcat.first_emptysegm > 0 then
begin
if gapcat.no_of_emptysegm > 0 then
begin
used:= used + 1;
tab(used,1):= gapcat.first_emptysegm;
tab(used,2):= gapcat.first_emptysegm + gapcat.no_of_emptysegm - 1;
tab(used,3):= no;
segm:= segm + gapcat.no_of_emptysegm;
if total_size < tab(used,2) + 1
then total_size:= tab(used,2) + 1;
end
else
begin
check_gapcat:= true;
print_error(gapcat);
end;
end
else
if gapcat.first_emptysegm < 0 then
begin
check_gapcat:= true;
print_error(gapcat);
end;
end gapentries;
newposition(gapcat,0,gapcat_updated,gapcat_leftblock);
<*+1*>
if test shift(-2) then write(out,<:<10>check gapcat, used/ segm::>,used,segm);
<*-1*>
end check_gapcat;
\f
boolean procedure check_crossref;
<*******************************>
begin
integer
_ i,
_ j;
boolean
_ first;
procedure overskrift;
<*******************>
begin
first:= false;
write(out,"nl",3,
_ <:- - - owerlap errors in catalogs or between catalogs - - -:>,"nl",1,
_ <:**********************************************************:>,"nl",2);
end overskrift;
<* sortering af tabellerne *>
if entry_used > 0 then
quicksort(entry_table,entry_used,3,1);
if gap_used > 0 then
quicksort(gap_table,gap_used,3,1);
check_crossref:= false;
first := true;
<* test af overlap i packcatalog *>
for i:= 1 step 1 until entry_used - 1 do
if entry_table(i,1) > 0 then
begin
if entry_table(i,2) >= entry_table(i+1,1) then
begin
check_crossref:= true;
if first then overskrift;
write(out,"nl",1,
_ <:area no. =:>,<<ddddd>,entry_table(i,3),
_ <:, owerlaps with area no. =:>,entry_table(i+1,3));
end;
end;
<* test af overlap i hulkatalog *>
for i:=1 step 1 until gap_used - 1 do
if gap_table(i,2) >= gap_table(i+1,1) then
begin
check_crossref:= true;
if first then overskrift;
write(out,"nl",1,
_ <:gap no. =:>,<<ddddd>,gap_table(i,3),
_ <:, owerlaps with gap no. =:>,gap_table(i+1,3));
end;
<* test af konsistens mellem de to kataloger *>
if entry_used > 0 and gap_used > 0 then
for i:=1 step 1 until entry_used do
if entry_table(i,1) > 0 then
begin
for j:=1 step 1 until gap_used do
if entry_table(i,1) <= gap_table (j,1)
and gap_table (j,1) <= entry_table(i,2)
or entry_table(i,1) <= gap_table (j,2)
and gap_table (j,2) <= entry_table(i,2) then
begin
check_crossref:= true;
if first then overskrift;
write(out,"nl",1,
_ <:area no. =:>,<<ddddd>,i,
_ <:, owerlaps with gap no. =:>,j);
end;
end konsistens check;
<*+1*>
if test shift(-2) then write(out,<:<10>check crossref:>);
<*-1*>
end check_crossref;
\f
check_catalogs:= false;
pack_error:= check_packcat(entry_table,entry_used,entry_segm,hashkey_error);
if gapcat_used then
gap_error:= check_gapcat(gapcat,gap_table,gap_used,gap_segm)
else
begin <* vi låner bufferen packcat ! *>
newposition(packcat,0,packcat_updated,packcat_leftblock);
gap_error:= check_gapcat(packcat,gap_table,gap_used,gap_segm);
end;
cross_error:= check_crossref;
<* nu gennemføres den afsluttende testning *>
if -,pack_error and -,gap_error and -,cross_error
and tail(1) = total_size
and tail(7) = entry_used
and tail(10) = gap_used then
begin
head.packfile_size := total_size;
head.no_of_entries := entry_used;
head.no_of_segm := entry_segm;
head.no_of_gaps := gap_used ;
head.no_of_gapsegm := gap_segm ;
if hashkey_error then
recompute_hashkeys(true);
write(out,"nl",3,<:- - - packfile reset - should be ok !:>,"nl",1);
end
else
begin
check_catalogs:= true;
write(out,"nl",3,<:- - - errors in dimensions of packfile - - -:>,"nl",1,
_ <:********************************************:>,"nl",2);
write(out,<< -ddddddddd>,
_ <:parameter actual value registered value registered value<10>:>,
_ <: accounted in entry-tail in packfile-head<10>:>,
_ <:========================================================================<10>:>,
_ <:<10>packfile size :>,total_size,tail(1),head.packfile_size,
_ <:<10>no of entries :>,entry_used,tail(7),head.no_of_entries,
_ <:<10>no of gaps :>,gap_used,tail(10),head.no_of_gaps,
_ <:<10>:>,
_ <:<10>no of segments :>,entry_segm,"sp",2,"-",16,head.no_of_segm,
_ <:<10>no of gapsegments :>,gap_segm,"sp",2,"-",16,head.no_of_gapsegm);
end;
not_reg:= tail(1) - head.first_areasegm - entry_segm - gap_segm;
if not_reg > 0 then
write(out,<:<10><10>* no of segments not registered in gapcat =:>,not_reg);
<*+1*>
if test shift(-2) then write(out,<:<10>check catalogs, not registered =:>,not_reg);
<*-1*>
end check_catalogs;
\f
procedure lookup_auxdoc(aux_name,rel_nametable_adr);
<**************************************************>
value rel_nametable_adr ;
long array aux_name ;
integer rel_nametable_adr ;
<*
finder for en katalogindgang uden tilknyttet areal
navnet på det aux. document, hvor denne findes i
det pågældende auxiliary catalog, dvs. permkey større
end min_auxcat_permkey ( = 2)
*>
begin
long array
_ aux_doc(1:2);
integer array
_ first_bsnametable_adr(1:1),
_ chaintable_adr(1:1);
<* hent nametable address for første drum chain *>
if system(5,92,first_bsnametable_adr) = 0
then system(9,0,<:<10>corecopy:>);
<* evt. hentes nametable address for første disc chain *>
if first_bsnametable_adr(1) = 0 then
begin
if system(5,94,first_bsnametable_adr) = 0
then system(9,0,<:<10>corecopy:>);
end;
<* nu hentes adressen på den relevante chain table *>
if system(5,first_bsnametable_adr(1) + rel_nametable_adr, chaintable_adr) = 0
then system(9,0,<:<10>corecopy:>);
<* nu hentes navnet på det ønskede document i chain table , rel. adr. = -18 *>
if system(5,chaintable_adr(1) - 18,aux_doc) = 0
then system(9,0,<:<10>corecopy:>);
aux_name(1):= aux_doc(1); aux_name(2):= aux_doc(2);
end lookup_auxdoc;
\f
integer procedure lookup_entry(entry,bases,name,scope);
<*****************************************************>
integer array entry,bases ;
long array name ;
integer scope ;
<*
søger katalogindgangen specificeret ved 'name'
og 'scope' i main-catalog
returværdi:
-1: entry findes ikke med det angivne scope
0: entry findes
1: entry med tilhørende areal findes
*>
begin
zone
_ look(1,1,stderror);
integer array
_ catbase(1:2);
integer
_ return,
_ helpscope,
_ lower_index,
_ upper_index;
if scope > login and scope <> undefined then
begin
lower_index:=case scope + 1 of (3,3,5,7,7);
upper_index:=case scope + 1 of (4,4,6,8,8);
<* katalogbaser ændres med hensyn til scope *>
catbase(1):=bases(lower_index);
catbase(2):=bases(upper_index);
return:=monitor(72)set_cat_base:(myself,0,catbase);
if return <> 0 then monitor_error(72,myself,return,true);
end;
open(look,0,name,0);
return:=monitor(76)lookup_head_and_tail:(look,0,entry);
if return <> 0 and return <> 3 then
monitor_error(76,look,return,true);
close(look,true);
if return = 0 then
begin
helpscope:=entry_scope(entry,bases);
if scope = undefined and helpscope < systemscope and helpscope <> undefined
then scope:=helpscope;
lookup_entry:=
if scope = helpscope and helpscope <> undefined
then (if entry.areasize >= 0 then 1 else 0)
else -1;
<*+1*>
if test shift(-2) then
begin
print_entry(out,entry,bases,helpscope,normlist);
write(out,<:, lookup:>);
end;
<*-1*>
end
else lookup_entry:= -1;
if scope > login and scope <> undefined then
begin
<* katalogbaserne sættes tilbage til standard *>
return:=monitor(72)set_cat_base:(myself,0,bases);
if return <> 0 then monitor_error(72,myself,return,true);
end;
end lookup_entry;
\f
boolean procedure search_catalogentry(catalog,entry,bases,scope);
<***************************************************************>
zone catalog ;
integer array entry,bases ;
integer scope ;
<*
søger frem i main catalog for at finde entries, som opfylder
udvælgelseskriterier angivet ved scope eller subtext
returværdi = true sålænge der findes flere entries i main catalog
*>
begin
own integer
_ catalogentries,
_ entryno;
integer
_ no;
boolean
_ found;
long array field
_ subname;
if catalogentries = 0 then
begin
integer array
_ tail(1:10);
no:=monitor(42)lookup_entry:(catalog,0,tail);
if no <> 0 then monitor_error(42,catalog,no,true);
catalog_entries:= 512//34 * tail(1);
end;
found:= false;
repeat
inrec6(catalog,34);
entryno:=entryno + 1;
if catalog.key <> -1 then
begin
<*
det undersøges om entry er synlig for processen
og er indeholdt i processens max. baser
*>
if extend catalog.lowerbase <= lower_catbase and extend catalog.upperbase >= upper_catbase
and extend catalog.lowerbase >= bases(7) and extend catalog.upperbase <= bases(8) then
begin
<*+1*>
if test shift(-4) then
begin
print_entry(out,catalog.entrybase_adr,bases,undefined,normlist);
write(out,<:, search main catalog:>);
end;
<*-1*>
if scopeboo then
begin
scope:=entry_scope(catalog.entry_baseadr,bases);
if scope <> undefined then
found:=scopelist(scope);
end;
if -,found and no_of_subtext > 0 then
begin
subname:= subtext_adr;
for no:=1, no + 1 while no <= no_of_subtext and -,found do
begin
found:=subcompare(catalog.entryname,optionlist.subname);
subname:=subname + 12;
end;
end;
end synlig;
end catalogkey <> -1;
until found or entryno = catalog_entries;
if found and -,scopeboo then
scope:=entry_scope(catalog.entry_baseadr,bases);
if found then
tofrom(entry,catalog.entry_baseadr,34);
search_catalogentry:=found;
<*+1*>
if test shift(-2) and found then
begin
print_entry(out,entry,bases,scope,normlist);
write(out,<:, search catalogentry:>);
end;
<*-1*>
end search_catalogentry;
\f
procedure lookup_error(ud,la,scope,intern,type);
<**********************************************>
value scope,intern,type ;
zone ud ;
long array la ;
integer scope, type ;
boolean intern ;
<*
udskriver fejlmeddelelse når entry ikke findes
*>
begin
outchar(ud,'nl');
write(ud,"sp",44 - write(ud,la));
if scope <> undefined then
write(ud,"sp",24 -
write(ud,case scope + 1 of (<:temp:>,<:login:>,<:user:>,
_ <:project:>,<:system:>)))
else
write(ud,"sp",24);
if intern then
write(ud,"sp",11 - write(ud,ownerid))
else
write(ud,"sp",11);
write(ud,"sp",5,case type of (
_ <:*** entry not found:>,
_ <:*** entryname reserved:>)
);
end lookup_error;
\f
integer procedure print_date(z,short);
<************************************>
value short ;
zone z ;
integer short ;
<* udskriver dato og klokkeslet fra shortclock *>
begin
integer
_ date;
real
_ clock;
date:= systime(6,short,clock);
print_date:=
write(z,<:d.:>,<<dddddd>,date,<:.:>,<<zddd>,clock/100);
end print_date;
\f
procedure print_head_and_tail(z,entry,bases,scope);
<*************************************************>
zone z ;
integer array entry,bases ;
integer scope ;
<*
udskriver head og tail for <entry>
*>
begin
integer
_ i;
write(z,"sp",13 - write(z,"nl",1,entry.entryname),<:=set:>);
if entry.areasize >= 0 then
write(z,entry.areasize)
else
write(z,entry.areasize shift(-12),<:.:>,<<d>,entry.areasize extract 12);
write(z,"sp",1,entry.documentname);
i:= 6;
if entry.entrytail(i-5) <> 0
and entry.entrytail(4) shift(-12) <> 4
and entry.entrytail(4) shift(-12) < 32 then
begin
outchar(z,'sp');
print_date(z,entry.entrytail(i-5));
i:= i + 1;
end;
for i:= i step 1 until 10 do
if entry.entrytail(i-5) = 0 then
write(z,<: 0:>)
else
write(z,entry.entrytail(i-5) shift (-12),
_ <:.:>,<<d>,entry.entrytail(i-5) extract 12);
write(z,<: ; :>,case (if scope = undefined then entry_scope(entry,bases) else scope) + 1
_ of (<:temp:>,<:login:>,<:user:>,<:project:>,<:system:>,<:***:>));
if entry.auxdocname(1) <> empty then write(z,<:.:>,entry.auxdocname);
if entry.password(1) <> empty then write(z,<:.:>,entry.password);
write(z,"nl",1,"sp",12,<:; :>,entry.key shift(-12),
_ entry.key extract 12 shift(-3),entry.key extract 3,
_ entry.lowerbase,entry.upperbase);
end print_head_and_tail;
\f
integer procedure print_modekind(z,modekind);
<*******************************************>
value modekind ;
zone z ;
integer modekind ;
begin
integer
_ mode,
_ kind,
_ codeix,
_ modeix;
kind:= modekind extract 12;
mode:= modekind shift (-12) extract 11;
modeix:= mode//2 + 1;
codeix:= if kind <= 20 and mode <= 10 then
(case kind//2 + 1 of (
<* kind/mode *>
<* 0 *> case modeix of ( 1, 0, 0, 0, 0, 0),
<* 2 *> case modeix of ( 0, 0, 0, 0, 0, 0),
<* 4 *> case modeix of ( 2, 0, 0, 0, 0, 0),
<* 6 *> case modeix of ( 0, 0, 0, 0, 0, 0),
<* 8 *> case modeix of ( 3, 0, 0, 0, 0, 0),
<* 10 *> case modeix of ( 4, 5, 6, 7, 0, 0),
<* 12 *> case modeix of ( 8, 9,10,11,12, 0),
<* 14 *> case modeix of (13, 0, 0, 0, 0, 0),
<* 16 *> case modeix of (14, 0, 0, 0,15,16),
<* 18 *> case modeix of (17,18,19,20, 0, 0),
<* 20 *> case modeix of (21, 0, 0, 0, 0, 0),
0)) else 0;
print_modekind:=
if codeix > 0 then
write(z,case codeix of (
_ <:ip:>,<:bs:>,<:tw:>,<:tro:>,<:tre:>,
_ <:trn:>,<:trf:>,<:tpo:>,<:tpe:>,<:tpn:>,
_ <:tpf:>,<:tpf:>,<:lp:>,<:crb:>,<:crd:>,
_ <:crc:>,<:mto:>,<:mte:>,<:nrz:>,<:nrze:>,
_ <:pl:>))
else
write(z,<<dddd>,mode,<:.:>,<<d>,kind);
end print_modekind;
\f
procedure print_entry(z,entry,bases,scope,type);
<**********************************************>
value scope,type ;
zone z ;
integer array entry,bases ;
integer scope,type ;
<*
udskriver oplysninger for en katalogingang på
zonen <z> afhængig af værdien af <type>.
type:
1: kun katalogindgangens første del udskrives
2: endvidere udskrives owner
3: owner, samt statistik delen udskrives
*>
begin
integer
_ k;
real
_ clock;
real array field
_ raf;
raf:= 0;
if scope = undefined then
scope:= entry_scope(entry,bases);
outtext(z,-12,entry.entryname.raf,1);
if entry.areasize >= 0 then
write(z,<< dddddddd>,entry.areasize)
else
write(z,"sp",9 - print_modekind(z,entry.areasize));
k:=
write(z,"sp",3,entry.documentname);
write(z,"sp",23 - (if entry.areasize < 0 then
write(z,<:.:>,true,22 - k,entry.auxdocname) + k else k));
write(z,"sp",9 - write(z,case scope + 1 of
_ (<:temp:>,<:login:>,<:user:>,
_ <:project:>,<:system:>,<:***:>)));
if entry.entrytail(1) <> 0
and entry.entrytail(4) shift (-12) <> 4
and entry.entrytail(4) shift (-12) < 32
then
write(z,<:d.:>,<<dddddd.dddd>,
_ systime(6,entry.entrytail(1),clock)
_ + clock/1000000,"sp",2)
else
write(z,"sp",15);
if type = 2 or type = 3 then
outtext(z,11,entry.password.raf,1)
else
write(z,"sp",11);
if type = 3 then
write(z,"sp",1,<< dddddd>,
_ entry.packdate,
_ entry.last_accessdate,
_ entry.no_of_read,
_ entry.no_of_point,
_ entry.storeaddress);
end print_entry;\f
procedure print_heading(z,type);
<******************************>
zone z ;
integer type ;
begin
write(z,"nl",1,case type of (
<:NAME KIND/SIZE DOCUMENT SCOPE DATE:>,
<:NAME KIND/SIZE DOCUMENT SCOPE DATE OWNER:>,
<:NAME KIND/SIZE DOCUMENT SCOPE DATE OWNER PACKDATE ACCESS READS POINT SEGMNO:>,
<::>),"nl",1);
end heading;
\f
<*+2*>
procedure print_packhead(z);
<**************************>
zone z ;
<* udskriver packfilens filhovede *>
begin
integer array field
_ iaf;
iaf := 0;
setposition(z,0,0);
inrec6(z,512);
write(out,"ff",1,"nl",1,<:contents of packfilehead:>,"nl",2);
write(out,<<ddddddddd>,
_ <:<10>packentry length ::>,z.iaf(1),
_ <:<10>max packentries ::>,z.iaf(2),
_ <:<10>---------------------::>,z.iaf(3),
_ <:<10>max gapentries ::>,z.iaf(4),
_ <:<10>---------------------::>,z.iaf(5),
_ <:<10>gapcatalog adr ::>,z.iaf(6),
_ <:<10>first areasegm ::>,z.iaf(7),
_ <:<10>no of entries ::>,z.iaf(8),
_ <:<10>no of segm ::>,z.iaf(9),
_ <:<10>no of gaps ::>,z.iaf(10),
_ <:<10>no of gapsegm ::>,z.iaf(11),
_ <:<10>retention days ::>,z.iaf(12),
_ <:<10>last update ::>,z.iaf(13),
_ <:<10>packfile size ::>,z.iaf(14),
_ <:<10>creation date ::>,z.iaf(15),
_ <:<10>update mark ::>,z.iaf(16),
_ <:<10>hashtable size ::>,z.iaf(17),
_ <:<10>last function ::>,z.iaf(18),
_ <:<10>extend mark ::>,z.iaf(19),
<::> );
end print_packhead;
\f
procedure print_packcat(cat);
<***************************>
zone cat ;
<*
udskriver hele packfilens katalog
*>
begin
integer
_ no;
write(out,"ff",1,"nl",1,<:contents of packcatalog:>,"nl",2);
print_heading(out,3);
setposition(cat,0,1);
for no:=1 step 1 until head.packentries do
begin
inrec6(cat,head.entrylength);
if cat.key <> 0 then
print_entry(out,cat.entry_baseadr,intern_bases,undefined,statlist)
else write(out,"nl",1,<:------------:>,"sp",103);
write(out,<<ddddd>,no);
end;
end print_packcat;
\f
procedure print_gapcat(gap);
<**************************>
zone gap ;
<*
udskriver indholdet af hulkataloget
*>
begin
integer
_ no;
write(out,"ff",1,"nl",1,<:contents of gapcatalog:>,"nl",2);
write(out,<:<10>firstsegm segm entryno<10>:>);
setposition(gap,0,head.gapcat_adr);
for no:=1 step 1 until head.gapentries do
begin
inrec6(gap,4);
if gap.first_emptysegm <> 0 then
write(out,"nl",1,<<dddddddd>,gap.first_emptysegm,gap.no_of_emptysegm,no)
else
write(out,"nl",1,<<dddddddd>,"-",16,no);
end;
end print_gapcat;
<*-2*>
\f
<*+2*>
procedure print_tables;
<*********************>
<* udskriver indholdet af hashtable og linktable *>
begin
integer
_ ix,
_ collisions,
_ chain_count,
_ max_chain,
_ ix1;
write(out,<:<12><10><10>contents of hashtables<10>:>);
collisions:= 0;
max_chain := 0;
for ix:=1 step 1 until head.hashtable_size do
begin
write(out,"nl",1,<<ddddddddd>,ix,hashtable(ix) extract 12);
if ix <= head.packentries then
begin
write(out,<<ddddddddd>,linktable(ix) extract 12);
if linktable(ix) extract 12 <> nil
and linktable(ix) extract 12 <> free
then collisions:= collisions + 1;
end;
if hashtable(ix) extract 12 <> nil then
begin
chain_count:= 0;
ix1:= hashtable(ix) extract 12;
while ix1 <> nil do
begin
chain_count:= chain_count + 1;
ix1:= linktable(ix1) extract 12;
end;
if chain_count > max_chain
then max_chain:= chain_count;
end;
end hashtable;
write(out,"nl",2,
_ <:<10>no of collisions =:>,collisions,
_ <:<10>longest chain sequence =:>,max_chain);
end print_tables;
<*-2*>
\f
procedure testblok(z,s,b);
<************************>
zone z ;
integer s,b ;
<*
anvendes til test af transporter
*>
begin
<*+2*>
integer array
_ zdescr(1:20),
_ sh_descr(1:12);
real array field
_ zname;
zname:= 2;
if s shift(-1) extract 1 = 1 then
begin <* normal answer *>
getzone6(z,zdescr);
getshare6(z,sh_descr,zdescr(17));
if sh_descr(7) <= blocktable_size then
begin
transfer_table(sh_descr(7),zdescr(13) - 4) :=
transfer_table(sh_descr(7),zdescr(13) - 4) + 1;
end;
bloktransfer:= bloktransfer + 1;
end
else
<*-2*>
stderror(z,s,b);
end testblok;
\f
integer procedure entry_scope(entry,bases);
<*****************************************>
integer array entry,bases ;
<*
finder scope på katalogindgang beskrevet i tail
på grundlag af processens baser
returværdi:
0 : temp
1 : login
2 : user
3 : project
4 : system
5 : undefined
*>
begin
long
_ lower_base,
_ upper_base;
lower_base:=entry(2);
upper_base:=entry(3);
case entry(1) extract 3 + 1 of
begin
<* permkey = 0, maybee temp *>
entry_scope:=
if lower_base = extend bases(3)
and upper_base = extend bases(4)
then 0
else 5;
<* permkey = 1, undefined *>
entry_scope:=5;
<* permkey = 2, maybee login *>
entry_scope:=
if lower_base = extend bases(3)
and upper_base = extend bases(4)
then 1
else 5;
<* permkey = 3, maybee user, project or system *>
entry_scope:=
if lower_base = extend bases(5)
and upper_base = extend bases(6)
then 2
else
if lower_base = extend bases(7)
and upper_base = extend bases(8)
then 3
else
if lower_base <= extend bases(7)
and upper_base >= extend bases(8)
then 4
else 5;
end case;
end entry_scope;
\f
boolean procedure open_special(z,doc,bases,scope,pos);
<****************************************************>
value scope,pos ;
zone z ;
long array doc ;
integer array bases ;
integer scope,pos ;
<*
åbner z til baggrundslager område med givet scope
*>
begin
integer array
_ dummy(1:12),
_ catbase(1:2);
integer
_ return,
_ lower_index,
_ upper_index;
if scope > login then
begin
lower_index:=case scope + 1 of (3,3,5,7,7);
upper_index:=case scope + 1 of (4,4,6,8,8);
<* katalogbaser ændres med hensyn til scope *>
catbase(1):=bases(lower_index);
catbase(2):=bases(upper_index);
return:=monitor(72)set_cat_base:(myself,0,catbase);
if return <> 0 then monitor_error(72,myself,return,true);
end;
<*
zonen åbnes til området, zonestate = after open
arealprocess oprettes og området reserveres,
og nametable address initialiseres
*>
open(z,4,doc,0);
open_special:= true;
return:= monitor(52)create_area_process:(z,0,catbase);
if return <> 0 then
begin
open_special:= false;
if return <> 3 then
monitor_error(52,z,return,true);
end
else
begin
return:= monitor(8)reserve_process:(z,0,catbase);
if return <> 0 then
begin
open_special:= false;
if return <> 1 then
monitor_error(8,z,return,true);
end
else
begin
monitor(16)send_message:(z,1,dummy);
monitor(18)wait_answer_:(z,1,dummy);
setposition(z,0,pos);
end;
end;
<*+1*>
if test shift(-2) then
write(out,<:<10>openspecial, :>,doc,<:, scope :>,scope,
_ "sp",3,if return = 0 then <:ok:> else <:not ok:>);
<*-1*>
<* katalogbaserne sættes tilbage til standard *>
if scope > login then
begin
return:=monitor(72)set_cat_base:(myself,0,bases);
if return <> 0 then monitor_error(72,myself,return,true);
end;
end open_special;
\f
boolean procedure change_scope(z,kit,bases,newscope);
<***************************************************>
value newscope ;
zone z ;
integer array kit,bases ;
integer newscope ;
<*
ændrer scope på katalogindgang eller baggrundslagerområde
knyttet til zonen 'z' til 'newscope'
*>
begin
integer array
_ entry_base(1:2);
integer
_ return,
_ lower_index,
_ upper_index,
_ catalog_key;
boolean
_ success;
success:=true;
catalog_key:=case newscope + 1 of (0,2,3,3);
lower_index:=case newscope + 1 of (3,3,5,7);
upper_index:=case newscope + 1 of (4,4,6,8);
entry_base(1):=bases(lower_index);
entry_base(2):=bases(upper_index);
return:=monitor(90)permanent_entry_in_aux_cat:(z,catalog_key,kit);
if return <> 0 then
begin
success:=false;
if return <> 2 and return <> 5 and return <> 6 then
monitor_error(50,z,return,true);
end
else
begin
return:=monitor(74)set_entry_base:(z,0,entry_base);
if return <> 0 then
begin
success:=false;
if return <> 3 then
monitor_error(74,z,return,true);
end;
end;
change_scope:=success;
end change_scope;
\f
integer procedure create_entry(entry,newkit,bases,scope);
<*******************************************************>
value scope ;
integer array entry, bases ;
long array newkit ;
integer scope ;
<*
opretter en katalogindgang svarende til entry_tail,
samt et tilhørende baggrundslagerområde
med det specificerede 'scope'
create_entry, result =
-2 : name conflict
-1 : no resources
0 : creation ok
1 : temp, no login resources
*>
begin
zone
_ z(if entry(8) >= 0 then 128 else 1,1,stderror);
integer array
_ ia(1:20),
_ name,
_ kit(1:4),
_ tail(1:10),
_ catbase(1:2);
integer
_ result,
_ return,
_ lower_index,
_ upper_index,
_ catalog_key;
boolean
_ success;
integer array field
_ doc_name,
_ entry_name,
_ tail_base;
integer field
_ size;
entry_name:=6;
tail_base :=14;
size :=16;
doc_name :=16;
success := true;
result := 0;
<* bestemmelse af det relevante documentnavn *>
if newkit(1) <> empty then
begin
if entry.size >= 0 then
tofrom(entry.doc_name,newkit,8);
tofrom(kit,newkit,8);
end
else
begin
if entry.size >= 0 then
tofrom(kit,entry.doc_name,8)
else
tofrom(kit,entry.auxdocname,8);
end;
tofrom(tail,entry.tailbase,20);
tofrom(name,entry.entryname,8);
if scope > login then
begin
<* oprettelse af entry med baser forskellige fra std. baser *>
open(z,if entry.size >= 0 then 4 else 0,<::>,0);
return:=monitor(40)create_entry:(z,0,tail);
if return <> 0 then
begin
success:=false;
result := -1;
if return <> 2 and return <> 4 then
monitor_error(40,z,return,true);
end
else
begin
if change_scope(z,kit,bases,scope) then
begin
return:=monitor(46)rename_entry:(z,0,name);
if return = 3 then
begin
success:=false;
result := -2;
end
else
if return <> 0 then monitor_error(46,z,return,true);
end
else
begin
success:=false;
result := -1;
end;
if -,success then
begin
return:=monitor(48)remove_entry:(z,0,tail);
if return <> 0 then monitor_error(48,z,return,true);
end;
end;
end
else
begin
<* opretttelse af entry med std. baser *>
open(z,if entry.size >= 0 then 4 else 0,entry.entryname,0);
return:=monitor(40)create_entry:(z,0,tail);
<* en evt. eksisterende entry fjernes, hvis areal skal oprettes *>
if return = 3 and entry.size >= 0 then
begin
return:=monitor(76)lookup_head_and_tail:(z,0,ia);
if return <> 0 then monitor_error(76,z,return,true);
return:=monitor(48)remove_entry:(z,0,ia);
if return <> 0 and return <> 5 then
monitor_error(48,z,return,true);
return:=monitor(40)create_entry:(z,0,tail);
end;
if return <> 0 then
begin
success:=false;
result := if return = 3 then (-2) else (-1);
if return <> 2 and return <> 3 and return <> 4 then
monitor_error(40,z,return,true);
end;
if scope = login and success then
begin
catalog_key:= 2;
return:=monitor(90)permanent_entry_in_aux_cat:(z,catalog_key,kit);
if return <> 0 then
begin
result:= 1;
if return <> 2 and return <> 5 and return <> 6 then
monitor_error(50,z,return,true);
end;
end;
end;
close(z,true);
create_entry:= result;
<*+1*>
if test shift(-2) then write(out,<:<10>create_entry, result = :>,<<-dd>,result);
<*-1*>
end create_entry;
\f
procedure newposition(z,segmno,updated,length);
<*********************************************>
value segmno ;
zone z ;
integer segmno, length ;
boolean updated ;
<*
tilbageskriver et opdateret segment
efter brug af inrec6 (= swoprec6)
*>
begin
integer
_ akt_segmno;
getposition(z,0,akt_segmno);
if segmno = -1 <* næste blok *> then
segmno:= akt_segmno + 1;
<*+1*>
if test shift(-2) then
write(out,<:<10>newposition, segmno =:>,segmno,<:, akt. segmno =:>,akt_segmno,
_ if updated then <:, updated:> else <:, not updated:>);
<*-1*>
if akt_segmno > 0 then
begin
if segmno <> akt_segmno then
begin
if updated then
begin <* blokken tilbageskrives *>
updated:= false;
setposition(z,0,akt_segmno);
outrec6(z,512);
setposition(z,0,segmno);
<* packfilens tail opdateres *>
if akt_segmno < head.gapcat_adr then
set_packtail(head,packtail,1)
else
set_packtail(head,packtail,2);
end
else
setposition(z,0,segmno);
end
else
begin <* recordbase sættes tilbage til bufferbase *>
integer array
_ zdescr(1:20);
getzone6(z,zdescr);
zdescr(14):= zdescr(15) - 4*zdescr(20)//zdescr(18);
zdescr(16):= 0;
setzone6(z,zdescr);
end;
end
else
setposition(z,0,segmno);
length:= 512;
end newposition;
\f
integer procedure nextrecord(z,length,updated,lbytes);
<****************************************************>
value length ;
zone z ;
integer length, lbytes ;
boolean updated ;
<* læser næste record og skifter blok om nødvendigt *>
begin
if length > lbytes then
newposition(z,-1 <* næste blok *>,updated,lbytes);
nextrecord:= inrec6(z,length);
lbytes:= lbytes - length;
<*+1*>
<*
if test shift(-2) then
write(out,<:<10>nextrecord, length =:>,<<ddddd>,length,
_ <:, leftbytes =:>,lbytes);
*>
<*-1*>
end nextrecord;
\f
procedure find_record(z,startsegm,recordno,length,updated,leftblock);
<*******************************************************************>
value startsegm,recordno,length ;
zone z ;
integer startsegm,recordno,length, leftblock ;
boolean updated ;
begin
integer array
_ zdescr(1:20);
integer
_ entries_pr_segm,
_ act_pos,
_ pos,
_ left;
entries_pr_segm:= 512//length;
pos := (recordno - 1) // entries_pr_segm + startsegm;
left := (recordno - 1) mod entries_pr_segm;
getposition(z,0,act_pos);
if pos <> act_pos then
begin
newposition(z,pos,updated,leftblock);
inrec6(z,0);
end;
getzone6(z,zdescr);
zdescr(14):= zdescr(15) - 4*zdescr(20)//zdescr(18) + left*length;
zdescr(16):= length;
setzone6(z,zdescr);
leftblock:= 512 - (left + 1) * length;
<*+1*>
if test shift(-2) then
write(out,<:<10>find record, entryno =:>,<<dddddd>,recordno,<:, pos =:>,pos,
_ <:, left =:>,left,<:, leftblock =:>,leftblock);
<*-1*>
end find_record;
\f
procedure swop_cat(packcat,packcat_updated,gapcat,gapcat_updated);
<****************************************************************>
zone packcat, gapcat ;
boolean packcat_updated, gapcat_updated ;
<*
tilbageskriver katalogsegmenter for at opnå veldefinerede
recovery punter i packfilen under opdatering, så genstart er mulig
*>
begin
integer array
_ zdescr(1:20);
integer
_ pos;
if packcat_updated then
begin
getposition(packcat,0,pos);
getzone6(packcat,zdescr);
setposition(packcat,0,pos);
outrec6(packcat,512);
packcat_updated:= false;
outrec6(packcat,0);
setzone6(packcat,zdescr);
set_packtail(head,packtail,1);
<*+1*> if test shift(-2) then
<*-1*> write(out,<:<10>swop packcat segm =:>,pos);
end;
if gapcat_updated then
begin
getposition(gapcat,0,pos);
getzone6(gapcat,zdescr);
setposition(gapcat,0,pos);
outrec6(gapcat,512);
gapcat_updated:= false;
outrec6(gapcat,0);
setzone6(gapcat,zdescr);
set_packtail(head,packtail,2);
<*+1*> if test shift(-2) then
<*-1*> write(out,<:<10>swop gapcat segm =:>,pos);
end;
end swop_cat;
\f
procedure set_packtail(z,tail,type);
<**********************************>
zone z ;
integer array tail ;
integer type ;
<*
gemmer forskellige oplysninger
i packfilens entry tail
type = 0: kun opdatering af packfile size
type = 1: opdatering af packcat
type = 2: opdatering af gapcat
type = 3: samtidig opdatering af begge kataloger
*>
begin
integer
_ return;
tail(1):=z.packfile_size;
tail(6):=systime(7,0,0.0);
if type = 1 or type = 3 then
begin
tail(7):=z.no_of_entries;
tail(8):=0;
end;
if type = 2 or type = 3 then
tail(10):=z.no_of_gaps;
return := monitor(44)change_entry:(z,0,tail);
if return <> 0 then
monitor_error(44,z,return,true);
end set_packtail;
\f
procedure check_transfer(z,updated);
<*********************************>
zone z ;
boolean updated ;
begin
integer array
_ zdescr(1:20),
_ shdescr(1:12);
getzone6(z,zdescr);
getshare6(z,shdescr,zdescr(17));
if zdescr(13) = 6 <* after outrec6 *> then
begin
if shdescr(1) <> 0 <* free share *>
and shdescr(1) <> 1 <* ready share *>
then
begin <* repeat output *>
zdescr(9):= zdescr(9) - 1;
setzone6(z,zdescr);
updated:= true;
write(out,<:<10>*** warning transfer repeated, segno =:>,zdescr(9));
end
else
if zdescr(16) > 0 then
begin
zdescr(9):= zdescr(9) - 1;
setzone6(z,zdescr);
end;
end;
<*+1*>
if test shift(-2) then
write(out,<:<10>check transfer, after repair:>,
_ <:<10>segm count =:>,zdescr(9),
_ <:<10>zonestate =:>,zdescr(13),
_ <:<10>sharestate =:>,shdescr(1),
_ <:<10>recordlength =:>,zdescr(16));
<*-1*>
end check_transfer;
\f
boolean procedure
_ movearea(toarea,topos,toscope,fromarea,frompos,fromscope,bufsegm,segm);
<*******************************************************************************>
value topos,toscope, frompos,fromscope,bufsegm,segm ;
long array toarea, fromarea ;
integer topos,toscope, frompos,fromscope,bufsegm,segm ;
begin
procedure flip;
begin
getzone6(buf,fromdescr);
setzone6(buf, todescr);
end;
procedure flop;
begin
getzone6(buf, todescr);
setzone6(buf,fromdescr);
end;
zone
_ buf(128 * (if bufsegm > segm then segm else bufsegm),1,stderror);
integer array
_ todescr,
_ fromdescr(1:20);
integer
_ bufsize,
_ segmcount;
boolean
_ ok1,
_ ok2;
ok1:= ok2:= true;
<*+1*>
if test shift(-2) then
write(out,<:<10>movearea, :>,toarea,<<dddd>,topos,"sp",3,fromarea,frompos,
_ <:, bufsegm =:>,bufsegm,<:, segm =:>,segm);
<*-1*>
if toscope = undefined then
begin
open(buf,4,toarea,0);
setposition(buf,0,topos);
end
else
ok1:= open_special(buf,toarea,process_bases,toscope,topos);
getzone6(buf,todescr);
close(buf,false);
if fromscope = undefined then
begin
open(buf,4,fromarea,0);
setposition(buf,0,frompos);
end
else
ok2:= open_special(buf,fromarea,process_bases,fromscope,frompos);
getzone6(buf,fromdescr);
if ok1 and ok2 then
begin
if bufsegm > segm then bufsegm:=segm;
bufsize:=bufsegm * 512;
segmcount:=0;
repeat
segmcount:=segmcount + bufsegm;
if segmcount > segm then
bufsize:=(segm - segmcount + bufsegm) * 512;
inrec6 (buf,bufsize); flip;
outrec6(buf,bufsize);
outrec6(buf, 0); flop;
<*+1*>
if test shift(-3) then
begin
datatransfer:= datatransfer + 2;
segmtransfer:= segmtransfer + 2 * bufsize // 512;
end;
<*-1*>
until segmcount >= segm;
end ok;
close(buf,true); flip;
close(buf,true); flop;
movearea:= ok1 and ok2;
end movearea;
\f
integer procedure compute_hashkey(name,owner);
<********************************************>
long array name,owner ;
<*
beregner hashkey på grundlag af name og owner,
dvs. opslagsnøglen til hashtabellen
*>
begin
long
_ keylong;
integer
_ keyint;
keylong:= name(1) + name(2) + owner(1) + owner(2);
keyint := keylong shift(-24) extract 24 +
_ keylong extract 24 ;
keyint := keyint shift(-12) + keyint extract 12;
compute_hashkey:= keyint mod head.hashtable_size + 1;
<*+1*>
if test shift(-2) then
write(out,<:<10>hashkey =:>,keyint mod head.hashtable_size + 1);
<*-1*>
end compute_hashkey;
\f
procedure initialize_hashtables(cat);
<***********************************>
zone cat ;
<*
proceduren initialiserer hashtable og
linktable ved et gennemløb af packfilens
entry katalog
*>
begin
integer
_ linkix,
_ ix;
<* defaultværdierne initialiseres *>
nil := 0;
free:= 4095;
<* tabellerne start-initialiseres *>
for ix:=1 step 1 until head.hashtable_size
do hashtable(ix):= false add nil;
for ix:=1 step 1 until head.packentries
do linktable(ix):= false add free;
setposition(cat,0,1);
for ix:=1 step 1 until head.packentries do
begin
inrec6(cat,head.entrylength);
if cat.key <> 0 then
begin
if hashtable(cat.hashkey) extract 12 = nil then
begin
hashtable(cat.hashkey):= false add ix;
linktable(ix) := false add nil;
end
else
begin
linkix:= hashtable(cat.hashkey) extract 12;
while linktable(linkix) extract 12 <> nil
do linkix:= linktable(linkix) extract 12;
linktable(linkix):= false add ix;
linktable(ix) := false add nil;
end;
<*+1*>
if test shift(-2) then
write(out,<:<10>initialize hashtables, hashkey =:>,<<ddddd>,cat.hashkey,
_ <:, index =:>,ix,<:, entryindex =:>,cat.entryindex);
<*-1*>
end key <> 0;
end genneløb af katalog;
setposition(cat,0,0);
end initialize hashtables;
\f
integer procedure insert_tableentry(cat,name,owner,hkey);
<******************************************************>
value hkey ;
zone cat ;
long array name,owner ;
integer hkey ;
<*
indsætter hashnøglen svarende til name og owner
i <entry>, finder en ledig plads til <entry>
og indsætter oplysningerne i hashtable og linktable
*>
begin
integer
_ ix,
_ lastix;
if hkey = 0 then
hkey:= compute_hashkey(name,owner);
if hashtable(hkey) extract 12 = nil then
begin
ix:= if hkey <= head.packentries then hkey else 1;
while linktable(ix) extract 12 <> free
do ix:= if ix < head.packentries then ix + 1 else 1;
hashtable(hkey):= false add ix;
linktable(ix) := false add nil;
end
else
begin
ix:= hashtable(hkey) extract 12;
while linktable(ix) extract 12 <> nil do
ix:= linktable(ix) extract 12;
lastix:= ix;
ix := if ix < head.packentries then ix + 1 else 1;
while linktable(ix) extract 12 <> free
do ix:= if ix < head.packentries then ix + 1 else 1;
linktable(lastix):= false add ix;
linktable(ix) := false add nil;
end;
find_record(cat,1,ix,head.entrylength,packcat_updated,packcat_leftblock);
cat.hashkey:= hkey;
cat.entryindex:= ix;
insert_tableentry:= ix;
<*+1*>
if test shift(-2) then
write(out,<:<10>insert tableentry, :>,name,<:, :>,owner,
_ <:, result =:>,ix);
<*-1*>
end insert_tableentry;
\f
procedure delete_tableentry(hashkey,entryno);
<*******************************************>
value hashkey,entryno ;
integer hashkey,entryno ;
<*
sletter entryno i linktable, hvis denne er den
eneste med indgang = hashkey, slettes indgangen
i hashtable
*>
begin
integer
_ ix;
if hashtable(hashkey) extract 12 = entryno then
begin
if linktable(entryno) extract 12 = nil
then hashtable(hashkey):= false add nil
else hashtable(hashkey):= linktable(entryno);
linktable(entryno):= false add free;
end
else
begin
ix:= hashtable(hashkey) extract 12;
while linktable(ix) extract 12 <> entryno
do ix:= linktable(ix) extract 12;
if linktable(entryno) extract 12 <> nil
then linktable(ix):= linktable(entryno)
else linktable(ix):= false add nil;
linktable(entryno):= false add free;
end;
<*+1*>
if test shift(-2) then
write(out,<:<10>delete tableentry, hashkey/entryno, :>,hashkey,entryno);
<*-1*>
end delete_tableentry;
\f
boolean procedure search_tableentry(cat,name,owner,bases,scope);
<**************************************************************>
value scope ;
zone cat ;
long array name,owner ;
integer array bases ;
integer scope ;
<* søger ud fra hashkey, en entry med det specificerede scope *>
begin
integer
_ ix,
_ hashkey;
boolean
_ search;
hashkey:= compute_hashkey(name,owner);
ix:= hashtable(hashkey) extract 12;
search:= true;
while search and ix <> nil do
begin
find_record(cat,1,ix,head.entrylength,packcat_updated,packcat_leftblock);
if name(1) = cat.entryname(1)
and name(2) = cat.entryname(2)
and owner(1) = cat.password(1)
and owner(2) = cat.password(2)
then search:= (entry_scope(cat.entrybase_adr,bases) <> scope);
if search then ix:= linktable(ix) extract 12;
end while search;
hashkey_computed := hashkey;
search_tableentry:= if ix <> nil then true else false;
<*+1*>
if test shift(-2) then
write(out,<:<10>search tableentry: :>,name,<:, :>,owner,
_ <:, scope =:>,scope,<:, result =:>,ix);
<*-1*>
end search_tableentry;
\f
boolean procedure lookup_tableentry(cat,name,owner,bases,scope);
<**************************************************************>
zone cat ;
long array name,owner ;
integer array bases ;
integer scope ;
<*
søger alle entries med <name> og <owner>, og returnerer scope
og entryno for den entry, der har det laveste scope
*>
begin
integer array
_ scopefound(temp:systemscope);
integer
_ entries_found,
_ ix,
_ lastix,
_ hashkey,
_ helpscope;
boolean
_ search;
for ix:=temp step 1 until systemscope
do scopefound(ix):= 0;
hashkey:= compute_hashkey(name,owner);
ix:= hashtable(hashkey) extract 12;
entries_found:=0;
search:= true;
while search and ix <> nil do
begin
find_record(cat,1,ix,head.entrylength,packcat_updated,packcat_leftblock);
if name(1) = cat.entryname(1)
and name(2) = cat.entryname(2)
and owner(1) = cat.password(1)
and owner(2) = cat.password(2)
then
begin
helpscope:= entry_scope(cat.entrybase_adr,bases);
if helpscope <> undefined then
begin
entries_found:= entries_found + 1;
scopefound(helpscope):= ix;
if helpscope = temp
or entries_found = 5
then search:= false;
end;
end;
lastix:= ix;
ix := linktable(ix) extract 12;
end while search;
if entries_found > 0 then
begin
for helpscope:=temp, helpscope
while helpscope <> undefined do
if scopefound(helpscope) > 0 then
begin
ix := scopefound(helpscope);
scope := helpscope ;
helpscope:= undefined ;
end
else helpscope:= helpscope + 1;
if ix <> lastix then
find_record(cat,1,ix,head.entrylength,packcat_updated,packcat_leftblock);
end
else ix:= nil;
lookup_tableentry:= if ix <> nil then true else false;
<*+1*>
if test shift(-2) then
write(out,<:<10>lookup tableentry: :>,name,<:, :>,owner,
_ <:, scope =:>,scope,<:, result =:>,ix);
<*-1*>
end lookup_tableentry;
\f
boolean procedure subcompare(text1,text2);
<****************************************>
long array text1,text2 ;
<*
tester om <text1> indledes med subtext <text2>
returværdien er da 'true' ellers 'false'
*>
begin
long
_ t1,
_ t2;
integer
_ index,
_ pos;
boolean
_ equal;
index:=1; equal:=true;
while equal and text2(index) extract 8 <> 'nul' do
begin
equal:=text1(index) = text2(index);
index:=index + 1;
end;
if equal then
begin
t1:=text1(index); t2:=text2(index);
pos:=-48;
for pos:=pos + 8
while equal
and t2 shift pos extract 8 <> 'nul'
do equal:=t1 shift pos extract 8 = t2 shift pos extract 8;
end;
subcompare:=equal;
end subcompare;
\f
integer procedure get_nextentryspec(name,nameadr);
<************************************************>
long array name ;
long array field nameadr ;
<*
henter næste bestilling af entries fra fillisten,
som er givet på formen
<name> eller
<name>.scope.<scopespec>
returværdier:
<name> og
<get_nextentryspec> = scope
*>
begin
long
_ scopeel;
integer
_ ix;
if optionlist.filelist_adr.nameadr(3) = '.' then
begin
scopeel:=optionlist.filelist_adr.nameadr(7);
get_nextentryspec:=
if scopeel = long <:temp:> then temp else
if scopeel = long <:login:> then login else
if scopeel = long <:user:> then user else
_ project ;
end
else
get_nextentryspec:= undefined;
for ix:= 1, 2 do
name(ix):= optionlist.filelist_adr.nameadr(ix);
nameadr:= nameadr + (if optionlist.filelist_adr.nameadr(3) = '.' then 36 else 12);
end get_nextentryspec;
\f
boolean procedure scan_packentry(packcat,bases,namelist,sublist,id,scope,found_namelist);
<***************************************************************************************>
zone packcat ;
integer array bases ;
long array namelist,sublist,id ;
integer scope ;
boolean array found_namelist ;
<*
søger en katalogindgang i packfilen som opfylder et af udvælgelseskriterierne
<navn>
<navn>.scope.<scopespec>
subtext.<præfix>
scope.<scopeklasse>
<scan_packentry> er true sålænge der findes flere mulige katalogindgange
anvendes kun til searchpack funktionen !!
*>
begin
own integer
_ entryno,
_ entryused;
long
_ scopeel;
integer
_ no,
_ helpscope;
boolean
_ entryfound;
long array field
_ name,
_ subname;
if entryno = 0 then
newposition(packcat,1,packcat_updated,packcat_leftblock);
entryfound:= false;
while entryno < head.packentries and -,entryfound do
begin
inrec6(packcat,head.entrylength);
entryno:= entryno + 1;
if packcat.key <> 0 then
begin
entryused:= entryused + 1;
<*
katalogindgangen skal være synlig for processen,
eller alle entries medtages uanset baserne,
og ownerid skal stemme overens, hvis ikke alle
katalogindgange medtages
*>
if (extend packcat.lowerbase <= bases(3)
and extend packcat.upperbase >= bases(4)
and (extend packcat.lowerbase >= bases(7)
and extend packcat.upperbase <= bases(8)
or system_packfile))
and (packcat.password(1) = id(1)
and packcat.password(2) = id(2)
or allowner)
or allpackfile
then
begin
helpscope:= undefined;
<*+1*>
if test shift(-1) then
begin
print_entry(out,packcat.entrybase_adr,bases,undefined,statlist);
write(out,<:, scan packentry:>);
end;
<*-1*>
<*
det undersøges nu om katalogindgangen
overhovedet er interessandt
*>
if no_of_files > 0 then
begin <* filliste er angivet *>
name:= 0;
for no:=1, no + 1 while no <= no_of_files and -,entryfound do
begin
if namelist.name(1) = packcat.entryname(1)
and namelist.name(2) = packcat.entryname(2) then
begin
if namelist.name(3) = '.' then
begin
scopeel:= namelist.name(7);
helpscope:=
if scopeel = long <:temp:> then temp else
if scopeel = long <:login:> then login else
if scopeel = long <:user:> then user else
_ project ;
end
else
helpscope:= undefined;
entryfound:=
if helpscope = undefined then true
else helpscope = entry_scope(packcat.entry_baseadr,bases);
if entryfound then
found_namelist(no):= true;
end name;
name:=name + (if namelist.name(3) = '.' then 36 else 12);
end no_of_files;
end filelist
;
<* der søges ved hjælp af scope eller subtext *>
if -,entryfound and scopeboo then
begin
helpscope:= entry_scope(packcat.entry_baseadr,bases);
if helpscope <> undefined then
entryfound:= scopelist(helpscope);
end;
if -,entryfound and no_of_subtext > 0 then
begin
subname:= 0;
for no:=1, no + 1 while no <= no_of_subtext and -,entryfound do
begin
entryfound:= subcompare(packcat.entryname,sublist.subname);
subname := subname + 12;
end;
end;
if -,entryfound then
begin
if no_of_files = 0 and -,scopeboo and no_of_subtext = 0
then entryfound:= true;
end;
end udvalgt entry;
end key <> 0;
end entryno;
if entryfound and helpscope = undefined then
helpscope:= entry_scope(packcat.entry_baseadr,bases);
scope:= helpscope; scan_packentry:= entryfound;
<*+1*>
if test shift(-2) and entryfound then
begin
print_entry(out,packcat.entrybase_adr,bases,scope,statlist);
write(out,<:, scan packentry:>);
end;
<*-1*>
end scan_packentry;
\f
boolean procedure next_packentry(packcat,bases,sublist,id,scope);
<***************************************************************>
zone packcat ;
integer array bases ;
long array sublist,id ;
integer scope ;
<*
søger en katalogindgang i packfilen, som opfylder et af kriterierne
subtext.<præfix>
scope.<scopeklasse>
<next_packentry> er true sålænge der findes flere mulige katalog-
indgange i packfilens katalog
*>
begin
own integer
_ entryno,
_ entryused;
integer
_ helpscope,
_ no;
boolean
_ entryfound;
long array field
_ subname;
if entryno = 0 then
newposition(packcat,1,packcat_updated,packcat_leftblock);
entryfound:= false;
while entryno < head.packentries and entryused < head.no_of_entries and -,entryfound do
begin
nextrecord(packcat,head.entrylength,packcat_updated,packcat_leftblock);
entryno:= entryno + 1;
if packcat.key <> 0 then
begin
entryused:= entryused + 1;
<*
katalogindgangen skal være synlig for processen,
og ownerid skal stemme overens med det angivne
*>
if extend packcat.lowerbase <= bases(3)
and extend packcat.upperbase >= bases(4)
and (extend packcat.lowerbase >= bases(7)
and extend packcat.upperbase <= bases(8)
or system_packfile)
and packcat.password(1) = id(1)
and packcat.password(2) = id(2)
then
begin
<*+1*>
if test shift(-1) then
begin
print_entry(out,packcat.entrybase_adr,bases,undefined,statlist);
write(out,<:, next packentry:>);
end;
<*-1*>
helpscope:= undefined;
if scopeboo then
begin
helpscope:= entry_scope(packcat.entrybase_adr,bases);
if helpscope <> undefined then
entryfound:= scopelist(helpscope);
end;
if -,entryfound and no_of_subtext > 0 then
begin
subname:= 0;
for no:=1, no + 1 while no <= no_of_subtext and -,entryfound do
begin
entryfound:= subcompare(packcat.entryname,sublist.subname);
subname := subname + 12;
end;
end;
end udvalgt entry;
end key <> 0;
end entryno;
if entryfound and helpscope = undefined then
helpscope:= entry_scope(packcat.entrybase_adr,bases);
scope:= helpscope; next_packentry:= entryfound;
<*+1*>
if test shift(-2) and entryfound then
begin
print_entry(out,packcat.entrybase_adr,bases,scope,statlist);
write(out,<:, next packentry:>);
end;
<*-1*>
end next_packentry;
\f
boolean procedure search_gap(gap,size);
<*************************************>
value size ;
zone gap ;
integer size ;
<*
søger et hul i hulkataloget, som er
større end eller lig med <size>
*>
begin
integer
_ no,
_ gapno,
_ min_gapadr,
_ min_gapsize;
boolean
_ gap_found;
newposition(gap,head.gapcat_adr,gapcat_updated,gapcat_leftblock);
no:= gapno :=
min_gapadr := 0 ;
min_gapsize:= maxint;
gap_found := false ;
while no < head.gapentries and gapno < head.no_of_gaps and -,gap_found do
begin
nextrecord(gap,4,gapcat_updated,gapcat_leftblock);
no:=no + 1;
if gap.first_emptysegm > 0 then
begin
gapno:=gapno + 1;
if gap.no_of_emptysegm = size
then gap_found:= true
else
if gap.no_of_emptysegm > size
and gap.no_of_emptysegm < min_gapsize then
begin
min_gapsize:= gap.no_of_emptysegm;
min_gapadr := no;
end;
end;
end søgning;
<* evt. skal en tidligere observeret indgang findes igen *>
if no >= min_gapadr and min_gapadr > 0 and -,gap_found then
begin
if no > min_gapadr then
find_record(gap,head.gapcat_adr,min_gapadr,4,gapcat_updated,gapcat_leftblock);
gap_found:= true;
end;
search_gap:= gap_found;
<*+1*>
if test shift(-2) then
begin
if gap_found then
write(out,<:<10>search gap, gap found: :>,<<ddddd>,gap.first_emptysegm,gap.no_of_emptysegm)
else
write(out,<:<10>search gap, gap not found:>);
end;
<*-1*>
end search_gap;
\f
boolean procedure delete_packentry(cat,gap);
<******************************************>
zone cat,gap ;
<*
sletter den aktuelle packfile_entry i cat
og indsætter de tomme segmenter i hulkataloget
*>
begin
integer
_ test_scope,
_ no,
_ gapno,
_ type;
boolean
_ expand;
integer field
_ i_field;
<*+1*> if test shift(-2) then
<*-1*> test_scope:= entry_scope(cat.entrybase_adr,intern_bases);
<* evt. kun entry *>
if cat.storeaddress = 0 then
begin
cat.key:=0;
head.no_of_entries :=head.no_of_entries - 1;
packcat_updated:= true;
end
else
<* evt. sidste område i packfile - denne kortes ned *>
if cat.storeaddress + cat.areasize = head.packfile_size then
begin
cat.key:=0;
head.packfile_size :=head.packfile_size - cat.areasize;
head.no_of_entries :=head.no_of_entries - 1;
head.no_of_segm :=head.no_of_segm - cat.areasize;
packcat_updated:= true;
end
else
<* det slettede område indsættes i hulkataloget *>
begin
<*
først undersøges om det er muligt at udvide et eksisterende hul
ellers må hullet indsættes i hulkataloget
*>
expand:=false;
no:=gapno:= 0;
newposition(gap,head.gapcat_adr,gapcat_updated,gapcat_leftblock);
while -,expand and no < head.gapentries and gapno < head.no_of_gaps do
begin
nextrecord(gap,4,gapcat_updated,gapcat_leftblock);
no:=no + 1;
if gap.first_emptysegm > 0 then
begin
gapno:=gapno + 1;
if cat.storeaddress = gap.first_emptysegm + gap.no_of_emptysegm then
begin
expand:=true;
type:=1;
end
else
if cat.storeaddress + cat.areasize = gap.first_emptysegm then
begin
expand:=true;
type:=2;
end;
end gapentry > 0;
end search;
<* evt. søges en fri gap_entry *>
if -,expand and head.gapentries - head.no_of_gaps > 0 then
begin
newposition(gap,head.gapcat_adr,gapcat_updated,gapcat_leftblock);
repeat
nextrecord(gap,4,gapcat_updated,gapcat_leftblock);
until gap.first_emptysegm = 0;
end;
<* entry slettes *>
if expand or head.gapentries - head.no_of_gaps > 0 then
begin
cat.key:=0;
head.no_of_entries :=head.no_of_entries - 1;
head.no_of_segm :=head.no_of_segm - cat.areasize;
packcat_updated:= true;
end;
if expand then
begin
if type = 1 then
gap.no_of_emptysegm:=gap.no_of_emptysegm + cat.areasize
else
begin
gap.first_emptysegm:=cat.storeaddress;
gap.no_of_emptysegm:=gap.no_of_emptysegm + cat.areasize;
end;
head.no_of_gapsegm := head.no_of_gapsegm + cat.areasize;
gapcat_updated:= true;
end expand
else
if head.gapentries - head.no_of_gaps > 0 then
begin
gap.first_emptysegm :=cat.storeaddress;
gap.no_of_emptysegm :=cat.areasize ;
head.no_of_gaps := head.no_of_gaps + 1;
head.no_of_gapsegm := head.no_of_gapsegm + cat.areasize;
gapcat_updated:= true;
end
else
begin
print_entry(ud,cat.entry_baseadr,intern_bases,undefined,ownerlist);
write(ud,"sp",5,<:*** gapcatalog is full, not deleted:>);
end;
end indsættelse i hulkatalog og sletning;
delete_packentry:= if cat.key = 0 then true else false;
<*+1*>
if test shift(-2) then
begin
print_entry(out,cat.entrybase_adr,intern_bases,test_scope,statlist);
write(out,<:, delete :>,if cat.key = 0 then <:ok:> else <:not ok:>);
end;
<*-1*>
<* resten af entry slettes *>
if cat.key = 0 then
begin
if hashing_used then delete_tableentry(cat.hashkey,cat.entryindex);
for i_field:= head.entrylength step -2 until 4
do cat.i_field:= 0;
swop_cat(cat,packcat_updated,gap,gapcat_updated);
end;
end delete_packentry;
\f
boolean procedure insert_packentry(cat,gap,entry,bases,catalog_scope,scope,hkey);
<******************************************************************************>
value catalog_scope,scope,hkey ;
zone cat,gap ;
integer array entry,bases ;
integer catalog_scope,scope,hkey ;
<*
katalogindgangen og det evt. tilhørende dataområde forsøges
indsat i packfilens katalog og fortrinsvis i tomme huller
insert_packentry=true, hvis indsættelsen lykkedes
*>
begin
integer
_ position,
_ return;
boolean
_ gap_found,
_ entry_found,
_ packfile_extended,
_ skip;
<* alle temp og login entries lægges på min. userbase *>
if scope = temp or scope = login then
begin
if entry.lowerbase > bases(5) then
begin
entry.upperbase:=entry.upperbase - (entry.lowerbase - bases(5));
entry.lowerbase:=bases(5);
end;
end;
<* hvis der er tale om et område, søges et hul i hulkataloget *>
if entry.areasize > 0 and head.no_of_gaps > 0 then
gap_found:= search_gap(gap,entry.areasize)
else
gap_found:= false;
<* der søges en plads til katalogindgangen *>
if head.packentries - head.no_of_entries > 0 then
begin
entry_found:= true;
insert_tableentry(cat,entry.entryname,ownerid,hkey);
end
else entry_found:= false;
skip:= false;
if entry_found then
begin
<* evt. skal packfilen udvides *>
packfile_extended:= false;
if entry.areasize > 0 and -,gap_found then
begin
integer array
_ tail(1:10);
return:=monitor(42,head,0,tail);
if return <> 0 then
monitor_error(42,head,return,true);
tail(1):=head.packfile_size + entry.areasize;
return :=monitor(44,head,0,tail);
if return = 0 then
begin
position:=head.packfile_size;
packfile_extended:= true;
end
else
begin
skip:= true;
print_entry(ud,entry,bases,scope,normlist);
write(ud,"sp",5,<:*** packfile cannot be extended, area not inserted:>);
if return <> 6 then
monitor_error(44,head,return,true);
end;
end
else
if gap_found then
position:= gap.first_emptysegm;
<* området overføres til packfilen *>
if entry.areasize > 0 and -,skip then
begin
skip:= -,movearea(packfile,position,undefined,
_ entry.entryname,0,catalog_scope,
_ max_bufsegm,entry.areasize);
if skip then
begin
print_entry(ud,entry,bases,scope,normlist);
write(ud,"sp",5,<:*** entry in use, not inserted:>);
end;
end;
<* det evt.fundne hul fjernes fra kataloget eller reduceres *>
if gap_found and -,skip then
begin
if gap.no_of_emptysegm = entry.areasize then
begin
head.no_of_gaps :=head.no_of_gaps - 1;
head.no_of_gapsegm :=head.no_of_gapsegm - entry.areasize;
gap.first_emptysegm :=gap.no_of_emptysegm := 0;
end
else
begin
head.no_of_gapsegm :=head.no_of_gapsegm - entry.areasize;
gap.first_emptysegm :=gap.first_emptysegm + entry.areasize;
gap.no_of_emptysegm :=gap.no_of_emptysegm - entry.areasize;
end;
gapcat_updated:= true;
end;
<* katalog indgangen indsættes i packfilens katalog *>
if -,skip then
begin
tofrom(cat.entry_baseadr,entry,34);
if entry.areasize > 0 then
cat.storeaddress:=position;
cat.password(1) := ownerid(1);
cat.password(2) := ownerid(2);
cat.packdate := date;
cat.last_accessdate
_ := date;
cat.no_of_read := 0;
cat.no_of_point := 0;
if entry.areasize < 0 then
begin
if newkit(1) <> empty then
tofrom(cat.auxdocname,newkit,8)
else
lookup_auxdoc(cat.auxdocname,if entry.key shift(-12) > 0 then
_ entry.key shift(-12) - 2048 else 0);
end;
head.no_of_entries := head.no_of_entries + 1;
if packfile_extended then
head.packfile_size := head.packfile_size + entry.areasize;
if entry.areasize > 0 then
head.no_of_segm := head.no_of_segm + entry.areasize;
packcat_updated:= true;
swop_cat(cat,packcat_updated,gap,gapcat_updated);
end if -,skip;
end entry_found
else
begin
skip:= true;
print_entry(ud,entry,bases,scope,normlist);
write(ud,"sp",5,<:*** no free entries, not inserted:>);
end;
insert_packentry:= -,skip;
<*+1*>
if test shift(-2) then
begin
print_entry(out,entry,bases,scope,normlist);
write(out,<:, insert :>,if -,skip then <:ok:> else <:not ok:>);
end;
<*-1*>
end insert_packentry;
\f
procedure reorganize_gapcat(gap);
<*******************************>
zone gap ;
<*
afkorter packfilen såfremt denne
afsluttes med ubrugte huller
*>
begin
integer array
_ gap_tab(1:head.no_of_gaps,1:3);
real
_ base,
_ c,
_ r0,
_ r;
integer
_ last_found,
_ gapno,
_ gapused;
<*+1*>
if test shift(-5) then
begin
systime(1,0,base);
c:=systime(1,base,r0);
end;
<*-1*>
gapused:= 0;
newposition(gap,head.gapcat_adr,gapcat_updated,gapcat_leftblock);
for gapno:=1 step 1 until head.gapentries do
begin
nextrecord(gap,4,gapcat_updated,gapcat_leftblock);
if gap.first_emptysegm > 0 then
begin
gapused:= gapused + 1;
if gapused <= head.no_of_gaps then
begin
gap_tab(gapused,1):= gap.first_emptysegm;
gap_tab(gapused,2):= gapno ;
gap_tab(gapused,3):= gap.no_of_emptysegm;
end
else
break(<:*** used entries in gapcat exceeds no of gapentries:>,gapused,true);
end;
end;
<* tabellen sorteres i stigende orden efter første segment nr. *>
quicksort(gap_tab,gapused,3,1);
<* nu løbes tabellen igennem og hulkataloget reorganiseres evt. *>
last_found:= 0;
while gapused > 0 do
begin
<*+1*>
if test shift(-2) then
write(out,<:<10>reorganize gapcat, entryused =:>,<<ddddddd>,gapused,
_ <:, first emptysegm =:>,gap_tab(gapused,1),
_ <:, no of emptysegm =:>,gap_tab(gapused,3));
<*-1*>
<* det undersøges om packfilen kan afkortes *>
if gap_tab(gapused,1) + gap_tab(gapused,3) >= head.packfile_size then
begin
find_record(gap,head.gapcat_adr,gap_tab(gapused,2),4,gapcat_updated,gapcat_leftblock);
<*+1*>
if test shift(-2) then
write(out,<:<10>reorganize gapcat, packfile was cut down by segm =:>,head.packfile_size - gap.first_emptysegm);
<*-1*>
head.no_of_gaps := head.no_of_gaps - 1;
head.no_of_gapsegm := head.no_of_gapsegm - gap.no_of_emptysegm;
head.packfile_size := gap.first_emptysegm ;
gap.first_emptysegm:=
gap.no_of_emptysegm:= 0;
gapcat_updated := true;
end
else
<* det undersøges om nogle huller kan sammenlægges *>
if gapused > 1 then
begin
if gap_tab(gapused - 1, 1) + gap_tab(gapused - 1, 3) = gap_tab(gapused,1) then
begin
if last_found <> gap_tab(gapused,2) then
find_record(gap,head.gapcat_adr,gap_tab(gap_used,2),4,gapcat_updated,gapcat_leftblock);
head.no_of_gaps := head.no_of_gaps - 1;
gap.first_emptysegm:=
gap.no_of_emptysegm:= 0;
gapcat_updated := true;
find_record(gap,head.gapcat_adr,gap_tab(gap_used - 1, 2),4,gapcat_updated,gapcat_leftblock);
last_found:= gap_tab(gapused - 1, 2);
gap.no_of_emptysegm:= gap_tab(gapused - 1, 3):= gap.no_of_emptysegm + gap_tab(gapused,3);
gapcat_updated := true;
<*+1*>
if test shift(-2) then
write(out,<:<10>reorganise gapcat, two gaps reduced to one, first segm =:>,
_ <<ddddd>,gap_tab(gapused-1,1),<:, no of segm =:>,gap_tab(gapused-1,3));
<*-1*>
end;
end;
gapused:= gapused - 1;
end;
<*+1*>
if test shift(-5) then
begin
c:=systime(1,base,r) - c;
r:=r - r0;
write(out,<:<10>reorganisering af gapcat, cputid/realtid :>,<<ddd.dddd>,c,r);
end;
<*-1*>
end reorganize_gapcat;
\f
integer procedure compute_last_date(act_date,days);
<*************************************************>
value act_date,days ;
integer act_date,days ;
<*
proceduren beregner datoen på den dag, som ligger
<days> antal dage før <act_date>
*>
begin
integer
_ dd,
_ mm,
_ yy,
_ counter;
dd:= act_date mod 100;
mm:= act_date // 100 mod 100;
yy:= act_date // 10000;
for counter:= 1 step 1 until days do
begin
dd:= dd - 1;
if dd < 1 then
begin
mm:= mm - 1;
if mm < 1 then
begin
mm:= 12;
yy:= yy - 1;
end if mm < 1;
dd:= case mm of (31,if yy mod 4 = 0 then 29 else 28,31,30,31,30,31,31,30,31,30,31);
end if dd < 1;
end no of days;
compute_last_date:= yy * 10000 + mm * 100 + dd;
<*+1*> if test shift(-2) then
<*-1*> write(out,<:<10>compute last date =:>,<< dd dd dd>,yy*10000+mm*100+dd);
end compute_last_date;
\f
procedure purge(cat,gap,lastdate,type,list);
<******************************************>
value lastdate,type,list ;
zone cat,gap ;
integer lastdate,type ;
boolean list ;
<*
sletter entries i packfilen, som er ældre end
<lastdate> afhængig af slettetypen <type>
type:
1: entrydate
2: packdate
3: lastaccessdate
*>
begin
integer array
_ saveentry(1:head.entrylength//2);
integer
_ total_entryused,
_ entryno,
_ entryused,
_ test_date;
newposition(cat,1,packcat_updated,packcat_leftblock);
total_entryused := head.no_of_entries; <* gemmes da entries slettes undervejs *>
entryno:= entryused:= 0;
while entryno < head.packentries and entryused < total_entryused do
begin
nextrecord(cat,head.entrylength,packcat_updated,packcat_leftblock);
entryno:= entryno + 1;
if cat.key <> 0 then
begin
entryused:= entryused + 1;
test_date:=
case type of (
if cat.entrytail(1) <> 0 and cat.entrytail(4) <> 4 and cat.entrytail(4) < 32
then systime(6,cat.entrytail(1),0.0) else lastdate,
cat.packdate,
cat.last_accessdate);
<*+1*>
if test shift(-2) then
write(out,<:<10>purge, testdate =:>,<< dd dd dd>,test_date,<:, lastdate =:>,lastdate,<:, type =:>,<<dd>,type);
<*-1*>
if test_date < lastdate then
begin
if list then
tofrom(saveentry,cat.entrybase_adr,head.entrylength);
if delete_packentry(cat,gap) and list then
print_entry(ud,saveentry,intern_bases,undefined,ownerlist);
end;
end cat.key <> 0;
end entries;
end purge;
\f
procedure pack;
<*************>
<*
indsætter de ønskede katalogindgange
og evt. tilhørende områder i packfilen
*>
begin
boolean procedure reserved(name,scope);
<*************************************>
long array name ;
integer scope ;
<*
undersøger om det er tilladt at pakke
en angiven entry med specificeret scope
*>
begin
reserved:=
if name(1) = long <:c:> and scope = temp
or name(1) = long <:v:> and scope = temp
or name(1) = long <:primo:> add 'u' and name(2) = long <:t:> and scope = login
or name(1) = long <:pack:>
or name(1) = packfile(1) and name(2) = packfile(2)
or name(1) = outfile(1) and name(2) = outfile(2)
then true else false;
end reserved;
procedure set_newscope(entry);
<****************************>
integer array entry ;
begin
integer
_ ix;
entry.key:= entry.key shift(-3) shift 3
_ add (case newscope + 1 of (0,2,3,3));
ix:= case newscope + 1 of (3,3,5,7);
entry.lowerbase:= process_bases(ix);
entry.upperbase:= process_bases(ix + 1);
end;
procedure remove_entry(name,scope);
<*********************************>
value scope ;
long array name ;
integer scope ;
<*
sletter en entry, som er indsat i packfilen
*>
begin
zone
_ rem(1,1,stderror);
integer array
_ ia(1:2);
integer
_ ix,
_ return;
if scope > login then
begin
ix := case scope + 1 of (3,3,5,7);
ia(1):= process_bases(ix);
ia(2):= process_bases(ix + 1);
return:= monitor(72)set_cat_base:(myself,0,ia);
if return <> 0 then monitor_error(72,myself,return,true);
end;
open(rem,0,name,0);
return:= monitor(48)remove_entry:(rem,0,ia);
if return <> 0 then
begin
monitor_error(48,rem,return,false);
write(ud,<:<10>*** entry could not be removed after pack:>);
end;
close(rem,true);
if scope > login then
begin
return:= monitor(72)set_cat_base:(myself,0,process_bases);
if return <> 0 then monitor_error(72,myself,return,true);
end;
end remove_entry;
long array
_ name(1:2);
integer array
_ save_entry(1:head.entrylength//2),
_ catalogentry(1:17);
integer
_ nextname_adr,
_ fileno,
_ look_return;
boolean
_ ok;
integer array field
_ last_part;
last_part:= 34;
print_heading(ud,normlist);
if no_of_files > 0 then
begin
nextname_adr:= 0;
for fileno:=1 step 1 until no_of_files do
begin
scope:= get_nextentryspec(name,nextname_adr);
<*
katalogindgangen søges, og såfremt den findes
pakkes den med det evt. tilhørende område
*>
look_return:=lookup_entry(catalogentry,process_bases,name,scope);
if look_return = -1
or reserved(name,scope) then
lookup_error(ud,name,scope,false,if look_return = -1 then 1 else 2)
else
begin
tofrom(save_entry,catalogentry,34);
if newscope <> undefined then set_newscope(catalogentry);
if newkit(1) <> empty and catalogentry.areasize >= 0 then
tofrom(catalogentry.documentname,newkit,8);
ok:=
if search_tableentry(packcat,name,ownerid,intern_bases,
_ if newscope = undefined then scope else newscope)
then delete_packentry(packcat,gapcat)
else true;
if ok then
begin
if insert_packentry(packcat,gapcat,catalogentry,intern_bases,scope,
_ if newscope = undefined then scope else newscope,hashkey_computed) then
begin
tofrom(saveentry.last_part,packcat.last_part,head.entrylength-34);
print_entry(ud,save_entry,process_bases,scope,normlist);
if remove then remove_entry(name,scope);
end;
end;
end pack of entry;
end denne fil;
end no_of_files
;
<* der søges direkte i main-catalog *>
if scopeboo or no_of_subtext > 0 then
begin
zone
_ look(128*2,2,stderror);
open(look,4,<:catalog:>,0);
while search_catalogentry(look,catalogentry,process_bases,scope) do
if -,reserved(catalogentry.entryname,scope) then
begin
tofrom(save_entry,catalogentry,34);
if newscope <> undefined then set_newscope(catalogentry);
if newkit(1) <> empty and catalogentry.areasize >= 0 then
tofrom(catalogentry.documentname,newkit,8);
ok:=
if search_tableentry(packcat,catalogentry.entryname,ownerid,intern_bases,
_ if newscope = undefined then scope else newscope)
then delete_packentry(packcat,gapcat)
else true;
if ok then
begin
if insert_packentry(packcat,gapcat,catalogentry,intern_bases,scope,
_ if newscope = undefined then scope else newscope,hashkey_computed) then
begin
tofrom(saveentry.last_part,packcat.last_part,head.entrylength-34);
print_entry(ud,save_entry,process_bases,scope,normlist);
if remove then remove_entry(catalogentry.entryname,scope);
end;
end;
end catalog;
close(look,true);
end;
end pack;
\f
procedure unpack;
<***************>
<*
opretter de relevante entries og områder
på baggrundslager ud fra oplysninger i
packfilens katalog med scope = login
hvis newscope ikke er angivet.
hvis changekit er angivet oprettes på
det navngivne baggrundslager dokument
*>
begin
long array
_ name(1:2);
integer array
_ saveentry(1:head.entrylength//2);
integer
_ create_result,
_ fileno,
_ nextname_adr;
boolean
_ ok,
_ found;
procedure create;
<***************>
begin
tofrom(saveentry,packcat.entrybase_adr,head.entrylength);
create_result:= create_entry(saveentry,newkit,process_bases,newscope);
if create_result >= 0 then
begin
if saveentry.areasize > 0 then
ok:= movearea(saveentry.entryname,0,newscope,
_ packfile,saveentry.storeaddress,undefined,
_ max_bufsegm,saveentry.areasize)
else ok:= true;
if -,ok then
begin
print_entry(ud,packcat.entrybase_adr,intern_bases,scope,normlist);
write(ud,"sp",5,<:*** area move not complete:>);
end
else
begin
print_entry(ud,packcat.entrybase_adr,intern_bases,scope,normlist);
if create_result = 1 then
write(ud,"sp",5,<:*** temp, no login resources:>);
<* statistikkerne opdateres *>
if -,system_packfile then
begin
packcat.no_of_read:= packcat.no_of_read + 1;
packcat.lastaccess_date:= date;
packcat_updated:= true;
end;
end;
end
else
begin
print_entry(ud,packcat.entrybase_adr,intern_bases,scope,normlist);
write(ud,"sp",5,case abs create_result of (
_ <:*** no resources:>,<:*** name conflict:>));
end;
end create;
print_heading(ud,normlist);
nextname_adr:= 0;
for fileno:=1 step 1 until no_of_files do
begin
scope:= get_nextentryspec(name,nextname_adr);
found:=
if scope = undefined then
lookup_tableentry(packcat,name,ownerid,intern_bases,scope)
else
search_tableentry(packcat,name,ownerid,intern_bases,scope);
if found then create
else lookup_error(ud,name,scope,false,1);
end;
if scopeboo or no_of_subtext > 0 then
begin
while next_packentry(packcat,intern_bases,optionlist.subtext_adr,ownerid,scope)
do create;
end;
end unpack;
\f
procedure searchpack;
<*******************>
<*
lister indholdet af packfile
*>
begin
long array
_ helpname,
_ name(1:2);
integer array
_ dummy(1:1);
boolean array
_ namefound(1:(if no_of_files > 0 then no_of_files else 1));
integer
_ namebase,
_ records,
_ no;
<* all.owner er default for alle filer undtagen "publicpack" *>
if (packfile(1) <> long <:publi:> add 'c'
or packfile(2) <> long <:pack:>)
and ownerid(1) = long <::>
then allowner:= true;
for no:=1 step 1 until no_of_files do
namefound(no):= false;
write(ud,<< dddddd>,
_ "nl",2,<:size =:>,head.packfile_size,
_ "sp",5,<:creation date =:>,head.creation_date,
_ "nl",1,<:max. entries =:>,head.packentries,
_ "sp",5,<:max. gaps =:>,head.gapentries,
_ "nl",1,<:used entries =:>,head.no_of_entries,
_ "sp",5,<:segments =:>,head.no_of_segm,
_ "nl",1,<:gaps =:>,head.no_of_gaps,
_ "sp",5,<:gapsegments =:>,head.no_of_gapsegm);
if head.retention_days < maxint then
write(ud,<< dddddd>,
_ "nl",2,<:retention days =:>,head.retention_days);
write(ud,"nl",2);
case listtype of
begin
print_heading(ud,ownerlist);
print_heading(ud,statlist);
;
end;
begin
zone helpz(128,1,stderror);
helpname(1):= helpname(2):= empty;
connect(helpz,helpname,head.gapcat_adr - 1);
records:= 0;
while scan_packentry(packcat,intern_bases,optionlist.filelist_adr,
_ optionlist.subtext_adr,ownerid,scope,namefound)
do
begin
records:= records + 1;
outrec6(helpz,head.entrylength);
tofrom (helpz,packcat,head.entrylength);
helpz.entryindex:= scope;
end;
close(helpz,true);
end;
if records > 0 then
begin
if records > 1 then
begin
no:= 1;
discsort(string helpname(increase(no)),head.entrylength,records,1,0,
<* key 1 *> password + 4,
<* key 2 *> password + 8,
<* key 3 *> entryname + 4,
<* key 4 *> entryname + 8,
<* key 5 *> entryindex);
end records > 1;
begin
zone helpz(128,1,stderror);
connect(helpz,helpname,0);
for no:= 1 step 1 until records do
begin
inrec6(helpz,head.entrylength);
scope:=helpz.entryindex;
if listtype < 3
then print_entry(ud,helpz.entrybase_adr,intern_bases,scope,
_ case listtype of(ownerlist,statlist))
else print_head_and_tail(ud,helpz.entry_baseadr,intern_bases,scope);
end;
monitor(48)remove_entry:(helpz,0,dummy);
close(helpz,true);
end;
end records > 0;
<* test af hvorvidt specificerede navne blev fundet *>
if no_of_files > 0 then
begin
namebase:= 0;
for no:=1 step 1 until no_of_files do
begin
scope:= get_nextentryspec(name,namebase);
if -,namefound(no) then
lookup_error(ud,name,scope,false,1);
end;
end;
end searchpack;
\f
procedure clearpack;
<******************>
<*
sletter de specificerede
packentries og evt.
tilhørende områder
*>
begin
long array
_ name(1:2);
integer array
_ saveentry(1:head.entrylength//2);
integer
_ nextname_adr,
_ fileno;
boolean
_ entryfound;
print_heading(ud,normlist);
nextname_adr:= 0;
for fileno:=1 step 1 until no_of_files do
begin
scope:= get_nextentryspec(name,nextname_adr);
entryfound:=
if scope = undefined then
lookup_tableentry(packcat,name,ownerid,intern_bases,scope)
else
search_tableentry(packcat,name,ownerid,intern_bases,scope);
if entryfound then
begin
tofrom(saveentry,packcat.entry_baseadr,head.entrylength);
if delete_packentry(packcat,gapcat) then
print_entry(ud,saveentry,intern_bases,scope,normlist);
end
else
lookup_error(ud,name,scope,false,1);
end no_of_files;
end clearpack;
\f
procedure repack;
<***************>
begin
procedure set_securityfile(entry);
<********************************>
integer array entry ;
begin
integer
_ i,
_ return;
if secu_tail(1) = -1 then
begin
integer array
_ ia(1:10),
_ kit(1:4);
long array field
_ device;
device:= 2;
for i:= 1 step 1 until 10 do
secu_tail(i):= 0;
if -,security then
begin
secu_tail.device(1):= extend 1 shift 24; <* disckit is prefered *>
secu_tail.device(2):= long <::> ;
end
else
if -,get_permkit_name(secu_tail.device) then
break(<:*** security requires permanent resources to create file "repacksafe":>,0,true);
open(secu,4,securityfile,0);
secu_tail(1):= 1;
return:= monitor(42)lookup_entry:(secu,0,ia);
if return = 0 then
begin
if ia(1) = 0 then
begin
return:= monitor(48)remove_entry:(secu,0,ia);
if return <> 0 then
monitor_error(48,secu,return,false);
end;
if ia(1) <> 0 or return <> 0 then
break(<:*** security file "repacksafe" exist from a previous run !!:>,0,true);
end;
return:= monitor(40)create_entry:(secu,0,secu_tail);
if return <> 0 then
monitor_error(40,secu,return,true);
if security then
begin
tofrom(kit,secu_tail.device,8);
if -,change_scope(secu,kit,process_bases,user) then
begin
return:= monitor(48)remove_entry:(secu,0,secu_tail);
if return <> 0 then
begin
write(out,<:<10>*** area repacksafe not removed:>);
monitor_error(48,secu,return,false);
end;
break(<:*** "repacksafe" cannot be made permanent:>,0,true);
end;
end;
end;
secu_tail(1):= entry.areasize;
for i:=6 step 1 until 10 do
secu_tail(i):= entry.entrytail(i-5);
return:= monitor(44)change_entry:(secu,0,secu_tail);
if return <> 0 then
begin
i:= monitor(48)remove_entry:(secu,0,secu_tail);
if i <> 0 then
begin
write(out,<:<10>*** area "repacksafe" not removed:>);
monitor_error(48,secu,i,false);
end;
if return = 6 then
break(<:*** no resources to set "repacksafe", needed segments =:>,secu_tail(1),true)
else
monitor_error(44,secu,return,true);
end;
end set_securityfile;
procedure cut_securityfile;
<*************************>
<*
sætter størrelsen af securityfilen
"repacksafe" til 0 segmenter
*>
begin
integer i;
for i:= 1, 6 step 1 until 10 do
secu_tail(i):= 0;
i:= monitor(44)change_entry:(secu,0,secu_tail);
if i <> 0 then
monitor_error(44,secu,i,true);
end cut_securityfile;
zone
_ secu(128,1,stderror);
long array
_ securityfile(1:2);
integer array
_ entry_tab(1:(if head.no_of_entries > 0 then head.no_of_entries else 1),1:3),
_ secu_tail(1:10);
integer
_ i,
_ segm_pointer,
_ old_address,
_ entryno,
_ entryused;
boolean
_ packcat_extension;
packcat_extension:= dim_packentries > head.packentries;
print_heading(ud,ownerlist);
<* gennemløb af packcat *>
entryused:= 0;
newposition(packcat,1,packcat_updated,packcat_leftblock);
for entryno:=1 step 1 until head.packentries do
begin
nextrecord(packcat,head.entrylength,packcat_updated,packcat_leftblock);
if packcat.key <> 0 then
begin
entryused:= entryused + 1;
if entryused <= head.no_of_entries then
begin
entry_tab(entryused,1):= packcat.storeaddress;
entry_tab(entryused,2):= entryno;
entry_tab(entryused,3):= packcat.areasize ;
end
else
break(<:*** used entries in packcat exceeds no of entries:>,entryused,true);
end;
end;
<* sortering af tabellen *>
quicksort(entry_tab,entryused,3,1);
<* klargøring af securityområde *>
securityfile(1):= long <:repac:> add 'k';
securityfile(2):= long <:safe:> ;
secu_tail(1) := -1; <* bevirker initialisering af området *>
<* evt. ændring af katalogernes størrelse i packfilen *>
if dim_packentries > 0 or dim_gapentries > 0 then
begin
boolean
_ extension_ok,
_ gap_found;
integer
_ return,
_ newsize,
_ newgapcat_adr,
_ new_first_areasegm,
_ totalused;
if dim_packentries < head.packentries
then dim_packentries:= head.packentries;
if dim_gapentries = 0
then dim_gapentries := head.gapentries;
newsize:=
1 +
(dim_packentries - 1)//(512//head.entrylength) + 1 +
(dim_gapentries - 1)//(512//4) + 1;
newgapcat_adr:=
1 + (dim_packentries - 1)//(512//head.entrylength) + 1;
new_first_areasegm:=
newgapcat_adr + (dim_gapentries - 1)//(512//4) + 1;
extension_ok:= true;
if newsize > head.first_areasegm then
begin
totalused:= entryused;
entryused:= 0 ;
<* entries uden areal overspringes *>
repeat entryused:= entryused + 1
until entryused = head.no_of_entries
or entry_tab(entryused,1) <> 0;
segmpointer:= head.first_areasegm;
<* den egentlige flytning af områder påbegyndes *>
while segm_pointer < newsize
and entryused <= head.no_of_entries
and extension_ok
do
begin
<* området må evt. flyttes *>
if entry_tab(entryused,1) < newsize then
begin
find_record(packcat,1,entry_tab(entryused,2),head.entrylength,
_ packcat_updated,packcat_leftblock);
gap_found:=
if head.no_of_gaps > 0 then
search_gap(gapcat,entry_tab(entryused,3))
else false;
if gap_found then
begin
if movearea(packfile,gapcat.first_emptysegm,undefined,
_ packfile,packcat.storeaddress,undefined,
_ max_bufsegm,packcat.areasize)
then
begin
entry_tab(entryused,1):=
packcat.storeaddress := gapcat.first_emptysegm;
packcat_updated := true;
if packcat.areasize = gapcat.no_of_emptysegm then
begin
gapcat.first_emptysegm:=
gapcat.no_of_emptysegm:= 0;
head.no_of_gaps := head.no_of_gaps - 1;
end
else
<* hullet reduceres *>
gapcat.first_emptysegm:= gapcat.first_emptysegm + packcat.areasize;
gapcat_updated := true;
end if movearea;
end if gapfound
else
<* packfilen må udvides *>
begin
packtail(1):= packtail(1) + packcat.areasize;
return:= monitor(44)change_entry:(head,0,packtail);
if return = 0 then
begin
if movearea(packfile,head.packfile_size,undefined,
_ packfile,packcat.store_address,undefined,
_ max_bufsegm,packcat.areasize)
then
begin
entry_tab(entryused,1):=
packcat.storeaddress := head.packfile_size;
head.packfile_size := head.packfile_size + packcat.areasize;
packcat_updated := true;
end
else
extension_ok:= false;
end
else
begin
extension_ok:= false;
write(out,"nl",2,<:*** no resources, packfile cannot be extended !:>);
if return <> 6 then
monitor_error(44,head,return,true);
end;
end udvidelse;
end flytning af område
else
segm_pointer:= entry_tab(entryused,1);
entryused:= entryused + 1;
end extensionløkke;
<* entrytabellen må sorteres igen *>
quicksort(entrytab,totalused,3,1);
end newsize > head.first_areasegm;
if extension_ok then
begin
<* det markeres at entry-kataloget er under udvidelse *>
if packcat_extension then
begin
newposition(packcat,0,packcat_updated,packcat_leftblock);
head.extend_mark:= 1;
setposition(head,0,0);
swoprec6(head,512);
end;
<* de nye katalogsegmenter nulstilles *>
if new_first_areasegm > head.first_areasegm then
begin
gapcat_updated:= false;
setposition(gapcat,0,head.gapcat_adr);
outrec6(gapcat,512);
for i:= 1 step 1 until 128 do
gapcat(i):= real <::>;
for i:= head.gapcat_adr + 1 step 1 until new_first_areasegm - 1 do
outrec6(gapcat,512);
setposition(gapcat,0,0);
head.no_of_gaps:= head.no_of_gapsegm:= 0;
set_packtail(head,packtail,2);
end;
head.gapcat_adr := newgapcat_adr;
head.first_areasegm:= new_first_areasegm;
head.gap_entries := dim_gapentries ;
<* der beregnes ny nøgler til hashtabellen *>
if packcat_extension then
begin
head.pack_entries := dim_packentries;
head.hashtable_size:= compute_hashtable_size(head.packentries);
newposition(packcat,1,packcat_updated,packcat_leftblock);
for entryno:=1 step 1 until head.packentries do
begin
nextrecord(packcat,head.entrylength,packcat_updated,packcat_leftblock);
if packcat.key <> 0 then
begin
packcat.hashkey:= compute_hashkey(packcat.entryname,packcat.password);
packcat_updated:= true;
end;
end;
newposition(packcat,0,packcat_updated,packcat_leftblock);
head.extend_mark:= 0;
setposition(head,0,0);
swoprec6(head,512);
end nye hashnøgler;
end;
end udvidelse af kataloger;
<* for at undgå fejl nulstilles hulkataloget indledningsvis *>
if -,packcat_extension then
begin
gapcat_updated:= false;
setposition(gapcat,0,head.gapcat_adr);
outrec6(gapcat,512);
for i:= 1 step 1 until 128 do
gapcat(i):= real <::>;
for i:= head.gapcat_adr + 1 step 1 until head.first_areasegm - 1 do
outrec6(gapcat,512);
setposition(gapcat,0,0);
head.no_of_gaps := 0;
head.no_of_gapsegm:= 0;
set_packtail(head,packtail,2);
end nulstilling;
<* nu er hulkataloget ude af spillet *>
entryused:= 0;
<* entries uden areal overspringes *>
repeat entryused:= entryused + 1;
until entryused = head.no_of_entries
or entry_tab(entryused,1) <> 0;
<* nu kan repack begynde *>
segm_pointer:= head.first_areasegm;
while entryused <= head.no_of_entries do
begin
<*+1*>
if test shift(-2) then
write(out,<:<10>repack, entryuse, storeadr, recordno, size, segmpoint<10>:>,
_ "sp",6,<< dddddd>,entryused,entry_tab(entryused,1),entry_tab(entryused,2),
_ entry_tab(entryused,3),segmpointer);
<*-1*>
if segm_pointer < entry_tab(entryused,1) then
begin
find_record(packcat,1,entry_tab(entryused,2),head.entrylength,
_ packcat_updated,packcat_leftblock);
<* direkte flytning *>
if packcat.areasize <= packcat.storeaddress - segm_pointer then
begin
movearea(packfile,segm_pointer,undefined,
_ packfile,packcat.storeaddress,undefined,
_ maxbufsegm,packcat.areasize);
print_entry(ud,packcat.entrybase_adr,intern_bases,undefined,ownerlist);
end
else
<* indirekte flytning *>
begin
set_securityfile(packcat.entry_baseadr);
movearea(security_file,0,undefined,
_ packfile,packcat.storeaddress,undefined,
_ maxbufsegm,packcat.areasize);
print_entry(ud,packcat.entrybase_adr,intern_bases,undefined,ownerlist);
movearea(packfile,segm_pointer,undefined,
_ security_file,0,undefined,
_ maxbufsegm,packcat.areasize);
end;
<* opdatering af packentry *>
old_address := packcat.storeaddress;
packcat.storeaddress:= segm_pointer;
packcat_updated := true;
write(ud,"sp",5,<:repack ok:>);
if secu_tail(1) > 0 then cut_securityfile;
segm_pointer:= segm_pointer + packcat.areasize;
swop_cat(packcat,packcat_updated,gapcat,gapcat_updated);
end flyt areal
else
segm_pointer:= segm_pointer + entry_tab(entryused,3);
entryused:= entryused + 1;
end no_of_entries;
head.packfile_size:= segm_pointer;
set_packtail(head,pack_tail,0);
if head.extend_mark > 0 then
head.extend_mark := 0;
head.last_function:= 0;
if secu_tail(1) > -1 then
begin
i:= monitor(48)remove_entry:(secu,0,secu_tail);
if i <> 0 then
monitor_error(48,secu,i,false);
end;
end repack;
\f
procedure pointpack;
<******************>
<*
opretter entries, som peger på
de relevante områder i packfilen,
på baggrundslager ud fra oplysninger i
packfilens katalog med scope = temp
hvis newscope ikke er angivet.
hvis changekit er angivet oprettes på
det navngivne baggrundslager dokument
*>
begin
long array
_ name(1:2);
integer array
_ saveentry(1:head.entrylength//2);
integer
_ create_result,
_ ix,
_ fileno,
_ nextname_adr;
boolean
_ ok,
_ found;
procedure create;
<***************>
begin
tofrom(saveentry,packcat.entrybase_adr,head.entrylength);
if saveentry.storeaddress > 0 then
begin
saveentry.entrytail(3):= saveentry.storeaddress;
for ix:=2, 4, 5 do
saveentry.entrytail(ix):= 0;
for ix:=1,2 do
saveentry.auxdocname(ix):= saveentry.documentname(ix);
for ix:=1, 2 do
saveentry.documentname(ix):= packfile(ix);
saveentry.areasize:= 1 shift 23 add 4; <* mode = 0, kind = 4 *>
create_result:= create_entry(saveentry,newkit,process_bases,newscope);
if create_result >= 0 then
begin
print_entry(ud,packcat.entrybase_adr,intern_bases,scope,normlist);
if create_result = 1 then
write(ud,"sp",5,<:*** temp, no login resources:>);
<* statistikkerne opdateres *>
if -,system_packfile then
begin
packcat.no_of_point:= packcat.no_of_point + 1;
packcat.lastaccess_date:= date;
packcat_updated:= true;
end;
end
else
begin
print_entry(ud,packcat.entrybase_adr,intern_bases,scope,normlist);
write(ud,"sp",5,case abs create_result of (
_ <:*** no resources:>,<:*** name conflict:>));
end;
end
else
begin
print_entry(ud,packcat.entrybase_adr,intern_bases,scope,normlist);
write(ud,"sp",5,<:*** not area entry:>);
end;
end create;
print_heading(ud,normlist);
nextname_adr:= 0;
for fileno:=1 step 1 until no_of_files do
begin
scope:= get_nextentryspec(name,nextname_adr);
found:=
if scope = undefined then
lookup_tableentry(packcat,name,ownerid,intern_bases,scope)
else
search_tableentry(packcat,name,ownerid,intern_bases,scope);
if found then create
else lookup_error(ud,name,scope,false,1);
end;
if scopeboo or no_of_subtext > 0 then
begin
while next_packentry(packcat,intern_bases,optionlist.subtext_adr,ownerid,scope)
do if packcat.storeaddress > 0 then create;
end;
end pointpack;
\f
procedure purgepack;
<******************>
<*
sletter alle entries
i packfilen, uanset
nøglekriterier, såfremt
de er ældre end <lastdate>
*>
begin
print_heading(ud,ownerlist);
purge(packcat,gapcat,lastdate,deletetype,true);
end purgepack;
\f
procedure convertpack;
write(out,<:<10>*** convertpack not implemented !:>);
\f
<* erklæring af buffere og hjælpezoner *>
zone
_ myself(1,1,stderror), <* egen process, ændring af katalogbase *>
_ packcat(128,1,testblok), <* til packfilens entry katalog *>
_ gapcat(if gapcat_used then 128 else 1,
_ 1,testblok); <* til packfilens hulkatalog *>
<*+2*>
integer array
_ transfer_table(1:blocktable_size,1:3); <* til test af bloktransporter *>
<*-2*>
boolean array
_ hashtable(1:if hashing_used then <* primær hashtabel til søgning *>
_ head.hashtable_size else 1),
_ linktable(1:if hashing_used then <* linker entries med samme hashnøgle *>
_ head.packentries else 1);
integer
_ packcat_leftblock, <* gemmer resterende bytes i akt. blok *>
_ gapcat_leftblock, <* do *>
_ hashkey_computed, <* gemmer allerede beregnet hashnøgle *>
_ status, <* statusord til test af transporter *>
_ count, <* hjælpevariabel *>
_ help; <* hjælpevariabel *>
boolean
_ exit, <* styrevariabel ved fejlafvikling *>
_ packcat_updated, <* angiver om packcat blok er opdateret *>
_ gapcat_updated; <* angiver om gapcat blok er opdateret *>
<*+2*>
<* testvariable *>
integer
_ bloktransfer,
_ datatransfer,
_ segmtransfer;
bloktransfer:=
datatransfer:=
segmtransfer:= 0;
<*-2*>
\f
<* intialisering af styrevariable *>
exit :=
packcat_updated:=
gapcat_updated := false;
\f
<* h o v e d p r o g r a m *>
<* bestemmelse af maksimale bufferlængde for flytning af arealer *>
begin
real array ra(1:2);
max_bufsegm := (system(2,0,ra) - 5000) // 512;
if max_bufsegm <= 0 then max_bufsegm := 1 ;
<*+2*>
if test shift(-3) then
write(out,"nl",2,<:free core for main programrun =:>,system(2,0,ra),
_ "nl",2,<:max. buffer segments =:>,max_bufsegm);
<*-2*>
end;
<*+2*>
if test shift(-3) then
status:=1 shift 1 else
<*-2*>
status:=0;
<*+2*>
if test shift(-3) then
for count:=1 step 1 until head.first_areasegm - 1 do
for help :=1, 2, 3 do
transfer_table(count,help):= 0;
<*-2*>
<* der åbnes til katalogerne *>
open(myself,0,<::>,0);
open(packcat,4,packfile,status);
if gapcat_used then
open(gapcat,4,packfile,status);
<* nu kan den egentlige afvikling begynde *>
if -,current_output
then connect(ud,outfile,1);
write(ud,"nl",1,programname,<:, packfile = :>,packfile,<:, :>);
print_date(ud,packtail(6));
if ownerid(1) <> empty
then write(ud,<:<10>owner.:>,ownerid);
if newscope <> undefined
then write(ud,<:<10>newscope.:>, case newscope + 1 of
_ (<:temp:>,<:login:>,<:user:>,<:project:>));
if newkit(1) <> empty then
write(ud,<:<10>changekit.:>,newkit);
if viewbase_set then
write(ud,<:<10>base.:>,<<d>,viewbases(1),<:.:>,viewbases(2));
if remove then write(ud,<:<10>remove.yes:>);
<* owner skal angives ved public packfile *>
if packfile(1) = long <:publi:> add 'c' and packfile(2) = long <:pack:>
and ownerid(1) = empty
and -,allowner
and -,allpackfile
and program_function <> repacksym
and program_function <> purgepacksym
then
break(<:*** on publicpack owner must be specified:>,0,true);
<* det testes om packfilen har været udsat for ukorrekt afslutning *>
if head.extend_mark = 1 then
recompute_hashkeys(true);
if head.update_mark = 0 then
head.update_mark:= if check_packfile_head(head,packtail) then 1 else 0
else
check_packfile_head(head,packtail);
if head.update_mark = 1 then
head.update_mark:= if check_catalogs(head,packtail) then 1 else 0;
if program_function <> searchpacksym then
begin
if head.update_mark = 0 and -,system_packfile then
begin
if head.last_function <> repacksym then <* repack sætter selv last_function til 0 ! *>
head.last_function := program_function;
head.update_mark := 1;
setposition(head,0,0);
swoprec6(head,512);
end
else
if head.update_mark = 1 then
break(<:*** contents of packfile not ok - please consult users manual !:>,0,true);
end;
<* det undersøges om en evt. tidligere repack ikke er afsluttet *>
if head.last_function = repacksym
and program_function <> repacksym
and program_function <> searchpacksym
then break(<:*** previous repack not finished - must be run again !:>,0,true);
trap(abort);
if hashing_used
then initialize_hashtables(packcat);
<* automatisk sletning af entries *>
if program_function = repacksym
and dim_retention > 0
then head.retentiondays:= dim_retention;
if head.retentiondays < maxint and head.lastupdate < date and gapcat_used then
begin
purge(packcat,gapcat,compute_last_date(date,head.retentiondays),3,false);
head.lastupdate:= date;
end;
empty_out(out); <* generede udskrifter afsendes *>
if -,current_output then outchar(ud,'nl');
case program_function of
begin
pack;
unpack;
searchpack;
clearpack;
repack;
pointpack;
purgepack;
convertpack;
end case program_function;
if (program_function = packsym
or program_function = clearpacksym
or program_function = purgepacksym)
and head.no_of_gaps > 0
then reorganize_gapcat(gapcat);
if head.update_mark = 1
and program_function <> searchpacksym
then head.update_mark:= 0;
if false then
abort:
begin
exit:= true;
if alarmcause extract 24 <> -9
and trapmode <> -1
then
begin
<*+2*>
test:= test shift(-1) shift 1 add 1;
<*-2*>
write(out,"nl",3,
_ <:----------------------------------------------------<10>:>,
_ <:! *** program funktionsfejl - bør fejlmeldes !!! !<10>:>,
_ <:! - Henvendelse til systemvedligeholdelses !<10>:>,
_ <:! - personalet på Handelshøjskolens Datacenter. !<10>:>,
_ <:! - Vedlæg denne udskrift - på forhånd tak ! !<10>:>,
_ <:----------------------------------------------------<10>:>);
end;
trapmode:= 0;
check_transfer(packcat,packcat_updated);
if gapcat_used then
check_transfer(gapcat,gapcat_used);
if program_function = packsym
or program_function = repacksym then
set_packtail(head,packtail,0);
end;
close(head,true);
newposition(packcat,0,packcat_updated,packcat_leftblock);
close(packcat,true);
if gapcat_used then
begin
newposition(gapcat,0,gapcat_updated,gapcat_leftblock);
close(gapcat,true);
end;
trap(0);
if exit then
write(out,"nl",2,<:*** run abort, packfile was closed correctly:>,"nl",1);
write(ud,"nl",2,programname,<: end:>,"nl",1);
if convert or -,current_output then
outchar(ud,'em');
if -,current_output then
close(ud,true);
if convert then
print_area(ud,0);
<*+2*>
if test shift(-5) then
begin
cputime:= systime(1,timebase,realtime) - cputime;
write(out,"nl",2,<<ddddd.dd>,<:cputime =:>,cputime,
_ <:, realtime =:>,realtime);
end;
if test then
begin
open(head,4,packfile,0);
open(packcat,4,packfile,0);
print_packhead(head);
if hashing_used then print_tables;
print_packcat_(packcat);
print_gapcat__(packcat);
close(head,true);
close(packcat,true);
end;
if test shift(-3) then
begin
write(out,"ff",1,"nl",2,<:bloktransporter til/fra kataloger:>,"nl",2);
write(out,<:segmno inrec6 outrec6 swoprec6<10>:>);
for count:=1 step 1 until blocktable_size do
begin
write(out,"nl",1,<<dddddd>,count);
for help:=1, 2, 3 do
write(out,<<ddddddddd>,transfer_table(count,help));
end;
write(out,"nl",2,
_ <:<10>transporter af katalogsegmenter =:>,bloktransfer,
_ <:<10>transporter af datablokke =:>,datatransfer,
_ <:<10>transporter af datasegmenter =:>,segmtransfer);
end;
<*-2*>
end procedure main;
\f
zone
_ pack_head(128,1,stderror); <* indeholder packfilens hovede (segmno. 0 *>
long array
_ optionlist(1:maxindex); <* indeholder den indlæste parameterliste *>
integer
_ blocktable_size,
_ count;
\f
<* her starter den egentlige programafvikling *>
<* ========================================== *>
<* dato beregnes *>
cputime:= systime(1,0.0,timebase);
date := systime(4,timebase,0.0);
<* programkaldet læses, parameterlisten testes og analyseres *>
read_program_call;
<* baserne for den aktuelle kørende process bestemmes *>
system(11,0,process_bases);
system(11,0,intern_bases);
<* std. baser og katalog baser lægges på min. user base *>
if intern_bases(3) > intern_bases(5) then
begin
intern_bases(4):= intern_bases(4) - (intern_bases(3) - intern_bases(5));
intern_bases(3):= intern_bases(5);
end;
if intern_bases(1) > intern_bases(5) then
begin
intern_bases(2):= intern_bases(2) - (intern_bases(1) - intern_bases(5));
intern_bases(1):= intern_bases(5);
end;
if viewbase_set then
for count:= 3, 5, 7 do
begin
intern_bases(count) := viewbases(1);
intern_bases(count + 1) := viewbases(2);
end;
lower_catbase:= process_bases(1);
upper_catbase:= process_bases(2);
<*+1*>
if test shift(-2) then
write(out,<:<10><10>intern process bases:<10>:>,
_ <:<10>std. bases::>,<< -ddddddd>,intern_bases(3),intern_bases(4),
_ <:<10>user bases::>,intern_bases(5),intern_bases(6),
_ <:<10>max. bases::>,intern_bases(7),intern_bases(8));
<*-1*>
<* test af ressourcer *>
ressource_check(<* size *> 16384, <* buf *> 2, <* area *> 4);
<* der åbnes til packfilen, ved pack oprettes denne evt. *>
initialize_packfile_head(pack_head);
<*
nu afvikles hovedprogrammet og proceduren main
kaldes afhængig af om kørselsoversigten ønskes
på current output eller specificeret medium
*>
<*+2*>
if test shift(-3) then
blocktable_size:= packhead.first_areasegm - 1 else
<*-2*>
blocktable_size:= 1;
if current_output
then main(out,pack_head)
else
begin
zone overs(128,1,stderror);
main(overs,pack_head);
end;
end global programblok;
end
▶EOF◀