2 * ADF Library. (C) 1997-1999 Laurent Clevy
17 #include "defendian.h"
24 #include "adf_cache.h"
26 extern struct Env adfEnv
;
33 RETCODE
adfRenameEntry(struct Volume
*vol
, SECTNUM pSect
, char *oldName
,
34 SECTNUM nPSect
, char *newName
)
36 struct bEntryBlock parent
, previous
, entry
, nParent
;
37 SECTNUM nSect2
, nSect
, prevSect
, tmpSect
;
38 int hashValueO
, hashValueN
, len
;
39 char name2
[MAXNAMELEN
+1], name3
[MAXNAMELEN
+1];
43 if (strcmp(oldName
,newName
)==0)
46 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
47 len
= strlen(newName
);
48 myToUpper(name2
, newName
, len
, intl
);
49 myToUpper(name3
, oldName
, strlen(oldName
), intl
);
50 /* newName == oldName ? */
52 if (adfReadEntryBlock( vol
, pSect
, &parent
)!=RC_OK
)
55 hashValueO
= adfGetHashValue(oldName
, intl
);
57 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, oldName
, &entry
, &prevSect
);
59 (*adfEnv
.wFct
)("adfRenameEntry : existing entry not found");
63 /* change name and parent dir */
64 entry
.nameLen
= min(31, strlen(newName
));
65 memcpy(entry
.name
, newName
, entry
.nameLen
);
66 entry
.parent
= nPSect
;
67 tmpSect
= entry
.nextSameHash
;
69 entry
.nextSameHash
= 0;
70 if (adfWriteEntryBlock(vol
, nSect
, &entry
)!=RC_OK
)
73 /* del from the oldname list */
77 parent
.hashTable
[hashValueO
] = tmpSect
;
78 if (parent
.secType
==ST_ROOT
)
79 rc
= adfWriteRootBlock(vol
, pSect
, (struct bRootBlock
*)&parent
);
81 rc
= adfWriteDirBlock(vol
, pSect
, (struct bDirBlock
*)&parent
);
87 if (adfReadEntryBlock(vol
, prevSect
, &previous
)!=RC_OK
)
89 /* entry.nextSameHash (tmpSect) could be == 0 */
90 previous
.nextSameHash
= tmpSect
;
91 if (adfWriteEntryBlock(vol
, prevSect
, &previous
)!=RC_OK
)
96 if (adfReadEntryBlock( vol
, nPSect
, &nParent
)!=RC_OK
)
99 hashValueN
= adfGetHashValue(newName
, intl
);
100 nSect2
= nParent
.hashTable
[ hashValueN
];
103 nParent
.hashTable
[ hashValueN
] = nSect
;
104 if (nParent
.secType
==ST_ROOT
)
105 rc
= adfWriteRootBlock(vol
, nPSect
, (struct bRootBlock
*)&nParent
);
107 rc
= adfWriteDirBlock(vol
, nPSect
, (struct bDirBlock
*)&nParent
);
110 /* a list exists : addition at the end */
111 /* len = strlen(newName);
115 if (adfReadEntryBlock(vol
, nSect2
, &previous
)!=RC_OK
)
117 if (previous
.nameLen
==len
) {
118 myToUpper(name3
,(char *)previous
.name
,previous
.nameLen
,intl
);
119 if (strncmp(name3
,name2
,len
)==0) {
120 (*adfEnv
.wFct
)("adfRenameEntry : entry already exists");
124 nSect2
= previous
.nextSameHash
;
125 //printf("sect=%ld\n",nSect2);
128 previous
.nextSameHash
= nSect
;
129 if (previous
.secType
==ST_DIR
)
130 rc
=adfWriteDirBlock(vol
, previous
.headerKey
,
131 (struct bDirBlock
*)&previous
);
132 else if (previous
.secType
==ST_FILE
)
133 rc
=adfWriteFileHdrBlock(vol
, previous
.headerKey
,
134 (struct bFileHeaderBlock
*)&previous
);
136 (*adfEnv
.wFct
)("adfRenameEntry : unknown entry type");
144 if (isDIRCACHE(vol
->dosType
)) {
146 adfUpdateCache(vol
, &parent
, (struct bEntryBlock
*)&entry
,TRUE
);
149 adfDelFromCache(vol
,&parent
,entry
.headerKey
);
150 adfAddInCache(vol
,&nParent
,&entry
);
154 if (isDIRCACHE(vol->dosType) && pSect!=nPSect) {
155 adfUpdateCache(vol, &nParent, (struct bEntryBlock*)&entry,TRUE);
165 RETCODE
adfRemoveEntry(struct Volume
*vol
, SECTNUM pSect
, char *name
)
167 struct bEntryBlock parent
, previous
, entry
;
168 SECTNUM nSect2
, nSect
;
172 if (adfReadEntryBlock( vol
, pSect
, &parent
)!=RC_OK
)
174 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, name
, &entry
, &nSect2
);
176 (*adfEnv
.wFct
)("adfRemoveEntry : entry not found");
179 /* if it is a directory, is it empty ? */
180 if ( entry
.secType
==ST_DIR
&& !isDirEmpty((struct bDirBlock
*)&entry
) ) {
181 (*adfEnv
.wFct
)("adfRemoveEntry : directory not empty");
184 /* printf("name=%s nSect2=%ld\n",name, nSect2);*/
186 /* in parent hashTable */
188 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
189 hashVal
= adfGetHashValue( name
, intl
);
190 /*printf("hashTable=%d nexthash=%d\n",parent.hashTable[hashVal],
191 entry.nextSameHash);*/
192 parent
.hashTable
[hashVal
] = entry
.nextSameHash
;
193 if (adfWriteEntryBlock(vol
, pSect
, &parent
)!=RC_OK
)
198 if (adfReadEntryBlock(vol
, nSect2
, &previous
)!=RC_OK
)
200 previous
.nextSameHash
= entry
.nextSameHash
;
201 if (adfWriteEntryBlock(vol
, nSect2
, &previous
)!=RC_OK
)
205 if (entry
.secType
==ST_FILE
) {
206 adfFreeFileBlocks(vol
, (struct bFileHeaderBlock
*)&entry
);
207 if (adfEnv
.useNotify
)
208 (*adfEnv
.notifyFct
)(pSect
,ST_FILE
);
210 else if (entry
.secType
==ST_DIR
) {
211 adfSetBlockFree(vol
, nSect
);
212 /* free dir cache block : the directory must be empty, so there's only one cache block */
213 if (isDIRCACHE(vol
->dosType
))
214 adfSetBlockFree(vol
, entry
.extension
);
215 if (adfEnv
.useNotify
)
216 (*adfEnv
.notifyFct
)(pSect
,ST_DIR
);
219 (*adfEnv
.wFct
)("adfRemoveEntry : secType not supported");
223 if (isDIRCACHE(vol
->dosType
))
224 adfDelFromCache(vol
, &parent
, entry
.headerKey
);
226 adfUpdateBitmap(vol
);
236 RETCODE
adfSetEntryComment(struct Volume
* vol
, SECTNUM parSect
, char* name
,
239 struct bEntryBlock parent
, entry
;
242 if (adfReadEntryBlock( vol
, parSect
, &parent
)!=RC_OK
)
244 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, name
, &entry
, NULL
);
246 (*adfEnv
.wFct
)("adfSetEntryComment : entry not found");
250 entry
.commLen
= min(MAXCMMTLEN
, strlen(newCmt
));
251 memcpy(entry
.comment
, newCmt
, entry
.commLen
);
253 if (entry
.secType
==ST_DIR
)
254 adfWriteDirBlock(vol
, nSect
, (struct bDirBlock
*)&entry
);
255 else if (entry
.secType
==ST_FILE
)
256 adfWriteFileHdrBlock(vol
, nSect
, (struct bFileHeaderBlock
*)&entry
);
258 (*adfEnv
.wFct
)("adfSetEntryComment : entry secType incorrect");
260 if (isDIRCACHE(vol
->dosType
))
261 adfUpdateCache(vol
, &parent
, (struct bEntryBlock
*)&entry
, TRUE
);
271 RETCODE
adfSetEntryAccess(struct Volume
* vol
, SECTNUM parSect
, char* name
,
274 struct bEntryBlock parent
, entry
;
277 if (adfReadEntryBlock( vol
, parSect
, &parent
)!=RC_OK
)
279 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, name
, &entry
, NULL
);
281 (*adfEnv
.wFct
)("adfSetEntryAccess : entry not found");
285 entry
.access
= newAcc
;
286 if (entry
.secType
==ST_DIR
)
287 adfWriteDirBlock(vol
, nSect
, (struct bDirBlock
*)&entry
);
288 else if (entry
.secType
==ST_FILE
)
289 adfWriteFileHdrBlock(vol
, nSect
, (struct bFileHeaderBlock
*)&entry
);
291 (*adfEnv
.wFct
)("adfSetEntryAccess : entry secType incorrect");
293 if (isDIRCACHE(vol
->dosType
))
294 adfUpdateCache(vol
, &parent
, (struct bEntryBlock
*)&entry
, FALSE
);
304 BOOL
isDirEmpty(struct bDirBlock
*dir
)
308 for(i
=0; i
<HT_SIZE
; i
++)
309 if (dir
->hashTable
[i
]!=0)
320 void adfFreeDirList(struct List
* list
)
322 struct List
*root
, *cell
;
326 adfFreeEntry(cell
->content
);
327 if (cell
->subdir
!=NULL
)
328 adfFreeDirList(cell
->subdir
);
339 struct List
* adfGetRDirEnt(struct Volume
* vol
, SECTNUM nSect
, BOOL recurs
)
341 struct bEntryBlock entryBlk
;
342 struct List
*cell
, *head
;
347 struct bEntryBlock parent
;
350 if (adfEnv
.useDirCache
&& isDIRCACHE(vol
->dosType
))
351 return (adfGetDirEntCache(vol
, nSect
, recurs
));
354 if (adfReadEntryBlock(vol
,nSect
,&parent
)!=RC_OK
)
357 hashTable
= parent
.hashTable
;
359 for(i
=0; i
<HT_SIZE
; i
++) {
360 if (hashTable
[i
]!=0) {
361 entry
= (struct Entry
*)malloc(sizeof(struct Entry
));
363 adfFreeDirList(head
);
364 (*adfEnv
.eFct
)("adfGetDirEnt : malloc");
367 if (adfReadEntryBlock(vol
, hashTable
[i
], &entryBlk
)!=RC_OK
) {
368 adfFreeDirList(head
);
371 if (adfEntBlock2Entry(&entryBlk
, entry
)!=RC_OK
) {
372 adfFreeDirList(head
); return NULL
;
374 entry
->sector
= hashTable
[i
];
377 head
= cell
= newCell(0, (void*)entry
);
379 cell
= newCell(cell
, (void*)entry
);
381 adfFreeDirList(head
); return NULL
;
384 if (recurs
&& entry
->type
==ST_DIR
)
385 cell
->subdir
= adfGetRDirEnt(vol
,entry
->sector
,recurs
);
387 /* same hashcode linked list */
388 nextSector
= entryBlk
.nextSameHash
;
389 while( nextSector
!=0 ) {
390 entry
= (struct Entry
*)malloc(sizeof(struct Entry
));
392 adfFreeDirList(head
);
393 (*adfEnv
.eFct
)("adfGetDirEnt : malloc");
396 if (adfReadEntryBlock(vol
, nextSector
, &entryBlk
)!=RC_OK
) {
397 adfFreeDirList(head
); return NULL
;
400 if (adfEntBlock2Entry(&entryBlk
, entry
)!=RC_OK
) {
401 adfFreeDirList(head
);
404 entry
->sector
= nextSector
;
406 cell
= newCell(cell
, (void*)entry
);
408 adfFreeDirList(head
); return NULL
;
411 if (recurs
&& entry
->type
==ST_DIR
)
412 cell
->subdir
= adfGetRDirEnt(vol
,entry
->sector
,recurs
);
414 nextSector
= entryBlk
.nextSameHash
;
419 /* if (parent.extension && isDIRCACHE(vol->dosType) )
420 adfReadDirCache(vol,parent.extension);
430 struct List
* adfGetDirEnt(struct Volume
* vol
, SECTNUM nSect
)
432 return adfGetRDirEnt(vol
, nSect
, FALSE
);
440 void adfFreeEntry(struct Entry
*entry
)
447 free(entry
->comment
);
456 RETCODE
adfToRootDir(struct Volume
*vol
)
458 vol
->curDirPtr
= vol
->rootBlock
;
463 SECTNUM
adfCurrentDir(struct Volume
* vol
)
465 return vol
->curDirPtr
;
473 RETCODE
adfChangeDir(struct Volume
* vol
, char *name
)
475 struct bEntryBlock entry
;
478 if (adfReadEntryBlock( vol
, vol
->curDirPtr
, &entry
)!=RC_OK
)
480 nSect
= adfNameToEntryBlk(vol
, entry
.hashTable
, name
, &entry
, NULL
);
481 /*printf("adfChangeDir=%d\n",nSect);*/
483 vol
->curDirPtr
= nSect
;
484 /* if (*adfEnv.useNotify)
485 (*adfEnv.notifyFct)(0,ST_ROOT);*/
497 RETCODE
adfParentDir(struct Volume
* vol
)
499 struct bEntryBlock entry
;
501 if (vol
->curDirPtr
!=vol
->rootBlock
) {
502 if (adfReadEntryBlock( vol
, vol
->curDirPtr
, &entry
)!=RC_OK
)
504 vol
->curDirPtr
= entry
.parent
;
514 RETCODE
adfEntBlock2Entry(struct bEntryBlock
*entryBlk
, struct Entry
*entry
)
516 char buf
[MAXCMMTLEN
+1];
519 entry
->type
= entryBlk
->secType
;
520 entry
->parent
= entryBlk
->parent
;
522 len
= min(entryBlk
->nameLen
, MAXNAMELEN
);
523 strncpy(buf
, (char *)entryBlk
->name
, len
);
525 entry
->name
= strdup(buf
);
526 if (entry
->name
==NULL
)
528 //printf("len=%d name=%s parent=%ld\n",entryBlk->nameLen, entry->name,entry->parent );
529 adfDays2Date( entryBlk
->days
, &(entry
->year
), &(entry
->month
), &(entry
->days
));
530 entry
->hour
= entryBlk
->mins
/60;
531 entry
->mins
= entryBlk
->mins
%60;
532 entry
->secs
= entryBlk
->ticks
/50;
536 entry
->comment
= NULL
;
538 switch(entryBlk
->secType
) {
542 entry
->access
= entryBlk
->access
;
543 len
= min(entryBlk
->commLen
, MAXCMMTLEN
);
544 strncpy(buf
, (char *)entryBlk
->comment
, len
);
546 entry
->comment
= strdup(buf
);
547 if (entry
->comment
==NULL
) {
553 entry
->access
= entryBlk
->access
;
554 entry
->size
= entryBlk
->byteSize
;
555 len
= min(entryBlk
->commLen
, MAXCMMTLEN
);
556 strncpy(buf
, (char *)entryBlk
->comment
, len
);
558 entry
->comment
= strdup(buf
);
559 if (entry
->comment
==NULL
) {
566 entry
->real
= entryBlk
->realEntry
;
570 (*adfEnv
.wFct
)("unknown entry type");
581 SECTNUM
adfNameToEntryBlk(struct Volume
*vol
, ULONG ht
[], char* name
,
582 struct bEntryBlock
*entry
, SECTNUM
*nUpdSect
)
585 char upperName
[MAXNAMELEN
+1];
586 char upperName2
[MAXNAMELEN
+1];
593 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
594 hashVal
= adfGetHashValue( name
, intl
);
595 nameLen
= strlen(name
);
596 myToUpper( upperName
, name
, nameLen
, intl
);
599 /*printf("name=%s ht[%d]=%d upper=%s len=%d\n",name,hashVal,nSect,upperName,nameLen);
600 printf("hashVal=%d\n",adfGetHashValue(upperName, intl ));
601 if (!strcmp("españa.country",name)) {
603 for(i=0; i<HT_SIZE; i++) printf("ht[%d]=%d ",i,ht[i]);
611 if (adfReadEntryBlock(vol
, nSect
, entry
)!=RC_OK
)
613 if (nameLen
==entry
->nameLen
) {
614 myToUpper( upperName2
, (char *)entry
->name
, nameLen
, intl
);
615 //printf("2=%s %s\n",upperName2,upperName);
616 found
= strncmp(upperName
, upperName2
, nameLen
)==0;
620 nSect
= entry
->nextSameHash
;
622 }while( !found
&& nSect
!=0 );
624 if ( nSect
==0 && !found
)
639 adfAccess2String(ULONG acc
)
641 static char ret
[8+1];
643 strcpy(ret
,"----rwed");
644 if (hasD(acc
)) ret
[7]='-';
645 if (hasE(acc
)) ret
[6]='-';
646 if (hasW(acc
)) ret
[5]='-';
647 if (hasR(acc
)) ret
[4]='-';
648 if (hasA(acc
)) ret
[3]='a';
649 if (hasP(acc
)) ret
[2]='p';
650 if (hasS(acc
)) ret
[1]='s';
651 if (hasH(acc
)) ret
[0]='h';
660 * if 'thisSect'==-1, allocate a sector, and insert its pointer into the hashTable of 'dir', using the
661 * name 'name'. if 'thisSect'!=-1, insert this sector pointer into the hashTable
662 * (here 'thisSect' must be allocated before in the bitmap).
664 SECTNUM
adfCreateEntry(struct Volume
*vol
, struct bEntryBlock
*dir
, char *name
,
668 struct bEntryBlock updEntry
;
671 char name2
[MAXNAMELEN
+1], name3
[MAXNAMELEN
+1];
672 SECTNUM nSect
, newSect
, newSect2
;
673 struct bRootBlock
* root
;
675 //puts("adfCreateEntry in");
677 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
679 myToUpper(name2
, name
, len
, intl
);
680 hashValue
= adfGetHashValue(name
, intl
);
681 nSect
= dir
->hashTable
[ hashValue
];
684 if (thisSect
!=(SECTNUM
)-1)
687 newSect
= adfGet1FreeBlock(vol
);
688 if (newSect
==(SECTNUM
)-1) {
689 (*adfEnv
.wFct
)("adfCreateEntry : nSect==-1");
694 dir
->hashTable
[ hashValue
] = newSect
;
695 if (dir
->secType
==ST_ROOT
) {
696 root
= (struct bRootBlock
*)dir
;
697 adfTime2AmigaTime(adfGiveCurrentTime(),
698 &(root
->cDays
),&(root
->cMins
),&(root
->cTicks
));
699 rc
=adfWriteRootBlock(vol
, vol
->rootBlock
, root
);
702 adfTime2AmigaTime(adfGiveCurrentTime(),&(dir
->days
),&(dir
->mins
),&(dir
->ticks
));
703 rc
=adfWriteDirBlock(vol
, dir
->headerKey
, (struct bDirBlock
*)dir
);
705 //puts("adfCreateEntry out, dir");
707 adfSetBlockFree(vol
, newSect
);
715 if (adfReadEntryBlock(vol
, nSect
, &updEntry
)!=RC_OK
)
717 if (updEntry
.nameLen
==len
) {
718 myToUpper(name3
,(char *)updEntry
.name
,updEntry
.nameLen
,intl
);
719 if (strncmp(name3
,name2
,len
)==0) {
720 (*adfEnv
.wFct
)("adfCreateEntry : entry already exists");
724 nSect
= updEntry
.nextSameHash
;
727 if (thisSect
!=(SECTNUM
)-1)
730 newSect2
= adfGet1FreeBlock(vol
);
731 if (newSect2
==(SECTNUM
)-1) {
732 (*adfEnv
.wFct
)("adfCreateEntry : nSect==-1");
738 updEntry
.nextSameHash
= newSect2
;
739 if (updEntry
.secType
==ST_DIR
)
740 rc
=adfWriteDirBlock(vol
, updEntry
.headerKey
, (struct bDirBlock
*)&updEntry
);
741 else if (updEntry
.secType
==ST_FILE
)
742 rc
=adfWriteFileHdrBlock(vol
, updEntry
.headerKey
,
743 (struct bFileHeaderBlock
*)&updEntry
);
745 (*adfEnv
.wFct
)("adfCreateEntry : unknown entry type");
747 //puts("adfCreateEntry out, hash");
749 adfSetBlockFree(vol
, newSect2
);
763 char adfIntlToUpper(char cin
)
765 unsigned char c
= (unsigned char)cin
;
766 return (c
>='a' && c
<='z') || (c
>=224 && c
<=254 && c
!=247) ? c
- ('a'-'A') : c
;
769 char adfToUpper(char cin
)
771 unsigned char c
= (unsigned char)cin
;
772 return (c
>='a' && c
<='z') ? c
- ('a'-'A') : c
;
780 myToUpper( char *nstr
, char *ostr
, int nlen
, BOOL intl
)
785 for(i
=0; i
<nlen
; i
++)
786 nstr
[i
]=adfIntlToUpper(ostr
[i
]);
788 for(i
=0; i
<nlen
; i
++)
789 nstr
[i
]=adfToUpper(ostr
[i
]);
799 adfGetHashValue(char *name
, BOOL intl
)
805 len
= hash
= strlen(name
);
806 for(i
=0; i
<len
; i
++) {
808 upper
= adfIntlToUpper(name
[i
]);
810 upper
= toupper(name
[i
]);
811 hash
= (hash
* 13 + (unsigned char)upper
) & 0x7ff;
813 hash
= hash
% HT_SIZE
;
823 void printEntry(struct Entry
* entry
)
825 printf("%-30s %2d %6ld ", entry
->name
, entry
->type
, (long)entry
->sector
);
826 printf("%2d/%02d/%04d %2d:%02d:%02d",entry
->days
, entry
->month
, entry
->year
,
827 entry
->hour
, entry
->mins
, entry
->secs
);
828 if (entry
->type
==ST_FILE
)
829 printf("%8ld ",entry
->size
);
832 if (entry
->type
==ST_FILE
|| entry
->type
==ST_DIR
)
833 printf("%-s ",adfAccess2String(entry
->access
));
834 if (entry
->comment
!=NULL
)
835 printf("%s ",entry
->comment
);
844 RETCODE
adfCreateDir(struct Volume
* vol
, SECTNUM nParent
, char* name
)
847 struct bDirBlock dir
;
848 struct bEntryBlock parent
;
850 if (adfReadEntryBlock(vol
, nParent
, &parent
)!=RC_OK
)
853 /* -1 : do not use a specific, already allocated sector */
854 nSect
= adfCreateEntry(vol
, &parent
, name
, -1);
856 (*adfEnv
.wFct
)("adfCreateDir : no sector available");
859 memset(&dir
, 0, sizeof(struct bDirBlock
));
860 dir
.nameLen
= min(MAXNAMELEN
, strlen(name
));
861 memcpy(dir
.dirName
,name
,dir
.nameLen
);
862 dir
.headerKey
= nSect
;
864 if (parent
.secType
==ST_ROOT
)
865 dir
.parent
= vol
->rootBlock
;
867 dir
.parent
= parent
.headerKey
;
868 adfTime2AmigaTime(adfGiveCurrentTime(),&(dir
.days
),&(dir
.mins
),&(dir
.ticks
));
870 if (isDIRCACHE(vol
->dosType
)) {
871 /* for adfCreateEmptyCache, will be added by adfWriteDirBlock */
872 dir
.secType
= ST_DIR
;
873 adfAddInCache(vol
, &parent
, (struct bEntryBlock
*)&dir
);
874 adfCreateEmptyCache(vol
, (struct bEntryBlock
*)&dir
, -1);
877 /* writes the dirblock, with the possible dircache assiocated */
878 if (adfWriteDirBlock(vol
, nSect
, &dir
)!=RC_OK
)
881 adfUpdateBitmap(vol
);
883 if (adfEnv
.useNotify
)
884 (*adfEnv
.notifyFct
)(nParent
,ST_DIR
);
894 RETCODE
adfCreateFile(struct Volume
* vol
, SECTNUM nParent
, char *name
,
895 struct bFileHeaderBlock
*fhdr
)
898 struct bEntryBlock parent
;
899 //puts("adfCreateFile in");
900 if (adfReadEntryBlock(vol
, nParent
, &parent
)!=RC_OK
)
903 /* -1 : do not use a specific, already allocated sector */
904 nSect
= adfCreateEntry(vol
, &parent
, name
, (SECTNUM
)-1);
905 if (nSect
==-1) return RC_ERROR
;
906 /*printf("new fhdr=%d\n",nSect);*/
908 memset(fhdr
->fileName
, 0xff, MAXNAMELEN
+1);
909 fhdr
->nameLen
= min(MAXNAMELEN
, strlen(name
));
910 memcpy(fhdr
->fileName
,name
,fhdr
->nameLen
);
911 fhdr
->headerKey
= nSect
;
912 if (parent
.secType
==ST_ROOT
)
913 fhdr
->parent
= vol
->rootBlock
;
914 else if (parent
.secType
==ST_DIR
)
915 fhdr
->parent
= parent
.headerKey
;
917 (*adfEnv
.wFct
)("adfCreateFile : unknown parent secType");
918 adfTime2AmigaTime(adfGiveCurrentTime(),
919 &(fhdr
->days
),&(fhdr
->mins
),&(fhdr
->ticks
));
921 if (adfWriteFileHdrBlock(vol
,nSect
,fhdr
)!=RC_OK
)
924 if (isDIRCACHE(vol
->dosType
))
925 adfAddInCache(vol
, &parent
, (struct bEntryBlock
*)fhdr
);
927 adfUpdateBitmap(vol
);
929 if (adfEnv
.useNotify
)
930 (*adfEnv
.notifyFct
)(nParent
,ST_FILE
);
940 RETCODE
adfReadEntryBlock(struct Volume
* vol
, SECTNUM nSect
, struct bEntryBlock
*ent
)
942 unsigned char buf
[512];
944 if (adfReadBlock(vol
, nSect
, buf
)!=RC_OK
)
947 memcpy(ent
, buf
, 512);
949 if (nSect
== vol
->rootBlock
)
950 swapEndian((UBYTE
*)ent
, SWBL_ROOT
);
952 swapEndian((UBYTE
*)ent
, SWBL_ENTRY
);
954 /*printf("readentry=%d\n",nSect);*/
955 if (ent
->checkSum
!=adfNormalSum(buf
,20,512)) {
956 (*adfEnv
.wFct
)("adfReadEntryBlock : invalid checksum");
959 if (ent
->type
!=T_HEADER
) {
960 (*adfEnv
.wFct
)("adfReadEntryBlock : T_HEADER id not found");
963 if (ent
->nameLen
<0 || ent
->nameLen
>MAXNAMELEN
|| ent
->commLen
>MAXCMMTLEN
) {
964 (*adfEnv
.wFct
)("adfReadEntryBlock : nameLen or commLen incorrect");
965 printf("nameLen=%d, commLen=%d, name=%s sector%ld\n",
966 ent
->nameLen
,ent
->commLen
,ent
->name
, (long)ent
->headerKey
);
977 RETCODE
adfWriteEntryBlock(struct Volume
* vol
, SECTNUM nSect
, struct bEntryBlock
*ent
)
979 unsigned char buf
[512];
983 memcpy(buf
, ent
, sizeof(struct bEntryBlock
));
986 if (nSect
== vol
->rootBlock
)
987 swapEndian(buf
, SWBL_ROOT
);
989 swapEndian(buf
, SWBL_ENTRY
);
991 newSum
= adfNormalSum(buf
,20,sizeof(struct bEntryBlock
));
992 swLong(buf
+20, newSum
);
994 if (adfWriteBlock(vol
, nSect
, buf
)!=RC_OK
)
1005 RETCODE
adfWriteDirBlock(struct Volume
* vol
, SECTNUM nSect
, struct bDirBlock
*dir
)
1007 unsigned char buf
[512];
1011 /*printf("wdirblk=%d\n",nSect);*/
1012 dir
->type
= T_HEADER
;
1014 dir
->hashTableSize
= 0;
1015 dir
->secType
= ST_DIR
;
1017 memcpy(buf
, dir
, sizeof(struct bDirBlock
));
1019 swapEndian(buf
, SWBL_DIR
);
1021 newSum
= adfNormalSum(buf
,20,sizeof(struct bDirBlock
));
1022 swLong(buf
+20, newSum
);
1024 if (adfWriteBlock(vol
, nSect
, buf
)!=RC_OK
)
1032 /*###########################################################################*/