Beispiel #1
0
/*
 * adfUndelFile
 *
 */
RETCODE adfUndelFile(struct Volume* vol, SECTNUM pSect, SECTNUM nSect, struct bFileHeaderBlock* entry)
{
    long i;
    char name[MAXNAMELEN+1];
    struct bEntryBlock parent;
    RETCODE rc;
    struct FileBlocks fileBlocks;

    /* check if the given parent sector pointer seems OK */
    if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
        return rc;

    if (pSect!=entry->parent) {
        (*adfEnv.wFct)("adfUndelFile : the given parent sector isn't the entry parent");
        return RC_ERROR;
    }

    adfGetFileBlocks(vol, entry, &fileBlocks);

    for(i=0; i<fileBlocks.nbData; i++)
        if ( !adfIsBlockFree(vol,fileBlocks.data[i]) )
            return RC_ERROR;
        else
            adfSetBlockUsed(vol, fileBlocks.data[i]);
    for(i=0; i<fileBlocks.nbExtens; i++)
        if ( !adfIsBlockFree(vol,fileBlocks.extens[i]) )
            return RC_ERROR;
        else
            adfSetBlockUsed(vol, fileBlocks.extens[i]);

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

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

    strncpy(name, entry->fileName, entry->nameLen);
    name[(int)entry->nameLen] = '\0';
    /* insert the entry in the parent hashTable, with the headerKey sector pointer */
    adfCreateEntry(vol, &parent, name, entry->headerKey);

    if (isDIRCACHE(vol->dosType))
        adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);

    adfUpdateBitmap(vol);

    return RC_OK;
}
/*
 * adfCreateDir
 *
 */
RETCODE adfCreateDir(struct Volume* vol, SECTNUM nParent, char* name)
{
    SECTNUM nSect;
    struct bDirBlock dir;
    struct bEntryBlock parent;

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

    /* -1 : do not use a specific, already allocated sector */
    nSect = adfCreateEntry(vol, &parent, name, -1);
    if (nSect==-1) {
        (*adfEnv.wFct)("adfCreateDir : no sector available");
        return RC_ERROR;
    }
    memset(&dir, 0, sizeof(struct bDirBlock));
    dir.nameLen = (char)min(MAXNAMELEN, strlen(name));
    memcpy(dir.dirName,name,dir.nameLen);
    dir.headerKey = nSect;

    if (parent.secType==ST_ROOT)
        dir.parent = vol->rootBlock;
    else
        dir.parent = parent.headerKey;
    adfTime2AmigaTime(adfGiveCurrentTime(),&(dir.days),&(dir.mins),&(dir.ticks));

    if (isDIRCACHE(vol->dosType)) {
        /* for adfCreateEmptyCache, will be added by adfWriteDirBlock */
        dir.secType = ST_DIR;
        adfAddInCache(vol, &parent, (struct bEntryBlock *)&dir);
        adfCreateEmptyCache(vol, (struct bEntryBlock *)&dir, -1);
    }

    /* writes the dirblock, with the possible dircache assiocated */
    if (adfWriteDirBlock(vol, nSect, &dir)!=RC_OK)
		return RC_ERROR;

    adfUpdateBitmap(vol);

    if (adfEnv.useNotify)
        (*adfEnv.notifyFct)(nParent,ST_DIR);

    return RC_OK;
}
Beispiel #3
0
/*
 * adfUndelDir
 *
 */
RETCODE adfUndelDir(struct Volume* vol, SECTNUM pSect, SECTNUM nSect, 
    struct bDirBlock* entry)
{
    RETCODE rc;
    struct bEntryBlock parent;
    char name[MAXNAMELEN+1];

    /* check if the given parent sector pointer seems OK */
    if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
        return rc;

    if (pSect!=entry->parent) {
        (*adfEnv.wFct)("adfUndelDir : the given parent sector isn't the entry parent");
        return RC_ERROR;
    }

    if (!adfIsBlockFree(vol, entry->headerKey))
        return RC_ERROR;
    if (isDIRCACHE(vol->dosType) && !adfIsBlockFree(vol,entry->extension))
        return RC_ERROR;

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

    strncpy(name, entry->dirName, entry->nameLen);
    name[(int)entry->nameLen] = '\0';
    /* insert the entry in the parent hashTable, with the headerKey sector pointer */
    adfSetBlockUsed(vol,entry->headerKey);
    adfCreateEntry(vol, &parent, name, entry->headerKey);

    if (isDIRCACHE(vol->dosType)) {
        adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
        adfSetBlockUsed(vol,entry->extension);
    }

    adfUpdateBitmap(vol);

    return RC_OK;
}
/*
 * adfCreateFile
 *
 */
RETCODE adfCreateFile(struct Volume* vol, SECTNUM nParent, char *name,
    struct bFileHeaderBlock *fhdr)
{
    SECTNUM nSect;
    struct bEntryBlock parent;
/*puts("adfCreateFile in");*/
    if (adfReadEntryBlock(vol, nParent, &parent)!=RC_OK)
		return RC_ERROR;

    /* -1 : do not use a specific, already allocated sector */
    nSect = adfCreateEntry(vol, &parent, name, -1);
    if (nSect==-1) return RC_ERROR;
/*printf("new fhdr=%d\n",nSect);*/
    memset(fhdr,0,512);
    fhdr->nameLen = (char)min(MAXNAMELEN, strlen(name));
    memcpy(fhdr->fileName,name,fhdr->nameLen);
    fhdr->headerKey = nSect;
    if (parent.secType==ST_ROOT)
        fhdr->parent = vol->rootBlock;
    else if (parent.secType==ST_DIR)
        fhdr->parent = parent.headerKey;
    else
        (*adfEnv.wFct)("adfCreateFile : unknown parent secType");
    adfTime2AmigaTime(adfGiveCurrentTime(),
        &(fhdr->days),&(fhdr->mins),&(fhdr->ticks));

    if (adfWriteFileHdrBlock(vol,nSect,fhdr)!=RC_OK)
		return RC_ERROR;

    if (isDIRCACHE(vol->dosType))
        adfAddInCache(vol, &parent, (struct bEntryBlock *)fhdr);

    adfUpdateBitmap(vol);

    if (adfEnv.useNotify)
        (*adfEnv.notifyFct)(nParent,ST_FILE);

    return RC_OK;
}
/*
 * adfUpdateCache
 *
 */
RETCODE adfUpdateCache(struct Volume *vol, struct bEntryBlock *parent, 
    struct bEntryBlock *entry, BOOL entryLenChg)
{
    struct bDirCacheBlock dirc;
    SECTNUM nSect;
    struct CacheEntry caEntry, newEntry;
    int offset, oldOffset, n;
    BOOL found;
    int i, oLen, nLen;
    int sLen; /* shift length */

    nLen = adfEntry2CacheEntry(entry, &newEntry);

    nSect = parent->extension;
    found = FALSE;
    do {
/*printf("dirc=%ld\n",nSect);*/
        if (adfReadDirCBlock(vol, nSect, &dirc)!=RC_OK)
			return RC_ERROR;
        offset = 0; n = 0;
        /* search entry to update with its header_key */
        while(n < dirc.recordsNb && !found) {
            oldOffset = offset;
            /* offset is updated */
            adfGetCacheEntry(&dirc, &offset, &caEntry);
            oLen = offset-oldOffset;
            sLen = oLen-nLen;
/*printf("olen=%d nlen=%d\n",oLen,nLen);*/
            found = (caEntry.header==newEntry.header);
            if (found) {
                if (!entryLenChg || oLen==nLen) {
                    /* same length : remplace the old values */
                    adfPutCacheEntry(&dirc, &oldOffset, &newEntry);
/*if (entryLenChg) puts("oLen==nLen");*/
                    if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
                        return RC_ERROR;
                }
                else if (oLen>nLen) {
/*puts("oLen>nLen");*/
                    /* the new record is shorter, write it, 
                     * then shift down the following records 
                     */
                    adfPutCacheEntry(&dirc, &oldOffset, &newEntry);
                    for(i=oldOffset+nLen; i<(488-sLen); i++)
                        dirc.records[i] = dirc.records[i+sLen];
                    /* then clear the following bytes */
                    for(i=488-sLen; i<488; i++)
                        dirc.records[i] = (char)0;

                    if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
                        return RC_ERROR;
                }
                else {
                    /* the new record is larger */
/*puts("oLen<nLen");*/
                    adfDelFromCache(vol,parent,entry->headerKey);
                    adfAddInCache(vol,parent,entry);
/*puts("oLen<nLen end");*/

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

    if (found) {
        if (adfUpdateBitmap(vol)!=RC_OK)
			return RC_ERROR;
    }
    else
        (*adfEnv.wFct)("adfUpdateCache : entry not found");

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