Example #1
0
/*
 * adfFreeFileBlocks
 *
 */
RETCODE adfFreeFileBlocks(struct Volume* vol, struct bFileHeaderBlock *entry)
{
    int i;
    struct FileBlocks fileBlocks;
    RETCODE rc = RC_OK;

    adfGetFileBlocks(vol,entry,&fileBlocks);

    for(i=0; i<fileBlocks.nbData; i++) {
        adfSetBlockFree(vol, fileBlocks.data[i]);
    }
    for(i=0; i<fileBlocks.nbExtens; i++) {
        adfSetBlockFree(vol, fileBlocks.extens[i]);
    }

    free(fileBlocks.data);
    free(fileBlocks.extens);
		
    return rc;
}
Example #2
0
/*
 * adfCreateBitmap
 *
 * create bitmap structure in vol
 */
RETCODE adfCreateBitmap(struct Volume *vol)
{
    int32_t nBlock, mapSize ;
    int i, j;

    nBlock = vol->lastBlock - vol->firstBlock +1 - 2;

    mapSize = nBlock / (127*32);
    if ( (nBlock%(127*32))!=0 )
        mapSize++;
    vol->bitmapSize = mapSize;

    vol->bitmapTable = (struct bBitmapBlock**)malloc( sizeof(struct bBitmapBlock*)*mapSize );
    if (!vol->bitmapTable) {
        (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapTable");
        return RC_MALLOC;
    }

	vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
    if (!vol->bitmapBlocksChg) {
        free(vol->bitmapTable);
        (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocksChg");
        return RC_MALLOC;
    }

	vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
    if (!vol->bitmapBlocks) {
        free(vol->bitmapTable); free(vol->bitmapBlocksChg);
        (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocks");
        return RC_MALLOC;
    }

    for(i=0; i<mapSize; i++) {
        vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
        if (!vol->bitmapTable[i]) {
            free(vol->bitmapTable); free(vol->bitmapBlocksChg);
            for(j=0; j<i; j++) 
                free(vol->bitmapTable[j]);
            free(vol->bitmapTable);
			(*adfEnv.eFct)("adfCreateBitmap : malloc");
            return RC_MALLOC;
        }
    }

    for(i=vol->firstBlock+2; i<=(vol->lastBlock - vol->firstBlock); i++)
        adfSetBlockFree(vol, i);

    return RC_OK;
}
/*
 * adfDelFromCache
 *
 * delete one cache entry from its block. don't do 'records garbage collecting'
 */
RETCODE adfDelFromCache(struct Volume *vol, struct bEntryBlock *parent, 
    SECTNUM headerKey)
{
    struct bDirCacheBlock dirc;
    SECTNUM nSect, prevSect;
    struct CacheEntry caEntry;
    int offset, oldOffset, n;
    BOOL found;
    int entryLen;
    int i;
    RETCODE rc = RC_OK;

    prevSect = -1;
	nSect = parent->extension;
    found = FALSE;
    do {
        adfReadDirCBlock(vol, nSect, &dirc);
        offset = 0; n = 0;
        while(n < dirc.recordsNb && !found) {
            oldOffset = offset;
            adfGetCacheEntry(&dirc, &offset, &caEntry);
            found = (caEntry.header==headerKey);
            if (found) {
                entryLen = offset-oldOffset;
                if (dirc.recordsNb>1 || prevSect==-1) {
                    if (n<dirc.recordsNb-1) {
                        /* not the last of the block : switch the following records */
                        for(i=oldOffset; i<(488-entryLen); i++)
                            dirc.records[i] = dirc.records[i+entryLen];
                        /* and clear the following bytes */
                        for(i=488-entryLen; i<488; i++)
                            dirc.records[i] = 0;
                    }
                    else {
                        /* the last record of this cache block */
                        for(i=oldOffset; i<offset; i++)
                            dirc.records[i] = 0;
                    }
                    dirc.recordsNb--;
                    if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
						return -1;
                }
                else {
                    /* dirc.recordsNb ==1 or == 0 , prevSect!=-1 : 
                    * the only record in this dirc block and a previous dirc block exists 
                    */
                    adfSetBlockFree(vol, dirc.headerKey);
                    adfReadDirCBlock(vol, prevSect, &dirc);
                    dirc.nextDirC = 0L;
                    adfWriteDirCBlock(vol, prevSect, &dirc);

                    adfUpdateBitmap(vol);
                }
            }
            n++;
        }
        prevSect = nSect;
        nSect = dirc.nextDirC;
    }while(nSect!=0 && !found);

    if (!found)
        (*adfEnv.wFct)("adfUpdateCache : entry not found");

    return rc;
}
Example #4
0
/*
 * 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);
}
Example #5
0
/*
 * adfCreateEntry
 *
 * if 'thisSect'==-1, allocate a sector, and insert its pointer into the hashTable of 'dir', using the 
 * name 'name'. if 'thisSect'!=-1, insert this sector pointer  into the hashTable 
 * (here 'thisSect' must be allocated before in the bitmap).
 */
SECTNUM adfCreateEntry(struct Volume *vol, struct bEntryBlock *dir, char *name,
    SECTNUM thisSect )
{
    BOOL intl;
    struct bEntryBlock updEntry;
    int len, hashValue;
    RETCODE rc;
    char name2[MAXNAMELEN+1], name3[MAXNAMELEN+1];
    SECTNUM nSect, newSect, newSect2;
    struct bRootBlock* root;

/*puts("adfCreateEntry in");*/

    intl = isINTL(vol->dosType) || isDIRCACHE(vol->dosType);
    len = min(strlen(name), MAXNAMELEN) ;
    myToUpper((unsigned char*)name2, (unsigned char*)name, len, intl);
    hashValue = adfGetHashValue((unsigned char*)name, intl);
    nSect = dir->hashTable[ hashValue ];

    if ( nSect==0 ) {
        if (thisSect!=-1)
            newSect = thisSect;
        else {
            newSect = adfGet1FreeBlock(vol);
            if (newSect==-1) {
               (*adfEnv.wFct)("adfCreateEntry : nSect==-1");
               return -1;
            }
        }

        dir->hashTable[ hashValue ] = newSect;
        if (dir->secType==ST_ROOT) {
            root = (struct bRootBlock*)dir;
            adfTime2AmigaTime(adfGiveCurrentTime(),
                &(root->cDays),&(root->cMins),&(root->cTicks));
            rc=adfWriteRootBlock(vol, vol->rootBlock, root);
        }
        else {
            adfTime2AmigaTime(adfGiveCurrentTime(),&(dir->days),&(dir->mins),&(dir->ticks));
            rc=adfWriteDirBlock(vol, dir->headerKey, (struct bDirBlock*)dir);
        }
/*puts("adfCreateEntry out, dir");*/
        if (rc!=RC_OK) {
            adfSetBlockFree(vol, newSect);    
            return -1;
        }
        else
            return( newSect );
    }

    do {
        if (adfReadEntryBlock(vol, nSect, &updEntry)!=RC_OK)
			return -1;
        if (updEntry.nameLen==len) {
            myToUpper((unsigned char*)name3,(unsigned char*)updEntry.name,updEntry.nameLen,intl);
            if (strncmp(name3,name2,len)==0) {
                (*adfEnv.wFct)("adfCreateEntry : entry already exists");
                return -1;
            }
        }
        nSect = updEntry.nextSameHash;
    }while(nSect!=0);

    if (thisSect!=-1)
        newSect2 = thisSect;
    else {
        newSect2 = adfGet1FreeBlock(vol);
        if (newSect2==-1) {
            (*adfEnv.wFct)("adfCreateEntry : nSect==-1");
            return -1;
        }
    }
	 
    rc = RC_OK;
    updEntry.nextSameHash = newSect2;
    if (updEntry.secType==ST_DIR)
        rc=adfWriteDirBlock(vol, updEntry.headerKey, (struct bDirBlock*)&updEntry);
    else if (updEntry.secType==ST_FILE)
        rc=adfWriteFileHdrBlock(vol, updEntry.headerKey, 
		    (struct bFileHeaderBlock*)&updEntry);
    else
        (*adfEnv.wFct)("adfCreateEntry : unknown entry type");

/*puts("adfCreateEntry out, hash");*/
    if (rc!=RC_OK) {
        adfSetBlockFree(vol, newSect2);    
        return -1;
    }
    else
        return(newSect2);
}
Example #6
0
/*
 * adfRemoveEntry
 *
 */
RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM pSect, char *name)
{
    struct bEntryBlock parent, previous, entry;
    SECTNUM nSect2, nSect;
    int hashVal;
    BOOL intl;
    char buf[200];

    if (adfReadEntryBlock( vol, pSect, &parent )!=RC_OK)
		return RC_ERROR;
    nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, &nSect2);
    if (nSect==-1) {
      sprintf(buf, "adfRemoveEntry : entry '%s' not found", name);
        (*adfEnv.wFct)(buf);
        return RC_ERROR;
    }
    /* if it is a directory, is it empty ? */
    if ( entry.secType==ST_DIR && !isDirEmpty((struct bDirBlock*)&entry) ) {
      sprintf(buf, "adfRemoveEntry : directory '%s' not empty", name);
        (*adfEnv.wFct)(buf);
        return RC_ERROR;
    }
/*    printf("name=%s  nSect2=%ld\n",name, nSect2);*/

    /* in parent hashTable */
    if (nSect2==0) {
        intl = isINTL(vol->dosType) || isDIRCACHE(vol->dosType);
        hashVal = adfGetHashValue( (unsigned char*)name, intl );
/*printf("hashTable=%d nexthash=%d\n",parent.hashTable[hashVal],
 entry.nextSameHash);*/
        parent.hashTable[hashVal] = entry.nextSameHash;
        if (adfWriteEntryBlock(vol, pSect, &parent)!=RC_OK)
			return RC_ERROR;
    }
    /* in linked list */
    else {
        if (adfReadEntryBlock(vol, nSect2, &previous)!=RC_OK)
			return RC_ERROR;
        previous.nextSameHash = entry.nextSameHash;
        if (adfWriteEntryBlock(vol, nSect2, &previous)!=RC_OK)
			return RC_ERROR;
    }

    if (entry.secType==ST_FILE) {
        adfFreeFileBlocks(vol, (struct bFileHeaderBlock*)&entry);
        if (adfEnv.useNotify)
             (*adfEnv.notifyFct)(pSect,ST_FILE);
    }
    else if (entry.secType==ST_DIR) {
        adfSetBlockFree(vol, nSect);
        /* free dir cache block : the directory must be empty, so there's only one cache block */
        if (isDIRCACHE(vol->dosType))
            adfSetBlockFree(vol, entry.extension);
        if (adfEnv.useNotify)
            (*adfEnv.notifyFct)(pSect,ST_DIR);
    }
    else {
      sprintf(buf, "adfRemoveEntry : secType %d not supported", entry.secType);
        (*adfEnv.wFct)(buf);
        return RC_ERROR;
    }

    if (isDIRCACHE(vol->dosType))
        adfDelFromCache(vol, &parent, entry.headerKey);

    adfUpdateBitmap(vol);

    return RC_OK;
}