/*
 * adfWriteDataBlock
 *
 */
RETCODE adfWriteDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
{
    unsigned char buf[512];
    uint32_t newSum;
    struct bOFSDataBlock *dataB;
    RETCODE rc = RC_OK;

    newSum = 0L;
    if (isOFS(vol->dosType)) {
        dataB = (struct bOFSDataBlock *)data;
        dataB->type = T_DATA;
        memcpy(buf,dataB,512);
#ifdef LITT_ENDIAN
        swapEndian(buf, SWBL_DATA);
#endif
        newSum = adfNormalSum(buf,20,512);
        swLong(buf+20,newSum);
/*        *(int32_t*)(buf+20) = swapLong((unsigned char*)&newSum);*/
        adfWriteBlock(vol,nSect,buf);
    }
    else {
        adfWriteBlock(vol,nSect,data);
    }
/*printf("adfWriteDataBlock %ld\n",nSect);*/

    return rc;
}
/*
 * adfReadDataBlock
 *
 */
RETCODE adfReadDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
{
    unsigned char buf[512];
    struct bOFSDataBlock *dBlock;
    RETCODE rc = RC_OK;

    adfReadBlock(vol, nSect,buf);

    memcpy(data,buf,512);

    if (isOFS(vol->dosType)) {
#ifdef LITT_ENDIAN
        swapEndian(data, SWBL_DATA);
#endif
        dBlock = (struct bOFSDataBlock*)data;
/*printf("adfReadDataBlock %ld\n",nSect);*/

        if (dBlock->checkSum!=adfNormalSum(buf,20,sizeof(struct bOFSDataBlock)))
            (*adfEnv.wFct)("adfReadDataBlock : invalid checksum");
        if (dBlock->type!=T_DATA)
            (*adfEnv.wFct)("adfReadDataBlock : id T_DATA not found");
        if (dBlock->dataSize<0 || dBlock->dataSize>488)
            (*adfEnv.wFct)("adfReadDataBlock : dataSize incorrect");
        if ( !isSectNumValid(vol,dBlock->headerKey) )
			(*adfEnv.wFct)("adfReadDataBlock : headerKey out of range");
        if ( !isSectNumValid(vol,dBlock->nextData) )
			(*adfEnv.wFct)("adfReadDataBlock : nextData out of range");
    }

    return rc;
}
/*
 * adfReadNextFileBlock
 *
 */
RETCODE adfReadNextFileBlock(struct File* file)
{
    SECTNUM nSect;
    struct bOFSDataBlock *data;
    RETCODE rc = RC_OK;

    data =(struct bOFSDataBlock *) file->currentData;

    if (file->nDataBlock==0) {
        nSect = file->fileHdr->firstData;
    }
    else if (isOFS(file->volume->dosType)) {
        nSect = data->nextData;
    }
    else {
        if (file->nDataBlock<MAX_DATABLK)
            nSect = file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock];
        else {
            if (file->nDataBlock==MAX_DATABLK) {
                file->currentExt=(struct bFileExtBlock*)calloc(1,sizeof(struct bFileExtBlock));
                if (!file->currentExt) (*adfEnv.eFct)("adfReadNextFileBlock : malloc");
                adfReadFileExtBlock(file->volume, file->fileHdr->extension,
                    file->currentExt);
                file->posInExtBlk = 0;
            }
            else if (file->posInExtBlk==MAX_DATABLK) {
                adfReadFileExtBlock(file->volume, file->currentExt->extension,
                    file->currentExt);
                file->posInExtBlk = 0;
            }
            nSect = file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk];
            file->posInExtBlk++;
        }
    }
    adfReadDataBlock(file->volume,nSect,file->currentData);

    if (isOFS(file->volume->dosType) && data->seqNum!=file->nDataBlock+1)
        (*adfEnv.wFct)("adfReadNextFileBlock : seqnum incorrect");

    file->nDataBlock++;

    return rc;
}
Exemple #4
0
/*
 * adfCheckFile
 *
 */
RETCODE adfCheckFile(struct Volume* vol, SECTNUM nSect,
    struct bFileHeaderBlock* file, int level)
{
    struct bFileExtBlock extBlock;
    struct bOFSDataBlock dataBlock;
    struct FileBlocks fileBlocks;
    int n;
 
    adfGetFileBlocks(vol,file,&fileBlocks);
//printf("data %ld ext %ld\n",fileBlocks.nbData,fileBlocks.nbExtens);
    if (isOFS(vol->dosType)) {
        /* checks OFS datablocks */
        for(n=0; n<fileBlocks.nbData; n++) {
//printf("%ld\n",fileBlocks.data[n]);
            adfReadDataBlock(vol,fileBlocks.data[n],&dataBlock);
            if (dataBlock.headerKey!=fileBlocks.header)
                (*adfEnv.wFct)("adfCheckFile : headerKey incorrect");
            if (dataBlock.seqNum!=n+1)
                (*adfEnv.wFct)("adfCheckFile : seqNum incorrect");
            if (n<fileBlocks.nbData-1) {
                if (dataBlock.nextData!=fileBlocks.data[n+1])
                    (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
                if (dataBlock.dataSize!=vol->datablockSize)
                    (*adfEnv.wFct)("adfCheckFile : dataSize incorrect");
            }
            else { /* last datablock */
                if (dataBlock.nextData!=0)
                    (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
            }
        }
    }
    for(n=0; n<fileBlocks.nbExtens; n++) {
        adfReadFileExtBlock(vol,fileBlocks.extens[n],&extBlock);
        if (extBlock.parent!=file->headerKey)
            (*adfEnv.wFct)("adfCheckFile : extBlock parent incorrect");
        if (n<fileBlocks.nbExtens-1) {
            if (extBlock.extension!=fileBlocks.extens[n+1])
                (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
        }
        else
            if (extBlock.extension!=0)
                (*adfEnv.wFct)("adfCheckFile : nextData incorrect");
    }

    free(fileBlocks.data);
    free(fileBlocks.extens);

    return RC_OK;
}
/*
 * adfWriteFile
 *
 */
int32_t adfWriteFile(struct File *file, int32_t n, unsigned char *buffer)
{
    int32_t bytesWritten;
    unsigned char *dataPtr, *bufPtr;
    int size, blockSize;
    struct bOFSDataBlock *dataB;
    
    bytesWritten = 0;
    if (n==0) return (n);
/*puts("adfWriteFile");*/
    blockSize = file->volume->datablockSize;
    if (isOFS(file->volume->dosType)) {
        dataB =(struct bOFSDataBlock *)file->currentData;
        dataPtr = dataB->data;
    }
    else
        dataPtr = file->currentData;

    if (file->pos==0 || file->posInDataBlk==blockSize) {
        if (adfCreateNextFileBlock(file)==-1) {
            /* bug found by Rikard */
            (*adfEnv.wFct)("adfWritefile : no more free sector availbale");                        
            return bytesWritten;
        }
        file->posInDataBlk = 0;
    }

    bytesWritten = 0; bufPtr = buffer;
    while( bytesWritten<n ) {
        size = min(n-bytesWritten, blockSize-file->posInDataBlk);
        memcpy(dataPtr+file->posInDataBlk, bufPtr, size);
        bufPtr += size;
        file->pos += size;
        bytesWritten += size;
        file->posInDataBlk += size;
        if (file->posInDataBlk==blockSize && bytesWritten<n) {
            if (adfCreateNextFileBlock(file)==-1) {
                /* bug found by Rikard */
                (*adfEnv.wFct)("adfWritefile : no more free sector availbale");                        
                return bytesWritten;
            }
            file->posInDataBlk = 0;
        }
    }
    return( bytesWritten );
}
Exemple #6
0
/*
 * adfReadFile
 *
 */
long adfReadFile(struct File* file, long n, unsigned char *buffer)
{
    long bytesRead;
    unsigned char *dataPtr, *bufPtr;
    int blockSize, size;

    if (n==0) return(n);
    blockSize = file->volume->datablockSize;
    /*puts("adfReadFile");*/
    if (file->pos+n > file->fileHdr->byteSize)
        n = file->fileHdr->byteSize - file->pos;

    if (isOFS(file->volume->dosType))
        dataPtr = (unsigned char*)(file->currentData)+24;
    else
        dataPtr = file->currentData;

    if (file->pos==0 || file->posInDataBlk==blockSize) {
        adfReadNextFileBlock(file);
        file->posInDataBlk = 0;
    }

    bytesRead = 0;
    bufPtr = buffer;
    size = 0;
    while ( bytesRead < n ) {
        size = min(n-bytesRead, blockSize-file->posInDataBlk);
        memcpy(bufPtr, dataPtr+file->posInDataBlk, size);
        bufPtr += size;
        file->pos += size;
        bytesRead += size;
        file->posInDataBlk += size;
        if (file->posInDataBlk==blockSize && bytesRead<n) {
            adfReadNextFileBlock(file);
            file->posInDataBlk = 0;
        }
    }
    file->eof = (file->pos==file->fileHdr->byteSize);
    return( bytesRead );
}
/*
 * adfFileFlush
 *
 */
void adfFlushFile(struct File *file)
{
    struct bEntryBlock parent;
    struct bOFSDataBlock *data;

    if (file->currentExt) {
        if (file->writeMode)
            adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
                file->currentExt);
    }
    if (file->currentData) {
        if (file->writeMode) {
            file->fileHdr->byteSize = file->pos;
	        if (isOFS(file->volume->dosType)) {
                data = (struct bOFSDataBlock *)file->currentData;
                data->dataSize = file->posInDataBlk;
            }
            if (file->fileHdr->byteSize>0)
                adfWriteDataBlock(file->volume, file->curDataPtr, 
				    file->currentData);
        }
    }
    if (file->writeMode) {
        file->fileHdr->byteSize = file->pos;
/*printf("pos=%ld\n",file->pos);*/
        adfTime2AmigaTime(adfGiveCurrentTime(),
            &(file->fileHdr->days),&(file->fileHdr->mins),&(file->fileHdr->ticks) );
        adfWriteFileHdrBlock(file->volume, file->fileHdr->headerKey, file->fileHdr);

	    if (isDIRCACHE(file->volume->dosType)) {
/*printf("parent=%ld\n",file->fileHdr->parent);*/
            adfReadEntryBlock(file->volume, file->fileHdr->parent, &parent);
            adfUpdateCache(file->volume, &parent, (struct bEntryBlock*)file->fileHdr,FALSE);
        }
        adfUpdateBitmap(file->volume);
    }
}
/*
 * adfCreateNextFileBlock
 *
 */
SECTNUM adfCreateNextFileBlock(struct File* file)
{
    SECTNUM nSect, extSect;
    struct bOFSDataBlock *data;
	unsigned int blockSize;
    int i;
/*puts("adfCreateNextFileBlock");*/
    blockSize = file->volume->datablockSize;
    data = file->currentData;

    /* the first data blocks pointers are inside the file header block */
    if (file->nDataBlock<MAX_DATABLK) {
        nSect = adfGet1FreeBlock(file->volume);
        if (nSect==-1) return -1;
/*printf("adfCreateNextFileBlock fhdr %ld\n",nSect);*/
        if (file->nDataBlock==0)
            file->fileHdr->firstData = nSect;
        file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock] = nSect;
        file->fileHdr->highSeq++;
    }
    else {
        /* one more sector is needed for one file extension block */
        if ((file->nDataBlock%MAX_DATABLK)==0) {
            extSect = adfGet1FreeBlock(file->volume);
/*printf("extSect=%ld\n",extSect);*/
            if (extSect==-1) return -1;

            /* the future block is the first file extension block */
            if (file->nDataBlock==MAX_DATABLK) {
                file->currentExt=(struct bFileExtBlock*)calloc(1,sizeof(struct bFileExtBlock));
                if (!file->currentExt) {
                    adfSetBlockFree(file->volume, extSect);
                    (*adfEnv.eFct)("adfCreateNextFileBlock : malloc");
                    return -1;
                }
                file->fileHdr->extension = extSect;
            }

            /* not the first : save the current one, and link it with the future */
            if (file->nDataBlock>=2*MAX_DATABLK) {
                file->currentExt->extension = extSect;
/*printf ("write ext=%d\n",file->currentExt->headerKey);*/
                adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
                    file->currentExt);
            }

            /* initializes a file extension block */
            for(i=0; i<MAX_DATABLK; i++)
                file->currentExt->dataBlocks[i] = 0L;
            file->currentExt->headerKey = extSect;
            file->currentExt->parent = file->fileHdr->headerKey;
            file->currentExt->highSeq = 0L;
            file->currentExt->extension = 0L;
            file->posInExtBlk = 0L;
/*printf("extSect=%ld\n",extSect);*/
        }
        nSect = adfGet1FreeBlock(file->volume);
        if (nSect==-1) 
            return -1;
        
/*printf("adfCreateNextFileBlock ext %ld\n",nSect);*/

        file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk] = nSect;
        file->currentExt->highSeq++;
        file->posInExtBlk++;
    }

    /* builds OFS header */
    if (isOFS(file->volume->dosType)) {
        /* writes previous data block and link it  */
        if (file->pos>=blockSize) {
            data->nextData = nSect;
            adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
/*printf ("writedata=%d\n",file->curDataPtr);*/
        }
        /* initialize a new data block */
        for(i=0; i<(int)blockSize; i++)
            data->data[i]=0;
        data->seqNum = file->nDataBlock+1;
        data->dataSize = blockSize;
        data->nextData = 0L;
        data->headerKey = file->fileHdr->headerKey;
    }
    else
        if (file->pos>=blockSize) {
            adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
/*printf ("writedata=%d\n",file->curDataPtr);*/
            memset(file->currentData,0,512);
        }
            
/*printf("datablk=%d\n",nSect);*/
    file->curDataPtr = nSect;
    file->nDataBlock++;

    return(nSect);
}