Use CachePreDMA to flush data cache and obtain physical address of message to be...
[AROS.git] / tools / adflib / adf_salv.c
bloba36f6d70765bc0242e9cc2eee682e10236ad7ede
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_salv.c
6 */
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
12 #include "adf_salv.h"
13 #include "adf_bitm.h"
14 #include "adf_util.h"
15 #include "adf_disk.h"
16 #include "adf_dir.h"
17 #include "adf_file.h"
18 #include "adf_cache.h"
20 extern struct Env adfEnv;
23 * adfFreeGenBlock
26 void adfFreeGenBlock(struct GenBlock* block)
28 if (block->name!=NULL)
29 free(block->name);
34 * adfFreeDelList
37 void adfFreeDelList(struct List* list)
39 struct List *cell;
41 cell = list;
42 while(cell!=NULL) {
43 adfFreeGenBlock((struct GenBlock*)cell->content);
44 cell = cell->next;
46 freeList(list);
51 * adfGetDelEnt
54 struct List* adfGetDelEnt(struct Volume *vol)
56 struct GenBlock *block;
57 long i;
58 struct List *list, *head;
59 BOOL delEnt;
61 list = head = NULL;
62 block = NULL;
63 delEnt = TRUE;
64 for(i=0; i < vol->totalBlocks; i++) {
65 if (adfIsBlockFree(vol, i)) {
66 if (delEnt) {
67 block = (struct GenBlock*)malloc(sizeof(struct GenBlock));
68 if (!block) return NULL;
69 //printf("%p\n",block);
72 adfReadGenBlock(vol, i, block);
74 delEnt = (block->type==T_HEADER
75 && (block->secType==ST_DIR || block->secType==ST_FILE) );
77 if (delEnt) {
78 if (head==NULL)
79 list = head = newCell(NULL, (void*)block);
80 else
81 list = newCell(list, (void*)block);
86 if (block!=NULL && list!=NULL && block!=list->content) {
87 free(block);
88 // printf("%p\n",block);
90 return head;
95 * adfReadGenBlock
98 RETCODE adfReadGenBlock(struct Volume *vol, SECTNUM nSect, struct GenBlock *block)
100 unsigned char buf[LOGICAL_BLOCK_SIZE];
101 int len;
102 char name[MAXNAMELEN+1];
104 if (adfReadBlock(vol, nSect, buf)!=RC_OK)
105 return RC_ERROR;
107 block->type =(int) swapLong(buf);
108 block->secType =(int) swapLong(buf+vol->blockSize-4);
109 block->sect = nSect;
110 block->name = NULL;
112 if (block->type==T_HEADER) {
113 switch(block->secType) {
114 case ST_FILE:
115 case ST_DIR:
116 case ST_LFILE:
117 case ST_LDIR:
118 len = min(MAXNAMELEN, buf[vol->blockSize-80]);
119 strncpy(name, (char *)(buf+vol->blockSize-79), len);
120 name[len] = '\0';
121 block->name = strdup(name);
122 block->parent = swapLong(buf+vol->blockSize-12);
123 break;
124 case ST_ROOT:
125 break;
126 default:
130 return RC_OK;
135 * adfCheckParent
138 RETCODE adfCheckParent(struct Volume* vol, SECTNUM pSect)
140 struct GenBlock block;
142 if (adfIsBlockFree(vol, pSect)) {
143 (*adfEnv.wFct)("adfCheckParent : parent doesn't exists");
144 return RC_ERROR;
147 /* verify if parent is a DIR or ROOT */
148 adfReadGenBlock(vol, pSect, &block);
149 if ( block.type!=T_HEADER
150 || (block.secType!=ST_DIR && block.secType!=ST_ROOT) ) {
151 (*adfEnv.wFct)("adfCheckParent : parent secType is incorrect");
152 return RC_ERROR;
155 return RC_OK;
160 * adfUndelDir
163 RETCODE adfUndelDir(struct Volume* vol, SECTNUM pSect, SECTNUM nSect,
164 struct bDirBlock* entry)
166 RETCODE rc;
167 struct bEntryBlock parent;
168 char name[MAXNAMELEN+1];
170 /* check if the given parent sector pointer seems OK */
171 if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
172 return rc;
174 if (pSect!=entry->parent) {
175 (*adfEnv.wFct)("adfUndelDir : the given parent sector isn't the entry parent");
176 return RC_ERROR;
179 if (!adfIsBlockFree(vol, entry->headerKey))
180 return RC_ERROR;
181 if (isDIRCACHE(vol->dosType) && !adfIsBlockFree(vol,entry->extension))
182 return RC_ERROR;
184 if (adfReadEntryBlock(vol, pSect, &parent)!=RC_OK)
185 return RC_ERROR;
187 strncpy(name, entry->dirName, entry->nameLen);
188 name[(int)entry->nameLen] = '\0';
189 /* insert the entry in the parent hashTable, with the headerKey sector pointer */
190 adfSetBlockUsed(vol,entry->headerKey);
191 adfCreateEntry(vol, &parent, name, entry->headerKey);
193 if (isDIRCACHE(vol->dosType)) {
194 adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
195 adfSetBlockUsed(vol,entry->extension);
198 adfUpdateBitmap(vol);
200 return RC_OK;
205 * adfUndelFile
208 RETCODE adfUndelFile(struct Volume* vol, SECTNUM pSect, SECTNUM nSect, struct bFileHeaderBlock* entry)
210 long i;
211 char name[MAXNAMELEN+1];
212 struct bEntryBlock parent;
213 RETCODE rc;
214 struct FileBlocks fileBlocks;
216 /* check if the given parent sector pointer seems OK */
217 if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
218 return rc;
220 if (pSect!=entry->parent) {
221 (*adfEnv.wFct)("adfUndelFile : the given parent sector isn't the entry parent");
222 return RC_ERROR;
225 adfGetFileBlocks(vol, entry, &fileBlocks);
227 for(i=0; i<fileBlocks.nbData; i++)
228 if ( !adfIsBlockFree(vol,fileBlocks.data[i]) )
229 return RC_ERROR;
230 else
231 adfSetBlockUsed(vol, fileBlocks.data[i]);
232 for(i=0; i<fileBlocks.nbExtens; i++)
233 if ( !adfIsBlockFree(vol,fileBlocks.extens[i]) )
234 return RC_ERROR;
235 else
236 adfSetBlockUsed(vol, fileBlocks.extens[i]);
238 free(fileBlocks.data);
239 free(fileBlocks.extens);
241 if (adfReadEntryBlock(vol, pSect, &parent)!=RC_OK)
242 return RC_ERROR;
244 strncpy(name, entry->fileName, entry->nameLen);
245 name[(int)entry->nameLen] = '\0';
246 /* insert the entry in the parent hashTable, with the headerKey sector pointer */
247 adfCreateEntry(vol, &parent, name, entry->headerKey);
249 if (isDIRCACHE(vol->dosType))
250 adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
252 adfUpdateBitmap(vol);
254 return RC_OK;
259 * adfUndelEntry
262 RETCODE adfUndelEntry(struct Volume* vol, SECTNUM parent, SECTNUM nSect)
264 struct bEntryBlock entry;
266 adfReadEntryBlock(vol,nSect,&entry);
268 switch(entry.secType) {
269 case ST_FILE:
270 adfUndelFile(vol, parent, nSect, (struct bFileHeaderBlock*)&entry);
271 break;
272 case ST_DIR:
273 adfUndelDir(vol, parent, nSect, (struct bDirBlock*)&entry);
274 break;
275 default:
279 return RC_OK;
284 * adfCheckFile
287 RETCODE adfCheckFile(struct Volume* vol, SECTNUM nSect,
288 struct bFileHeaderBlock* file, int level)
290 struct bFileExtBlock extBlock;
291 struct bOFSDataBlock dataBlock;
292 struct FileBlocks fileBlocks;
293 int n;
295 adfGetFileBlocks(vol,file,&fileBlocks);
296 //printf("data %ld ext %ld\n",fileBlocks.nbData,fileBlocks.nbExtens);
297 if (isOFS(vol->dosType)) {
298 /* checks OFS datablocks */
299 for(n=0; n<fileBlocks.nbData; n++) {
300 //printf("%ld\n",fileBlocks.data[n]);
301 adfReadDataBlock(vol,fileBlocks.data[n],&dataBlock);
302 if (dataBlock.headerKey!=fileBlocks.header)
303 (*adfEnv.wFct)("adfCheckFile : headerKey incorrect");
304 if (dataBlock.seqNum!=n+1)
305 (*adfEnv.wFct)("adfCheckFile : seqNum incorrect");
306 if (n<fileBlocks.nbData-1) {
307 if (dataBlock.nextData!=fileBlocks.data[n+1])
308 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
309 if (dataBlock.dataSize!=vol->datablockSize)
310 (*adfEnv.wFct)("adfCheckFile : dataSize incorrect");
312 else { /* last datablock */
313 if (dataBlock.nextData!=0)
314 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
318 for(n=0; n<fileBlocks.nbExtens; n++) {
319 adfReadFileExtBlock(vol,fileBlocks.extens[n],&extBlock);
320 if (extBlock.parent!=file->headerKey)
321 (*adfEnv.wFct)("adfCheckFile : extBlock parent incorrect");
322 if (n<fileBlocks.nbExtens-1) {
323 if (extBlock.extension!=fileBlocks.extens[n+1])
324 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
326 else
327 if (extBlock.extension!=0)
328 (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
331 free(fileBlocks.data);
332 free(fileBlocks.extens);
334 return RC_OK;
339 * adfCheckDir
342 RETCODE adfCheckDir(struct Volume* vol, SECTNUM nSect, struct bDirBlock* dir,
343 int level)
349 return RC_OK;
354 * adfCheckEntry
357 RETCODE adfCheckEntry(struct Volume* vol, SECTNUM nSect, int level)
359 struct bEntryBlock entry;
360 RETCODE rc;
362 adfReadEntryBlock(vol,nSect,&entry);
364 switch(entry.secType) {
365 case ST_FILE:
366 rc = adfCheckFile(vol, nSect, (struct bFileHeaderBlock*)&entry, level);
367 break;
368 case ST_DIR:
369 rc = adfCheckDir(vol, nSect, (struct bDirBlock*)&entry, level);
370 break;
371 default:
372 printf("adfCheckEntry : not supported\n");
373 rc = RC_ERROR;
376 return rc;
380 /*#############################################################################*/