예제 #1
0
파일: adf_bitm.c 프로젝트: UIKit0/ADFlib
/*
 * adfUpdateBitmap
 *
 */
RETCODE adfUpdateBitmap(struct Volume *vol)
{
	int i;
    struct bRootBlock root;

/*printf("adfUpdateBitmap\n");*/
        
    if (adfReadRootBlock(vol, vol->rootBlock,&root)!=RC_OK)
		return RC_ERROR;

    root.bmFlag = BM_INVALID;
    if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
		return RC_ERROR;

    for(i=0; i<vol->bitmapSize; i++)
    if (vol->bitmapBlocksChg[i]) {
        if (adfWriteBitmapBlock(vol, vol->bitmapBlocks[i], vol->bitmapTable[i])!=RC_OK)
			return RC_ERROR;
  	    vol->bitmapBlocksChg[i] = FALSE;
    }

    root.bmFlag = BM_VALID;
    adfTime2AmigaTime(adfGiveCurrentTime(),&(root.days),&(root.mins),&(root.ticks));
    if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
		return RC_ERROR;

    return RC_OK;
}
예제 #2
0
파일: adf_bitm.c 프로젝트: UIKit0/ADFlib
/*
 * adfWriteNewBitmap
 *
 * write ext blocks and bitmap
 *
 * uses vol->bitmapSize, 
 */
RETCODE adfWriteNewBitmap(struct Volume *vol)
{
    struct bBitmapExtBlock bitme;
    SECTNUM *bitExtBlock;
    int n, i, k;
    int nExtBlock;
    int nBlock;
    SECTNUM *sectList;
    struct bRootBlock root;

    sectList=(SECTNUM*)malloc(sizeof(SECTNUM)*vol->bitmapSize);
    if (!sectList) {
		(*adfEnv.eFct)("adfCreateBitmap : sectList");
        return RC_MALLOC;
    }

    if (!adfGetFreeBlocks(vol, vol->bitmapSize, sectList)) {
        free(sectList);
		return RC_ERROR;
    }
	
    if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
        free(sectList);
		return RC_ERROR;
    }
    nBlock = 0;
    n = min( vol->bitmapSize, BM_SIZE );
    for(i=0; i<n; i++) {
        root.bmPages[i] = vol->bitmapBlocks[i] = sectList[i];
    }
    nBlock = n;

    /* for devices with more than 25*127 blocks == hards disks */
    if (vol->bitmapSize>BM_SIZE) {

        nExtBlock = (vol->bitmapSize-BM_SIZE)/127;
        if ((vol->bitmapSize-BM_SIZE)%127)
            nExtBlock++;

        bitExtBlock=(SECTNUM*)malloc(sizeof(SECTNUM)*nExtBlock);
        if (!bitExtBlock) {
            free(sectList);
			adfEnv.eFct("adfWriteNewBitmap : malloc failed");
            return RC_MALLOC;
        }

        if (!adfGetFreeBlocks(vol, nExtBlock, bitExtBlock)) {  
           free(sectList); free(bitExtBlock);
           return RC_MALLOC;
        }

        k = 0;
        root.bmExt = bitExtBlock[ k ];
        while( nBlock<vol->bitmapSize ) {
            i=0;
            while( i<127 && nBlock<vol->bitmapSize ) {
                bitme.bmPages[i] = vol->bitmapBlocks[nBlock] = sectList[i];
                i++;
                nBlock++;
            }
            if ( k+1<nExtBlock )
                bitme.nextBlock = bitExtBlock[ k+1 ];
            else
                bitme.nextBlock = 0;
            if (adfWriteBitmapExtBlock(vol, bitExtBlock[ k ], &bitme)!=RC_OK) {
                free(sectList); free(bitExtBlock);
				return RC_ERROR;
            }
            k++;
        }
        free( bitExtBlock );

    }
    free( sectList);

    if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
        return RC_ERROR;
    
    return RC_OK;
}
예제 #3
0
/*
 * adfRenameEntry
 *
 */ 
RETCODE adfRenameEntry(struct Volume *vol, SECTNUM pSect, char *oldName,
	SECTNUM nPSect, char *newName)
{
    struct bEntryBlock parent, previous, entry, nParent;
    SECTNUM nSect2, nSect, prevSect, tmpSect;
    int hashValueO, hashValueN, len;
    char name2[MAXNAMELEN+1], name3[MAXNAMELEN+1];
	BOOL intl;
    RETCODE rc;

    if (strcmp(oldName,newName)==0)
        return RC_OK;
    
    intl = isINTL(vol->dosType) || isDIRCACHE(vol->dosType);
    len = strlen(newName);
    myToUpper((unsigned char*)name2, (unsigned char*)newName, len, intl);
    myToUpper((unsigned char*)name3, (unsigned char*)oldName, strlen(oldName), intl);
    /* newName == oldName ? */

    if (adfReadEntryBlock( vol, pSect, &parent )!=RC_OK)
		return RC_ERROR;

    hashValueO = adfGetHashValue((unsigned char*)oldName, intl);

    nSect = adfNameToEntryBlk(vol, parent.hashTable, oldName, &entry, &prevSect);
    if (nSect==-1) {
        (*adfEnv.wFct)("adfRenameEntry : existing entry not found");
        return RC_ERROR;
    }

    /* change name and parent dir */
    entry.nameLen = (char)min(31, strlen(newName));
    memcpy(entry.name, newName, entry.nameLen);
    entry.parent = nPSect;
    tmpSect = entry.nextSameHash;

    entry.nextSameHash = 0;
    if (adfWriteEntryBlock(vol, nSect, &entry)!=RC_OK)
		return RC_ERROR;

    /* del from the oldname list */

    /* in hashTable */
    if (prevSect==0) {
        parent.hashTable[hashValueO] = tmpSect;
        if (parent.secType==ST_ROOT)
            rc = adfWriteRootBlock(vol, pSect, (struct bRootBlock*)&parent);
        else
            rc = adfWriteDirBlock(vol, pSect, (struct bDirBlock*)&parent);
        if (rc!=RC_OK)
            return rc;
    }
    else {
        /* in linked list */
	    if (adfReadEntryBlock(vol, prevSect, &previous)!=RC_OK)
            return RC_ERROR;
        /* entry.nextSameHash (tmpSect) could be == 0 */
        previous.nextSameHash = tmpSect;
        if (adfWriteEntryBlock(vol, prevSect, &previous)!=RC_OK)
            return RC_ERROR;
    }


    if (adfReadEntryBlock( vol, nPSect, &nParent )!=RC_OK)
		return RC_ERROR;

    hashValueN = adfGetHashValue((unsigned char*)newName, intl);
    nSect2 = nParent.hashTable[ hashValueN ];
    /* no list */
    if (nSect2==0) {
        nParent.hashTable[ hashValueN ] = nSect;
        if (nParent.secType==ST_ROOT)
            rc = adfWriteRootBlock(vol, nPSect, (struct bRootBlock*)&nParent);
        else
            rc = adfWriteDirBlock(vol, nPSect, (struct bDirBlock*)&nParent);
    }
    else {
        /* a list exists : addition at the end */
        /* len = strlen(newName);
                   * name2 == newName
                   */
        do {
            if (adfReadEntryBlock(vol, nSect2, &previous)!=RC_OK)
                return -1;
            if (previous.nameLen==len) {
                myToUpper((unsigned char*)name3,(unsigned char*)previous.name,previous.nameLen,intl);
                if (strncmp(name3,name2,len)==0) {
                    (*adfEnv.wFct)("adfRenameEntry : entry already exists");
                    return -1;
                }
            }
            nSect2 = previous.nextSameHash;
/*printf("sect=%ld\n",nSect2);*/
        }while(nSect2!=0);
        
        previous.nextSameHash = nSect;
        if (previous.secType==ST_DIR)
            rc=adfWriteDirBlock(vol, previous.headerKey, 
			       (struct bDirBlock*)&previous);
        else if (previous.secType==ST_FILE)
            rc=adfWriteFileHdrBlock(vol, previous.headerKey, 
                   (struct bFileHeaderBlock*)&previous);
        else {
            (*adfEnv.wFct)("adfRenameEntry : unknown entry type");
            rc = RC_ERROR;
        }
	
	}
    if (rc!=RC_OK)
        return rc;

    if (isDIRCACHE(vol->dosType)) {
		if (pSect==nPSect) {
            adfUpdateCache(vol, &parent, (struct bEntryBlock*)&entry,TRUE);
        }
        else {
            adfDelFromCache(vol,&parent,entry.headerKey);
            adfAddInCache(vol,&nParent,&entry);
        }
    }
/*
    if (isDIRCACHE(vol->dosType) && pSect!=nPSect) {
        adfUpdateCache(vol, &nParent, (struct bEntryBlock*)&entry,TRUE);
    }
*/
    return RC_OK;
}
예제 #4
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);
}
예제 #5
0
/*
 * adfCreateVol
 *
 * 
 */
struct Volume* adfCreateVol( struct Device* dev, int32_t start, int32_t len, 
    char* volName, int volType,struct DateTime * voldate )
{
    struct bBootBlock boot;
    struct bRootBlock root;
/*    struct bDirCacheBlock dirc;*/
    SECTNUM blkList[2];
    struct Volume* vol;
    int nlen;

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(0);

    vol=(struct Volume*)calloc(1,sizeof(struct Volume));
    if (!vol) { 
		(*adfEnv.eFct)("adfCreateVol : malloc vol");
        return NULL;
    }
	
    vol->dev = dev;
    vol->firstBlock = (dev->heads * dev->sectors)*start;
    vol->lastBlock = (vol->firstBlock + (dev->heads * dev->sectors)*len)-1;
    vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
/*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
 vol->lastBlock, vol->rootBlock);
*/
    vol->curDirPtr = vol->rootBlock;

    vol->readOnly = dev->readOnly;

    vol->mounted = TRUE;

    nlen = min( MAXNAMELEN, strlen(volName) );
    vol->volName = (char*)calloc(1,nlen+1);
    if (!vol->volName) { 
		(*adfEnv.eFct)("adfCreateVol : malloc");
		free(vol); return NULL;
    }
    memcpy(vol->volName, volName, nlen);
    vol->volName[nlen]='\0';

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(25);

    memset(&boot, 0, 1024);
    boot.dosType[3] = volType;
/*printf("first=%d last=%d\n", vol->firstBlock, vol->lastBlock);
printf("name=%s root=%d\n", vol->volName, vol->rootBlock);
*/
    if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
        free(vol->volName); free(vol);
        return NULL;
    }

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(20);

    if (adfCreateBitmap( vol )!=RC_OK) {
        free(vol->volName); free(vol);
        return NULL;
    }

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(40);


/*for(i=0; i<127; i++)
printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
*/
    if ( isDIRCACHE(volType) )
        adfGetFreeBlocks( vol, 2, blkList );
    else
        adfGetFreeBlocks( vol, 1, blkList );


/*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/

    memset(&root, 0, LOGICAL_BLOCK_SIZE);

    if (strlen(volName)>MAXNAMELEN)
        volName[MAXNAMELEN]='\0';
    root.nameLen = (char)strlen(volName);
    memcpy(root.diskName,volName,root.nameLen);

	if(voldate)
	{

		adfTime2AmigaTime(*voldate,&(root.coDays),&(root.coMins),&(root.coTicks));
	}
	else
	{
		adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
	}

    /* dircache block */
    if ( isDIRCACHE(volType) ) {
        root.extension = 0L;
        root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
        adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[1]);
    }

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(60);

    if (adfWriteRootBlock(vol, blkList[0], &root)!=RC_OK) {
        free(vol->volName); free(vol);
        return NULL;
    }

   /* fills root->bmPages[] and writes filled bitmapExtBlocks */
    if (adfWriteNewBitmap(vol)!=RC_OK)
		return NULL;

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(80);

    if (adfUpdateBitmap(vol)!=RC_OK)
		return NULL;

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(100);
/*printf("free blocks %ld\n",adfCountFreeBlocks(vol));*/

    /* will be managed by adfMount() later */
    adfFreeBitmap(vol);

    vol->mounted = FALSE;

    return(vol);
}