Annotation of qemu/roms/openbios/fs/grubfs/fsys_affs.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.