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

📄 dosdiroldlib.c

📁 vxworks操作系统的文件系统部分原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        switch( which )        {        case DH_TIME_CREAT:            tOff = pDirDesc->deDesc.creatTimeOff;            dOff = pDirDesc->deDesc.creatDateOff;            break;        case DH_TIME_MODIFY:            tOff = pDirDesc->deDesc.modifTimeOff;            dOff = pDirDesc->deDesc.modifDateOff;            break;        case DH_TIME_ACCESS:            tOff = pDirDesc->deDesc.accessTimeOff;            dOff = pDirDesc->deDesc.accessDateOff;            break;        default:            assert( FALSE );        }        if( dOff != (u_char)NONE )    	{    	dtBuf = DISK_TO_VX_16( pDirent + dOff );    	    	tm.tm_mday    = dtBuf & 0x1f;    		/* ANSI months are zero-based */	    	tm.tm_mon     = ((dtBuf >> 5) & 0x0f) - 1;    		/* DOS starts at 1980, ANSI starts at 1900 */	    	tm.tm_year    = ((dtBuf >> 9) & 0x7f) + 1980 - 1900;    	}    if( tOff != (u_char)NONE )    	{    	dtBuf = DISK_TO_VX_16( pDirent + tOff );    	    	tm.tm_sec     = (dtBuf & 0x1f) << 1;    	tm.tm_min     = (dtBuf >> 5) & 0x3f;    	tm.tm_hour    = (dtBuf >> 11) & 0x1f;    	}        /* encode into time_t format */        return mktime( &tm );    } /* dosDirOldTDDecode() *//***************************************************************************** dosDirOldTDEncode - encode time-date to disk format.** This routine takes time value is provided in <curTime> argument* and encodes it into directory entry format.* * Parameter <timesMask> defines which time fields to fill. Following* values can be bitwise or-ed:* DH_TIME_CREAT, DH_TIME_MODIFY, DH_TIME_ACCESS.** RETURNS: N/A.*/LOCAL void dosDirOldTDEncode    (    DOS_DIR_PDESCR_ID	pDirDesc,    u_char *	pDirEnt,    u_int	timesMask,    time_t	curTime	/* time to encode */    )    {    struct tm   tm;	/* buffer for split time-date */    u_char	timeB[2], dateB[2];	/* buffers for encoding */        localtime_r( &curTime, &tm );    /* encode time */        VX_TO_DISK_16( ( tm.tm_sec >> 1 ) |    		  ( tm.tm_min << 5 ) |    		  ( tm.tm_hour << 11 ), timeB );        /*     * encode date;     * in <pDate> year is related to 1980, but in tm,-to 1900     */    tm.tm_year =  ( tm.tm_year < 80 )? 80 : tm.tm_year;    VX_TO_DISK_16( tm.tm_mday | ( ( tm.tm_mon + 1 ) << 5 ) |    		  ( ( tm.tm_year - 80 ) <<  9 ), dateB );        /* put time-date into directory entry buffer */        if( timesMask & DH_TIME_CREAT &&        pDirDesc->deDesc.creatDateOff != (u_char)NONE  )    	{    	pDirEnt[ pDirDesc->deDesc.creatTimeOff ] = timeB[0];    	pDirEnt[ pDirDesc->deDesc.creatTimeOff + 1 ] = timeB[1];    	pDirEnt[ pDirDesc->deDesc.creatDateOff ] = dateB[0];    	pDirEnt[ pDirDesc->deDesc.creatDateOff + 1 ] = dateB[1];    	}    if( timesMask & DH_TIME_MODIFY &&        pDirDesc->deDesc.modifDateOff != (u_char)NONE  )    	{    	pDirEnt[ pDirDesc->deDesc.modifTimeOff ] = timeB[0];    	pDirEnt[ pDirDesc->deDesc.modifTimeOff + 1 ] = timeB[1];    	pDirEnt[ pDirDesc->deDesc.modifDateOff ] = dateB[0];    	pDirEnt[ pDirDesc->deDesc.modifDateOff + 1 ] = dateB[1];    	}    if( timesMask & DH_TIME_ACCESS &&        pDirDesc->deDesc.accessDateOff != (u_char)NONE  )    	{    	if( pDirDesc->deDesc.accessTimeOff != (u_char)NONE )    	    {    	    pDirEnt[ pDirDesc->deDesc.accessTimeOff ] = timeB[0];    	    pDirEnt[ pDirDesc->deDesc.accessTimeOff + 1 ] = timeB[1];    	    }    	pDirEnt[ pDirDesc->deDesc.accessDateOff ] = dateB[0];    	pDirEnt[ pDirDesc->deDesc.accessDateOff + 1 ] = dateB[1];    	}    } /* dosDirOldTDEncode() */    /***************************************************************************** dosDirOldNameEncode - encode name to disk format.** This routine encodes incoming file name to current volume* directory structure format* (8+3 uppercase or VxLong names). in the same time incoming* name is verified to be composed of valid characters.** RETURNS: OK or ERROR if name is invalid.* * ERRNO:* S_dosFsLib_ILLEGAL_NAME*/LOCAL STATUS dosDirOldNameEncode    (     DOS_DIR_PDESCR_ID	pDirDesc,    PATH_ARRAY_ID	pNamePtr,	/* name buffer */    u_char *	pDstName	/* buffer for name in disk format */    )    {    u_char const *	nameTransTbl;	/* name translation table */    u_char *	pSrc;	/* source name dynamic ptr */    u_char *	pDstBuf;	/* for debug output only */    int		i,j;		/* work */    u_char	extLen = pDirDesc->deDesc.extLen;    			/* extension length (0 - no extension) */        pDstBuf = pDstName;    nameTransTbl = ( pDirDesc->nameStyle == STDDOS )?    			shortNamesChar : longNamesChar;        bfill( (char *) pDstName,    	   pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,            SPACE );        /* encode name and check it by the way */        DBG_MSG( 600, "",0 ,0,0,0,0,0,0,0);    DBG_PRN_STR( 600, "%s\n", pNamePtr->pName, pNamePtr->nameLen, 0 );    for( i = 0, pSrc = pNamePtr->pName;    	 i < min( pDirDesc->deDesc.nameLen,    	 	  pNamePtr->nameLen );    	 i++, pDstName++, pSrc++  )    	{    	/* check for extension */    	    	if( extLen != 0 && *pSrc == DOT )    	    break;    	    	/* allow all high characters */    	    	if( *pSrc & 0x80 )    	    {    	    *pDstName = *pSrc;    	    continue;    	    }    	    	*pDstName = nameTransTbl[ *pSrc ];    	if( *pDstName == INVALID_CHAR )    	    goto error;    	}    /* check state */        if( i == pNamePtr->nameLen )    	goto retOK;	/* name finished */        if( extLen != 0 )	/* traditional DOS: 8.3 */    	{    	if( *pSrc != DOT )	/* name too long */    	    goto error;    	pSrc++;	/* pass DOT */    	pDstName += pDirDesc->deDesc.nameLen - i;    	i++;    	}    else	/* vxWorks old long names */    	goto error;	/* name too long */        /* encode extension */        for( j = 0; j < extLen && i < pNamePtr->nameLen;    	 i++, j++, pDstName++, pSrc++  )    	{    	/* allow all high characters */    	    	if( *pSrc & 0x80 )    	    {    	    *pDstName = *pSrc;    	    continue;    	    }    	    	*pDstName = nameTransTbl[ *pSrc ];    	if( *pDstName == INVALID_CHAR )    	    goto error;    	}        /* check status */        if( i < pNamePtr->nameLen )	/* extension too long */    	goto error;retOK:    DBG_PRN_STR( 600, "result: %s\n", pDstBuf,     		 pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,0 );    return OK;    error:    errnoSet( S_dosFsLib_ILLEGAL_NAME );    return ERROR;    } /* dosDirOldNameEncode() */    /***************************************************************************** dosDirOldDirentGet - get directory entry from disk.** This routine reads directory entry from disk. ** <which> argument defines which entry to get.* This routine can be* used for readdir (<which> = RD_FIRST/RD_CURRENT/RD_NEXT),* in what case <pFd> describes the* directory is being read, or for getting directory entry* corresponding to <pFd> (<which> = FD_ENTRY).** RETURNS: OK or ERROR if directory chain end reached or*  disk access error.*/LOCAL STATUS dosDirOldDirentGet    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    u_char *	pDirEnt,    RDE_OPTION	 which		/* which entry to get */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    DOS_DIR_HDL_ID	pDirHdl = (void *)&(pFd->pFileHdl->dirHdl);    int			dirEntSize = pDirDesc->deDesc.dirEntSize;    DOS_FILE_DESC	workFd;        /* prepare to operation */        if( which == FD_ENTRY ) /* get directory entry of file */    	{    	DBG_MSG( 600, "pFd = %p, FD_ENTRY\n", pFd ,0,0,0,0,0,0,0);    	/*    	 * it is being read directory entry of the file/dir,    	 * pointed by file descriptor.    	 * Prepare working fd.    	 */    	workFd = *pFd;    	workFd.curSec = pDirHdl->sector;    	workFd.pos = pDirHdl->offset;    	workFd.cbioCookie = pDirHdl->cookie;    	    	goto getEntry;    	}        /* readdir */        if(  which == RD_CURRENT )	/* read current dir entry */    	{    	assert( pFd->nSec != 0 );    	assert( pFd->curSec != 0 );    	    	goto getEntry;    	}        if( which == RD_FIRST )	/* read start dir entry */    	{    	DBG_MSG( 600, "pFd = %p, RD_FIRST\n", pFd ,0,0,0,0,0,0,0);    	dosDirOldRewindDir( pFd );	/* rewind directory */    	}    else if( which == RD_NEXT )	/* read next dir entry */    	{    	DBG_MSG( 600, "pFd = %p, RD_NEXT\n", pFd ,0,0,0,0,0,0,0);    	assert( pFd->curSec != 0 );    	    	/* correct position */    	    	pFd->pos += dirEntSize;    	    	/* check for sector bounds */    	    	if( OFFSET_IN_SEC( pFd->pVolDesc, pFd->pos ) == 0 )    	    {    	    pFd->curSec++;    	    pFd->nSec--;    	    }    	}    else	/* impossible flag */    	{    	assert( which != which );    	}     	    /* may be contiguous block finished - get next contiguous block */    	        if( pFd->nSec == 0 )    	{    	if( pFd->pVolDesc->pFatDesc->getNext(    	    			pFd, FAT_NOT_ALLOC ) == ERROR )    	    {    	    return ERROR;    	    }    	pFd->cbioCookie = (cookie_t) NULL;	/* we jumped to other sector */    	}        workFd = *pFd;    getEntry:    assert( OFFSET_IN_SEC( workFd.pVolDesc, workFd.pos ) <=		workFd.pVolDesc->bytesPerSec - dirEntSize );    	    /* read directory entry */        if( cbioBytesRW( workFd.pVolDesc->pCbio, workFd.curSec,    		     OFFSET_IN_SEC( workFd.pVolDesc, workFd.pos),		     (addr_t)pDirEnt, dirEntSize, CBIO_READ,    		     &workFd.cbioCookie ) == ERROR )    	{    	return ERROR;    	}    DBG_PRN_STR( 600, "entry: %s\n", pDirEnt,    		 pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen,0 );    		     return OK;    } /* dosDirOldDirentGet() */    /***************************************************************************** dosDirOldLkupInDir - look in directory for specified name.** This routine searches directory, that is pointed by <pFd> for name, that* is pointed by <pNamePtr> structure and fills <pFd> in accordance with* directory entry data, if found.** If name not found, <pFreeEnt> will be filled with pointer onto* some deleted entry in directory or onto free space in last directory* cluster. If both not found,* <pFreeEnt->sector> is set to 0.** RETURNS: OK or ERROR if name not found or invalid name.*/LOCAL STATUS dosDirOldLkupInDir    (    DOS_FILE_DESC_ID	pFd,	/* dos file descriptor to fill */    PATH_ARRAY_ID	pNamePtr,	/* name buffer */    DIRENT_PTR_ID	pFreeEnt	/* empty entry in directory */    )    {    DOS_DIR_PDESCR_ID	pDirDesc = (void *)pFd->pVolDesc->pDirDesc;    STATUS	status;	/* search result status */    u_int	nEntries;	/* number of entries in directory */    u_short	nameLen;	/* name length on disk */    u_char	name[  DOS_VX_LONG_NAME_LEN ]; /* name in disk format */    u_char	dirent[ DOS_VX_DIRENT_LEN ]; /* directory entry buffer */        nameLen = pDirDesc->deDesc.nameLen + pDirDesc->deDesc.extLen;    DBG_MSG( 400, "pFd = %p", pFd ,0,0,0,0,0,0,0);    DBG_PRN_STR( 400, "name: %s\n", pNamePtr->pName,    			pNamePtr->nameLen, 0 );        pFreeEnt->sector = 0;    pFreeEnt->offset = 0;        /* prepare name */        if( dosDirOldNameEncode( pDirDesc, pNamePtr, name ) == ERROR )    	return ERROR;        for( nEntries = 0, (status = dosDirOldDirentGet( pFd, dirent, RD_FIRST ));    	 (status != ERROR) && *dirent != LAST_DIRENT;    	 status = dosDirOldDirentGet( pFd, dirent, RD_NEXT ), nEntries++ )    	{    	/* pass volume label */    	    	if( *(dirent + pDirDesc->deDesc.atrribOff) & DOS_ATTR_VOL_LABEL )    	    continue;    	    	/* pass deleted entry, that later can be used to store new entry */    	    	if( *dirent == DOS_DEL_MARK )    	    {    	    pFreeEnt->sector = pFd->curSec;    	    pFreeEnt->offset = pFd->pos;    	    continue;    	    }    	    	/* compare names */    	    	if( bcmp( (char *)name, (char *)dirent, nameLen ) == 0 )    	    {    	    break;    	    }    	}        /* check result */        if( status == ERROR ||        ( IS_ROOT( pFd ) && nEntries > pDirDesc->rootMaxEntries ) )        {    	return ERROR;    	}        if(  *dirent == LAST_DIRENT )    	{        /* will create new entry on this place, if required */        	if( pFreeEnt->sector == 0 )    	    {    	    pFreeEnt->sector = pFd->curSec;    	    pFreeEnt->offset = pFd->pos;    	    }    	return ERROR;    	}        /* file found; fill file descriptor */        dosDirOldFillFd( pFd, dirent );    return OK;     } /* dosDirOldLkupInDir() */    /***************************************************************************** dosDirOldClustAdd - add and init cluster to directory.** RETURNS: OK or ERROR if no more cluster could be allocated.*/LOCAL STATUS dosDirOldClustAdd    (    DOS_FILE_DESC_ID	pFd    )    {    block_t	sec;	/* work count */        /* allocate cluster */        if( pFd->pVolDesc->pFatDesc->getNext( pFd, FAT_ALLOC_ONE ) == ERROR )    	return ERROR;        assert( pFd->pFileHdl->startClust != 0 );        /* fill cluster: */    for( sec = pFd->curSec; sec < pFd->curSec + pFd->nSec;         sec ++ )    	{    	if( cbioIoctl(pFd->pVolDesc->pCbio, CBIO_CACHE_NEWBLK,			(void *)sec ) == ERROR )    	    {    	    return ERROR;    	    }    	}            return OK;    } /* dosDirOldClustAdd() *//***************************************************************************** dosDirOldUpdateEntry - set new directory entry contents.** This routine pulls file size, attributes and so on out of* file descriptor and stores in the file directory entry.* * This function is also used for entry deletion. In this* case <flags> have to be set to DH_DELETE.** Time value provided in <curTime> can be encoded into appropriate* fields within directory entry structure in accordance with* <flags> argument. <flags> can be or-ed of* DH_TIME_CREAT, DH_TIME_MODIFY or DH_TIME_ACCESS.* If <curTime> is 0, current system time is used.

⌨️ 快捷键说明

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