Annotation of qemu/roms/openbios/fs/grubfs/fsys_affs.c, revision 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.