5 /******************************** RDB definitions */
6 #define RDB_LOCATION_LIMIT 16
7 #define IDNAME_RIGIDDISK 0x5244534B /* 'RDSK' */
12 unsigned long rdb_SummedLongs;
14 unsigned long rdb_HostID;
15 unsigned long rdb_BlockBytes;
16 unsigned long rdb_Flags;
17 unsigned long rdb_BadBlockList;
18 unsigned long rdb_PartitionList;
19 unsigned long rdb_FileSysHeaderList;
20 unsigned long rdb_DriveInit;
21 unsigned long rdb_Reserved1[6];
22 unsigned long rdb_Cylinders;
23 unsigned long rdb_Sectors;
24 unsigned long rdb_Heads;
25 unsigned long rdb_Interleave;
26 unsigned long rdb_Park;
27 unsigned long rdb_Reserved2[3];
28 unsigned long rdb_WritePreComp;
29 unsigned long rdb_ReducedWrite;
30 unsigned long rdb_StepRate;
31 unsigned long rdb_Reserved3[5];
32 unsigned long rdb_RDBBlocksLo;
33 unsigned long rdb_RDBBlocksHi;
34 unsigned long rdb_LoCylinder;
35 unsigned long rdb_HiCylinder;
36 unsigned long rdb_CylBlocks;
37 unsigned long rdb_AutoParkSeconds;
38 unsigned long rdb_HighRDSKBlock;
39 unsigned long rdb_Reserved4;
40 char rdb_DiskVendor[8];
41 char rdb_DiskProduct[16];
42 char rdb_DiskRevision[4];
43 char rdb_ControllerVendor[8];
44 char rdb_ControllerProduct[16];
45 char rdb_ControllerRevision[4];
46 char rdb_DriveInitName[40];
52 unsigned long pb_SummedLongs;
54 unsigned long pb_HostID;
55 unsigned long pb_Next;
56 unsigned long pb_Flags;
57 unsigned long pb_Reserved1[2];
58 unsigned long pb_DevFlags;
59 char pb_DriveName[32];
60 unsigned long pb_Reserved2[15];
61 unsigned long pb_Environment[20];
62 unsigned long pb_EReserved[12];
65 #define DE_TABLESIZE 0
66 #define DE_SIZEBLOCK 1
67 #define DE_BLOCKSIZE 2
69 #define DE_SECSPERBLOCK 4
70 #define DE_BLKSPERTRACK 5
71 #define DE_RESERVEDBLKS 6
73 #define DE_INTERLEAVE 8
76 #define DE_UPPERCYL DE_HIGHCYL
77 #define DE_NUMBUFFERS 11
78 #define DE_BUFMEMTYPE 12
79 #define DE_MEMBUFTYPE DE_BUFMEMTYPE
80 #define DE_MAXTRANSFER 13
86 #define DE_BOOTBLOCKS 19
89 /******************************** AFFS definitions */
107 int hashtable_size; //3
110 int hashtable[72]; //6-77
111 int bitmap_valid_flag; //78
112 int bitmap_ptrs[25]; //79-103
113 int bitmap_extension; //104
116 int root_ticks; //107;
117 char diskname[32]; //108-115
119 int volume_days; //118
120 int volume_mins; //119
121 int volume_ticks; //120
122 int creation_days; //121
123 int creation_mins; //122
124 int creation_ticks; //123
134 int hashtable[72]; //6-77
139 char comment[92]; //82-104
143 char name[32]; //108-115
158 int filekey_table[72]; //6-77
163 char comment[92]; //82-104
167 char name[32]; //108-115
177 struct FileKeyExtension{
183 int filekey_table[72]; //6-77
184 int info[46]; //78-123
199 unsigned int header_block;
200 struct Position current;
201 unsigned int filesize;
204 //#warning "Big vs. little endian for configure needed"
205 #define AROS_BE2LONG(l) \
207 ((((unsigned long)(l)) >> 24) & 0x000000FFUL) | \
208 ((((unsigned long)(l)) >> 8) & 0x0000FF00UL) | \
209 ((((unsigned long)(l)) << 8) & 0x00FF0000UL) | \
210 ((((unsigned long)(l)) << 24) & 0xFF000000UL) \
215 unsigned short flags;
216 unsigned short access_count;
217 unsigned int blockbuffer[128];
219 #define LockBuffer(x) (((struct CacheBlock *)(x))->flags |= 0x0001)
220 #define UnLockBuffer(x) (((struct CacheBlock *)(x))->flags &= ~0x0001)
222 #define MAX_CACHE_BLOCKS 10
225 struct ReadData file;
226 struct CacheBlock blocks[MAX_CACHE_BLOCKS];
229 #define bootBlock(x) ((struct BootBlock *)(x)->blockbuffer)
230 #define rootBlock(x) ((struct RootBlock *)(x)->blockbuffer)
231 #define dirHeader(x) ((struct DirHeader *)(x)->blockbuffer)
232 #define fileHeader(x) ((struct FileHeader *)(x)->blockbuffer)
233 #define extensionBlock(x) ((struct FileKeyExtension *)(x)->blockbuffer)
235 #define rdsk(x) ((struct RigidDiskBlock *)(x)->blockbuffer)
236 #define part(x) ((struct PartitionBlock *)(x)->blockbuffer)
238 static struct FSysBuffer *fsysb;
239 static int blockoffset; /* offset if there is an embedded RDB partition */
240 static int rootb; /* block number of root block */
241 static int rdbb; /* block number of rdb block */
243 static void initCache(void)
247 for (i=0;i<MAX_CACHE_BLOCKS;i++)
249 fsysb->blocks[i].blocknum = -1;
250 fsysb->blocks[i].flags = 0;
251 fsysb->blocks[i].access_count = 0;
255 static struct CacheBlock *getBlock(unsigned int block)
257 struct CacheBlock *freeblock;
260 /* get first unlocked block */
264 freeblock = &fsysb->blocks[i++];
265 } while (freeblock->flags & 0x0001);
266 /* search through list if block is already loaded in */
267 for (i=0;i<MAX_CACHE_BLOCKS;i++)
269 if (fsysb->blocks[i].blocknum == block)
271 fsysb->blocks[i].access_count++;
272 return &fsysb->blocks[i];
274 if (!(fsysb->blocks[i].flags & 0x0001))
275 if (freeblock->access_count>fsysb->blocks[i].access_count)
276 freeblock = &fsysb->blocks[i];
278 freeblock->blocknum = block;
279 devread(block+blockoffset, 0, 512, (char *)freeblock->blockbuffer);
283 static unsigned int calcChkSum(unsigned short SizeBlock, unsigned int *buffer)
285 unsigned int sum=0,count=0;
287 for (count=0;count<SizeBlock;count++)
288 sum += AROS_BE2LONG(buffer[count]);
292 int affs_mount(void) {
293 struct CacheBlock *cblock;
297 (current_drive & 0x80) &&
298 (current_partition != 0xFFFFFF) &&
299 (current_slice != 0x30)
302 fsysb = (struct FSysBuffer *)FSYS_BUF;
305 /* check for rdb partitiontable */
306 for (i=0;i<RDB_LOCATION_LIMIT;i++)
308 cblock = getBlock(i);
311 ((AROS_BE2LONG(bootBlock(cblock)->id) & 0xFFFFFF00)==0x444F5300) &&
312 ((AROS_BE2LONG(bootBlock(cblock)->id) & 0xFF)>0)
314 (AROS_BE2LONG(cblock->blockbuffer[0]) == IDNAME_RIGIDDISK)
318 if (i == RDB_LOCATION_LIMIT)
320 if (AROS_BE2LONG(cblock->blockbuffer[0]) == IDNAME_RIGIDDISK)
322 /* we have an RDB partition table within a MBR-Partition */
327 /* partition type is 0x30 = AROS and AFFS formatted */
328 rdbb = RDB_LOCATION_LIMIT;
329 rootb = (part_length-1+2)/2;
330 cblock = getBlock(rootb);
332 (AROS_BE2LONG(rootBlock(cblock)->p_type) != T_SHORT) ||
333 (AROS_BE2LONG(rootBlock(cblock)->s_type) != ST_ROOT) ||
334 calcChkSum(128, cblock->blockbuffer)
343 static int seek(unsigned long offset)
345 struct CacheBlock *cblock;
349 block = fsysb->file.header_block;
352 fsysb->file.current.filekey = 71-(togo % 72);
354 fsysb->file.current.byte = offset % 512;
355 fsysb->file.current.offset = offset;
356 while ((togo) && (block))
358 disk_read_func = disk_read_hook;
359 cblock = getBlock(block);
360 disk_read_func = NULL;
361 block = AROS_BE2LONG(extensionBlock(cblock)->extension);
366 fsysb->file.current.block = block;
370 int affs_read(char *buf, int len) {
371 struct CacheBlock *cblock;
373 unsigned int readbytes = 0;
375 if (fsysb->file.current.offset != filepos)
378 return ERR_FILELENGTH;
380 if (fsysb->file.current.block == 0)
382 if (len>(fsysb->file.filesize-fsysb->file.current.offset))
383 len=fsysb->file.filesize-fsysb->file.current.offset;
384 disk_read_func = disk_read_hook;
385 cblock = getBlock(fsysb->file.current.block);
386 disk_read_func = NULL;
389 disk_read_func = disk_read_hook;
390 if (fsysb->file.current.filekey<0)
392 fsysb->file.current.filekey = 71;
393 fsysb->file.current.block = AROS_BE2LONG(extensionBlock(cblock)->extension);
394 if (fsysb->file.current.block)
396 cblock = getBlock(fsysb->file.current.block);
398 //#warning "else shouldn't occour"
401 size -= fsysb->file.current.byte;
409 extensionBlock(cblock)->filekey_table
410 [fsysb->file.current.filekey]
412 fsysb->file.current.byte, size, (char *)((long)buf+readbytes)
414 fsysb->file.current.byte += size;
422 extensionBlock(cblock)->filekey_table
423 [fsysb->file.current.filekey]
425 fsysb->file.current.byte, size, (char *)((long)buf+readbytes)
427 fsysb->file.current.byte = 0;
428 fsysb->file.current.filekey--;
430 disk_read_func = NULL;
434 fsysb->file.current.offset += readbytes;
435 filepos = fsysb->file.current.offset;
439 static unsigned char capitalch(unsigned char ch, unsigned char flags)
442 if ((flags==0) || (flags==1))
443 return (unsigned char)((ch>='a') && (ch<='z') ? ch-('a'-'A') : ch);
445 return (unsigned char)(((ch>=224) && (ch<=254) && (ch!=247)) ||
446 ((ch>='a') && (ch<='z')) ? ch-('a'-'A') : ch);
449 // str2 is a BCPL string
450 static int noCaseStrCmp(char *str1, char *str2, unsigned char flags)
452 unsigned char length;
456 if ((*str1==0) && (length==0))
459 // if ((*str1==0) && (*str2==0)) return 1;
460 } while (capitalch(*str1++,flags)==capitalch(*str2++,flags));
462 return (*str1) ? 1 : -1;
465 static unsigned int getHashKey(char *name,unsigned int tablesize, unsigned char flags)
470 while (name[length] != 0)
473 length=(length * 13 +capitalch(*name++,flags)) & 0x7FF;
474 return length%tablesize;
477 static grub_error_t getHeaderBlock(char *name, struct CacheBlock **dirh)
481 key = getHashKey(name, 72, 1);
482 if (!dirHeader(*dirh)->hashtable[key])
483 return ERR_FILE_NOT_FOUND;
484 *dirh = getBlock(AROS_BE2LONG(dirHeader(*dirh)->hashtable[key]));
485 if (calcChkSum(128, (*dirh)->blockbuffer))
488 printf("ghb: %d\n", (*dirh)->blocknum);
490 return ERR_FSYS_CORRUPT;
492 if (AROS_BE2LONG(dirHeader(*dirh)->p_type) != T_SHORT)
493 return ERR_BAD_FILETYPE;
494 while (noCaseStrCmp(name,dirHeader(*dirh)->name,1) != 0)
496 if (!dirHeader(*dirh)->hashchain)
497 return ERR_FILE_NOT_FOUND;
498 *dirh = getBlock(AROS_BE2LONG(dirHeader(*dirh)->hashchain));
499 if (calcChkSum(128, (*dirh)->blockbuffer))
502 printf("ghb2: %d\n", (*dirh)->blocknum);
504 return ERR_FSYS_CORRUPT;
506 if (AROS_BE2LONG(dirHeader(*dirh)->p_type) != T_SHORT)
507 return ERR_BAD_FILETYPE;
512 static char *copyPart(char *src, char *dst)
514 while ((*src != '/') && (*src))
519 /* cut off spaces at the end */
525 static grub_error_t findBlock(char *name, struct CacheBlock **dirh)
530 name++; /* skip "/" */
531 /* partition table part */
532 if (rdbb < RDB_LOCATION_LIMIT)
537 *dirh = getBlock(rdbb);
540 name = copyPart(name, dname);
541 bpc = AROS_BE2LONG(rdsk(*dirh)->rdb_Sectors)*AROS_BE2LONG(rdsk(*dirh)->rdb_Heads);
542 block = AROS_BE2LONG(rdsk(*dirh)->rdb_PartitionList);
545 *dirh = getBlock(block);
546 if (noCaseStrCmp(dname, part(*dirh)->pb_DriveName, 1) == 0)
548 block = AROS_BE2LONG(part(*dirh)->pb_Next);
551 return ERR_FILE_NOT_FOUND;
553 ((AROS_BE2LONG(part(*dirh)->pb_Environment[DE_DOSTYPE]) & 0xFFFFFF00)!=0x444F5300) ||
554 ((AROS_BE2LONG(part(*dirh)->pb_Environment[DE_DOSTYPE]) & 0xFF)==0)
556 return ERR_BAD_FILETYPE;
557 blockoffset = AROS_BE2LONG(part(*dirh)->pb_Environment[DE_LOWCYL]);
558 rootb = AROS_BE2LONG(part(*dirh)->pb_Environment[DE_HIGHCYL]);
559 rootb = rootb-blockoffset+1; /* highcyl-lowcyl+1 */
561 rootb = rootb-1+AROS_BE2LONG(part(*dirh)->pb_Environment[DE_RESERVEDBLKS]);
566 /* filesystem part */
567 *dirh = getBlock(rootb);
571 (AROS_BE2LONG(dirHeader(*dirh)->s_type) != ST_ROOT) &&
572 (AROS_BE2LONG(dirHeader(*dirh)->s_type) != ST_USERDIR)
574 return ERR_BAD_FILETYPE;
575 name = copyPart(name, dname);
576 errnum = getHeaderBlock(dname, dirh);
584 static void checkPossibility(char *filename, char *bstr)
588 if (noCaseStrCmp(filename, bstr, 1)<=0)
590 if (print_possibilities>0)
591 print_possibilities = -print_possibilities;
592 memcpy(cstr, bstr+1, bstr[0]);
594 print_a_completion(cstr);
598 #define checkPossibility(a, b) do { } while(0)
601 int affs_dir(char *dirname)
603 struct CacheBlock *buffer1;
604 struct CacheBlock *buffer2;
605 char *current = dirname;
607 char *fname = filename;
610 if (print_possibilities)
614 while (*current != '/')
623 errnum = findBlock(dirname, &buffer1);
626 if (AROS_BE2LONG(dirHeader(buffer1)->p_type) == IDNAME_RIGIDDISK)
628 block = AROS_BE2LONG(rdsk(buffer1)->rdb_PartitionList);
631 buffer1 = getBlock(block);
632 checkPossibility(filename, part(buffer1)->pb_DriveName);
633 block = AROS_BE2LONG(part(buffer1)->pb_Next);
637 if (print_possibilities>0)
638 print_possibilities = -print_possibilities;
641 else if (AROS_BE2LONG(dirHeader(buffer1)->p_type) == T_SHORT)
646 block = dirHeader(buffer1)->hashtable[i];
649 buffer2 = getBlock(AROS_BE2LONG(block));
650 if (calcChkSum(128, buffer2->blockbuffer))
652 errnum = ERR_FSYS_CORRUPT;
655 if (AROS_BE2LONG(dirHeader(buffer2)->p_type) != T_SHORT)
657 errnum = ERR_BAD_FILETYPE;
660 checkPossibility(filename, dirHeader(buffer2)->name);
661 block = dirHeader(buffer2)->hashchain;
664 UnLockBuffer(buffer1);
667 if (print_possibilities>0)
668 print_possibilities = -print_possibilities;
673 errnum = ERR_BAD_FILETYPE;
676 while (*current != '/')
681 *current++ = *fname++;
682 //#warning "TODO: add some more chars until possibilities differ"
683 if (print_possibilities>0)
684 errnum = ERR_FILE_NOT_FOUND;
685 return (print_possibilities<0);
689 while (*current && !isspace(*current))
690 *fname++ = *current++;
693 errnum = findBlock(filename, &buffer2);
696 if (AROS_BE2LONG(fileHeader(buffer2)->s_type)!=ST_FILE)
698 errnum = ERR_BAD_FILETYPE;
701 fsysb->file.header_block = AROS_BE2LONG(fileHeader(buffer2)->own_key);
702 fsysb->file.current.block = AROS_BE2LONG(fileHeader(buffer2)->own_key);
703 fsysb->file.current.filekey = 71;
704 fsysb->file.current.byte = 0;
705 fsysb->file.current.offset = 0;
706 fsysb->file.filesize = AROS_BE2LONG(fileHeader(buffer2)->bytesize);
708 filemax = fsysb->file.filesize;