/* * 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; }
/* * 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 ); }
/* * 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); }