static errcode_t inode_open(const char *name, int flags, io_channel *channel) { io_channel io = NULL; struct inode_private_data *prev, *data = NULL; errcode_t retval; int open_flags; if (name == 0) return EXT2_ET_BAD_DEVICE_NAME; for (data = top_intern, prev = NULL; data; prev = data, data = data->next) if (strcmp(name, data->name) == 0) break; if (!data) return ENOENT; if (prev) prev->next = data->next; else top_intern = data->next; retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io); if (retval) goto cleanup; memset(io, 0, sizeof(struct struct_io_channel)); io->magic = EXT2_ET_MAGIC_IO_CHANNEL; io->manager = inode_io_manager; retval = ext2fs_get_mem(strlen(name)+1, &io->name); if (retval) goto cleanup; strcpy(io->name, name); io->private_data = data; io->block_size = 1024; io->read_error = 0; io->write_error = 0; io->refcount = 1; open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0; retval = ext2fs_file_open2(data->fs, data->ino, (data->flags & CHANNEL_HAS_INODE) ? &data->inode : 0, open_flags, &data->file); if (retval) goto cleanup; *channel = io; return 0; cleanup: if (io && io->name) ext2fs_free_mem(&io->name); if (data) ext2fs_free_mem(&data); if (io) ext2fs_free_mem(&io); return retval; }
int ext2_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode) { //ext2_log_trace("fileStruct %p, path %s, flags %i, mode %i\n", fileStruct, path, flags, mode); ext2_file_state* file = STATE(fileStruct); // Get the volume descriptor for this path file->vd = ext2GetVolume(path); if (!file->vd) { r->_errno = ENODEV; return -1; } // Lock ext2Lock(file->vd); // Determine which mode the file is opened for file->flags = flags; if ((flags & 0x03) == O_RDONLY) { file->read = true; file->write = false; file->append = false; } else if ((flags & 0x03) == O_WRONLY) { file->read = false; file->write = true; file->append = (flags & O_APPEND); } else if ((flags & 0x03) == O_RDWR) { file->read = true; file->write = true; file->append = (flags & O_APPEND); } else { r->_errno = EACCES; ext2Unlock(file->vd); return -1; } // Try and find the file and (if found) ensure that it is not a directory file->ni = ext2OpenEntry(file->vd, path); if (file->ni && LINUX_S_ISDIR(file->ni->ni.i_mode)) { ext2CloseEntry(file->vd, file->ni); ext2Unlock(file->vd); r->_errno = EISDIR; return -1; } // Are we creating this file? if ((flags & O_CREAT) && !file->ni) // Create the file file->ni = ext2Create(file->vd, path, S_IFREG, NULL); // exit(0); // Sanity check, the file should be open by now if (!file->ni) { ext2Unlock(file->vd); r->_errno = ENOENT; return -1; } // Make sure we aren't trying to write to a read-only file if (!(file->vd->fs->flags & EXT2_FLAG_RW) && file->write) { ext2CloseEntry(file->vd, file->ni); ext2Unlock(file->vd); r->_errno = EROFS; return -1; } errcode_t err = ext2fs_file_open2(file->vd->fs, file->ni->ino, &file->ni->ni, file->write ? EXT2_FLAG_RW : 0, &file->fd); if(err != 0) { ext2CloseEntry(file->vd, file->ni); ext2Unlock(file->vd); r->_errno = ENOENT; return -1; } // Truncate the file if requested if ((flags & O_TRUNC) && file->write) { if (ext2fs_file_set_size2(file->fd, 0) != 0) { ext2CloseEntry(file->vd, file->ni); ext2Unlock(file->vd); r->_errno = errno; return -1; } file->ni->ni.i_size = file->ni->ni.i_size_high = 0; } // Set the files current position ext2fs_file_llseek(file->fd, file->append ? EXT2_I_SIZE(&file->ni->ni) : 0, SEEK_SET, 0); //ext2_log_trace("file->len %lld\n", EXT2_I_SIZE(&file->ni->ni)); // Update file times ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME); // Insert the file into the double-linked FILO list of open files if (file->vd->firstOpenFile) { file->nextOpenFile = file->vd->firstOpenFile; file->vd->firstOpenFile->prevOpenFile = file; } else { file->nextOpenFile = NULL; } file->prevOpenFile = NULL; file->vd->firstOpenFile = file; file->vd->openFileCount++; // Sync access time ext2Sync(file->vd, file->ni); file->is_ntfs = 0; // Unlock ext2Unlock(file->vd); return (int)(s64)fileStruct; }
int ext2_file_to_sectors (struct _reent *r,const char *path,uint32_t *sec_out,uint32_t *size_out,int max,int phys) { ntfs_file_state fileStruct; ext2_file_state* file = STATE(&fileStruct); // Get the volume descriptor for this path file->vd = ext2GetVolume(path); if (!file->vd) { r->_errno = ENODEV; return -1; } // Lock ext2Lock(file->vd); file->flags = 0; file->read = true; file->write = false; file->append = false; // Try and find the file and (if found) ensure that it is not a directory file->ni = ext2OpenEntry(file->vd, path); if (file->ni && LINUX_S_ISDIR(file->ni->ni.i_mode)) { ext2CloseEntry(file->vd, file->ni); ext2Unlock(file->vd); r->_errno = EISDIR; return -1; } // Sanity check, the file should be open by now if (!file->ni) { ext2Unlock(file->vd); r->_errno = ENOENT; return -1; } errcode_t err = ext2fs_file_open2(file->vd->fs, file->ni->ino, &file->ni->ni, 0, &file->fd); if(err != 0) { ext2CloseEntry(file->vd, file->ni); ext2Unlock(file->vd); r->_errno = ENOENT; return -1; } //ext2_log_trace("file->len %lld\n", EXT2_I_SIZE(&file->ni->ni)); // Update file times ext2UpdateTimes(file->vd, file->ni, EXT2_UPDATE_ATIME); // Insert the file into the double-linked FILO list of open files if (file->vd->firstOpenFile) { file->nextOpenFile = file->vd->firstOpenFile; file->vd->firstOpenFile->prevOpenFile = file; } else { file->nextOpenFile = NULL; } file->prevOpenFile = NULL; file->vd->firstOpenFile = file; file->vd->openFileCount++; // Sync access time ext2Sync(file->vd, file->ni); file->is_ntfs = 0; u64 read = 0; err = 0; // Read from the files data attribute //err = ext2fs_file_read(file->fd, ptr, len, &read); u64 len = 0; ext2fs_file_llseek(file->fd, 0, SEEK_END, (__u64 *) &len); // Set the files current position ext2fs_file_llseek(file->fd, 0, SEEK_SET, 0); u32 current_block = 0; err = ext2fs_file_read_sectors(file->fd, len, &read, sec_out, size_out, ¤t_block, max); if (err || read <= 0 || read > len) { ext2Unlock(file->vd); r->_errno = errno; current_block = err ? err : -1; goto end; } end: // Close the file ext2CloseFile(file); // Remove the file from the double-linked FILO list of open files file->vd->openFileCount--; if (file->nextOpenFile) file->nextOpenFile->prevOpenFile = file->prevOpenFile; if (file->prevOpenFile) file->prevOpenFile->nextOpenFile = file->nextOpenFile; else file->vd->firstOpenFile = file->nextOpenFile; ext2Unlock(file->vd); return current_block; }
static void print_inline_journal_information(ext2_filsys fs) { journal_superblock_t *jsb; struct ext2_inode inode; ext2_file_t journal_file; errcode_t retval; ino_t ino = fs->super->s_journal_inum; char buf[1024]; __u32 *mask_ptr, mask, m; int i, j, size, printed = 0; if (fs->flags & EXT2_FLAG_IMAGE_FILE) return; retval = ext2fs_read_inode(fs, ino, &inode); if (retval) { com_err(program_name, retval, "%s", _("while reading journal inode")); exit(1); } retval = ext2fs_file_open2(fs, ino, &inode, 0, &journal_file); if (retval) { com_err(program_name, retval, "%s", _("while opening journal inode")); exit(1); } retval = ext2fs_file_read(journal_file, buf, sizeof(buf), 0); if (retval) { com_err(program_name, retval, "%s", _("while reading journal super block")); exit(1); } ext2fs_file_close(journal_file); jsb = (journal_superblock_t *) buf; if (be32_to_cpu(jsb->s_header.h_magic) != JFS_MAGIC_NUMBER) { fprintf(stderr, "%s", _("Journal superblock magic number invalid!\n")); exit(1); } printf("%s", _("Journal features: ")); for (i=0, mask_ptr=&jsb->s_feature_compat; i <3; i++,mask_ptr++) { mask = be32_to_cpu(*mask_ptr); for (j=0,m=1; j < 32; j++, m<<=1) { if (mask & m) { printf(" %s", e2p_jrnl_feature2string(i, m)); printed++; } } } if (printed == 0) printf(" (none)"); printf("\n"); fputs(_("Journal size: "), stdout); if ((fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && (inode.i_flags & EXT4_HUGE_FILE_FL)) size = inode.i_blocks / (fs->blocksize / 1024); else size = inode.i_blocks >> 1; if (size < 8192) printf("%uk\n", size); else printf("%uM\n", size >> 10); printf(_("Journal length: %u\n" "Journal sequence: 0x%08x\n" "Journal start: %u\n"), (unsigned int)ntohl(jsb->s_maxlen), (unsigned int)ntohl(jsb->s_sequence), (unsigned int)ntohl(jsb->s_start)); if (jsb->s_feature_compat & ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_CHECKSUM)) printf(_("Journal checksum type: crc32\n")); if (jsb->s_feature_incompat & ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2)) printf(_("Journal checksum type: %s\n" "Journal checksum: 0x%08x\n"), journal_checksum_type_str(jsb->s_checksum_type), ext2fs_be32_to_cpu(jsb->s_checksum)); if (jsb->s_errno != 0) printf(_("Journal errno: %d\n"), (int) ntohl(jsb->s_errno)); }
void do_logdump(int argc, char **argv) { int c; int retval; char *out_fn; FILE *out_file; char *inode_spec = NULL; char *journal_fn = NULL; int journal_fd = 0; int use_sb = 0; ext2_ino_t journal_inum; struct ext2_inode journal_inode; ext2_file_t journal_file; char *tmp; struct journal_source journal_source; struct ext2_super_block *es = NULL; journal_source.where = 0; journal_source.fd = 0; journal_source.file = 0; dump_all = 0; dump_contents = 0; dump_descriptors = 1; block_to_dump = ANY_BLOCK; bitmap_to_dump = -1; inode_block_to_dump = ANY_BLOCK; inode_to_dump = -1; reset_getopt(); while ((c = getopt (argc, argv, "ab:ci:f:s")) != EOF) { switch (c) { case 'a': dump_all++; break; case 'b': block_to_dump = strtoul(optarg, &tmp, 0); if (*tmp) { com_err(argv[0], 0, "Bad block number - %s", optarg); return; } dump_descriptors = 0; break; case 'c': dump_contents++; break; case 'f': journal_fn = optarg; break; case 'i': inode_spec = optarg; dump_descriptors = 0; break; case 's': use_sb++; break; default: goto print_usage; } } if (optind != argc && optind != argc-1) { goto print_usage; } if (current_fs) es = current_fs->super; if (inode_spec) { int inode_group, group_offset, inodes_per_block; if (check_fs_open(argv[0])) return; inode_to_dump = string_to_inode(inode_spec); if (!inode_to_dump) return; inode_group = ((inode_to_dump - 1) / es->s_inodes_per_group); group_offset = ((inode_to_dump - 1) % es->s_inodes_per_group); inodes_per_block = (current_fs->blocksize / sizeof(struct ext2_inode)); inode_block_to_dump = current_fs->group_desc[inode_group].bg_inode_table + (group_offset / inodes_per_block); inode_offset_to_dump = ((group_offset % inodes_per_block) * sizeof(struct ext2_inode)); printf("Inode %u is at group %u, block %u, offset %u\n", inode_to_dump, inode_group, inode_block_to_dump, inode_offset_to_dump); } if (optind == argc) { out_file = stdout; } else { out_fn = argv[optind]; out_file = fopen(out_fn, "w"); if (!out_file < 0) { com_err(argv[0], errno, "while opening %s for logdump", out_fn); return; } } if (block_to_dump != ANY_BLOCK && current_fs != NULL) { group_to_dump = ((block_to_dump - es->s_first_data_block) / es->s_blocks_per_group); bitmap_to_dump = current_fs->group_desc[group_to_dump].bg_block_bitmap; } if (!journal_fn && check_fs_open(argv[0])) return; if (journal_fn) { /* Set up to read journal from a regular file somewhere */ journal_fd = open(journal_fn, O_RDONLY, 0); if (journal_fd < 0) { com_err(argv[0], errno, "while opening %s for logdump", journal_fn); return; } journal_source.where = JOURNAL_IS_EXTERNAL; journal_source.fd = journal_fd; } else if ((journal_inum = es->s_journal_inum)) { if (use_sb) { if (es->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS) { com_err(argv[0], 0, "no journal backup in super block\n"); return; } memset(&journal_inode, 0, sizeof(struct ext2_inode)); memcpy(&journal_inode.i_block[0], es->s_jnl_blocks, EXT2_N_BLOCKS*4); journal_inode.i_size = es->s_jnl_blocks[16]; journal_inode.i_links_count = 1; journal_inode.i_mode = LINUX_S_IFREG | 0600; } else { if (debugfs_read_inode(journal_inum, &journal_inode, argv[0])) return; } retval = ext2fs_file_open2(current_fs, journal_inum, &journal_inode, 0, &journal_file); if (retval) { com_err(argv[0], retval, "while opening ext2 file"); return; } journal_source.where = JOURNAL_IS_INTERNAL; journal_source.file = journal_file; } else { char uuid[37]; uuid_unparse(es->s_journal_uuid, uuid); journal_fn = blkid_get_devname(NULL, "UUID", uuid); if (!journal_fn) journal_fn = blkid_devno_to_devname(es->s_journal_dev); if (!journal_fn) { com_err(argv[0], 0, "filesystem has no journal"); return; } journal_fd = open(journal_fn, O_RDONLY, 0); if (journal_fd < 0) { com_err(argv[0], errno, "while opening %s for logdump", journal_fn); free(journal_fn); return; } fprintf(out_file, "Using external journal found at %s\n", journal_fn); free(journal_fn); journal_source.where = JOURNAL_IS_EXTERNAL; journal_source.fd = journal_fd; } dump_journal(argv[0], out_file, &journal_source); if (journal_source.where == JOURNAL_IS_INTERNAL) ext2fs_file_close(journal_file); else close(journal_fd); if (out_file != stdout) fclose(out_file); return; print_usage: fprintf(stderr, "%s: Usage: logdump [-ac] [-b<block>] [-i<inode>]\n\t" "[-f<journal_file>] [output_file]\n", argv[0]); }