📄 e2fs.c
字号:
__FUNCTION__, name, namelen, dir_ino);#endif if (!e2fs_get_inode(e2fs, dir_ino, &inode)) {#if DEBUG_E2FS > 0 diag_printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, dir_ino);#endif return NULL; } nbytes = SWAB_LE32(inode.size); nblocks = (nbytes + e2fs->blocksize - 1) / e2fs->blocksize; last_block_size = nbytes % e2fs->blocksize; if (last_block_size == 0) last_block_size = e2fs->blocksize; for (i = 0; i < nblocks; i++) { if (!e2fs_inode_block(e2fs, &inode, i, &block_nr)) return NULL; if (block_nr) { if (!__READ_BLOCK(block_nr)) return NULL; } else memset(blockbuf, 0, e2fs->blocksize); dir = search_dir_block(e2fs, blockbuf, name, namelen); if (dir != NULL) return dir; } return NULL;}typedef struct ino_info { cyg_uint32 ino; cyg_uint32 parent_ino; cyg_uint8 filetype;} ino_info_t;static int e2fs_inode_lookup(e2fs_desc_t *e2fs, cyg_uint32 dir_ino, const char *pathname, ino_info_t *info);// Starting from the given directory, find the inode number, filetype, and// parent inode for the file pointed to by the given symbolic link inode.// If successful, fills out ino_info_t and return true.//static inte2fs_follow_symlink(e2fs_desc_t *e2fs, cyg_uint32 dir_ino, cyg_uint32 sym_ino, ino_info_t *info){#define MAX_SYMLINK_NAME 255 char symlink[MAX_SYMLINK_NAME+1]; int pathlen; cyg_uint32 block_nr; e2fs_inode_t inode; if (!e2fs_get_inode(e2fs, sym_ino, &inode)) {#if DEBUG_E2FS > 0 diag_printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, sym_ino);#endif return 0; } pathlen = SWAB_LE32(inode.size); if (pathlen > MAX_SYMLINK_NAME) return 0; if (inode.blocks) { if (!e2fs_inode_block(e2fs, &inode, 0, &block_nr)) return 0; if (block_nr) { if (!PARTITION_READ(e2fs->part, E2FS_BLOCK_TO_SECTOR(e2fs, block_nr), blockbuf, e2fs->blocksize/SECTOR_SIZE)) 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 e2fs_inode_lookup(e2fs, dir_ino, symlink, info);}// Starting from the given directory, find the inode number, filetype, and// parent inode for the given file pathname.// If successful, fills out ino_info_t and return true.//static inte2fs_inode_lookup(e2fs_desc_t *e2fs, cyg_uint32 dir_ino, const char *pathname, ino_info_t *info){ int len, pathlen; const char *p; e2fs_dir_entry_t *dir = NULL; if (!pathname || (pathlen = strlen(pathname)) == 0) return 0; if (*pathname == '/') { if (--pathlen == 0) { info->ino = info->parent_ino = E2FS_ROOT_INO; info->filetype = E2FS_FTYPE_DIR; return 1; } ++pathname; dir_ino = E2FS_ROOT_INO; } while (pathlen) { // find next delimiter in path. for (p = pathname, len = 0; len < pathlen; len++, p++) { // skip delimiter if found. if (*p == '/') { ++p; --pathlen; break; } } dir = e2fs_dir_lookup(e2fs, dir_ino, pathname, len); if (dir == NULL) return 0; pathlen -= len; pathname = p; switch (dir->filetype) { case E2FS_FTYPE_SYMLINK: // follow the symbolic link (this will cause recursion) if (!e2fs_follow_symlink(e2fs, 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 != E2FS_FTYPE_DIR) return 0; dir_ino = info->ino; break; case E2FS_FTYPE_DIR: if (pathlen) dir_ino = SWAB_LE32(dir->inode); break; case E2FS_FTYPE_REG_FILE: if (pathlen) return 0; // regular file embedded in middle of path break; case E2FS_FTYPE_UNKNOWN: case E2FS_FTYPE_CHRDEV: case E2FS_FTYPE_BLKDEV: case E2FS_FTYPE_FIFO: case E2FS_FTYPE_SOCK: default: return 0; } } info->ino = SWAB_LE32(dir->inode); info->parent_ino = dir_ino; info->filetype = dir->filetype; return 1;}struct read_info { e2fs_desc_t e2fs_desc; e2fs_inode_t inode; cyg_uint32 fsize; cyg_uint32 fpos;};static void *e2fs_open(partition_t *p, const char *filepath){ static struct read_info rinfo; ino_info_t ino_info; // mount partition if (e2fs_mount(p, &rinfo.e2fs_desc) != 0) { diag_printf("mount failed.\n"); return NULL; } // find file inode if (!e2fs_inode_lookup(&rinfo.e2fs_desc, E2FS_ROOT_INO, filepath, &ino_info)) { diag_printf("%s: e2fs_inode_lookup failed\n", __FUNCTION__); return NULL; } // read inode if (!e2fs_get_inode(&rinfo.e2fs_desc, ino_info.ino, &rinfo.inode)) { diag_printf("%s: e2fs_get_inode failed for ino[%d]\n", __FUNCTION__, ino_info.ino); return NULL; } rinfo.fsize = SWAB_LE32(rinfo.inode.size); rinfo.fpos = 0; return &rinfo;}static inte2fs_read(void *fp, char *buf, cyg_uint32 nbytes){ struct read_info *info = fp; e2fs_desc_t *e2fs; cyg_uint32 nread = 0, rem, block_nr, bindex, to_read; if ((info->fpos + nbytes) > info->fsize) nbytes = info->fsize - info->fpos; e2fs = &info->e2fs_desc; // see if we need to copy leftover data from last read call rem = e2fs->blocksize - (info->fpos % e2fs->blocksize); if (rem != e2fs->blocksize) { char *p = (char *)blockbuf + e2fs->blocksize - rem; if (rem > nbytes) rem = nbytes; memcpy(buf, p, rem); nread += rem; buf += rem; info->fpos += rem; } // now loop through blocks if we're not done bindex = info->fpos / e2fs->blocksize; while (nread < nbytes) { if (!e2fs_inode_block(e2fs, &info->inode, bindex, &block_nr)) return -1; if (block_nr) { if (!PARTITION_READ(e2fs->part, E2FS_BLOCK_TO_SECTOR(e2fs, block_nr), blockbuf, e2fs->blocksize/SECTOR_SIZE)) return 0; } else memset(blockbuf, 0, e2fs->blocksize); to_read = nbytes - nread; if (to_read > e2fs->blocksize) to_read = e2fs->blocksize; memcpy(buf, blockbuf, to_read); nread += to_read; buf += to_read; info->fpos += to_read; ++bindex; } return nread;}#if DEBUG_E2FS > 4static void dump_sb(struct e2fs_super_block *s){ diag_printf("inode_count: %d\n", SWAB_LE32(s->inodes_count)); diag_printf("blocks_count: %d\n", SWAB_LE32(s->blocks_count)); diag_printf("r_blocks_count: %d\n", SWAB_LE32(s->r_blocks_count)); diag_printf("free_blocks_count: %d\n", SWAB_LE32(s->free_blocks_count)); diag_printf("free_inodes_count: %d\n", SWAB_LE32(s->free_inodes_count)); diag_printf("first_data_block: %d\n", SWAB_LE32(s->first_data_block)); diag_printf("log_block_size: %d\n", SWAB_LE32(s->log_block_size)); diag_printf("log_frag_size: %d\n", SWAB_LE32(s->log_frag_size)); diag_printf("blocks_per_group: %d\n", SWAB_LE32(s->blocks_per_group)); diag_printf("frags_per_group: %d\n", SWAB_LE32(s->frags_per_group)); diag_printf("inodes_per_group: %d\n", SWAB_LE32(s->inodes_per_group)); diag_printf("mnt_count: %d\n", SWAB_LE16(s->mnt_count)); diag_printf("max_mnt_count: %d\n", SWAB_LE16(s->max_mnt_count)); diag_printf("magic: %d\n", SWAB_LE16(s->magic)); diag_printf("state: %d\n", SWAB_LE16(s->state)); diag_printf("errors: %d\n", SWAB_LE16(s->errors)); diag_printf("minor_rev_level: %d\n", SWAB_LE16(s->minor_rev_level)); diag_printf("lastcheck: %d\n", SWAB_LE32(s->lastcheck)); diag_printf("checkinterval: %d\n", SWAB_LE32(s->checkinterval)); diag_printf("creator_os: %d\n", SWAB_LE32(s->creator_os)); diag_printf("rev_level: %d\n", SWAB_LE32(s->rev_level));}static void dump_inode(struct e2fs_inode *i){ int j, n; diag_printf("mode: %o\n", SWAB_LE16(i->mode)); diag_printf("uid: %o\n", SWAB_LE16(i->uid)); diag_printf("size: %d\n", SWAB_LE32(i->size)); diag_printf("gid: %o\n", SWAB_LE16(i->gid)); diag_printf("links: %d\n", SWAB_LE16(i->links_count)); diag_printf("blocks: %d\n", SWAB_LE32(i->blocks)); n = i->blocks; if (n > E2FS_N_BLOCKS) n = E2FS_N_BLOCKS; for (j = 0; j < n; j++) diag_printf(" block: %d\n", SWAB_LE32(i->block[j]));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -