summaryrefslogtreecommitdiff
path: root/app/baisy/2.2.1-schulis/src/dir.dos
blob: fd348a1eb9fa0d55623f3358e327eaa8da75a64e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
PACKET dirDEFINES opendir,insertdirentry,deletedirentry,initdirds,fileinfo,
formatdir,dirlist,fileexists,subdirexists,allfiles,allsubdirs:LET 
maxdirentrys=1000;INITFLAG VAR dirblockdsused:=FALSE ;DATASPACE VAR 
dirblockds;BOUND STRUCT (ALIGN dummy,ROW 64REAL daten)VAR dirblock;REAL VAR 
lastreaddirblockno;PROC initdirblockio:lastreaddirblockno:=-1.0;IF NOT 
initialized(dirblockdsused)THEN dirblockds:=nilspace;dirblock:=dirblockdsFI .
END PROC initdirblockio;PROC readdirblock(REAL CONST blocknr):IF 
lastreaddirblockno<>blocknrTHEN lastreaddirblockno:=-1.0;
readdiskblockandcloseworkiferror(dirblockds,2,blocknr);lastreaddirblockno:=
blocknrFI .END PROC readdirblock;PROC writedirblock(REAL CONST blocknr):
writediskblockandcloseworkiferror(dirblockds,2,blocknr);lastreaddirblockno:=
blocknr.END PROC writedirblock;PROC writedirblock:IF lastreaddirblockno<0.0
THEN errorstop("Lesefehler")FI ;writedirblock(lastreaddirblockno)END PROC 
writedirblock;PROC getdirentry(TEXT VAR entrybuffer,INT CONST blockentryno):
entrybuffer:=32*".";INT CONST replaceoffset:=4*blockentryno;replace(
entrybuffer,1,dirblock.daten[replaceoffset+1]);replace(entrybuffer,2,dirblock
.daten[replaceoffset+2]);replace(entrybuffer,3,dirblock.daten[replaceoffset+3
]);replace(entrybuffer,4,dirblock.daten[replaceoffset+4]).END PROC 
getdirentry;PROC putdirentry(TEXT CONST entrybuffer,INT CONST blockentryno):
INT CONST offset:=4*blockentryno;dirblock.daten[offset+1]:=entrybufferRSUB 1;
dirblock.daten[offset+2]:=entrybufferRSUB 2;dirblock.daten[offset+3]:=
entrybufferRSUB 3;dirblock.daten[offset+4]:=entrybufferRSUB 4.END PROC 
putdirentry;LET DIRPOS =REAL ;DIRPOS PROC dirpos(REAL CONST blocknr,INT 
CONST entrynr):blocknr*16.0+real(entrynr).END PROC dirpos;REAL PROC blockno(
DIRPOS CONST p):floor(p/16.0)END PROC blockno;INT PROC entryno(DIRPOS CONST p
):int(pMOD 16.0)END PROC entryno;PROC incr(DIRPOS VAR p):pINCR 1.0.END PROC 
incr;LET FREELIST =STRUCT (ROW maxdirentrysDIRPOS stack,INT stacktop,DIRPOS 
beginoffreearea,endofdir,REAL dirroot);PROC initfreelist(FREELIST VAR flist,
REAL CONST root):flist.stacktop:=0;flist.beginoffreearea:=dirpos(9.0e99,0);
flist.endofdir:=dirpos(-1.0,0);flist.dirroot:=root.END PROC initfreelist;
PROC store(FREELIST VAR flist,DIRPOS CONST freepos):flist.stacktopINCR 1;
flist.stack[flist.stacktop]:=freepos.END PROC store;PROC storebeginoffreearea
(FREELIST VAR flist,DIRPOS CONST begin):flist.beginoffreearea:=beginEND PROC 
storebeginoffreearea;PROC storeendofdir(FREELIST VAR flist,DIRPOS CONST end):
flist.endofdir:=endEND PROC storeendofdir;DIRPOS PROC freedirpos(FREELIST 
VAR flist):enablestop;DIRPOS VAR result;IF flist.stacktop>0THEN popELIF NOT 
freeareaemptyTHEN firstoffreeareaELIF expansionallowededTHEN 
allocatenewdircluster;result:=freedirpos(flist)ELSE errorstop(
"Directory voll")FI ;result.pop:result:=flist.stack[flist.stacktop];flist.
stacktopDECR 1.freeareaempty:flist.beginoffreearea>flist.endofdir.
firstoffreearea:result:=flist.beginoffreearea;incr(flist.beginoffreearea).
expansionalloweded:flist.dirroot>=2.0.allocatenewdircluster:REAL CONST 
newdircluster:=availablefatentry;REAL VAR lastentryno;
searchlastentrynooffatchain;fatentry(newdircluster,lastfatchainentry);
fatentry(lastentryno,newdircluster);writefat;storebeginoffreearea(flist,
dirpos(firstnewblock,0));storeendofdir(flist,dirpos(lastnewblock,15));
initnewdircluster.searchlastentrynooffatchain:lastentryno:=flist.dirroot;
WHILE NOT islastfatchainentry(fatentry(lastentryno))REP lastentryno:=fatentry
(lastentryno)PER .firstnewblock:beginofcluster(newdircluster).lastnewblock:
beginofcluster(newdircluster)+real(sectorspercluster-1).initnewdircluster:
TEXT CONST emptydirentry:=32*"�";INT VAR i;FOR iFROM 0UPTO 15REP putdirentry(
emptydirentry,i)PER ;disablestop;REAL VAR blockno:=firstnewblock;WHILE 
blockno<=lastnewblockREP writedirblock(blockno)PER .END PROC freedirpos;LET 
FILEENTRY =STRUCT (TEXT dateandtime,REAL size,firstcluster,DIRPOS dirpos),
FILELIST =STRUCT (THESAURUS thes,ROW maxdirentrysFILEENTRY entry);PROC 
initfilelist(FILELIST VAR flist):flist.thes:=emptythesaurus.END PROC 
initfilelist;PROC storefileentry(FILELIST VAR flist,TEXT CONST entrytext,
DIRPOS CONST position):INT VAR entryindex;insert(flist.thes,filename,
entryindex);storefileentry(flist.entry[entryindex],entrytext,position).
filename:TEXT CONST namepre:=compress(subtext(entrytext,1,8)),namepost:=
compress(subtext(entrytext,9,11));IF namepost<>""THEN namepre+"."+namepost
ELSE namepreFI .END PROC storefileentry;PROC storefileentry(FILEENTRY VAR 
fentry,TEXT CONST entrytext,DIRPOS CONST position):fentry.firstcluster:=real(
entrytextISUB 14);fentry.dateandtime:=dosdate+"  "+dostime;fentry.size:=dint(
entrytextISUB 15,entrytextISUB 16);fentry.dirpos:=position.dosdate:day+"."+
month+"."+year.day:text2(code(entrytextSUB 25)MOD 32).month:text2(code(
entrytextSUB 25)DIV 32+8*(code(entrytextSUB 26)MOD 2)).year:text(80+code(
entrytextSUB 26)DIV 2,2).dostime:hour+":"+minute.hour:text2(code(entrytext
SUB 24)DIV 8).minute:text2(code(entrytextSUB 23)DIV 32+8*(code(entrytextSUB 
24)MOD 8)).END PROC storefileentry;TEXT PROC text2(INT CONST intvalue):IF 
intvalue<10THEN "0"+text(intvalue)ELSE text(intvalue)FI .END PROC text2;
DIRPOS PROC fileentrypos(FILELIST CONST flist,TEXT CONST filename):INT CONST 
linkindex:=link(flist.thes,filename);IF linkindex=0THEN errorstop(
"Die Datei """+filename+""" gibt es nicht")FI ;flist.entry[linkindex].dirpos.
END PROC fileentrypos;PROC delete(FILELIST VAR flist,TEXT CONST filename):
INT VAR dummy;delete(flist.thes,filename,dummy).END PROC delete;PROC fileinfo
(FILELIST CONST flist,TEXT CONST filename,REAL VAR firstclusterno,storage):
INT CONST linkindex:=link(flist.thes,filename);IF linkindex=0THEN errorstop(
"Die Datei """+filename+""" gibt es nicht")FI ;firstclusterno:=flist.entry[
linkindex].firstcluster;storage:=flist.entry[linkindex].sizeEND PROC fileinfo
;BOOL PROC contains(FILELIST VAR flist,TEXT CONST filename):flist.thes
CONTAINS filenameEND PROC contains;PROC list(FILE VAR f,FILELIST CONST flist)
:INT VAR index:=0;TEXT VAR name;get(flist.thes,name,index);WHILE index>0REP 
listfile;get(flist.thes,name,index)PER .listfile:write(f,centeredname);write(
f,"  ");write(f,text(flist.entry[index].size,11,0));write(f,
" Bytes belegt      ");write(f,flist.entry[index].dateandtime);write(f,
"  +++  ");write(f,text(flist.entry[index].firstcluster));line(f).
centeredname:INT VAR pointpos:=pos(name,".");IF pointpos>0THEN namepre+"."+
namepostELSE text(name,12)FI .namepre:text(subtext(name,1,pointpos-1),8).
namepost:text(subtext(name,pointpos+1,pointpos+4),3).END PROC list;LET 
DIRENTRY =REAL ,DIRLIST =STRUCT (THESAURUS thes,ROW maxdirentrysDIRENTRY 
entry);PROC initdirlist(DIRLIST VAR dlist):dlist.thes:=emptythesaurus.END 
PROC initdirlist;PROC storesubdirentry(DIRLIST VAR dlist,TEXT CONST entrytext
):INT VAR entryindex;insert(dlist.thes,subdirname,entryindex);dlist.entry[
entryindex]:=real(entrytextISUB 14).subdirname:TEXT CONST namepre:=compress(
subtext(entrytext,1,8)),namepost:=compress(subtext(entrytext,9,11));IF 
namepost<>""THEN namepre+"."+namepostELSE namepreFI .END PROC 
storesubdirentry;REAL PROC firstclusterofsubdir(DIRLIST CONST dlist,TEXT 
CONST name):INT CONST linkindex:=link(dlist.thes,name);IF linkindex=0THEN 
errorstop("Das Unterverzeichnis """+name+""" gibt es nicht")FI ;dlist.entry[
linkindex].END PROC firstclusterofsubdir;BOOL PROC contains(DIRLIST CONST 
dlist,TEXT CONST subdirname):dlist.thesCONTAINS subdirnameEND PROC contains;
PROC list(FILE VAR f,DIRLIST CONST dlist):INT VAR index:=0;TEXT VAR name;get(
dlist.thes,name,index);WHILE index>0REP listdir;get(dlist.thes,name,index)
PER .listdir:write(f,centeredname);write(f,"   <DIR>");write(f,"  +++  ");
write(f,text(dlist.entry[index]));line(f).centeredname:INT VAR pointpos:=pos(
name,".");IF pointpos>0THEN namepre+"."+namepostELSE text(name,12)FI .namepre
:text(subtext(name,1,pointpos-1),8).namepost:text(subtext(name,pointpos+1,
pointpos+4),3).END PROC list;LET DIR =BOUND STRUCT (FILELIST filelist,
DIRLIST dirlist,FREELIST freelist,TEXT path);DIR VAR dir;DATASPACE VAR dirds;
INITFLAG VAR dirdsused:=FALSE ;PROC opendir(TEXT CONST pathstring):
initdirblockio;initdirds;dir.path:=pathstring;loadmaindir;TEXT VAR restpath:=
pathstring;WHILE restpath<>""REP TEXT CONST subdirname:=nextsubdirname(
restpath);loadsubdirPER .loadmaindir:initfilelist(dir.filelist);initdirlist(
dir.dirlist);initfreelist(dir.freelist,0.0);storeendofdir(dir.freelist,dirpos
(lastmaindirsector,15));BOOL VAR waslastdirsector:=FALSE ;REAL VAR blockno:=
firstmaindirsector;INT VAR i;FOR iFROM 1UPTO dirsectorsREP loaddirblock(
blockno,waslastdirsector);blocknoINCR 1.0UNTIL waslastdirsectorPER .
firstmaindirsector:real(beginofdir).lastmaindirsector:real(beginofdir+
dirsectors-1).loadsubdir:REAL VAR clusterno:=firstclusterofsubdir(dir.dirlist
,subdirname);waslastdirsector:=FALSE ;initfilelist(dir.filelist);initdirlist(
dir.dirlist);initfreelist(dir.freelist,clusterno);WHILE NOT 
islastfatchainentry(clusterno)REP loadsubdirentrysofcluster;clusterno:=
fatentry(clusterno)UNTIL waslastdirsectorPER .loadsubdirentrysofcluster:
storeendofdir(dir.freelist,dirpos(lastblocknoofcluster,15));blockno:=
beginofcluster(clusterno);FOR iFROM 1UPTO sectorsperclusterREP loaddirblock(
blockno,waslastdirsector);blocknoINCR 1.0UNTIL waslastdirsectorPER .
lastblocknoofcluster:beginofcluster(clusterno)+real(sectorspercluster-1).END 
PROC opendir;PROC loaddirblock(REAL CONST blockno,BOOL VAR waslastblock):
waslastblock:=FALSE ;readdirblock(blockno);INT VAR entryno;TEXT VAR entry;
FOR entrynoFROM 0UPTO 15REP getdirentry(entry,entryno);processentryUNTIL 
waslastblockPER .processentry:SELECT pos("�.�",entrySUB 1)OF CASE 1:
endofdirsearchCASE 2:CASE 3:freeentryOTHERWISE 
volumelabelorfileentryorsubdirentryEND SELECT .endofdirsearch:waslastblock:=
TRUE ;storebeginoffreearea(dir.freelist,dirpos(blockno,entryno)).freeentry:
store(dir.freelist,dirpos(blockno,entryno)).
volumelabelorfileentryorsubdirentry:INT CONST byte11:=code(entrySUB 12);IF (
byte11AND 8)>0THEN ELIF (byte11AND 16)>0THEN subdirentryELSE fileentryFI .
subdirentry:storesubdirentry(dir.dirlist,entry).fileentry:storefileentry(dir.
filelist,entry,dirpos(blockno,entryno)).END PROC loaddirblock;TEXT PROC 
nextsubdirname(TEXT VAR pathstring):TEXT VAR subdirname;IF (pathstringSUB 1)
<>"\"THEN errorstop("ungültige Pfadbezeichnung")FI ;INT CONST backslashpos:=
pos(pathstring,"\",2);IF backslashpos=0THEN subdirname:=subtext(pathstring,2)
;pathstring:=""ELSE subdirname:=subtext(pathstring,2,backslashpos-1);
pathstring:=subtext(pathstring,backslashpos)FI ;dosname(subdirname,readmodus)
.END PROC nextsubdirname;PROC initdirds:IF initialized(dirdsused)THEN forget(
dirds)FI ;dirds:=nilspace;dir:=dirds.END PROC initdirds;PROC insertdirentry(
TEXT CONST name,REAL CONST startcluster,storage):DIRPOS CONST inspos:=
freedirpos(dir.freelist);TEXT CONST entrystring:=entryname+" "+(10*"�")+
dostime+dosdate+entrystartcluster+entrystorage;writeentryondisk;
writeentryindirds.entryname:INT CONST pointpos:=pos(name,".");IF pointpos>0
THEN subtext(name,1,pointpos-1)+(9-pointpos)*" "+subtext(name,pointpos+1)+(3-
LENGTH name+pointpos)*" "ELSE name+(11-LENGTH name)*" "FI .dostime:TEXT 
CONST akttime:=timeofday(clock(1));code((minuteMOD 8)*32)+code(8*hour+minute
DIV 8).hour:int(subtext(akttime,1,2)).minute:int(subtext(akttime,4,5)).
dosdate:TEXT CONST aktdate:=date(clock(1));code(32*(monthMOD 8)+day)+code((
year-80)*2+monthDIV 8).day:int(subtext(aktdate,1,2)).month:int(subtext(
aktdate,4,5)).year:int(subtext(aktdate,7,8)).entrystartcluster:TEXT VAR 
buffer2:="12";replace(buffer2,1,lowword(startcluster));buffer2.entrystorage:
TEXT VAR buffer4:="1234";replace(buffer4,1,lowword(storage));replace(buffer4,
2,highword(storage));buffer4.writeentryondisk:readdirblock(blockno(inspos));
putdirentry(entrystring,entryno(inspos));writedirblock.writeentryindirds:
storefileentry(dir.filelist,entrystring,inspos).END PROC insertdirentry;PROC 
deletedirentry(TEXT CONST name):TEXT VAR entry;DIRPOS CONST delpos:=
fileentrypos(dir.filelist,name);readdirblock(blockno(delpos));getdirentry(
entry,entryno(delpos));putdirentry("�"+subtext(entry,2,32),entryno(delpos));
writedirblock;delete(dir.filelist,name);store(dir.freelist,delpos).END PROC 
deletedirentry;PROC formatdir:initdirblockio;initdirds;buildemptydirblock;
REAL VAR blockno:=real(beginofdir);disablestop;FOR iFROM 1UPTO dirsectorsREP 
writedirblock(blockno);blocknoINCR 1.0PER ;enablestop;dir.path:="";
initfilelist(dir.filelist);initdirlist(dir.dirlist);initfreelist(dir.freelist
,0.0);storebeginoffreearea(dir.freelist,dirpos(real(beginofdir),0));
storeendofdir(dir.freelist,dirpos(lastmaindirsector,15)).buildemptydirblock:
INT VAR i;FOR iFROM 0UPTO 15REP putdirentry(32*"�",i)PER .lastmaindirsector:
real(beginofdir+dirsectors-1).END PROC formatdir;PROC fileinfo(TEXT CONST 
filename,REAL VAR startcluster,size):fileinfo(dir.filelist,filename,
startcluster,size)END PROC fileinfo;THESAURUS PROC allfiles:THESAURUS VAR t:=
dir.filelist.thes;tEND PROC allfiles;THESAURUS PROC allsubdirs:dir.dirlist.
thesEND PROC allsubdirs;BOOL PROC fileexists(TEXT CONST filename):contains(
dir.filelist,filename)END PROC fileexists;BOOL PROC subdirexists(TEXT CONST 
subdirname):contains(dir.dirlist,subdirname)END PROC subdirexists;PROC 
dirlist(DATASPACE VAR ds):openlistfile;headline(listfile,listfilehead);list(
listfile,dir.filelist);list(listfile,dir.dirlist).openlistfile:forget(ds);ds
:=nilspace;FILE VAR listfile:=sequentialfile(output,ds);putline(listfile,"").
listfilehead:"DOS"+pathstring.pathstring:IF dir.path<>""THEN "     PATH: "+
dir.pathELSE ""FI .END PROC dirlist;END PACKET dir;