compiler/clib/include: removed unused & unneeded files.
[AROS.git] / tools / adflib / adf_dir.c
blobabccc95e6e06a4f72fe8600f3fb8e3305f82ded8
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_dir.c
6 * directory code
7 */
9 #include<stdlib.h>
10 #include<string.h>
11 #include<ctype.h>
13 #include"adf_dir.h"
14 #include"adf_str.h"
15 #include"adf_util.h"
16 #include"defendian.h"
17 #include"adf_blk.h"
18 #include"adf_raw.h"
19 #include"adf_disk.h"
20 #include"adf_bitm.h"
21 #include"adf_file.h"
22 #include"adf_err.h"
23 #include"adf_cache.h"
25 extern struct Env adfEnv;
29 * adfRenameEntry
31 */
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];
39 BOOL intl;
40 RETCODE rc;
42 if (strcmp(oldName,newName)==0)
43 return RC_OK;
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)
52 return RC_ERROR;
54 hashValueO = adfGetHashValue((unsigned char*)oldName, intl);
56 nSect = adfNameToEntryBlk(vol, parent.hashTable, oldName, &entry, &prevSect);
57 if (nSect==-1) {
58 (*adfEnv.wFct)("adfRenameEntry : existing entry not found");
59 return RC_ERROR;
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)
70 return RC_ERROR;
72 /* del from the oldname list */
74 /* in hashTable */
75 if (prevSect==0) {
76 parent.hashTable[hashValueO] = tmpSect;
77 if (parent.secType==ST_ROOT)
78 rc = adfWriteRootBlock(vol, pSect, (struct bRootBlock*)&parent);
79 else
80 rc = adfWriteDirBlock(vol, pSect, (struct bDirBlock*)&parent);
81 if (rc!=RC_OK)
82 return rc;
84 else {
85 /* in linked list */
86 if (adfReadEntryBlock(vol, prevSect, &previous)!=RC_OK)
87 return RC_ERROR;
88 /* entry.nextSameHash (tmpSect) could be == 0 */
89 previous.nextSameHash = tmpSect;
90 if (adfWriteEntryBlock(vol, prevSect, &previous)!=RC_OK)
91 return RC_ERROR;
95 if (adfReadEntryBlock( vol, nPSect, &nParent )!=RC_OK)
96 return RC_ERROR;
98 hashValueN = adfGetHashValue((unsigned char*)newName, intl);
99 nSect2 = nParent.hashTable[ hashValueN ];
100 /* no list */
101 if (nSect2==0) {
102 nParent.hashTable[ hashValueN ] = nSect;
103 if (nParent.secType==ST_ROOT)
104 rc = adfWriteRootBlock(vol, nPSect, (struct bRootBlock*)&nParent);
105 else
106 rc = adfWriteDirBlock(vol, nPSect, (struct bDirBlock*)&nParent);
108 else {
109 /* a list exists : addition at the end */
110 /* len = strlen(newName);
111 * name2 == newName
113 do {
114 if (adfReadEntryBlock(vol, nSect2, &previous)!=RC_OK)
115 return -1;
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");
120 return -1;
123 nSect2 = previous.nextSameHash;
124 //printf("sect=%ld\n",nSect2);
125 }while(nSect2!=0);
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);
134 else {
135 (*adfEnv.wFct)("adfRenameEntry : unknown entry type");
136 rc = RC_ERROR;
140 if (rc!=RC_OK)
141 return rc;
143 if (isDIRCACHE(vol->dosType)) {
144 if (pSect==nPSect) {
145 adfUpdateCache(vol, &parent, (struct bEntryBlock*)&entry,TRUE);
147 else {
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);
157 return RC_OK;
161 * adfRemoveEntry
164 RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM pSect, char *name)
166 struct bEntryBlock parent, previous, entry;
167 SECTNUM nSect2, nSect;
168 int hashVal;
169 BOOL intl;
171 if (adfReadEntryBlock( vol, pSect, &parent )!=RC_OK)
172 return RC_ERROR;
173 nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, &nSect2);
174 if (nSect==-1) {
175 (*adfEnv.wFct)("adfRemoveEntry : entry not found");
176 return RC_ERROR;
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");
181 return RC_ERROR;
183 /* printf("name=%s nSect2=%ld\n",name, nSect2);*/
185 /* in parent hashTable */
186 if (nSect2==0) {
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)
193 return RC_ERROR;
195 /* in linked list */
196 else {
197 if (adfReadEntryBlock(vol, nSect2, &previous)!=RC_OK)
198 return RC_ERROR;
199 previous.nextSameHash = entry.nextSameHash;
200 if (adfWriteEntryBlock(vol, nSect2, &previous)!=RC_OK)
201 return RC_ERROR;
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);
217 else {
218 (*adfEnv.wFct)("adfRemoveEntry : secType not supported");
219 return RC_ERROR;
222 if (isDIRCACHE(vol->dosType))
223 adfDelFromCache(vol, &parent, entry.headerKey);
225 adfUpdateBitmap(vol);
227 return RC_OK;
232 * adfSetEntryComment
235 RETCODE adfSetEntryComment(struct Volume* vol, SECTNUM parSect, char* name,
236 char* newCmt)
238 struct bEntryBlock parent, entry;
239 SECTNUM nSect;
241 if (adfReadEntryBlock( vol, parSect, &parent )!=RC_OK)
242 return RC_ERROR;
243 nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, NULL);
244 if (nSect==-1) {
245 (*adfEnv.wFct)("adfSetEntryComment : entry not found");
246 return RC_ERROR;
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);
256 else
257 (*adfEnv.wFct)("adfSetEntryComment : entry secType incorrect");
259 if (isDIRCACHE(vol->dosType))
260 adfUpdateCache(vol, &parent, (struct bEntryBlock*)&entry, TRUE);
262 return RC_OK;
267 * adfSetEntryAccess
270 RETCODE adfSetEntryAccess(struct Volume* vol, SECTNUM parSect, char* name,
271 long newAcc)
273 struct bEntryBlock parent, entry;
274 SECTNUM nSect;
276 if (adfReadEntryBlock( vol, parSect, &parent )!=RC_OK)
277 return RC_ERROR;
278 nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, NULL);
279 if (nSect==-1) {
280 (*adfEnv.wFct)("adfSetEntryAccess : entry not found");
281 return RC_ERROR;
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);
289 else
290 (*adfEnv.wFct)("adfSetEntryAccess : entry secType incorrect");
292 if (isDIRCACHE(vol->dosType))
293 adfUpdateCache(vol, &parent, (struct bEntryBlock*)&entry, FALSE);
295 return RC_OK;
300 * isDirEmpty
303 BOOL isDirEmpty(struct bDirBlock *dir)
305 int i;
307 for(i=0; i<HT_SIZE; i++)
308 if (dir->hashTable[i]!=0)
309 return FALSE;
311 return TRUE;
316 * adfFreeDirList
319 void adfFreeDirList(struct List* list)
321 struct List *root, *cell;
323 root = cell = list;
324 while(cell!=NULL) {
325 adfFreeEntry(cell->content);
326 if (cell->subdir!=NULL)
327 adfFreeDirList(cell->subdir);
328 cell = cell->next;
330 freeList(root);
335 * adfGetRDirEnt
338 struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM nSect, BOOL recurs )
340 struct bEntryBlock entryBlk;
341 struct List *cell, *head;
342 int i;
343 struct Entry *entry;
344 SECTNUM nextSector;
345 long *hashTable;
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)
354 return NULL;
356 hashTable = parent.hashTable;
357 cell = head = NULL;
358 for(i=0; i<HT_SIZE; i++) {
359 if (hashTable[i]!=0) {
360 entry = (struct Entry *)malloc(sizeof(struct Entry));
361 if (!entry) {
362 adfFreeDirList(head);
363 (*adfEnv.eFct)("adfGetDirEnt : malloc");
364 return NULL;
366 if (adfReadEntryBlock(vol, hashTable[i], &entryBlk)!=RC_OK) {
367 adfFreeDirList(head);
368 return NULL;
370 if (adfEntBlock2Entry(&entryBlk, entry)!=RC_OK) {
371 adfFreeDirList(head); return NULL;
373 entry->sector = hashTable[i];
375 if (head==NULL)
376 head = cell = newCell(0, (void*)entry);
377 else
378 cell = newCell(cell, (void*)entry);
379 if (cell==NULL) {
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));
390 if (!entry) {
391 adfFreeDirList(head);
392 (*adfEnv.eFct)("adfGetDirEnt : malloc");
393 return NULL;
395 if (adfReadEntryBlock(vol, nextSector, &entryBlk)!=RC_OK) {
396 adfFreeDirList(head); return NULL;
399 if (adfEntBlock2Entry(&entryBlk, entry)!=RC_OK) {
400 adfFreeDirList(head);
401 return NULL;
403 entry->sector = nextSector;
405 cell = newCell(cell, (void*)entry);
406 if (cell==NULL) {
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);
421 return head;
426 * adfGetDirEnt
429 struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect )
431 return adfGetRDirEnt(vol, nSect, FALSE);
436 * adfFreeEntry
439 void adfFreeEntry(struct Entry *entry)
441 if (entry==NULL)
442 return;
443 if (entry->name)
444 free(entry->name);
445 if (entry->comment)
446 free(entry->comment);
447 free(entry);
452 * adfToRootDir
455 RETCODE adfToRootDir(struct Volume *vol)
457 vol->curDirPtr = vol->rootBlock;
459 return RC_OK;
464 * adfChangeDir
467 RETCODE adfChangeDir(struct Volume* vol, char *name)
469 struct bEntryBlock entry;
470 SECTNUM nSect;
472 if (adfReadEntryBlock( vol, vol->curDirPtr, &entry )!=RC_OK)
473 return RC_ERROR;
474 nSect = adfNameToEntryBlk(vol, entry.hashTable, name, &entry, NULL);
475 /*printf("adfChangeDir=%d\n",nSect);*/
476 if (nSect!=-1) {
477 vol->curDirPtr = nSect;
478 /* if (*adfEnv.useNotify)
479 (*adfEnv.notifyFct)(0,ST_ROOT);*/
480 return RC_OK;
482 else
483 return RC_ERROR;
488 * adfParentDir
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)
497 return RC_ERROR;
498 vol->curDirPtr = entry.parent;
500 return RC_OK;
505 * adfEntBlock2Entry
508 RETCODE adfEntBlock2Entry(struct bEntryBlock *entryBlk, struct Entry *entry)
510 char buf[MAXCMMTLEN+1];
511 int len;
513 entry->type = entryBlk->secType;
514 entry->parent = entryBlk->parent;
516 len = min(entryBlk->nameLen, MAXNAMELEN);
517 strncpy(buf, entryBlk->name, len);
518 buf[len] = '\0';
519 entry->name = strdup(buf);
520 if (entry->name==NULL)
521 return RC_MALLOC;
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;
528 entry->access = -1;
529 entry->size = 0L;
530 entry->comment = NULL;
531 entry->real = 0L;
532 switch(entryBlk->secType) {
533 case ST_ROOT:
534 break;
535 case ST_DIR:
536 entry->access = entryBlk->access;
537 len = min(entryBlk->commLen, MAXCMMTLEN);
538 strncpy(buf, entryBlk->comment, len);
539 buf[len] = '\0';
540 entry->comment = strdup(buf);
541 if (entry->comment==NULL) {
542 free(entry->name);
543 return RC_MALLOC;
545 break;
546 case ST_FILE:
547 entry->access = entryBlk->access;
548 entry->size = entryBlk->byteSize;
549 len = min(entryBlk->commLen, MAXCMMTLEN);
550 strncpy(buf, entryBlk->comment, len);
551 buf[len] = '\0';
552 entry->comment = strdup(buf);
553 if (entry->comment==NULL) {
554 free(entry->name);
555 return RC_MALLOC;
557 break;
558 case ST_LFILE:
559 case ST_LDIR:
560 entry->real = entryBlk->realEntry;
561 case ST_LSOFT:
562 break;
563 default:
564 (*adfEnv.wFct)("unknown entry type");
567 return RC_OK;
572 * adfNameToEntryBlk
575 SECTNUM adfNameToEntryBlk(struct Volume *vol, long ht[], char* name,
576 struct bEntryBlock *entry, SECTNUM *nUpdSect)
578 int hashVal;
579 unsigned char upperName[MAXNAMELEN+1];
580 unsigned char upperName2[MAXNAMELEN+1];
581 SECTNUM nSect;
582 int nameLen;
583 BOOL found;
584 SECTNUM updSect;
585 BOOL intl;
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 );
592 nSect = ht[hashVal];
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)) {
596 int i;
597 for(i=0; i<HT_SIZE; i++) printf("ht[%d]=%d ",i,ht[i]);
599 if (nSect==0)
600 return -1;
602 updSect = 0;
603 found = FALSE;
604 do {
605 if (adfReadEntryBlock(vol, nSect, entry)!=RC_OK)
606 return -1;
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;
612 if (!found) {
613 updSect = nSect;
614 nSect = entry->nextSameHash;
616 }while( !found && nSect!=0 );
618 if ( nSect==0 && !found )
619 return -1;
620 else {
621 if (nUpdSect!=NULL)
622 *nUpdSect = updSect;
623 return nSect;
629 * Access2String
632 char*
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';
647 return(ret);
652 * adfCreateEntry
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,
659 SECTNUM thisSect )
661 BOOL intl;
662 struct bEntryBlock updEntry;
663 int len, hashValue;
664 RETCODE rc;
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);
672 len = strlen(name);
673 myToUpper((unsigned char*)name2, (unsigned char*)name, len, intl);
674 hashValue = adfGetHashValue((unsigned char*)name, intl);
675 nSect = dir->hashTable[ hashValue ];
677 if ( nSect==0 ) {
678 if (thisSect!=-1)
679 newSect = thisSect;
680 else {
681 newSect = adfGet1FreeBlock(vol);
682 if (newSect==-1) {
683 (*adfEnv.wFct)("adfCreateEntry : nSect==-1");
684 return -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);
695 else {
696 adfTime2AmigaTime(adfGiveCurrentTime(),&(dir->days),&(dir->mins),&(dir->ticks));
697 rc=adfWriteDirBlock(vol, dir->headerKey, (struct bDirBlock*)dir);
699 //puts("adfCreateEntry out, dir");
700 if (rc!=RC_OK) {
701 adfSetBlockFree(vol, newSect);
702 return -1;
704 else
705 return( newSect );
708 do {
709 if (adfReadEntryBlock(vol, nSect, &updEntry)!=RC_OK)
710 return -1;
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");
715 return -1;
718 nSect = updEntry.nextSameHash;
719 }while(nSect!=0);
721 if (thisSect!=-1)
722 newSect2 = thisSect;
723 else {
724 newSect2 = adfGet1FreeBlock(vol);
725 if (newSect2==-1) {
726 (*adfEnv.wFct)("adfCreateEntry : nSect==-1");
727 return -1;
731 rc = RC_OK;
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);
738 else
739 (*adfEnv.wFct)("adfCreateEntry : unknown entry type");
741 //puts("adfCreateEntry out, hash");
742 if (rc!=RC_OK) {
743 adfSetBlockFree(vol, newSect2);
744 return -1;
746 else
747 return(newSect2);
754 * adfIntlToUpper
757 unsigned char
758 adfIntlToUpper(unsigned char c)
760 return (c>='a' && c<='z') || (c>=224 && c<=254 && c!=247) ? c - ('a'-'A') : c ;
763 unsigned char
764 adfToUpper(unsigned char c)
766 return (c>='a' && c<='z') ? c - ('a'-'A') : c ;
770 * myToUpper
773 void
774 myToUpper( unsigned char *nstr, unsigned char *ostr, int nlen, BOOL intl )
776 int i;
778 if (intl)
779 for(i=0; i<nlen; i++)
780 nstr[i]=adfIntlToUpper(ostr[i]);
781 else
782 for(i=0; i<nlen; i++)
783 nstr[i]=adfToUpper(ostr[i]);
784 nstr[nlen]='\0';
789 * adfGetHashValue
792 int
793 adfGetHashValue(unsigned char *name, BOOL intl)
795 unsigned long hash, len;
796 unsigned int i;
797 unsigned char upper;
799 len = hash = strlen((char*)name);
800 for(i=0; i<len; i++) {
801 if (intl)
802 upper = adfIntlToUpper(name[i]);
803 else
804 upper = toupper(name[i]);
805 hash = (hash * 13 + upper) & 0x7ff;
807 hash = hash % HT_SIZE;
809 return(hash);
814 * printEntry
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);
824 else
825 printf(" ");
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);
830 putchar('\n');
835 * adfCreateDir
838 RETCODE adfCreateDir(struct Volume* vol, SECTNUM nParent, char* name)
840 SECTNUM nSect;
841 struct bDirBlock dir;
842 struct bEntryBlock parent;
844 if (adfReadEntryBlock(vol, nParent, &parent)!=RC_OK)
845 return RC_ERROR;
847 /* -1 : do not use a specific, already allocated sector */
848 nSect = adfCreateEntry(vol, &parent, name, -1);
849 if (nSect==-1) {
850 (*adfEnv.wFct)("adfCreateDir : no sector available");
851 return RC_ERROR;
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;
860 else
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)
873 return RC_ERROR;
875 adfUpdateBitmap(vol);
877 if (adfEnv.useNotify)
878 (*adfEnv.notifyFct)(nParent,ST_DIR);
880 return RC_OK;
885 * adfCreateFile
888 RETCODE adfCreateFile(struct Volume* vol, SECTNUM nParent, char *name,
889 struct bFileHeaderBlock *fhdr)
891 SECTNUM nSect;
892 struct bEntryBlock parent;
893 //puts("adfCreateFile in");
894 if (adfReadEntryBlock(vol, nParent, &parent)!=RC_OK)
895 return RC_ERROR;
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);*/
901 memset(fhdr,0,512);
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;
909 else
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)
915 return RC_ERROR;
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);
925 return RC_OK;
930 * adfReadEntryBlock
933 RETCODE adfReadEntryBlock(struct Volume* vol, SECTNUM nSect, struct bEntryBlock *ent)
935 unsigned char buf[512];
937 if (adfReadBlock(vol, nSect, buf)!=RC_OK)
938 return RC_ERROR;
940 memcpy(ent, buf, 512);
941 #ifdef LITT_ENDIAN
942 swapEndian((unsigned char*)ent, SWBL_ENTRY);
943 #endif
944 /*printf("readentry=%d\n",nSect);*/
945 if (ent->checkSum!=adfNormalSum((unsigned char*)buf,20,512)) {
946 (*adfEnv.wFct)("adfReadEntryBlock : invalid checksum");
947 return RC_ERROR;
949 if (ent->type!=T_HEADER) {
950 (*adfEnv.wFct)("adfReadEntryBlock : T_HEADER id not found");
951 return RC_ERROR;
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);
959 return RC_OK;
964 * adfWriteEntryBlock
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));
975 #ifdef LITT_ENDIAN
976 swapEndian(buf, SWBL_ENTRY);
977 #endif
978 newSum = adfNormalSum(buf,20,sizeof(struct bEntryBlock));
979 swLong(buf+20, newSum);
981 if (adfWriteBlock(vol, nSect, buf)!=RC_OK)
982 return RC_ERROR;
984 return RC_OK;
989 * adfWriteDirBlock
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;
1000 dir->highSeq = 0;
1001 dir->hashTableSize = 0;
1002 dir->secType = ST_DIR;
1004 memcpy(buf, dir, sizeof(struct bDirBlock));
1005 #ifdef LITT_ENDIAN
1006 swapEndian(buf, SWBL_DIR);
1007 #endif
1008 newSum = adfNormalSum(buf,20,sizeof(struct bDirBlock));
1009 swLong(buf+20, newSum);
1011 if (adfWriteBlock(vol, nSect, buf)!=RC_OK)
1012 return RC_ERROR;
1014 return RC_OK;
1019 /*###########################################################################*/