|
|
1.1 ! root 1: #ifdef FSYS_AFFS ! 2: #include "shared.h" ! 3: #include "filesys.h" ! 4: ! 5: /******************************** RDB definitions */ ! 6: #define RDB_LOCATION_LIMIT 16 ! 7: #define IDNAME_RIGIDDISK 0x5244534B /* 'RDSK' */ ! 8: ! 9: struct RigidDiskBlock ! 10: { ! 11: unsigned long rdb_ID; ! 12: unsigned long rdb_SummedLongs; ! 13: long rdb_ChkSum; ! 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]; ! 47: }; ! 48: ! 49: struct PartitionBlock ! 50: { ! 51: unsigned long pb_ID; ! 52: unsigned long pb_SummedLongs; ! 53: long pb_ChkSum; ! 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]; ! 63: }; ! 64: ! 65: #define DE_TABLESIZE 0 ! 66: #define DE_SIZEBLOCK 1 ! 67: #define DE_BLOCKSIZE 2 ! 68: #define DE_NUMHEADS 3 ! 69: #define DE_SECSPERBLOCK 4 ! 70: #define DE_BLKSPERTRACK 5 ! 71: #define DE_RESERVEDBLKS 6 ! 72: #define DE_PREFAC 7 ! 73: #define DE_INTERLEAVE 8 ! 74: #define DE_LOWCYL 9 ! 75: #define DE_HIGHCYL 10 ! 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 ! 81: #define DE_MASK 14 ! 82: #define DE_BOOTPRI 15 ! 83: #define DE_DOSTYPE 16 ! 84: #define DE_BAUD 17 ! 85: #define DE_CONTROL 18 ! 86: #define DE_BOOTBLOCKS 19 ! 87: ! 88: ! 89: /******************************** AFFS definitions */ ! 90: #define T_SHORT 2 ! 91: #define T_LIST 16 ! 92: ! 93: #define ST_FILE -3 ! 94: #define ST_ROOT 1 ! 95: #define ST_USERDIR 2 ! 96: ! 97: struct BootBlock{ ! 98: int id; ! 99: int chksum; ! 100: int rootblock; ! 101: int data[127]; ! 102: }; ! 103: ! 104: struct RootBlock{ ! 105: int p_type; //0 ! 106: int n1[2]; //1-2 ! 107: int hashtable_size; //3 ! 108: int n2; //4 ! 109: int checksum; //5 ! 110: int hashtable[72]; //6-77 ! 111: int bitmap_valid_flag; //78 ! 112: int bitmap_ptrs[25]; //79-103 ! 113: int bitmap_extension; //104 ! 114: int root_days; //105 ! 115: int root_mins; //106 ! 116: int root_ticks; //107; ! 117: char diskname[32]; //108-115 ! 118: int n3[2]; //116-117 ! 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 ! 125: int n4[3]; //124-126 ! 126: int s_type; //127 ! 127: }; ! 128: ! 129: struct DirHeader { ! 130: int p_type; //0 ! 131: int own_key; //1 ! 132: int n1[3]; //2-4 ! 133: int checksum; //5 ! 134: int hashtable[72]; //6-77 ! 135: int n2; //78 ! 136: int owner; //79 ! 137: int protection; //80 ! 138: int n3; //81 ! 139: char comment[92]; //82-104 ! 140: int days; //105 ! 141: int mins; //106 ! 142: int ticks; //107 ! 143: char name[32]; //108-115 ! 144: int n4[2]; //116-117 ! 145: int linkchain; //118 ! 146: int n5[5]; //119-123 ! 147: int hashchain; //124 ! 148: int parent; //125 ! 149: int n6; //126 ! 150: int s_type; //127 ! 151: }; ! 152: ! 153: struct FileHeader { ! 154: int p_type; //0 ! 155: int own_key; //1 ! 156: int n1[3]; //2-4 ! 157: int checksum; //5 ! 158: int filekey_table[72]; //6-77 ! 159: int n2; //78 ! 160: int owner; //79 ! 161: int protection; //80 ! 162: int bytesize; //81 ! 163: char comment[92]; //82-104 ! 164: int days; //105 ! 165: int mins; //106 ! 166: int ticks; //107 ! 167: char name[32]; //108-115 ! 168: int n3[2]; //116-117 ! 169: int linkchain; //118 ! 170: int n4[5]; //119-123 ! 171: int hashchain; //124 ! 172: int parent; //125 ! 173: int extension; //126 ! 174: int s_type; //127 ! 175: }; ! 176: ! 177: struct FileKeyExtension{ ! 178: int p_type; //0 ! 179: int own_key; //1 ! 180: int table_size; //2 ! 181: int n1[2]; //3-4 ! 182: int checksum; //5 ! 183: int filekey_table[72]; //6-77 ! 184: int info[46]; //78-123 ! 185: int n2; //124 ! 186: int parent; //125 ! 187: int extension; //126 ! 188: int s_type; //127 ! 189: }; ! 190: ! 191: struct Position { ! 192: unsigned int block; ! 193: short filekey; ! 194: unsigned short byte; ! 195: unsigned int offset; ! 196: }; ! 197: ! 198: struct ReadData { ! 199: unsigned int header_block; ! 200: struct Position current; ! 201: unsigned int filesize; ! 202: }; ! 203: ! 204: //#warning "Big vs. little endian for configure needed" ! 205: #define AROS_BE2LONG(l) \ ! 206: ( \ ! 207: ((((unsigned long)(l)) >> 24) & 0x000000FFUL) | \ ! 208: ((((unsigned long)(l)) >> 8) & 0x0000FF00UL) | \ ! 209: ((((unsigned long)(l)) << 8) & 0x00FF0000UL) | \ ! 210: ((((unsigned long)(l)) << 24) & 0xFF000000UL) \ ! 211: ) ! 212: ! 213: struct CacheBlock { ! 214: int blocknum; ! 215: unsigned short flags; ! 216: unsigned short access_count; ! 217: unsigned int blockbuffer[128]; ! 218: }; ! 219: #define LockBuffer(x) (((struct CacheBlock *)(x))->flags |= 0x0001) ! 220: #define UnLockBuffer(x) (((struct CacheBlock *)(x))->flags &= ~0x0001) ! 221: ! 222: #define MAX_CACHE_BLOCKS 10 ! 223: ! 224: struct FSysBuffer { ! 225: struct ReadData file; ! 226: struct CacheBlock blocks[MAX_CACHE_BLOCKS]; ! 227: }; ! 228: ! 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) ! 234: ! 235: #define rdsk(x) ((struct RigidDiskBlock *)(x)->blockbuffer) ! 236: #define part(x) ((struct PartitionBlock *)(x)->blockbuffer) ! 237: ! 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 */ ! 242: ! 243: static void initCache(void) ! 244: { ! 245: int i; ! 246: ! 247: for (i=0;i<MAX_CACHE_BLOCKS;i++) ! 248: { ! 249: fsysb->blocks[i].blocknum = -1; ! 250: fsysb->blocks[i].flags = 0; ! 251: fsysb->blocks[i].access_count = 0; ! 252: } ! 253: } ! 254: ! 255: static struct CacheBlock *getBlock(unsigned int block) ! 256: { ! 257: struct CacheBlock *freeblock; ! 258: int i; ! 259: ! 260: /* get first unlocked block */ ! 261: i = 0; ! 262: do ! 263: { ! 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++) ! 268: { ! 269: if (fsysb->blocks[i].blocknum == block) ! 270: { ! 271: fsysb->blocks[i].access_count++; ! 272: return &fsysb->blocks[i]; ! 273: } ! 274: if (!(fsysb->blocks[i].flags & 0x0001)) ! 275: if (freeblock->access_count>fsysb->blocks[i].access_count) ! 276: freeblock = &fsysb->blocks[i]; ! 277: } ! 278: freeblock->blocknum = block; ! 279: devread(block+blockoffset, 0, 512, (char *)freeblock->blockbuffer); ! 280: return freeblock; ! 281: } ! 282: ! 283: static unsigned int calcChkSum(unsigned short SizeBlock, unsigned int *buffer) ! 284: { ! 285: unsigned int sum=0,count=0; ! 286: ! 287: for (count=0;count<SizeBlock;count++) ! 288: sum += AROS_BE2LONG(buffer[count]); ! 289: return sum; ! 290: } ! 291: ! 292: int affs_mount(void) { ! 293: struct CacheBlock *cblock; ! 294: int i; ! 295: ! 296: if ( ! 297: (current_drive & 0x80) && ! 298: (current_partition != 0xFFFFFF) && ! 299: (current_slice != 0x30) ! 300: ) ! 301: return 0; ! 302: fsysb = (struct FSysBuffer *)FSYS_BUF; ! 303: blockoffset = 0; ! 304: initCache(); ! 305: /* check for rdb partitiontable */ ! 306: for (i=0;i<RDB_LOCATION_LIMIT;i++) ! 307: { ! 308: cblock = getBlock(i); ! 309: if ( ! 310: ( ! 311: ((AROS_BE2LONG(bootBlock(cblock)->id) & 0xFFFFFF00)==0x444F5300) && ! 312: ((AROS_BE2LONG(bootBlock(cblock)->id) & 0xFF)>0) ! 313: ) || ! 314: (AROS_BE2LONG(cblock->blockbuffer[0]) == IDNAME_RIGIDDISK) ! 315: ) ! 316: break; ! 317: } ! 318: if (i == RDB_LOCATION_LIMIT) ! 319: return 0; ! 320: if (AROS_BE2LONG(cblock->blockbuffer[0]) == IDNAME_RIGIDDISK) ! 321: { ! 322: /* we have an RDB partition table within a MBR-Partition */ ! 323: rdbb = i; ! 324: } ! 325: else if (i<2) ! 326: { ! 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); ! 331: if ( ! 332: (AROS_BE2LONG(rootBlock(cblock)->p_type) != T_SHORT) || ! 333: (AROS_BE2LONG(rootBlock(cblock)->s_type) != ST_ROOT) || ! 334: calcChkSum(128, cblock->blockbuffer) ! 335: ) ! 336: return 0; ! 337: } ! 338: else ! 339: return 0; ! 340: return 1; ! 341: } ! 342: ! 343: static int seek(unsigned long offset) ! 344: { ! 345: struct CacheBlock *cblock; ! 346: unsigned long block; ! 347: unsigned long togo; ! 348: ! 349: block = fsysb->file.header_block; ! 350: ! 351: togo = offset / 512; ! 352: fsysb->file.current.filekey = 71-(togo % 72); ! 353: togo /= 72; ! 354: fsysb->file.current.byte = offset % 512; ! 355: fsysb->file.current.offset = offset; ! 356: while ((togo) && (block)) ! 357: { ! 358: disk_read_func = disk_read_hook; ! 359: cblock = getBlock(block); ! 360: disk_read_func = NULL; ! 361: block = AROS_BE2LONG(extensionBlock(cblock)->extension); ! 362: togo--; ! 363: } ! 364: if (togo) ! 365: return 1; ! 366: fsysb->file.current.block = block; ! 367: return 0; ! 368: } ! 369: ! 370: int affs_read(char *buf, int len) { ! 371: struct CacheBlock *cblock; ! 372: unsigned short size; ! 373: unsigned int readbytes = 0; ! 374: ! 375: if (fsysb->file.current.offset != filepos) ! 376: { ! 377: if (seek(filepos)) ! 378: return ERR_FILELENGTH; ! 379: } ! 380: if (fsysb->file.current.block == 0) ! 381: return 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; ! 387: while (len) ! 388: { ! 389: disk_read_func = disk_read_hook; ! 390: if (fsysb->file.current.filekey<0) ! 391: { ! 392: fsysb->file.current.filekey = 71; ! 393: fsysb->file.current.block = AROS_BE2LONG(extensionBlock(cblock)->extension); ! 394: if (fsysb->file.current.block) ! 395: { ! 396: cblock = getBlock(fsysb->file.current.block); ! 397: } ! 398: //#warning "else shouldn't occour" ! 399: } ! 400: size = 512; ! 401: size -= fsysb->file.current.byte; ! 402: if (size>len) ! 403: { ! 404: size = len; ! 405: devread ! 406: ( ! 407: AROS_BE2LONG ! 408: ( ! 409: extensionBlock(cblock)->filekey_table ! 410: [fsysb->file.current.filekey] ! 411: )+blockoffset, ! 412: fsysb->file.current.byte, size, (char *)((long)buf+readbytes) ! 413: ); ! 414: fsysb->file.current.byte += size; ! 415: } ! 416: else ! 417: { ! 418: devread ! 419: ( ! 420: AROS_BE2LONG ! 421: ( ! 422: extensionBlock(cblock)->filekey_table ! 423: [fsysb->file.current.filekey] ! 424: )+blockoffset, ! 425: fsysb->file.current.byte, size, (char *)((long)buf+readbytes) ! 426: ); ! 427: fsysb->file.current.byte = 0; ! 428: fsysb->file.current.filekey--; ! 429: } ! 430: disk_read_func = NULL; ! 431: len -= size; ! 432: readbytes += size; ! 433: } ! 434: fsysb->file.current.offset += readbytes; ! 435: filepos = fsysb->file.current.offset; ! 436: return readbytes; ! 437: } ! 438: ! 439: static unsigned char capitalch(unsigned char ch, unsigned char flags) ! 440: { ! 441: ! 442: if ((flags==0) || (flags==1)) ! 443: return (unsigned char)((ch>='a') && (ch<='z') ? ch-('a'-'A') : ch); ! 444: else // DOS\(>=2) ! 445: return (unsigned char)(((ch>=224) && (ch<=254) && (ch!=247)) || ! 446: ((ch>='a') && (ch<='z')) ? ch-('a'-'A') : ch); ! 447: } ! 448: ! 449: // str2 is a BCPL string ! 450: static int noCaseStrCmp(char *str1, char *str2, unsigned char flags) ! 451: { ! 452: unsigned char length; ! 453: ! 454: length=str2++[0]; ! 455: do { ! 456: if ((*str1==0) && (length==0)) ! 457: return 0; ! 458: length--; ! 459: // if ((*str1==0) && (*str2==0)) return 1; ! 460: } while (capitalch(*str1++,flags)==capitalch(*str2++,flags)); ! 461: str1--; ! 462: return (*str1) ? 1 : -1; ! 463: } ! 464: ! 465: static unsigned int getHashKey(char *name,unsigned int tablesize, unsigned char flags) ! 466: { ! 467: unsigned int length; ! 468: ! 469: length=0; ! 470: while (name[length] != 0) ! 471: length++; ! 472: while (*name!=0) ! 473: length=(length * 13 +capitalch(*name++,flags)) & 0x7FF; ! 474: return length%tablesize; ! 475: } ! 476: ! 477: static grub_error_t getHeaderBlock(char *name, struct CacheBlock **dirh) ! 478: { ! 479: int key; ! 480: ! 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)) ! 486: { ! 487: #ifdef DEBUG_AFFS ! 488: printf("ghb: %d\n", (*dirh)->blocknum); ! 489: #endif ! 490: return ERR_FSYS_CORRUPT; ! 491: } ! 492: if (AROS_BE2LONG(dirHeader(*dirh)->p_type) != T_SHORT) ! 493: return ERR_BAD_FILETYPE; ! 494: while (noCaseStrCmp(name,dirHeader(*dirh)->name,1) != 0) ! 495: { ! 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)) ! 500: { ! 501: #ifdef DEBUG_AFFS ! 502: printf("ghb2: %d\n", (*dirh)->blocknum); ! 503: #endif ! 504: return ERR_FSYS_CORRUPT; ! 505: } ! 506: if (AROS_BE2LONG(dirHeader(*dirh)->p_type) != T_SHORT) ! 507: return ERR_BAD_FILETYPE; ! 508: } ! 509: return 0; ! 510: } ! 511: ! 512: static char *copyPart(char *src, char *dst) ! 513: { ! 514: while ((*src != '/') && (*src)) ! 515: *dst++ = *src++; ! 516: if (*src == '/') ! 517: src++; ! 518: *dst-- = 0; ! 519: /* cut off spaces at the end */ ! 520: while (*dst == ' ') ! 521: *dst-- = 0; ! 522: return src; ! 523: } ! 524: ! 525: static grub_error_t findBlock(char *name, struct CacheBlock **dirh) ! 526: { ! 527: char dname[32]; ! 528: int block; ! 529: ! 530: name++; /* skip "/" */ ! 531: /* partition table part */ ! 532: if (rdbb < RDB_LOCATION_LIMIT) ! 533: { ! 534: int bpc; ! 535: ! 536: blockoffset = 0; ! 537: *dirh = getBlock(rdbb); ! 538: if (*name==0) ! 539: return 0; ! 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); ! 543: while (block != -1) ! 544: { ! 545: *dirh = getBlock(block); ! 546: if (noCaseStrCmp(dname, part(*dirh)->pb_DriveName, 1) == 0) ! 547: break; ! 548: block = AROS_BE2LONG(part(*dirh)->pb_Next); ! 549: } ! 550: if (block == -1) ! 551: return ERR_FILE_NOT_FOUND; ! 552: if ( ! 553: ((AROS_BE2LONG(part(*dirh)->pb_Environment[DE_DOSTYPE]) & 0xFFFFFF00)!=0x444F5300) || ! 554: ((AROS_BE2LONG(part(*dirh)->pb_Environment[DE_DOSTYPE]) & 0xFF)==0) ! 555: ) ! 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 */ ! 560: rootb *= bpc; ! 561: rootb = rootb-1+AROS_BE2LONG(part(*dirh)->pb_Environment[DE_RESERVEDBLKS]); ! 562: rootb /= 2; ! 563: blockoffset *= bpc; ! 564: } ! 565: ! 566: /* filesystem part */ ! 567: *dirh = getBlock(rootb); ! 568: while (*name) ! 569: { ! 570: if ( ! 571: (AROS_BE2LONG(dirHeader(*dirh)->s_type) != ST_ROOT) && ! 572: (AROS_BE2LONG(dirHeader(*dirh)->s_type) != ST_USERDIR) ! 573: ) ! 574: return ERR_BAD_FILETYPE; ! 575: name = copyPart(name, dname); ! 576: errnum = getHeaderBlock(dname, dirh); ! 577: if (errnum) ! 578: return errnum; ! 579: } ! 580: return 0; ! 581: } ! 582: ! 583: #ifndef STAGE1_5 ! 584: static void checkPossibility(char *filename, char *bstr) ! 585: { ! 586: char cstr[32]; ! 587: ! 588: if (noCaseStrCmp(filename, bstr, 1)<=0) ! 589: { ! 590: if (print_possibilities>0) ! 591: print_possibilities = -print_possibilities; ! 592: memcpy(cstr, bstr+1, bstr[0]); ! 593: cstr[bstr[0]]=0; ! 594: print_a_completion(cstr); ! 595: } ! 596: } ! 597: #else ! 598: #define checkPossibility(a, b) do { } while(0) ! 599: #endif ! 600: ! 601: int affs_dir(char *dirname) ! 602: { ! 603: struct CacheBlock *buffer1; ! 604: struct CacheBlock *buffer2; ! 605: char *current = dirname; ! 606: char filename[128]; ! 607: char *fname = filename; ! 608: int i,block; ! 609: ! 610: if (print_possibilities) ! 611: { ! 612: while (*current) ! 613: current++; ! 614: while (*current != '/') ! 615: current--; ! 616: current++; ! 617: while (*current) ! 618: { ! 619: *fname++ = *current; ! 620: *current++ = 0; ! 621: } ! 622: *fname=0; ! 623: errnum = findBlock(dirname, &buffer1); ! 624: if (errnum) ! 625: return 0; ! 626: if (AROS_BE2LONG(dirHeader(buffer1)->p_type) == IDNAME_RIGIDDISK) ! 627: { ! 628: block = AROS_BE2LONG(rdsk(buffer1)->rdb_PartitionList); ! 629: while (block != -1) ! 630: { ! 631: buffer1 = getBlock(block); ! 632: checkPossibility(filename, part(buffer1)->pb_DriveName); ! 633: block = AROS_BE2LONG(part(buffer1)->pb_Next); ! 634: } ! 635: #ifndef STAGE1_5 ! 636: if (*filename == 0) ! 637: if (print_possibilities>0) ! 638: print_possibilities = -print_possibilities; ! 639: #endif ! 640: } ! 641: else if (AROS_BE2LONG(dirHeader(buffer1)->p_type) == T_SHORT) ! 642: { ! 643: LockBuffer(buffer1); ! 644: for (i=0;i<72;i++) ! 645: { ! 646: block = dirHeader(buffer1)->hashtable[i]; ! 647: while (block) ! 648: { ! 649: buffer2 = getBlock(AROS_BE2LONG(block)); ! 650: if (calcChkSum(128, buffer2->blockbuffer)) ! 651: { ! 652: errnum = ERR_FSYS_CORRUPT; ! 653: return 0; ! 654: } ! 655: if (AROS_BE2LONG(dirHeader(buffer2)->p_type) != T_SHORT) ! 656: { ! 657: errnum = ERR_BAD_FILETYPE; ! 658: return 0; ! 659: } ! 660: checkPossibility(filename, dirHeader(buffer2)->name); ! 661: block = dirHeader(buffer2)->hashchain; ! 662: } ! 663: } ! 664: UnLockBuffer(buffer1); ! 665: #ifndef STAGE1_5 ! 666: if (*filename == 0) ! 667: if (print_possibilities>0) ! 668: print_possibilities = -print_possibilities; ! 669: #endif ! 670: } ! 671: else ! 672: { ! 673: errnum = ERR_BAD_FILETYPE; ! 674: return 0; ! 675: } ! 676: while (*current != '/') ! 677: current--; ! 678: current++; ! 679: fname = filename; ! 680: while (*fname) ! 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); ! 686: } ! 687: else ! 688: { ! 689: while (*current && !isspace(*current)) ! 690: *fname++ = *current++; ! 691: *fname = 0; ! 692: ! 693: errnum = findBlock(filename, &buffer2); ! 694: if (errnum) ! 695: return 0; ! 696: if (AROS_BE2LONG(fileHeader(buffer2)->s_type)!=ST_FILE) ! 697: { ! 698: errnum = ERR_BAD_FILETYPE; ! 699: return 0; ! 700: } ! 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); ! 707: filepos = 0; ! 708: filemax = fsysb->file.filesize; ! 709: return 1; ! 710: } ! 711: } ! 712: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.