2 * ADF Library. (C) 1997-1999 Laurent Clevy
25 extern struct Env adfEnv
;
32 RETCODE
adfRenameEntry(struct Volume
*vol
, SECTNUM pSect
, char *oldName
,
33 SECTNUM nPSect
, char *newName
)
35 struct bEntryBlock parent
, previous
, entry
, nParent
;
36 SECTNUM nSect2
, nSect
, prevSect
, tmpSect
;
37 int hashValueO
, hashValueN
, len
;
38 char name2
[MAXNAMELEN
+1], name3
[MAXNAMELEN
+1];
42 if (strcmp(oldName
,newName
)==0)
45 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
46 len
= strlen(newName
);
47 myToUpper((unsigned char*)name2
, (unsigned char*)newName
, len
, intl
);
48 myToUpper((unsigned char*)name3
, (unsigned char*)oldName
, strlen(oldName
), intl
);
49 /* newName == oldName ? */
51 if (adfReadEntryBlock( vol
, pSect
, &parent
)!=RC_OK
)
54 hashValueO
= adfGetHashValue((unsigned char*)oldName
, intl
);
56 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, oldName
, &entry
, &prevSect
);
58 (*adfEnv
.wFct
)("adfRenameEntry : existing entry not found");
62 /* change name and parent dir */
63 entry
.nameLen
= min(31, strlen(newName
));
64 memcpy(entry
.name
, newName
, entry
.nameLen
);
65 entry
.parent
= nPSect
;
66 tmpSect
= entry
.nextSameHash
;
68 entry
.nextSameHash
= 0;
69 if (adfWriteEntryBlock(vol
, nSect
, &entry
)!=RC_OK
)
72 /* del from the oldname list */
76 parent
.hashTable
[hashValueO
] = tmpSect
;
77 if (parent
.secType
==ST_ROOT
)
78 rc
= adfWriteRootBlock(vol
, pSect
, (struct bRootBlock
*)&parent
);
80 rc
= adfWriteDirBlock(vol
, pSect
, (struct bDirBlock
*)&parent
);
86 if (adfReadEntryBlock(vol
, prevSect
, &previous
)!=RC_OK
)
88 /* entry.nextSameHash (tmpSect) could be == 0 */
89 previous
.nextSameHash
= tmpSect
;
90 if (adfWriteEntryBlock(vol
, prevSect
, &previous
)!=RC_OK
)
95 if (adfReadEntryBlock( vol
, nPSect
, &nParent
)!=RC_OK
)
98 hashValueN
= adfGetHashValue((unsigned char*)newName
, intl
);
99 nSect2
= nParent
.hashTable
[ hashValueN
];
102 nParent
.hashTable
[ hashValueN
] = nSect
;
103 if (nParent
.secType
==ST_ROOT
)
104 rc
= adfWriteRootBlock(vol
, nPSect
, (struct bRootBlock
*)&nParent
);
106 rc
= adfWriteDirBlock(vol
, nPSect
, (struct bDirBlock
*)&nParent
);
109 /* a list exists : addition at the end */
110 /* len = strlen(newName);
114 if (adfReadEntryBlock(vol
, nSect2
, &previous
)!=RC_OK
)
116 if (previous
.nameLen
==len
) {
117 myToUpper((unsigned char*)name3
,(unsigned char*)previous
.name
,previous
.nameLen
,intl
);
118 if (strncmp(name3
,name2
,len
)==0) {
119 (*adfEnv
.wFct
)("adfRenameEntry : entry already exists");
123 nSect2
= previous
.nextSameHash
;
124 //printf("sect=%ld\n",nSect2);
127 previous
.nextSameHash
= nSect
;
128 if (previous
.secType
==ST_DIR
)
129 rc
=adfWriteDirBlock(vol
, previous
.headerKey
,
130 (struct bDirBlock
*)&previous
);
131 else if (previous
.secType
==ST_FILE
)
132 rc
=adfWriteFileHdrBlock(vol
, previous
.headerKey
,
133 (struct bFileHeaderBlock
*)&previous
);
135 (*adfEnv
.wFct
)("adfRenameEntry : unknown entry type");
143 if (isDIRCACHE(vol
->dosType
)) {
145 adfUpdateCache(vol
, &parent
, (struct bEntryBlock
*)&entry
,TRUE
);
148 adfDelFromCache(vol
,&parent
,entry
.headerKey
);
149 adfAddInCache(vol
,&nParent
,&entry
);
153 if (isDIRCACHE(vol->dosType) && pSect!=nPSect) {
154 adfUpdateCache(vol, &nParent, (struct bEntryBlock*)&entry,TRUE);
164 RETCODE
adfRemoveEntry(struct Volume
*vol
, SECTNUM pSect
, char *name
)
166 struct bEntryBlock parent
, previous
, entry
;
167 SECTNUM nSect2
, nSect
;
171 if (adfReadEntryBlock( vol
, pSect
, &parent
)!=RC_OK
)
173 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, name
, &entry
, &nSect2
);
175 (*adfEnv
.wFct
)("adfRemoveEntry : entry not found");
178 /* if it is a directory, is it empty ? */
179 if ( entry
.secType
==ST_DIR
&& !isDirEmpty((struct bDirBlock
*)&entry
) ) {
180 (*adfEnv
.wFct
)("adfRemoveEntry : directory not empty");
183 /* printf("name=%s nSect2=%ld\n",name, nSect2);*/
185 /* in parent hashTable */
187 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
188 hashVal
= adfGetHashValue( (unsigned char*)name
, intl
);
189 /*printf("hashTable=%d nexthash=%d\n",parent.hashTable[hashVal],
190 entry.nextSameHash);*/
191 parent
.hashTable
[hashVal
] = entry
.nextSameHash
;
192 if (adfWriteEntryBlock(vol
, pSect
, &parent
)!=RC_OK
)
197 if (adfReadEntryBlock(vol
, nSect2
, &previous
)!=RC_OK
)
199 previous
.nextSameHash
= entry
.nextSameHash
;
200 if (adfWriteEntryBlock(vol
, nSect2
, &previous
)!=RC_OK
)
204 if (entry
.secType
==ST_FILE
) {
205 adfFreeFileBlocks(vol
, (struct bFileHeaderBlock
*)&entry
);
206 if (adfEnv
.useNotify
)
207 (*adfEnv
.notifyFct
)(pSect
,ST_FILE
);
209 else if (entry
.secType
==ST_DIR
) {
210 adfSetBlockFree(vol
, nSect
);
211 /* free dir cache block : the directory must be empty, so there's only one cache block */
212 if (isDIRCACHE(vol
->dosType
))
213 adfSetBlockFree(vol
, entry
.extension
);
214 if (adfEnv
.useNotify
)
215 (*adfEnv
.notifyFct
)(pSect
,ST_DIR
);
218 (*adfEnv
.wFct
)("adfRemoveEntry : secType not supported");
222 if (isDIRCACHE(vol
->dosType
))
223 adfDelFromCache(vol
, &parent
, entry
.headerKey
);
225 adfUpdateBitmap(vol
);
235 RETCODE
adfSetEntryComment(struct Volume
* vol
, SECTNUM parSect
, char* name
,
238 struct bEntryBlock parent
, entry
;
241 if (adfReadEntryBlock( vol
, parSect
, &parent
)!=RC_OK
)
243 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, name
, &entry
, NULL
);
245 (*adfEnv
.wFct
)("adfSetEntryComment : entry not found");
249 entry
.commLen
= min(MAXCMMTLEN
, strlen(newCmt
));
250 memcpy(entry
.comment
, newCmt
, entry
.commLen
);
252 if (entry
.secType
==ST_DIR
)
253 adfWriteDirBlock(vol
, nSect
, (struct bDirBlock
*)&entry
);
254 else if (entry
.secType
==ST_FILE
)
255 adfWriteFileHdrBlock(vol
, nSect
, (struct bFileHeaderBlock
*)&entry
);
257 (*adfEnv
.wFct
)("adfSetEntryComment : entry secType incorrect");
259 if (isDIRCACHE(vol
->dosType
))
260 adfUpdateCache(vol
, &parent
, (struct bEntryBlock
*)&entry
, TRUE
);
270 RETCODE
adfSetEntryAccess(struct Volume
* vol
, SECTNUM parSect
, char* name
,
273 struct bEntryBlock parent
, entry
;
276 if (adfReadEntryBlock( vol
, parSect
, &parent
)!=RC_OK
)
278 nSect
= adfNameToEntryBlk(vol
, parent
.hashTable
, name
, &entry
, NULL
);
280 (*adfEnv
.wFct
)("adfSetEntryAccess : entry not found");
284 entry
.access
= newAcc
;
285 if (entry
.secType
==ST_DIR
)
286 adfWriteDirBlock(vol
, nSect
, (struct bDirBlock
*)&entry
);
287 else if (entry
.secType
==ST_FILE
)
288 adfWriteFileHdrBlock(vol
, nSect
, (struct bFileHeaderBlock
*)&entry
);
290 (*adfEnv
.wFct
)("adfSetEntryAccess : entry secType incorrect");
292 if (isDIRCACHE(vol
->dosType
))
293 adfUpdateCache(vol
, &parent
, (struct bEntryBlock
*)&entry
, FALSE
);
303 BOOL
isDirEmpty(struct bDirBlock
*dir
)
307 for(i
=0; i
<HT_SIZE
; i
++)
308 if (dir
->hashTable
[i
]!=0)
319 void adfFreeDirList(struct List
* list
)
321 struct List
*root
, *cell
;
325 adfFreeEntry(cell
->content
);
326 if (cell
->subdir
!=NULL
)
327 adfFreeDirList(cell
->subdir
);
338 struct List
* adfGetRDirEnt(struct Volume
* vol
, SECTNUM nSect
, BOOL recurs
)
340 struct bEntryBlock entryBlk
;
341 struct List
*cell
, *head
;
346 struct bEntryBlock parent
;
349 if (adfEnv
.useDirCache
&& isDIRCACHE(vol
->dosType
))
350 return (adfGetDirEntCache(vol
, nSect
, recurs
));
353 if (adfReadEntryBlock(vol
,nSect
,&parent
)!=RC_OK
)
356 hashTable
= parent
.hashTable
;
358 for(i
=0; i
<HT_SIZE
; i
++) {
359 if (hashTable
[i
]!=0) {
360 entry
= (struct Entry
*)malloc(sizeof(struct Entry
));
362 adfFreeDirList(head
);
363 (*adfEnv
.eFct
)("adfGetDirEnt : malloc");
366 if (adfReadEntryBlock(vol
, hashTable
[i
], &entryBlk
)!=RC_OK
) {
367 adfFreeDirList(head
);
370 if (adfEntBlock2Entry(&entryBlk
, entry
)!=RC_OK
) {
371 adfFreeDirList(head
); return NULL
;
373 entry
->sector
= hashTable
[i
];
376 head
= cell
= newCell(0, (void*)entry
);
378 cell
= newCell(cell
, (void*)entry
);
380 adfFreeDirList(head
); return NULL
;
383 if (recurs
&& entry
->type
==ST_DIR
)
384 cell
->subdir
= adfGetRDirEnt(vol
,entry
->sector
,recurs
);
386 /* same hashcode linked list */
387 nextSector
= entryBlk
.nextSameHash
;
388 while( nextSector
!=0 ) {
389 entry
= (struct Entry
*)malloc(sizeof(struct Entry
));
391 adfFreeDirList(head
);
392 (*adfEnv
.eFct
)("adfGetDirEnt : malloc");
395 if (adfReadEntryBlock(vol
, nextSector
, &entryBlk
)!=RC_OK
) {
396 adfFreeDirList(head
); return NULL
;
399 if (adfEntBlock2Entry(&entryBlk
, entry
)!=RC_OK
) {
400 adfFreeDirList(head
);
403 entry
->sector
= nextSector
;
405 cell
= newCell(cell
, (void*)entry
);
407 adfFreeDirList(head
); return NULL
;
410 if (recurs
&& entry
->type
==ST_DIR
)
411 cell
->subdir
= adfGetRDirEnt(vol
,entry
->sector
,recurs
);
413 nextSector
= entryBlk
.nextSameHash
;
418 /* if (parent.extension && isDIRCACHE(vol->dosType) )
419 adfReadDirCache(vol,parent.extension);
429 struct List
* adfGetDirEnt(struct Volume
* vol
, SECTNUM nSect
)
431 return adfGetRDirEnt(vol
, nSect
, FALSE
);
439 void adfFreeEntry(struct Entry
*entry
)
446 free(entry
->comment
);
455 RETCODE
adfToRootDir(struct Volume
*vol
)
457 vol
->curDirPtr
= vol
->rootBlock
;
467 RETCODE
adfChangeDir(struct Volume
* vol
, char *name
)
469 struct bEntryBlock entry
;
472 if (adfReadEntryBlock( vol
, vol
->curDirPtr
, &entry
)!=RC_OK
)
474 nSect
= adfNameToEntryBlk(vol
, entry
.hashTable
, name
, &entry
, NULL
);
475 /*printf("adfChangeDir=%d\n",nSect);*/
477 vol
->curDirPtr
= nSect
;
478 /* if (*adfEnv.useNotify)
479 (*adfEnv.notifyFct)(0,ST_ROOT);*/
491 SECTNUM
adfParentDir(struct Volume
* vol
)
493 struct bEntryBlock entry
;
495 if (vol
->curDirPtr
!=vol
->rootBlock
) {
496 if (adfReadEntryBlock( vol
, vol
->curDirPtr
, &entry
)!=RC_OK
)
498 vol
->curDirPtr
= entry
.parent
;
508 RETCODE
adfEntBlock2Entry(struct bEntryBlock
*entryBlk
, struct Entry
*entry
)
510 char buf
[MAXCMMTLEN
+1];
513 entry
->type
= entryBlk
->secType
;
514 entry
->parent
= entryBlk
->parent
;
516 len
= min(entryBlk
->nameLen
, MAXNAMELEN
);
517 strncpy(buf
, entryBlk
->name
, len
);
519 entry
->name
= strdup(buf
);
520 if (entry
->name
==NULL
)
522 //printf("len=%d name=%s parent=%ld\n",entryBlk->nameLen, entry->name,entry->parent );
523 adfDays2Date( entryBlk
->days
, &(entry
->year
), &(entry
->month
), &(entry
->days
));
524 entry
->hour
= entryBlk
->mins
/60;
525 entry
->mins
= entryBlk
->mins
%60;
526 entry
->secs
= entryBlk
->ticks
/50;
530 entry
->comment
= NULL
;
532 switch(entryBlk
->secType
) {
536 entry
->access
= entryBlk
->access
;
537 len
= min(entryBlk
->commLen
, MAXCMMTLEN
);
538 strncpy(buf
, entryBlk
->comment
, len
);
540 entry
->comment
= strdup(buf
);
541 if (entry
->comment
==NULL
) {
547 entry
->access
= entryBlk
->access
;
548 entry
->size
= entryBlk
->byteSize
;
549 len
= min(entryBlk
->commLen
, MAXCMMTLEN
);
550 strncpy(buf
, entryBlk
->comment
, len
);
552 entry
->comment
= strdup(buf
);
553 if (entry
->comment
==NULL
) {
560 entry
->real
= entryBlk
->realEntry
;
564 (*adfEnv
.wFct
)("unknown entry type");
575 SECTNUM
adfNameToEntryBlk(struct Volume
*vol
, long ht
[], char* name
,
576 struct bEntryBlock
*entry
, SECTNUM
*nUpdSect
)
579 unsigned char upperName
[MAXNAMELEN
+1];
580 unsigned char upperName2
[MAXNAMELEN
+1];
587 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
588 hashVal
= adfGetHashValue( (unsigned char*)name
, intl
);
589 nameLen
= strlen(name
);
590 myToUpper( upperName
, (unsigned char*)name
, nameLen
, intl
);
593 /*printf("name=%s ht[%d]=%d upper=%s len=%d\n",name,hashVal,nSect,upperName,nameLen);
594 printf("hashVal=%d\n",adfGetHashValue(upperName, intl ));
595 if (!strcmp("españa.country",name)) {
597 for(i=0; i<HT_SIZE; i++) printf("ht[%d]=%d ",i,ht[i]);
605 if (adfReadEntryBlock(vol
, nSect
, entry
)!=RC_OK
)
607 if (nameLen
==entry
->nameLen
) {
608 myToUpper( upperName2
, (unsigned char*)entry
->name
, nameLen
, intl
);
609 //printf("2=%s %s\n",upperName2,upperName);
610 found
= strncmp(upperName
, upperName2
, nameLen
)==0;
614 nSect
= entry
->nextSameHash
;
616 }while( !found
&& nSect
!=0 );
618 if ( nSect
==0 && !found
)
633 adfAccess2String(long acc
)
635 static char ret
[8+1];
637 strcpy(ret
,"----rwed");
638 if (hasD(acc
)) ret
[7]='-';
639 if (hasE(acc
)) ret
[6]='-';
640 if (hasW(acc
)) ret
[5]='-';
641 if (hasR(acc
)) ret
[4]='-';
642 if (hasA(acc
)) ret
[3]='a';
643 if (hasP(acc
)) ret
[2]='p';
644 if (hasS(acc
)) ret
[1]='s';
645 if (hasH(acc
)) ret
[0]='h';
654 * if 'thisSect'==-1, allocate a sector, and insert its pointer into the hashTable of 'dir', using the
655 * name 'name'. if 'thisSect'!=-1, insert this sector pointer into the hashTable
656 * (here 'thisSect' must be allocated before in the bitmap).
658 SECTNUM
adfCreateEntry(struct Volume
*vol
, struct bEntryBlock
*dir
, char *name
,
662 struct bEntryBlock updEntry
;
665 char name2
[MAXNAMELEN
+1], name3
[MAXNAMELEN
+1];
666 SECTNUM nSect
, newSect
, newSect2
;
667 struct bRootBlock
* root
;
669 //puts("adfCreateEntry in");
671 intl
= isINTL(vol
->dosType
) || isDIRCACHE(vol
->dosType
);
673 myToUpper((unsigned char*)name2
, (unsigned char*)name
, len
, intl
);
674 hashValue
= adfGetHashValue((unsigned char*)name
, intl
);
675 nSect
= dir
->hashTable
[ hashValue
];
681 newSect
= adfGet1FreeBlock(vol
);
683 (*adfEnv
.wFct
)("adfCreateEntry : nSect==-1");
688 dir
->hashTable
[ hashValue
] = newSect
;
689 if (dir
->secType
==ST_ROOT
) {
690 root
= (struct bRootBlock
*)dir
;
691 adfTime2AmigaTime(adfGiveCurrentTime(),
692 &(root
->cDays
),&(root
->cMins
),&(root
->cTicks
));
693 rc
=adfWriteRootBlock(vol
, vol
->rootBlock
, root
);
696 adfTime2AmigaTime(adfGiveCurrentTime(),&(dir
->days
),&(dir
->mins
),&(dir
->ticks
));
697 rc
=adfWriteDirBlock(vol
, dir
->headerKey
, (struct bDirBlock
*)dir
);
699 //puts("adfCreateEntry out, dir");
701 adfSetBlockFree(vol
, newSect
);
709 if (adfReadEntryBlock(vol
, nSect
, &updEntry
)!=RC_OK
)
711 if (updEntry
.nameLen
==len
) {
712 myToUpper((unsigned char*)name3
,(unsigned char*)updEntry
.name
,updEntry
.nameLen
,intl
);
713 if (strncmp(name3
,name2
,len
)==0) {
714 (*adfEnv
.wFct
)("adfCreateEntry : entry already exists");
718 nSect
= updEntry
.nextSameHash
;
724 newSect2
= adfGet1FreeBlock(vol
);
726 (*adfEnv
.wFct
)("adfCreateEntry : nSect==-1");
732 updEntry
.nextSameHash
= newSect2
;
733 if (updEntry
.secType
==ST_DIR
)
734 rc
=adfWriteDirBlock(vol
, updEntry
.headerKey
, (struct bDirBlock
*)&updEntry
);
735 else if (updEntry
.secType
==ST_FILE
)
736 rc
=adfWriteFileHdrBlock(vol
, updEntry
.headerKey
,
737 (struct bFileHeaderBlock
*)&updEntry
);
739 (*adfEnv
.wFct
)("adfCreateEntry : unknown entry type");
741 //puts("adfCreateEntry out, hash");
743 adfSetBlockFree(vol
, newSect2
);
758 adfIntlToUpper(unsigned char c
)
760 return (c
>='a' && c
<='z') || (c
>=224 && c
<=254 && c
!=247) ? c
- ('a'-'A') : c
;
764 adfToUpper(unsigned char c
)
766 return (c
>='a' && c
<='z') ? c
- ('a'-'A') : c
;
774 myToUpper( unsigned char *nstr
, unsigned char *ostr
, int nlen
, BOOL intl
)
779 for(i
=0; i
<nlen
; i
++)
780 nstr
[i
]=adfIntlToUpper(ostr
[i
]);
782 for(i
=0; i
<nlen
; i
++)
783 nstr
[i
]=adfToUpper(ostr
[i
]);
793 adfGetHashValue(unsigned char *name
, BOOL intl
)
795 unsigned long hash
, len
;
799 len
= hash
= strlen((char*)name
);
800 for(i
=0; i
<len
; i
++) {
802 upper
= adfIntlToUpper(name
[i
]);
804 upper
= toupper(name
[i
]);
805 hash
= (hash
* 13 + upper
) & 0x7ff;
807 hash
= hash
% HT_SIZE
;
817 void printEntry(struct Entry
* entry
)
819 printf("%-30s %2d %6ld ", entry
->name
, entry
->type
, entry
->sector
);
820 printf("%2d/%02d/%04d %2d:%02d:%02d",entry
->days
, entry
->month
, entry
->year
,
821 entry
->hour
, entry
->mins
, entry
->secs
);
822 if (entry
->type
==ST_FILE
)
823 printf("%8ld ",entry
->size
);
826 if (entry
->type
==ST_FILE
|| entry
->type
==ST_DIR
)
827 printf("%-s ",adfAccess2String(entry
->access
));
828 if (entry
->comment
!=NULL
)
829 printf("%s ",entry
->comment
);
838 RETCODE
adfCreateDir(struct Volume
* vol
, SECTNUM nParent
, char* name
)
841 struct bDirBlock dir
;
842 struct bEntryBlock parent
;
844 if (adfReadEntryBlock(vol
, nParent
, &parent
)!=RC_OK
)
847 /* -1 : do not use a specific, already allocated sector */
848 nSect
= adfCreateEntry(vol
, &parent
, name
, -1);
850 (*adfEnv
.wFct
)("adfCreateDir : no sector available");
853 memset(&dir
, 0, sizeof(struct bDirBlock
));
854 dir
.nameLen
= min(MAXNAMELEN
, strlen(name
));
855 memcpy(dir
.dirName
,name
,dir
.nameLen
);
856 dir
.headerKey
= nSect
;
858 if (parent
.secType
==ST_ROOT
)
859 dir
.parent
= vol
->rootBlock
;
861 dir
.parent
= parent
.headerKey
;
862 adfTime2AmigaTime(adfGiveCurrentTime(),&(dir
.days
),&(dir
.mins
),&(dir
.ticks
));
864 if (isDIRCACHE(vol
->dosType
)) {
865 /* for adfCreateEmptyCache, will be added by adfWriteDirBlock */
866 dir
.secType
= ST_DIR
;
867 adfAddInCache(vol
, &parent
, (struct bEntryBlock
*)&dir
);
868 adfCreateEmptyCache(vol
, (struct bEntryBlock
*)&dir
, -1);
871 /* writes the dirblock, with the possible dircache assiocated */
872 if (adfWriteDirBlock(vol
, nSect
, &dir
)!=RC_OK
)
875 adfUpdateBitmap(vol
);
877 if (adfEnv
.useNotify
)
878 (*adfEnv
.notifyFct
)(nParent
,ST_DIR
);
888 RETCODE
adfCreateFile(struct Volume
* vol
, SECTNUM nParent
, char *name
,
889 struct bFileHeaderBlock
*fhdr
)
892 struct bEntryBlock parent
;
893 //puts("adfCreateFile in");
894 if (adfReadEntryBlock(vol
, nParent
, &parent
)!=RC_OK
)
897 /* -1 : do not use a specific, already allocated sector */
898 nSect
= adfCreateEntry(vol
, &parent
, name
, -1);
899 if (nSect
==-1) return RC_ERROR
;
900 /*printf("new fhdr=%d\n",nSect);*/
902 fhdr
->nameLen
= min(MAXNAMELEN
, strlen(name
));
903 memcpy(fhdr
->fileName
,name
,fhdr
->nameLen
);
904 fhdr
->headerKey
= nSect
;
905 if (parent
.secType
==ST_ROOT
)
906 fhdr
->parent
= vol
->rootBlock
;
907 else if (parent
.secType
==ST_DIR
)
908 fhdr
->parent
= parent
.headerKey
;
910 (*adfEnv
.wFct
)("adfCreateFile : unknown parent secType");
911 adfTime2AmigaTime(adfGiveCurrentTime(),
912 &(fhdr
->days
),&(fhdr
->mins
),&(fhdr
->ticks
));
914 if (adfWriteFileHdrBlock(vol
,nSect
,fhdr
)!=RC_OK
)
917 if (isDIRCACHE(vol
->dosType
))
918 adfAddInCache(vol
, &parent
, (struct bEntryBlock
*)fhdr
);
920 adfUpdateBitmap(vol
);
922 if (adfEnv
.useNotify
)
923 (*adfEnv
.notifyFct
)(nParent
,ST_FILE
);
933 RETCODE
adfReadEntryBlock(struct Volume
* vol
, SECTNUM nSect
, struct bEntryBlock
*ent
)
935 unsigned char buf
[512];
937 if (adfReadBlock(vol
, nSect
, buf
)!=RC_OK
)
940 memcpy(ent
, buf
, 512);
942 swapEndian((unsigned char*)ent
, SWBL_ENTRY
);
944 /*printf("readentry=%d\n",nSect);*/
945 if (ent
->checkSum
!=adfNormalSum((unsigned char*)buf
,20,512)) {
946 (*adfEnv
.wFct
)("adfReadEntryBlock : invalid checksum");
949 if (ent
->type
!=T_HEADER
) {
950 (*adfEnv
.wFct
)("adfReadEntryBlock : T_HEADER id not found");
953 if (ent
->nameLen
<0 || ent
->nameLen
>MAXNAMELEN
|| ent
->commLen
>MAXCMMTLEN
) {
954 (*adfEnv
.wFct
)("adfReadEntryBlock : nameLen or commLen incorrect");
955 printf("nameLen=%d, commLen=%d, name=%s sector%ld\n",
956 ent
->nameLen
,ent
->commLen
,ent
->name
, ent
->headerKey
);
967 RETCODE
adfWriteEntryBlock(struct Volume
* vol
, SECTNUM nSect
, struct bEntryBlock
*ent
)
969 unsigned char buf
[512];
970 unsigned long newSum
;
973 memcpy(buf
, ent
, sizeof(struct bEntryBlock
));
976 swapEndian(buf
, SWBL_ENTRY
);
978 newSum
= adfNormalSum(buf
,20,sizeof(struct bEntryBlock
));
979 swLong(buf
+20, newSum
);
981 if (adfWriteBlock(vol
, nSect
, buf
)!=RC_OK
)
992 RETCODE
adfWriteDirBlock(struct Volume
* vol
, SECTNUM nSect
, struct bDirBlock
*dir
)
994 unsigned char buf
[512];
995 unsigned long newSum
;
998 /*printf("wdirblk=%d\n",nSect);*/
999 dir
->type
= T_HEADER
;
1001 dir
->hashTableSize
= 0;
1002 dir
->secType
= ST_DIR
;
1004 memcpy(buf
, dir
, sizeof(struct bDirBlock
));
1006 swapEndian(buf
, SWBL_DIR
);
1008 newSum
= adfNormalSum(buf
,20,sizeof(struct bDirBlock
));
1009 swLong(buf
+20, newSum
);
1011 if (adfWriteBlock(vol
, nSect
, buf
)!=RC_OK
)
1019 /*###########################################################################*/