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

📄 dosdiroldlib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
** RETURNS: OK or ERROR if name is invalid or disk access error*  occurred.**/LOCAL STATUS dosDirOldUpdateEntry    (    DOS_FILE_DESC_ID	pFd,    u_int		flags,    time_t		curTime		/* time to encode */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    u_char	dirent[ DOS_VX_DIRENT_LEN ]; /* directory entry buffer */        curTime = ( curTime == 0 )? time( NULL ) : curTime;        /* root directory has not its own entry */        if( IS_ROOT( pFd ) )    	{    	if( (flags & DH_TIME_MODIFY) != 0 )    	    pDirDesc->rootModifTime = curTime;    	else    	    assert( (flags & DH_TIME_MODIFY) != 0 );    	    	return OK;    	}        /* get directory entry */        if( dosDirOldDirentGet( pFd, dirent, FD_ENTRY ) == ERROR )    	return ERROR;        if( flags & DH_DELETE )	/* delete entry */    	{    	*dirent = DOS_DEL_MARK;    	goto store;    	}        /* encode other fields */        dirent[ pDirDesc->deDesc.atrribOff ] = pFd->pFileHdl->attrib;    START_CLUST_ENCODE( &pDirDesc->deDesc,    		        pFd->pFileHdl->startClust,  dirent );    VX_TO_DISK_32( pFd->pFileHdl->size,    		   dirent + pDirDesc->deDesc.sizeOff );    		       if( pDirDesc->deDesc.extSizeOff != (u_char) NONE )    	{    	EXT_SIZE_ENCODE( &pDirDesc->deDesc, dirent, pFd->pFileHdl->size );    	}        dosDirOldTDEncode( pDirDesc, dirent, flags, curTime );    store:        /* store directory entry */    return cbioBytesRW(    	pFd->pVolDesc->pCbio, pFd->pFileHdl->dirHdl.sector,    	OFFSET_IN_SEC( pFd->pVolDesc, pFd->pFileHdl->dirHdl.offset ),	(addr_t)dirent, pDirDesc->deDesc.dirEntSize, CBIO_WRITE,    	&pFd->pFileHdl->dirHdl.cookie );    } /* dosDirOldUpdateEntry *//***************************************************************************** dosDirOldFileCreateInDir - create new entry in directory.** This routine creates new directory entry in place of* deleted entry. If no deleted entry found in directory,* additional entry created at the directory tail.** <pFreeEnt> contains pointer onto a deleted entry in* directory or onto free space in last directory* cluster, that have been already allocated. If <pFreeEnt->sector> is 0,* suppose, that no unallocated entry exists in directory and* <pFd> reached directory FAT chain end. In this case one more cluster is* connected to directory chain and new entry is created in it.** RETURNS: OK or ERROR if new entry can not be created.** ERRNO:* S_dosFsLib_DIR_READ_ONLY* S_dosFsLib_INVALID_PARAMETER* S_dosFsLib_ROOT_DIR_FULL* */LOCAL STATUS dosDirOldFileCreateInDir    (    DOS_FILE_DESC_ID	pFd,		/* directory descriptor */    PATH_ARRAY_ID	pNamePtr,    u_int		creatOpt,	/* creat flags */    DIRENT_PTR_ID	pFreeEnt	/* empty entry in directory */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    DOS_DIR_HDL_ID	pDirHdl = (void *)&(pFd->pFileHdl->dirHdl);    cookie_t	cookie;	/* temp buffer */    u_char	dirent[ DOS_VX_DIRENT_LEN ] = {0}; /* directory entry buffer */    u_char	dirEntSize;    u_char	parentIsRoot = 0;	/* creation in root */        dirEntSize = pDirDesc->deDesc.dirEntSize;        /* check permissions */        if( pFd->pFileHdl->attrib & DOS_ATTR_RDONLY )    	{    	errnoSet( S_dosFsLib_DIR_READ_ONLY );    	return ERROR;    	}    	    /* only file and directory can be created */        if( !( S_ISREG( creatOpt ) || S_ISDIR( creatOpt ) ) )    	{    	errnoSet( S_dosFsLib_INVALID_PARAMETER );    	return ERROR;    	}        if( IS_ROOT( pFd ) )    	parentIsRoot = 1;            /* check/encode file name */        if( dosDirOldNameEncode( pDirDesc, pNamePtr, dirent ) == ERROR )    	return ERROR;        /* use empty entry, that was found during path lkup */        if( pFreeEnt->sector == 0 ) /* no free entries in directory */    	{    	if( IS_ROOT( pFd ) && pDirDesc->rootMaxEntries < (u_int)(-1) )    	    {    	    errnoSet( S_dosFsLib_ROOT_DIR_FULL );    	    return ERROR;    	    }    	    	/*  allocate one more cluster */    	    	if( dosDirOldClustAdd( pFd ) == ERROR )    	    return ERROR;    	    	pFreeEnt->sector = pFd->curSec;    	pFreeEnt->offset = pFd->pos;    	}    /* correct parent directory modification date/time */        dosDirOldUpdateEntry( pFd, DH_TIME_MODIFY, time( NULL ) );        /* --- create new entry --- */        /* at the beginning create generic (file) entry */        dosDirOldTDEncode(pDirDesc,                       dirent,                       (DH_TIME_CREAT | DH_TIME_MODIFY | DH_TIME_ACCESS),                       time( NULL ) );        cookie = pDirHdl->cookie;	/* backup cbio qsearch cookie */    /*     * point file descriptor on the new entree's position and     * fill file descriptor for new file     */    pFd->curSec = pFreeEnt->sector;    pFd->pos = pFreeEnt->offset;    dosDirOldFillFd( pFd, dirent );        DBG_MSG( 400, "create %s at: sector = %u offset = %u\n",    		( S_ISREG( creatOpt )? "FILE" : "DIRECTORY" ),    		pFreeEnt->sector, pFreeEnt->offset ,0,0,0,0,0);    DBG_PRN_STR( 400, "\tname: %s\n", dirent,    		 pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,0 );        /* write f i l e entry to disk */        if( S_ISREG( creatOpt ) )    	{    	return cbioBytesRW(    		pFd->pVolDesc->pCbio, pFreeEnt->sector,		OFFSET_IN_SEC( pFd->pVolDesc, pFreeEnt->offset ),    		(addr_t)dirent, dirEntSize, CBIO_WRITE, &cookie );    	}        /* --- now we deal with directory --- */        *(dirent + pDirDesc->deDesc.atrribOff) = DOS_ATTR_DIRECTORY;    pFd->pFileHdl->attrib = DOS_ATTR_DIRECTORY;        /*     * for directory we have to create two entries: "." and ".."     * start - allocate cluster and init it in structure.     */    if( dosDirOldClustAdd( pFd ) == ERROR )    	return ERROR;        START_CLUST_ENCODE( &pDirDesc->deDesc,    		        pFd->pFileHdl->startClust,  dirent );        /*     * second - init directory entry for ".";     * it is similar to directory entry itself, except name     */    bfill( (char *)dirent,    	   pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,    	   SPACE );    *dirent = DOT;    if( cbioBytesRW(    		pFd->pVolDesc->pCbio, pFd->curSec, 0, (addr_t)dirent,    		dirEntSize, CBIO_WRITE, &pDirHdl->cookie ) == ERROR )    	{    	return ERROR;    	}        pFd->pos += dirEntSize;    if( OFFSET_IN_SEC( pFd->pVolDesc, pFd->pos ) == 0 )    	{    	pFd->nSec --;    	pFd->curSec ++;    	}        /* if only one directory entry can be stored in cluster */        if( pFd->nSec == 0 )    	{    	if( dosDirOldClustAdd( pFd ) == ERROR )    	    return ERROR;    	}        /* third - creat ".." entry, that points to the parent directory */        if( parentIsRoot )    	{    	START_CLUST_ENCODE( &pDirDesc->deDesc, 0,  dirent );    	}    else    	{    	START_CLUST_ENCODE( &pDirDesc->deDesc,    		            pDirHdl->parDirStartCluster,  dirent );    	}        *(dirent + 1) = DOT;    if( cbioBytesRW(    		pFd->pVolDesc->pCbio, pFd->curSec,		OFFSET_IN_SEC(  pFd->pVolDesc, pFd->pos ), (addr_t)dirent,    		dirEntSize, CBIO_WRITE, &pDirHdl->cookie ) == ERROR )    	{    	return ERROR;    	}        /* now finish directory entry initialization */        dosDirOldRewindDir( pFd );	/* rewind directory */        dosDirOldNameEncode( pDirDesc, pNamePtr, dirent );    START_CLUST_ENCODE( &pDirDesc->deDesc,    		        pFd->pFileHdl->startClust,  dirent );    if( cbioBytesRW(    		pFd->pVolDesc->pCbio, pDirHdl->sector,		OFFSET_IN_SEC( pFd->pVolDesc, pDirHdl->offset ),     		(addr_t)dirent, dirEntSize, CBIO_WRITE,    		&pDirHdl->cookie ) == ERROR )    	{    	return ERROR;    	}    return OK;    } /* dosDirOldFileCreateInDir() */    /***************************************************************************** dosDirOldNameDecode - decode name from directory entry format.** RETURNS: OK or ERROR if no disk entries remain.*/LOCAL void dosDirOldNameDecode    (    DOS_DIR_PDESCR_ID	pDirDesc,    u_char *	pDirent,	/* directory entry buffer */    u_char *	pDstName	/* destination for directory name */    )    {    u_char *	pNameEnd = pDstName;    u_char *	pDstBuf;	/* for debug output */    u_char *	pDot = NULL;    u_char *	pSrc = pDirent;    int i, j, nameLen;        pDstBuf = pDstName;        for( pDot = NULL, nameLen = pDirDesc->deDesc.nameLen, i = 0; i  < 2;    	 i++, nameLen = pDirDesc->deDesc.extLen )    	{     	for( j = 0; j < nameLen; j++, pDstName++ )    	    {    	    *pDstName = *pSrc++;    	        	    if( *pDstName != SPACE )    	    	pNameEnd = pDstName + 1;    	    }    	    	if( pDirDesc->deDesc.extLen == 0 )	/* long name */    	    break;    	        	/* extension */    	    	if( pDot == NULL )	/* separate name and extension */    	    {    	    pDot = pNameEnd;    	    *pNameEnd++ = DOT;    	    pDstName = pNameEnd;    	    }    	else if( pDot + 1 == pNameEnd )    	    {    	    pNameEnd --;	/* empty extension - remove dot */    	    break;    	    }    	}        *pNameEnd = EOS;	/* terminate the name */    DBG_MSG( 600, "result: %s\n", pDstBuf ,0,0,0,0,0,0,0);    } /* dosDirOldNameDecode() */    /***************************************************************************** dosDirOldReaddir - FIOREADDIR backend.** Optionally this routine fills file descriptor for the encountered entry,* if <pResFd> is not NULL.** RETURNS: OK or ERROR if no disk entries remain.*/LOCAL STATUS dosDirOldReaddir    (    DOS_FILE_DESC_ID	pFd,	/* descriptor of the directory being read */    DIR *	pDir,	/* destination for directory name */    DOS_FILE_DESC_ID	pResFd	/* file descriptor to be filled for the */    				/* being returned */    				/* (if pResFd is not NULL) */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    int readFlag;    u_char	dirent[ DOS_VX_DIRENT_LEN ]; /* directory entry buffer */        assert( pFd->pFileHdl->attrib & DOS_ATTR_DIRECTORY );        /* check status of directory */        if( (int)pDir->dd_cookie == (-1) )    	return ERROR;        /* position must be directory entry size aligned */    if( pFd->pos % DOS_STDNAME_LEN != 0 )    	{    	errnoSet( S_dosFsLib_INVALID_PARAMETER );    	return ERROR;    	}    readFlag = ( pDir->dd_cookie == 0 )? RD_FIRST : RD_NEXT;        do    	{    	if( dosDirOldDirentGet( pFd, dirent, readFlag ) == ERROR )            {            pDir->dd_cookie = (-1);    	    return ERROR;    	    }    	readFlag = RD_NEXT;    	}    while( *dirent == DOS_DEL_MARK ||    	   (dirent[ pDirDesc->deDesc.atrribOff ] & DOS_ATTR_VOL_LABEL) != 0 );        if( *dirent == LAST_DIRENT )	/* end of directory */    	{    	pDir->dd_cookie = (-1);    	return ERROR;    	}        /* name decode */        dosDirOldNameDecode( pDirDesc, dirent,(u_char *)pDir->dd_dirent.d_name );        /* fill file descriptor for the entry */        if( pResFd != NULL )    	{    	void *	pFileHdl = pResFd->pFileHdl;    	    	/* prepare file descriptor contents */    	    	*pResFd = *pFd;    	pResFd->pFileHdl = pFileHdl;    	*pResFd->pFileHdl = *pFd->pFileHdl;    	    	dosDirOldFillFd( pResFd, dirent );    	}        pDir->dd_cookie = POS_TO_DD_COOKIE( pFd->pos );    return OK;    } /* dosDirOldReaddir() */    /***************************************************************************** dosDirOldPathLkup - lookup for file/dir in tree.** This routine recursively searches directory tree for the <path> and* fills file descriptor for the target entry if successful.* Optionally new entry may be created in accordance with flags* in argument <options>.** DOS4.0 style names are always case insensitive in contrary to* VxLong name, that always are compared case sensitively. So* DOS_O_CASENS is ignored in  <options> argument.** <options> :	O_CREAT - creat file;*		O_CREAT | DOS_ATTR_DIRECTORY - creat directory.*		<somth> | DOS_O_CASENS - lkup for name in case		                         sensitive manner (ignored).** RETURNS: OK or ERROR if file not found.** ERRNO:* S_dosFsLib_FILE_NOT_FOUND*/LOCAL STATUS dosDirOldPathLkup    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    void *	path,	/* path in tree */    u_int	options	/* optional creat flags */    )    {    PATH_ARRAY	namePtrArray [DOS_MAX_DIR_LEVELS + 1];    int		numPathLevels;    int		errnoBuf;	/* swap errno */    DIRENT_PTR	freeEnt;	/* empty (deleted) entry in directory */    u_char	dirLevel;	/* dynamic directory level counter */        assert( path != NULL );        /* disassemble path */        numPathLevels = dosDirOldPathParse( pFd->pVolDesc, path,     					namePtrArray );     if( numPathLevels == ERROR )    	return ERROR;    assert( numPathLevels <= DOS_MAX_DIR_LEVELS );        /* start from root directory */        dosDirOldFillFd( pFd, ROOT_DIRENT );        errnoBuf = errnoGet();    errnoSet( OK );    for( dirLevel = 0; dirLevel < numPathLevels; dirLevel ++  )    	{    	/* only directory can be searched */    	    	if( ! (pFd->pFileHdl->attrib & DOS_ATTR_DIRECTORY) )    	    break;    	    	if( dosDirOldLkupInDir( pFd, namePtrArray + dirLevel, &freeEnt )		== ERROR )    	    {    	    if( errnoGet() != OK )	/* subsequent error */    	    	return ERROR;    	    	    	    break;    	    }    	}        if( errnoGet() == OK )    	errnoSet( errnoBuf );        /* check result */        if( dirLevel == numPathLevels )    	{    	return OK;    	}        /* --- file not found --- */        /* only last file in path can be created */        if( dirLevel == numPathLevels - 1 &&  (options & O_CREAT) )    	{    	if( dosDirOldFileCreateInDir( pFd,    				      namePtrArray + dirLevel,

⌨️ 快捷键说明

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