#include #include #include #include #include #include #include #include "main.h" #include "disk.h" #include "config.h" struct ext2_super_block superblock; struct ext2_group_desc *group_desc_block; int read_super(int fd) { if (read(fd, &superblock, sizeof(superblock)) != sizeof(superblock)) return 0; if (superblock.s_magic != EXT2_SUPER_MAGIC || superblock.s_blocks_count == 0 || superblock.s_blocks_per_group == 0 || superblock.s_inodes_per_group == 0) return 0; if (superblock.s_mtime < SUPER_MTIME_MIN || superblock.s_mtime > SUPER_MTIME_MAX || superblock.s_creator_os != SUPER_CREATOR_OS) return 0; return 1; } static off_t _find_super(int fd, long block, unsigned long bs) { unsigned long bsiz; off_t off; for (bsiz = (unsigned long) EXT2_MIN_BLOCK_SIZE; bsiz <= (unsigned long) EXT2_MAX_BLOCK_SIZE; bsiz *= 2) { if (bs<0 || bs==bsiz) { if (block >= 0) off = block * bs; else off = 1024; lseek(fd, off, SEEK_SET); if (read(fd, &superblock, sizeof(superblock)) == sizeof(superblock)) { if ((nr_blocks = superblock.s_blocks_count) <= 0) return 0; bsiz = fs_size / nr_blocks; if (superblock.s_magic == EXT2_SUPER_MAGIC && bsiz == bs) { blocksize = bs; return (off); } else if (superblock.s_magic == EXT2_SUPER_MAGIC && bsiz > 1024-2) { blocksize = bs; /* ZZZ hack */ return (off); } else { fprintf(stderr, "M=0x%04x BS=%d", superblock.s_magic, superblock.s_log_block_size); fprintf(stderr, " (%lu = %llu / %lu)\n", bsiz, fs_size, nr_blocks); } } else fprintf(stderr, "Internal error 16378:2352\n"); return (0); } } return 0; } int find_super(int fd, long block, unsigned long bs) { off_t off; if ((off = _find_super(fd, block, bs)) == 0) return (0); nr_inodes = superblock.s_inodes_count; off += blocksize; groups = (int) ( (superblock.s_blocks_count + superblock.s_blocks_per_group - 1) / superblock.s_blocks_per_group); inodes_per_group = superblock.s_inodes_per_group; blocks_per_inodetable = ((inodes_per_group * sizeof(struct ext2_inode)) + blocksize - 1) / blocksize; if ( (group_desc_block = malloc(sizeof(struct ext2_group_desc) * groups)) == NULL) { fprintf(stderr, "Out of memory: Can't alocate group header\n"); exit(-1); } lseek(fd, off, SEEK_SET); if (read (fd, group_desc_block, sizeof(struct ext2_group_desc) * groups) != sizeof(struct ext2_group_desc) * groups) { fprintf(stderr, "Can't read group header\n"); exit(-1); } return (1); }