#include #include #include #include #include #include #include #include #define BASE_OFFSET 1024 #define USB_DEVICE "/dev/sda1" #define BLOCK_OFFSET(block) (BASE_OFFSET + (block - 1) * block_size) #define FILTER_BIT(byte, i) ((byte >> i) & 0x01) static unsigned int block_size = 0; unsigned int ptrs_per_block = 0; /* * STUDENTS IMPLEMENT THIS! This function will prompt the user for an inode * number, and then print out a portion of it to the console. */ void print_inode(int fd, struct ext2_super_block* super, struct ext2_group_desc* group); /* * reads the root inode from the USB drive and stores it in root_inode. * Returns the file descriptor. */ int get_root_inode(struct ext2_super_block* super, struct ext2_group_desc* group, struct ext2_inode* root_inode); /* * Function to read in an inode. */ void read_inode(int fd, //file descriptor struct ext2_super_block* super, //the superblock struct ext2_group_desc* group, //current group descriptor int inode_no, //the inode to process struct ext2_inode* inode //the place to store the inode data ); /* * Reads out block_no into buffer. */ void read_block(int fd, int block_no, char* buffer); int main(void){ int file_descriptor; struct ext2_inode root_inode; struct ext2_super_block super; struct ext2_group_desc group; file_descriptor = get_root_inode(&super, &group, &root_inode); print_inode(file_descriptor, &super, &group); close(file_descriptor); return 0; } /* * Prompt the user for an inode number and then print it out! */ void print_inode(int fd, struct ext2_super_block* super, struct ext2_group_desc* group){ int inode_num = -1; printf("What inode would you like to read? "); scanf("%d", &inode_num); /* * Here you need to check to make sure that inode_num is valid (i.e. * it is for a valid inode in this block group). Then fetch the inode * from disk, then print out: i_mode, the file size, creation time, * blocks count, and the file flags. */ } void read_block(int fd, int block_no, char* buffer){ lseek(fd, BLOCK_OFFSET(block_no), SEEK_SET); read(fd, buffer, block_size); } void read_inode(int fd, //file descriptor struct ext2_super_block* super, //the superblock struct ext2_group_desc* group, //current group descriptor int inode_no, //the inode to process struct ext2_inode* inode //the place to store the inode data ){ int group_no = inode_no/super->s_inodes_per_group; int inode_offset = (inode_no - group_no * super->s_inodes_per_group -1) * sizeof(struct ext2_inode); lseek(fd, BLOCK_OFFSET(group[group_no].bg_inode_table) + inode_offset, SEEK_SET); read(fd, inode, sizeof(struct ext2_inode)); } int get_root_inode(struct ext2_super_block* super, struct ext2_group_desc* group, struct ext2_inode* root_inode){ int fd; /* open USB device */ fd = open(USB_DEVICE, O_RDONLY); //opening the device for reading if(fd < 0){ //some kind of error occurred perror(USB_DEVICE); exit(1); //we give up at this point } /* Now we read in Mr. Superblock */ /* seeking across the 'disk' to the superblock location */ lseek(fd, BASE_OFFSET, SEEK_SET); /*actually reading in the bytes */ read(fd, super, sizeof(struct ext2_super_block)); /* Some sanity checks */ /* Make sure we're reading an EXT2 filesystem */ if(super->s_magic != EXT2_SUPER_MAGIC){ fprintf(stderr, "Not an Ext2 filesystem!\n"); exit(1); } block_size = 1024 << super->s_log_block_size; /*Now onto reading the group descriptor */ /* seek to the first descriptor */ lseek(fd, BASE_OFFSET + block_size, SEEK_SET); /* read it in */ read(fd, group, sizeof(struct ext2_group_desc)); /* Read the root inode */ read_inode(fd, super, group, 2, root_inode); return fd; }