⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drobj.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* DROBJ.C - Directory object manipulation routines
    pc_fndnode          -  Find a file or directory on disk and return a DROBJ.
    pc_get_inode        -  Find a filename within a subdirectory 
    static pc_findin    -  Find a filename in the same directory as argument.

    pc_get_mom          -  Find the parent inode of a subdirectory.

    pc_mkchild          -  Allocate a DROBJ and fill in based on parent object.
    pc_mknode           -  Create an empty subdirectory or file.
    pc_insert_inode - Called only by pc_mknode

    pc_rmnode           -  Delete an inode unconditionally.
    pc_update_inode -  Flush an inode to disk

    pc_read_obj     -  Assign an initialized BLKBUFF to a DROBJ
    pc_write_obj        -  Write a DROBJ's BLKBUFF to disk

    pc_get_root     -  Create the special ROOT object for a drive.
    pc_firstblock   -  Return the absolute block number of a directory
    pc_next_block   -  Calculate the next block owned by an object.
    pc_l_next_block -  Calculate the next block in a chain.

        We keep a shared image of directory entries around. These routines
        keep track of them for us.
    pc_marki        -  Set dr:sec:index, + stitch FINODE into the inode list
    pc_scani        -  Search for an inode in the internal inode list.
        Heap management routines

    pc_allocobj     - 
    pc_alloci           - 
    pc_free_all_i       - 
    pc_freei            -       
    pc_freeobj          - 

        Simple helper routines
    pc_dos2inode        -  
    pc_ino2dos          -   
    pc_init_inode       -   
    pc_isadir           - 

*/

#include <pcdisk.h>




 /**************************************************************************
    PC_FNDNODE -  Find a file or directory on disk and return a DROBJ.

 Description
    Take a full path name and traverse the path until we get to the file
    or subdir at the end of the path spec. When found allocate and init-
    ialize (OPEN) a DROBJ.

 Returns
    Returns a pointer to a DROBJ if the file was found, otherwise 0.

***************************************************************************/


/* Find "path" and create a DROBJ structure if found   */
DROBJ *pc_fndnode(char *path)                                   /*__fn__*/
{
    DROBJ *pobj;
    DROBJ *pmom;
    DROBJ *pchild;
    int  driveno;
    DDRIVE *pdrive;
    byte filename[FILENAMESIZE];
    byte fileext[4];

    /* Get past D: plust get drive number if there   */
    path = pc_parsedrive( &driveno, path );
    if (!path)
        return (0);
    
    /* Find the drive   */
    pdrive = pc_drno2dr(driveno);
    if (!pdrive)
        return (0);
    /* Get the top of the current path   */
    if ( *path == char_backslash )
    {
        pobj = pc_get_root(pdrive);
        path++;
    }
    else
    {
        pobj = pc_get_cwd(pdrive);
    }

    if (!pobj)
        return (0);

    /* Search through the path til exausted   */
    while (*path)
    {
        path = pc_nibbleparse((char*) filename,(char*) fileext, path );
        if (!path)
        {
            pc_freeobj(pobj);
            return (0);
        }
#if (RTFS_SUBDIRS)
        if (pc_isdot( filename, fileext ))
            ;
#endif
        else
        {
            /* Find Filename in pobj. and initialize lpobj with result   */
            pchild = pc_get_inode(0, pobj, filename, fileext, FALSE);
            if (!pchild)
            {
                pc_freeobj(pobj);
                return (0);
            }
#if (RTFS_SUBDIRS)
            /* We found it. We have one special case. if "..". we need
                to shift up a level so we are not the child of mom
                but of grand mom. */
            if (pc_isdotdot( filename, fileext ))
            {
                /* Find pobj's parent. By looking back from ".."   */
                pmom = pc_get_mom(pchild);
                /* We're done with pobj for now   */
                pc_freeobj(pobj);

                if (!pmom)
                {
                    pc_freeobj(pchild);
                    return (0);
                }
                else
                {
                    /* We found the parent now free the child   */
                    pobj = pmom;
                    pc_freeobj(pchild);
                }
            }
            else
#endif      /* SUBDIRS */
            {
                /* We're done with pobj for now   */
                pc_freeobj(pobj);
                /* Make sure pobj points at the next inode   */
                pobj = pchild;
#if (RTFS_SUBDIRS)
#else
/* No subdirectory support. Return the one we found   */
                return (pobj);
#endif
            }
        }
    }
    return (pobj);
}




/***************************************************************************
    PC_GET_INODE -  Find a filename within a subdirectory 

 Description
    Search the directory pmom for the pattern or name in filename:ext and
    return the an initialized object. If pobj is NULL start the search at
    the top of pmom (getfirst) and allocate pobj before returning it. 
    Otherwise start the search at pobj (getnext). (see also pc_gfirst,
    pc_gnext)


    Note: Filename and ext must be right filled with spaces to 8 and 3 bytes
            respectively. Null termination does not matter.

 Returns
    Returns a drobj pointer or NULL if file not found.
***************************************************************************/

/* Give a directory mom. And a file name and extension. 
    Find find the file or dir and initialize pobj.
    If pobj is NULL. We allocate and initialize the object otherwise we get the
    next item in the chain of dirents.
*/

DROBJ *pc_get_inode( DROBJ *pobj, DROBJ *pmom, byte *filename, byte *fileext, BOOLEAN dowildcard) /*__fn__*/
{
    BOOLEAN  starting = FALSE;

    /* Create the child if just starting   */
    if (!pobj)
    {
        starting = TRUE;
        pobj = pc_mkchild(pmom);
        if (!pobj)
            return(0);
    }
    else    /* If doing a gnext don't get stuck in and endless loop */
    {
        if ( ++(pobj->blkinfo.my_index) >= INOPBLOCK )
        {
            if (!pc_next_block(pobj))
            {
                return (0);
            }
            else
                pobj->blkinfo.my_index = 0;
        }
    }
    if (pc_findin(pobj, filename, fileext,dowildcard))
    {
        return (pobj);
    }
    else
    {
        if (starting)
            pc_freeobj(pobj);
        return (0);
    }
}




#if (VFAT)
void pcdel2lfi(LFNINODE *lfi, int nsegs)    /* __fn__ */
{                                
    for (;nsegs;nsegs--, lfi--)
        lfi->lfnorder = PCDELETE;
}


BOOLEAN pc_deleteseglist(DDRIVE *pdrive, SEGDESC *s)  /* __fn__ */
{                                                    
BLKBUFF *rbuf;
LFNINODE *lfi;
int ntodo;

    if (!s->nsegs)
        return(TRUE);
    /* Read segblock[0] and copy text   */

    rbuf = pc_read_blk(pdrive, s->segblock[0]);
    if (!rbuf)
        return(FALSE);
    lfi = (LFNINODE *) &rbuf->data[0];
    lfi += s->segindex;
    /* If the lfn segments span two blocks then segblock[0] contains the
       second block and segblock[1] contains the first.
       We delete all of the segments up to and including segindex 
       in the second block block value stored in segblock[0]. */
    /* 2-17-99 We add the check for s->segblock[1] here because
       nsegs >= segindex was inadvertantly catching the case where
       segindex == 1, nsegs == 1 and entry 0 in the block contained
       a valid entry from another file or volume name */
//DM: 3/14/99: fixed. Problem is that in some cases, ntodo is actually
//    increased (by 1) rather than decreased. For example, if nsegs is 1
//    and segindex is 1, then the file to delete is the 2nd directory entry.
//    The old logic would delete 2 entries, not 1, as requested, meaning
//    the directory entry for the file before the one being deleted got
//    hosed too!
    if (s->nsegs > s->segindex+1)
//    if (s->nsegs >= s->segindex && s->segblock[1])  WRONG 
        ntodo = s->segindex+1;
    else
        ntodo = s->nsegs;

    pcdel2lfi(lfi, ntodo);
    if ( !pc_write_blk ( rbuf ) )
    {
        pc_free_buf(rbuf,TRUE);         /* Error. Chuck the buffer */
        return (FALSE);
    }
    else
    {
        pc_free_buf(rbuf,FALSE);
    }
    if (s->segblock[1])
    {
        rbuf = pc_read_blk(pdrive, s->segblock[1]);
        if (!rbuf)
            return (FALSE);
        lfi = (LFNINODE *) &rbuf->data[0];
        lfi += 15;  /* The last index */
        pcdel2lfi(lfi, s->nsegs - ntodo);
        if ( !pc_write_blk ( rbuf ) )
        {
            pc_free_buf(rbuf,TRUE);         /* Error. Chuck the buffer */
            return (FALSE);
        }
        else
            pc_free_buf(rbuf,FALSE);
    }
    return(TRUE);
}

#if (1)

void text2lfi(char *lfn, LFNINODE *lfi, int nsegs, byte ncksum, byte order) /* __fn__ */
{
    int n;
    BOOLEAN end_of_lfn = FALSE;

    for (;nsegs && !end_of_lfn;nsegs--, lfi--, order++)
    {
        for(n=0; n<10; n += 2)
        {
            if (end_of_lfn)
                lfi->lfname1[n] = lfi->lfname1[n+1]= 0xff;
            else
            {
                lfi->lfname1[n] = *lfn++;
/* bug fix win95 lfn */
                lfi->lfname1[n+1] = 0;
                if (lfi->lfname1[n] == 0)
                    end_of_lfn = TRUE;
            }
        }
        for(n=0; n<12; n += 2)
        {
            if (end_of_lfn)
                lfi->lfname2[n] = lfi->lfname2[n+1] = 0xff;
            else
            {
                lfi->lfname2[n] = *lfn++;
/* bug fix win95 lfn */
                lfi->lfname2[n+1] = 0;
                if (lfi->lfname2[n] == 0)
                    end_of_lfn = TRUE;
            }
        }

        for(n=0; n<4; n+=2)
        {
            if (end_of_lfn)
                lfi->lfname3[n] = lfi->lfname3[n+1] = 0xff;
            else
            {
                lfi->lfname3[n] = *lfn++;
/* bug fix win95 lfn */
                lfi->lfname3[n+1] = 0;
                if (lfi->lfname3[n] == 0)
                    end_of_lfn = TRUE;
            }
        }

        if(*lfn == 0)
        {
            end_of_lfn = TRUE;
        }


        if (end_of_lfn)
            order |= FIRST_NAMESEG;
        lfi->lfnorder = order;
        lfi->lfnattribute = 0x0F;
        lfi->lfnres =  0;
        lfi->lfncksum = ncksum;
        lfi->lfncluster = 0x0000;
    }
}

#else


void text2lfi(char *lfn, LFNINODE *lfi, int nsegs, byte ncksum, byte order) /* __fn__ */
{
    int n;
    BOOLEAN end_of_lfn = FALSE;

    for (;nsegs && !end_of_lfn;nsegs--, lfi--, order++)
    {
        for(n=0; n<5; n++)
        {
            if (end_of_lfn)
                lfi->lfname1[n] = 0xffff;
            else
            {
                lfi->lfname1[n] = *lfn++;
                if (lfi->lfname1[n] == 0)
                    end_of_lfn = TRUE;
            }
        }
        for(n=0; n<6; n++)
        {
            if (end_of_lfn)
                lfi->lfname2[n] = 0xffff;
            else
            {
                lfi->lfname2[n] = *lfn++;
                if (lfi->lfname2[n] == 0)
                    end_of_lfn = TRUE;
            }
        }

        for(n=0; n<2; n++)
        {
            if (end_of_lfn)
                lfi->lfname3[n] = 0xffff;
            else
            {
                lfi->lfname3[n] = *lfn++;
                if (lfi->lfname3[n] == 0)
                    end_of_lfn = TRUE;
            }
        }

        if (end_of_lfn)
            order |= FIRST_NAMESEG;
        lfi->lfnorder = order;
        lfi->lfnattribute = 0x0F;
        lfi->lfnres =  0;
        lfi->lfncksum = ncksum;
        lfi->lfncluster = 0x0000;
    }
}



#endif
BOOLEAN pc_seglist2disk(DDRIVE * pdrive, SEGDESC *s, char *lfn) /* __fn__*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -