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

📄 ext2fs.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------*  search_dir_block*----------------------------------------------------------------------*/static EXT2_DIR_T *search_dir_block(EXT2_DESC_T *ext2fs, UINT32 *blkbuf,		 							char *name, int namelen, int type){    EXT2_DIR_T *dir;    UINT16 reclen, len;    UINT32 offset;    UINT8 filename[60+1];    offset = 0;    while (offset < ext2fs->blocksize)    {		dir = (EXT2_DIR_T *)((char *)blkbuf + offset);		reclen = SWAB_LE16(dir->reclen);		offset += reclen;		len = dir->namelen;		// terminate on anything which doesn't make sense		if (reclen < 8 || (len + 8) > reclen || offset > (ext2fs->blocksize + 1))			return NULL;		if (type == 0)		{			if (dir->inode && len == namelen && !strncmp(dir->name, name, len))			 	return dir;		}		else		{			switch(dir->filetype)			{				case EXT2_FTYPE_REG_FILE:	printf(" [FILE]    ");	break;				case EXT2_FTYPE_DIR:		printf(" [DIR]     ");	break;				case EXT2_FTYPE_CHRDEV:		printf(" [ChrDev]  ");	break;				case EXT2_FTYPE_BLKDEV:		printf(" [BlkDev]  ");	break;				case EXT2_FTYPE_FIFO:		printf(" [FIFO]    ");	break;				case EXT2_FTYPE_SOCK:		printf(" [SOCK]    ");	break;				case EXT2_FTYPE_SYMLINK:	printf(" [SYM]     ");	break;				case EXT2_FTYPE_UNKNOWN:					default:					printf(" [Unknown] ");	break;			}			if (len > 60)				len = 60;			memcpy(filename, dir->name, len);			filename[len] = 0x00;			printf(filename);			printf("\n");		}	}	return NULL;}/*----------------------------------------------------------------------*  ext2fs_dir_lookup *----------------------------------------------------------------------*/static EXT2_DIR_T * ext2fs_dir_lookup(EXT2_DESC_T *ext2fs, UINT32 dir_ino,										char  *name, int namelen, int type){    EXT2_INODE_T inode;    EXT2_DIR_T *dir;    UINT32 nblocks, last_block_size, i, block_nr, nbytes;	if (!ext2fs_get_inode(ext2fs, dir_ino, &inode))		return NULL;	nbytes = SWAB_LE32(inode.size);	nblocks = (nbytes + ext2fs->blocksize - 1) / ext2fs->blocksize;	last_block_size = nbytes % ext2fs->blocksize;	if (last_block_size == 0)		last_block_size = ext2fs->blocksize;    for (i = 0; i < nblocks; i++)    {		if (!ext2fs_inode_block(ext2fs, &inode, i, &block_nr))			return NULL;		if (block_nr)		{			if (!__READ_BLOCK(block_nr))				return NULL;		} else			memset(blockbuf, 0, ext2fs->blocksize);		dir = search_dir_block(ext2fs, blockbuf, name, namelen, type);		if (dir != NULL)			return dir;	}	return NULL;}/*----------------------------------------------------------------------*  ext2fs_follow_symlink *		Starting from the given directory, find the inode number, *		filetype, and parent inode for the file pointed to by the *		given symbolic link inode.*		f successful, fills out INODE_INFO_T and return true.*----------------------------------------------------------------------*/static int ext2fs_follow_symlink(EXT2_DESC_T *ext2fs, UINT32 dir_ino, UINT32 sym_ino, INODE_INFO_T *info){	#define MAX_SYMLINK_NAME 255	char symlink[MAX_SYMLINK_NAME+1];	int  pathlen;	UINT32 block_nr;	EXT2_INODE_T inode;    if (!ext2fs_get_inode(ext2fs, sym_ino, &inode))		return 0;	pathlen = SWAB_LE32(inode.size);	if (pathlen > MAX_SYMLINK_NAME)		return 0;	if (inode.blocks)    {		if (!ext2fs_inode_block(ext2fs, &inode, 0, &block_nr))			return 0;		if (block_nr)		{			if (!PARTITION_READ(ext2fs->part, EXT2_BLOCK_TO_SECTOR(ext2fs, block_nr),								ext2fs->blocksize/IDE_SECTOR_SIZE, blockbuf))				return 0;			memcpy(symlink, blockbuf, pathlen);		} else			return 0;	}	else	{		// small enough path to fit in inode struct		memcpy(symlink, (char *)&inode.block[0], pathlen);    }    symlink[pathlen] = 0;    return ext2fs_inode_lookup(ext2fs, dir_ino, symlink, info, 0);}/*----------------------------------------------------------------------*  ext2fs_inode_lookup*----------------------------------------------------------------------*/static int ext2fs_inode_lookup(EXT2_DESC_T *ext2fs, UINT32 dir_ino, char *pathname,								INODE_INFO_T *info, int type){    int len, pathlen;    char *p;    EXT2_DIR_T *dir = NULL;        if (!pathname || (pathlen = strlen(pathname)) == 0)		return 0;    if (*pathname == '/')    {		if (--pathlen == 0)		{	    	info->ino = info->parent_ino = EXT2_ROOT_INO;	    	info->filetype = EXT2_FTYPE_DIR;	    	return 1;		}		++pathname;		dir_ino = EXT2_ROOT_INO;    }    while (pathlen)    {		int is_file = 1;		// find next delimiter in path.		for (p = pathname, len = 0; len < pathlen; len++, p++)		{			// skip delimiter if found.			if (*p == '/')			{				++p;				--pathlen;				is_file = 0;				break;			}		}				if (type == 0)			dir = ext2fs_dir_lookup(ext2fs, dir_ino, pathname, len, type);		else			dir = ext2fs_dir_lookup(ext2fs, dir_ino, pathname, len, is_file);				if (dir == NULL)		    return 0;    			pathlen -= len;		pathname = p;    			switch (dir->filetype)		{			case EXT2_FTYPE_SYMLINK:				// follow the symbolic link (this will cause recursion)				if (!ext2fs_follow_symlink(ext2fs, dir_ino, SWAB_LE32(dir->inode), info))					return 0;				if (pathlen == 0)					return 1;				// must be a dir if we want to continue				if (info->filetype != EXT2_FTYPE_DIR)					return 0;				dir_ino = info->ino;				break;						case EXT2_FTYPE_DIR:				if (pathlen)					dir_ino = SWAB_LE32(dir->inode);				break;						case EXT2_FTYPE_REG_FILE:				if (pathlen)					return 0;  // regular file embedded in middle of path				break;    				case EXT2_FTYPE_UNKNOWN:			case EXT2_FTYPE_CHRDEV:			case EXT2_FTYPE_BLKDEV:			case EXT2_FTYPE_FIFO:			case EXT2_FTYPE_SOCK:			default:				return 0;		}	}        info->ino = SWAB_LE32(dir->inode);    info->parent_ino = dir_ino;    info->filetype = dir->filetype;    return 1;}/*----------------------------------------------------------------------*  ext2fs_read*----------------------------------------------------------------------*/int ext2fs_read(void *fp, char *buf, UINT32 nbytes){    FILE_T *info = fp;    EXT2_DESC_T *ext2fs;    UINT32 nread = 0, rem, block_nr, bindex, to_read;    if ((info->file_pos + nbytes) > info->file_size)		nbytes = info->file_size - info->file_pos;    ext2fs = info->ext2fs_desc;        // see if we need to copy leftover data from last read call    rem = ext2fs->blocksize - (info->file_pos % ext2fs->blocksize);    if (rem != ext2fs->blocksize)    {		char *p = (char *)blockbuf + ext2fs->blocksize - rem;		if (rem > nbytes)			rem = nbytes;		memcpy(buf, p, rem);		nread += rem;		buf  += rem;		info->file_pos += rem;    }    	// now loop through blocks if we're not done	bindex = info->file_pos / ext2fs->blocksize;	while (nread < nbytes)	{		if (!ext2fs_inode_block(ext2fs, &info->inode, bindex, &block_nr))			return -1;		if (block_nr)		{			if (!PARTITION_READ(ext2fs->part, EXT2_BLOCK_TO_SECTOR(ext2fs, block_nr),								ext2fs->blocksize/IDE_SECTOR_SIZE, blockbuf))				return 0;		} else			memset(blockbuf, 0, ext2fs->blocksize);			to_read = nbytes - nread;		if (to_read > ext2fs->blocksize)			to_read = ext2fs->blocksize;		memcpy(buf, blockbuf, to_read);		nread += to_read;		buf += to_read;		info->file_pos += to_read;		++bindex;    }    return nread;}/*----------------------------------------------------------------------*  ext2fs_close*----------------------------------------------------------------------*/int ext2fs_close(void *fp){    FILE_T *info = fp;		info->opened = 0;}	/*----------------------------------------------------------------------*  ext2fs_file_size*----------------------------------------------------------------------*/int ext2fs_file_size(void *fp){    FILE_T *info = fp;		return info->file_size;}/*----------------------------------------------------------------------*  ext2fs_ls*	List file*----------------------------------------------------------------------*/void ext2fs_ls(char *pathname){	INODE_INFO_T inode_info;	ext2fs_inode_lookup(&ext2fs_desc, EXT2_ROOT_INO, pathname, &inode_info, 1);}/*----------------------------------------------------------------------*  ext2fs_ls_cmd*	CLI command to list file*----------------------------------------------------------------------*/void ext2fs_ls_cmd(char argc, char *argv[]){	char pathname[81];	#if 1		if (argc <= 1)		strcpy(pathname, "/*");	else if (strlen(argv[1]) <= 80)		sprintf(pathname, "%s/*", argv[1]);	else		printf("Pathname is too long! (>= 80)\n");#else	strcpy(pathname, "/*");#endif	ide_init();	ext2fs_init();		ext2fs_ls(pathname);		}#endif // BOARD_SUPPORT_IDE

⌨️ 快捷键说明

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