define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / tools / adflib / adf_salv.c
blob9580005e419126886f61c99ddf2efc840aa579ba
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_salv.c
6 */
8 #include<string.h>
9 #include<stdlib.h>
11 #include "adf_salv.h"
12 #include "adf_bitm.h"
13 #include "adf_util.h"
14 #include "adf_disk.h"
15 #include "adf_dir.h"
16 #include "adf_file.h"
17 #include "adf_cache.h"
19 extern struct Env adfEnv;
22 * adfFreeGenBlock
25 void adfFreeGenBlock(struct GenBlock* block)
27 if (block->name!=NULL)
28 free(block->name);
33 * adfFreeDelList
36 void adfFreeDelList(struct List* list)
38 struct List *cell;
40 cell = list;
41 while(cell!=NULL) {
42 adfFreeGenBlock((struct GenBlock*)cell->content);
43 cell = cell->next;
45 freeList(list);
50 * adfGetDelEnt
53 struct List* adfGetDelEnt(struct Volume *vol)
55 struct GenBlock *block;
56 long i;
57 struct List *list, *head;
58 BOOL delEnt;
60 list = head = NULL;
61 block = NULL;
62 delEnt = TRUE;
63 for(i=vol->firstBlock; i<=vol->lastBlock; i++) {
64 if (adfIsBlockFree(vol, i)) {
65 if (delEnt) {
66 block = (struct GenBlock*)malloc(sizeof(struct GenBlock));
67 if (!block) return NULL;
68 //printf("%p\n",block);
71 adfReadGenBlock(vol, i, block);
73 delEnt = (block->type==T_HEADER
74 && (block->secType==ST_DIR || block->secType==ST_FILE) );
76 if (delEnt) {
77 if (head==NULL)
78 list = head = newCell(NULL, (void*)block);
79 else
80 list = newCell(list, (void*)block);
85 if (block!=NULL && list!=NULL && block!=list->content) {
86 free(block);
87 // printf("%p\n",block);
89 return head;
94 * adfReadGenBlock
97 RETCODE adfReadGenBlock(struct Volume *vol, SECTNUM nSect, struct GenBlock *block)
99 unsigned char buf[LOGICAL_BLOCK_SIZE];
100 int len;
101 char name[MAXNAMELEN+1];
103 if (adfReadBlock(vol, nSect, buf)!=RC_OK)
104 return RC_ERROR;
106 block->type =(int) swapLong(buf);
107 block->secType =(int) swapLong(buf+vol->blockSize-4);
108 block->sect = nSect;
109 block->name = NULL;
111 if (block->type==T_HEADER) {
112 switch(block->secType) {
113 case ST_FILE:
114 case ST_DIR:
115 case ST_LFILE:
116 case ST_LDIR:
117 len = min(MAXNAMELEN, buf[vol->blockSize-80]);
118 strncpy(name, buf+vol->blockSize-79, len);
119 name[len] = '\0';
120 block->name = strdup(name);
121 block->parent = swapLong(buf+vol->blockSize-12);
122 break;
123 case ST_ROOT:
124 break;
125 default:
129 return RC_OK;
134 * adfCheckParent
137 RETCODE adfCheckParent(struct Volume* vol, SECTNUM pSect)
139 struct GenBlock block;
141 if (adfIsBlockFree(vol, pSect)) {
142 (*adfEnv.wFct)("adfCheckParent : parent doesn't exists");
143 return RC_ERROR;
146 /* verify if parent is a DIR or ROOT */
147 adfReadGenBlock(vol, pSect, &block);
148 if ( block.type!=T_HEADER
149 || (block.secType!=ST_DIR && block.secType!=ST_ROOT) ) {
150 (*adfEnv.wFct)("adfCheckParent : parent secType is incorrect");
151 return RC_ERROR;
154 return RC_OK;
159 * adfUndelDir
162 RETCODE adfUndelDir(struct Volume* vol, SECTNUM pSect, SECTNUM nSect,
163 struct bDirBlock* entry)
165 RETCODE rc;
166 struct bEntryBlock parent;
167 char name[MAXNAMELEN+1];
169 /* check if the given parent sector pointer seems OK */
170 if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
171 return rc;
173 if (pSect!=entry->parent) {
174 (*adfEnv.wFct)("adfUndelDir : the given parent sector isn't the entry parent");
175 return RC_ERROR;
178 if (!adfIsBlockFree(vol, entry->headerKey))
179 return RC_ERROR;
180 if (isDIRCACHE(vol->dosType) && !adfIsBlockFree(vol,entry->extension))
181 return RC_ERROR;
183 if (adfReadEntryBlock(vol, pSect, &parent)!=RC_OK)
184 return RC_ERROR;
186 strncpy(name, entry->dirName, entry->nameLen);
187 name[(int)entry->nameLen] = '\0';
188 /* insert the entry in the parent hashTable, with the headerKey sector pointer */
189 adfSetBlockUsed(vol,entry->headerKey);
190 adfCreateEntry(vol, &parent, name, entry->headerKey);
192 if (isDIRCACHE(vol->dosType)) {
193 adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
194 adfSetBlockUsed(vol,entry->extension);
197 adfUpdateBitmap(vol);
199 return RC_OK;
204 * adfUndelFile
207 RETCODE adfUndelFile(struct Volume* vol, SECTNUM pSect, SECTNUM nSect, struct bFileHeaderBlock* entry)
209 long i;
210 char name[MAXNAMELEN+1];
211 struct bEntryBlock parent;
212 RETCODE rc;
213 struct FileBlocks fileBlocks;
215 /* check if the given parent sector pointer seems OK */
216 if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
217 return rc;
219 if (pSect!=entry->parent) {
220 (*adfEnv.wFct)("adfUndelFile : the given parent sector isn't the entry parent");
221 return RC_ERROR;
224 adfGetFileBlocks(vol, entry, &fileBlocks);
226 for(i=0; i<fileBlocks.nbData; i++)
227 if ( !adfIsBlockFree(vol,fileBlocks.data[i]) )
228 return RC_ERROR;
229 else
230 adfSetBlockUsed(vol, fileBlocks.data[i]);
231 for(i=0; i<fileBlocks.nbExtens; i++)
232 if ( !adfIsBlockFree(vol,fileBlocks.extens[i]) )
233 return RC_ERROR;
234 else
235 adfSetBlockUsed(vol, fileBlocks.extens[i]);
237 free(fileBlocks.data);
238 free(fileBlocks.extens);
240 if (adfReadEntryBlock(vol, pSect, &parent)!=RC_OK)
241 return RC_ERROR;
243 strncpy(name, entry->fileName, entry->nameLen);
244 name[(int)entry->nameLen] = '\0';
245 /* insert the entry in the parent hashTable, with the headerKey sector pointer */
246 adfCreateEntry(vol, &parent, name, entry->headerKey);
248 if (isDIRCACHE(vol->dosType))
249 adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
251 adfUpdateBitmap(vol);
253 return RC_OK;
258 * adfUndelEntry
261 RETCODE adfUndelEntry(struct Volume* vol, SECTNUM parent, SECTNUM nSect)
263 struct bEntryBlock entry;
265 adfReadEntryBlock(vol,nSect,&entry);
267 switch(entry.secType) {
268 case ST_FILE:
269 adfUndelFile(vol, parent, nSect, (struct bFileHeaderBlock*)&entry);
270 break;
271 case ST_DIR:
272 adfUndelDir(vol, parent, nSect, (struct bDirBlock*)&entry);
273 break;
274 default:
278 return RC_OK;
283 * adfCheckFile
286 RETCODE adfCheckFile(struct Volume* vol, SECTNUM nSect,
287 struct bFileHeaderBlock* file, int level)
289 struct bFileExtBlock extBlock;
290 struct bOFSDataBlock dataBlock;
291 struct FileBlocks fileBlocks;
292 int n;
294 adfGetFileBlocks(vol,file,&fileBlocks);
295 //printf("data %ld ext %ld\n",fileBlocks.nbData,fileBlocks.nbExtens);
296 if (isOFS(vol->dosType)) {
297 /* checks OFS datablocks */
298 for(n=0; n<fileBlocks.nbData; n++) {
299 //printf("%ld\n",fileBlocks.data[n]);
300 adfReadDataBlock(vol,fileBlocks.data[n],&dataBlock);
301 if (dataBlock.headerKey!=fileBlocks.header)
302 (*adfEnv.wFct)("adfCheckFile : headerKey incorrect");
303 if (dataBlock.seqNum!=n+1)
304 (*adfEnv.wFct)("adfCheckFile : seqNum incorrect");
305 if (n<fileBlocks.nbData-1) {
306 if (dataBlock.nextData!=fileBlocks.data[n+1])
307 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
308 if (dataBlock.dataSize!=vol->datablockSize)
309 (*adfEnv.wFct)("adfCheckFile : dataSize incorrect");
311 else { /* last datablock */
312 if (dataBlock.nextData!=0)
313 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
317 for(n=0; n<fileBlocks.nbExtens; n++) {
318 adfReadFileExtBlock(vol,fileBlocks.extens[n],&extBlock);
319 if (extBlock.parent!=file->headerKey)
320 (*adfEnv.wFct)("adfCheckFile : extBlock parent incorrect");
321 if (n<fileBlocks.nbExtens-1) {
322 if (extBlock.extension!=fileBlocks.extens[n+1])
323 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
325 else
326 if (extBlock.extension!=0)
327 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
330 free(fileBlocks.data);
331 free(fileBlocks.extens);
333 return RC_OK;
338 * adfCheckDir
341 RETCODE adfCheckDir(struct Volume* vol, SECTNUM nSect, struct bDirBlock* dir,
342 int level)
348 return RC_OK;
353 * adfCheckEntry
356 RETCODE adfCheckEntry(struct Volume* vol, SECTNUM nSect, int level)
358 struct bEntryBlock entry;
359 RETCODE rc;
361 adfReadEntryBlock(vol,nSect,&entry);
363 switch(entry.secType) {
364 case ST_FILE:
365 rc = adfCheckFile(vol, nSect, (struct bFileHeaderBlock*)&entry, level);
366 break;
367 case ST_DIR:
368 rc = adfCheckDir(vol, nSect, (struct bDirBlock*)&entry, level);
369 break;
370 default:
371 printf("adfCheckEntry : not supported\n");
372 rc = RC_ERROR;
375 return rc;
379 /*#############################################################################*/