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

📄 cdromfslib.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 5 页
字号:
    T_CDROM_FILE_ID	pFD,      /* cdrom file descriptor ID */    u_char *	name,             /* file name */    u_char *	pPTRec,           /* ptr to path table record */    u_int	dirRecNumInPT,    /* dir record no. in path table */    u_int	dirRecOffInPT     /* dir record offset in path table */    )    {    DIR	           dir;    BOOL absName = FALSE;    T_CDROM_FILE   bufFD;    char *	   pChar;    char           found;        assert (pVDList != NULL);    assert (pFD != NULL);    assert (name != NULL);        DBG_MSG(300)("name = %s\n", name);        /* what is the name, - absolute or to find last version? */    pChar = strchr (name, SEMICOL);    if (pChar != NULL) 	{	if (isdigit (*(pChar + 1)))	    absName = TRUE;	else	    *(pChar) = EOS;	}    found = 0;retry:    while (cdromFsIoctl (pFD, FIOREADDIR, (int)&dir) == OK)    	{    	int compRes;    		/* truncate current name in case last version search */	if (!absName)	    {	    pChar = strchr(dir.dd_dirent.d_name, SEMICOL);	    if (pChar != NULL)	        *pChar = EOS;	    }	compRes = strcmp (name, dir.dd_dirent.d_name);    		/* names in dir are sorted lexicographically */	if (!absName && compRes < 0)	    break;		/* any version of file found */	if (compRes == 0)	    {	    found = 1;	    /* if requested version */	    if (absName)	    	        return (cdromFsFillFDForFile (pVDList, pFD));    	    	    bufFD = *pFD;	/* safe found */    	    }    	}	/* while */        if (found == 0)    	{		/* case sensitive not found */        if (cdromFsFillFDForDir (pVDList, pFD, pPTRec, dirRecNumInPT,        			 dirRecOffInPT) == ERROR)	    return ERROR;	cdromFsStrUp (name, strlen(name));    	found = (char)(-1);	/* case insensitive */	goto retry;	}        if(found == (char)(-1))    	return ERROR;	/* not case sensitive nor insensitive found */    RESTORE_FD (bufFD, *pFD, ERROR);	/* return to a last found version */    return (cdromFsFillFDForFile(pVDList, pFD));    }    /********************************************************************************* cdromFsFindDirOnLevel - find directory within given PT dir hierarchy level.** This routine trys to find <name> within <dirLev>* PT dir hierarchy level, that have parent dir number <parDirNum>.* <pPT> points to PT buffer.* In <pPTRec> will be returned ptr to found PT record (if will).** RETURNS: record number or 0 if not found.*/LOCAL int cdromFsFindDirOnLevel    (    T_CDROMFS_VD_LST_ID	pVDList, /* ptr to volume descriptor list */    u_char *	name,	 	 /* dir name to search for (EOS terminated) */    u_char *	pPT,		 /* PT buffer */    u_int	parDirNum,	 /* evidently */    u_int	pathLev,	 /* level of <name> within path */    				 /* first path name lays on */    				 /* zero path level, but on second dir */    				 /* hierarchy level, so */    u_char **	ppRecord	 /* address of current PT record ptr */    )    {    int	offset;		   	   /* abs offset from PT start */    u_char * pUpCaseName = NULL;   /* ptr to upper case name found */    u_short	recNum;		   /* current record number */    u_short	upCaseRecNum = 0;  /* record number of upper case name found */    u_short	curRecParent;	   /* current record's parent record number */    u_short	nameLen;	   /* <name> length */    u_char	upCaseName[100] = {EOS};	        /*      * let us path = "/d0/d1/---[/fname]"     * first path name <d0> lays on zero path level, but on second directory     * hierarchy level, so if Level is dir hierarchy level, on which     * lays <name>, Level = <pathLev>+2, and therefore <pathLev> may     * be used for encounting  dir hierarchy levels' bounds arrays.     */    offset = pVDList->dirLevBordersOff[ pathLev ];     pPT += offset;    recNum = (pathLev == 0)? 2: pVDList->dirLevLastRecNum[ pathLev -1 ] + 1;    nameLen = strlen(name);    strncpy (upCaseName, name, nameLen + 1);    cdromFsStrUp (upCaseName, nameLen);        for (; recNum <= pVDList->dirLevLastRecNum[ pathLev ]; 	 recNum ++, offset = cdromFsNextPTRec(&pPT, offset, pVDList->PTSize))	{	int	compRes;	/* strncmp result */		PT_PARENT_REC (curRecParent, pPT);	if (curRecParent != parDirNum || nameLen != (u_short)*pPT)	    continue;		compRes = strncmp(name, pPT + ISO_PT_REC_DI, nameLen);	if (compRes == 0)	    {	    *ppRecord = pPT;	    return recNum;	    }	else if (strncmp(upCaseName, pPT + ISO_PT_REC_DI, nameLen) == 0)	    {	    pUpCaseName = pPT;	    upCaseRecNum = recNum;	    }	else if (compRes < 0)	/* PT records are sorted by name increasing */	    break;	}        if (pUpCaseName == NULL)	/* not found */    	return 0;        /* name found in upper case only */    *ppRecord = pUpCaseName;    return (upCaseRecNum);    }    /********************************************************************************* cdromFsFindPathInDirHierar - find file/directory within given dir hierarchy.** This routine tries to find <path> within given VD dir hierarchy.* and fill in T_CDROM_FILE structure.* Path levels (dir/file names) have to be splitted by EOS.** RETURNS: OK or ERROR if path not found.*/LOCAL STATUS cdromFsFindPathInDirHierar    (    T_CDROMFS_VD_LST_ID	pVDList, /* ptr to volume desc list */    u_char *	path,            /* path */    u_int	numPathLevs, 	 /* number of names in path */    T_CDROM_FILE_ID	pFD,	 /* FD to fill if full path found */    int	options			 /* not used currently */    )    {    int	curPathLev, parDirNum;    u_char *	pPT;    u_char *	pPTRec;    STATUS	retStat = ERROR;        assert (pVDList != NULL);    assert (path != NULL);    assert (pFD != NULL);        /*      * numPathLevs may not exceed number of directory hierarchy levels     * plus one for file name     */    if(numPathLevs > pVDList->numDirLevs + 1)        return ERROR;            pPT = cdromFsPTGet (pVDList, NULL);    if (pPT == NULL)	goto ret;    for (curPathLev = 0, parDirNum = 1, pPTRec = pPT;	 curPathLev < numPathLevs && curPathLev < pVDList->numDirLevs;	 path += strlen(path) + 1)	{	parDirNum = cdromFsFindDirOnLevel (pVDList, path, pPT, parDirNum,					   curPathLev, &pPTRec);	curPathLev++;		if (parDirNum == 0)	/* last name not found */	    break;	}        if (curPathLev == numPathLevs ||	(curPathLev == numPathLevs - 1 && parDirNum != 0 &&	 curPathLev == pVDList->numDirLevs)	)	{        retStat = cdromFsFillFDForDir (pVDList, pFD, pPTRec, parDirNum,				       0 /* not use now, since PT is read					  * wholly */				       );        				         if (retStat == ERROR || (parDirNum != 0 && curPathLev == numPathLevs))	    /* path found */	    goto ret;        }    else    	goto ret;        retStat = cdromFsFindFileInDir (pVDList, pFD, path, pPTRec, parDirNum, 0);    ret:    return retStat;    }    /********************************************************************************* cdromFsFindPath - find file/directory on given volume.** This routine trys to find <path> within all volume* primary/supplementary directory hierarcies and creates and fills in* T_CDROM_FILE structure for following accsess.* levels in path have to be splitted by '\' or '/'.** ERRNO: S_cdromFsLib_MAX_DIR_LEV_OVERFLOW* S_cdromFsLib_NO_SUCH_FILE_OR_DIRECTORY** RETURNS: T_CDROM_FILE_ID or NULL if any error encounted.*/LOCAL T_CDROM_FILE_ID cdromFsFindPath    (    CDROM_VOL_DESC_ID	pVolDesc,   /* ptr to volume descriptor */    u_char *	path,               /* path */    int	options                     /* search options */    )    {    T_CDROMFS_VD_LST_ID	pVDList;    T_CDROM_FILE_ID	pFD;    u_char	pPath[ CDROM_MAX_PATH_LEN + 1 ] = {EOS};    u_int	numPathLevs;        assert (pVolDesc != NULL);    assert (path != NULL);    #ifndef	ERR_SET_SELF    errnoSet(OK);#else    errno = OK;#endif        /* prepare path for processing (split to distinct directorys/file names) */    strncpy (pPath, path, CDROM_MAX_PATH_LEN);    path = pPath;        numPathLevs = cdromFsSplitPath (path);        if (numPathLevs == (-1))	return (T_CDROM_FILE_ID)ERROR;        if (numPathLevs > CDROM_MAX_DIR_LEV + 1)	/* one for file */    	{    	errnoSet (S_cdromFsLib_MAX_DIR_HIERARCHY_LEVEL_OVERFLOW);	return (T_CDROM_FILE_ID) ERROR;    	}        /* allocate T_CDROM_FILE structure */    pFD = cdromFsFDAlloc (pVolDesc);    if (pFD == NULL)	return (T_CDROM_FILE_ID)ERROR;        for (pVDList = (T_CDROMFS_VD_LST_ID) lstFirst (&(pVolDesc->VDList));    	  pVDList != NULL;    	  pVDList = (T_CDROMFS_VD_LST_ID) lstNext ((NODE *)pVDList))    	{	if (cdromFsFindPathInDirHierar (pVDList, path, numPathLevs,					pFD, options) == OK)	    return pFD;	}        /* file/directory not found */    cdromFsFDFree (pFD);    if (errnoGet() == OK)	errnoSet (S_cdromFsLib_NO_SUCH_FILE_OR_DIRECTORY);	    return (T_CDROM_FILE_ID)ERROR;    }/********************************************************************************* cdromFsFillStat - filling of stat structure ** This routine transfers data from T_CDROM_FILE structure to stat structure* defined in <sys/stat.h>** RETURNS: OK or ERROR if it cannot fill stat structure*/LOCAL STATUS cdromFsFillStat    (    T_CDROM_FILE_ID fd,                 /* File descriptor */    struct stat * arg                   /* Pointer to stat structure */    )    {    u_char *ptr;                        /* pointer to LogBlock       */    struct tm	recTime;		/* temp. structure           */    short tmp = 0;		        /* to form permission flags  */    short tmp2 = 0;		        /* to convert flags from EAR */        arg->st_blksize = fd->pVDList->LBSize;   /* We read by LogBlocks */        if (fd->FType == S_IFDIR)	/* In the case of directory */        {        ptr = cdromFsGetLB (fd->pVDList, fd->FStartLB, &(fd->sectBuf));        if (ptr == NULL)            return ERROR;        /* pointer to a sequence of Dir. Records, not data */        ptr += fd->FDataStartOffInLB;	        }    else	{	ptr = fd->FRecords;	/* In the case of File Section */	}        arg->st_size = fd->FSize;        arg->st_blocks = A_PER_B (fd->pVDList->LBSize, fd->FSize);        /* time fields */    recTime.tm_sec	= fd->FDateTime.seconds;    recTime.tm_min	= fd->FDateTime.minuts;    recTime.tm_hour	= fd->FDateTime.hour;    recTime.tm_mday	= fd->FDateTime.day;    recTime.tm_mon	= fd->FDateTime.month - 1;    recTime.tm_year	= fd->FDateTime.year;    fd->FDateTimeLong	= mktime (&recTime);    /*     * The DOS-FS time fields are not supported from VxWorks 5.2     * and above, but REQUIRED for 5.1.1 and lower to see valid     * file dates.     */#ifdef	VXWORKS_511    arg->st_fYear = fd->FDateTime.year + 1900;    arg->st_fMonth = fd->FDateTime.month;    arg->st_fDay = fd->FDateTime.day;    arg->st_fHour = fd->FDateTime.hour;    arg->st_fMinute = fd->FDateTime.minuts;    arg->st_fSecond = fd->FDateTime.seconds;    fd->FDateTimeLong	= 0;#endif /* VXWORKS_511 */    arg->st_atime = arg->st_mtime = arg->st_ctime = fd->FDateTimeLong;        /* bits of permissions  processing */        if (*(ptr + ISO_DIR_REC_FLAGS) & DRF_PROTECT)        {        if (*(ptr + ISO_DIR_REC_EAR_LEN) == 0) /* EAR must appear */            {            errnoSet (S_cdromFsLib_INVALID_DIR_REC_STRUCT);            return ERROR;            }        /* Read ExtAttrRecord */        ptr = cdromFsGetLB (fd->pVDList,			    fd->FStartLB - *(ptr + ISO_DIR_REC_EAR_LEN),			    &(fd->sectBuf));        if (ptr == NULL)            return ERROR;                    /*	 * Now we should transfer permission bits from ExtAttrRec    	 * Sequential reading of two bytes (processor independent)       	 */        tmp2 = (*(ptr + ISO_EAR_PERMIT) << 8) |               *(ptr + ISO_EAR_PERMIT + 1);        tmp |= (tmp2 & 0x01) ? 0 : S_IROTH;        tmp |= (tmp2 & 0x04) ? 0 : S_IXOTH;          tmp |= (tmp2 & 0x10) ? 0 : S_IRUSR;        tmp |= (tmp2 & 0x40) ? 0 : S_IXUSR;        tmp |= (tmp2 & 0x100) ? 0 : S_IRGRP;        tmp |= (tmp2 & 0x400) ? 0 : S_IXGRP;        tmp |= (tmp2 & 0x1000) ? 0 : S_IROTH;        tmp |= (tmp2 & 0x4000) ? 0 : S_IXOTH;  		        }    else        {	/* Every user has rights to read and execute */        tmp = S_ISUID | S_ISGID | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |              S_IXGRP | S_IROTH | S_IXOTH;        }		    arg->st_mode = fd->FType | tmp;             /* not fd->FDType */    return OK;    }/********************************************************************************* cdromFsCountMdu - counts current position offset in MDU ** This function counts only one value contained in a file descriptor of* cdromFs system - FCDOffInMDU. For this purpose reading of the file itself* is necessary (sequential, record after record). It is assumed that* absolute position of file pointer is written in the fd, and the previous* file pointer posit

⌨️ 快捷键说明

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