#include <stdio.h>
#include <stdlib.h>
#define BLOCK_SIZE 512
#define MBR_BLOCKS 1
#define I_NODE_SIZE 32
#define DATA_INDEX_OFFSET 18
#define INDEX_SIZE 2
#define FILE_ITEM_SIZE 16
#define FILE_NAME_SIZE 14
#define TYPE_DIR 1
#define TYPE_NORMAL_FILE 0
#define I_START_OFFSET 19
#define DATA_START_OFFSET 23
#define NUM_OF_FILE_ITEM_PER_BLOCK 32
#define NUM_DIRECT_INDEX 4
#define NUM_1_INDIRECT_INDEX 2
int compare(char *filename1,char *filename2);
long get_file_size(char *filename);
int main(){
unsigned short i_start;
unsigned short b_start;
FILE *fpr = fopen("lessos.img","rb");
if(fpr==NULL){
printf("%s\n","Open file failure!");
exit(0);
}
int meta_block_offset = MBR_BLOCKS * BLOCK_SIZE;
fseek(fpr,meta_block_offset + I_START_OFFSET,SEEK_SET);
fread(&i_start,sizeof(short),1,fpr);
printf("i_node start block %u\n",i_start);
fseek(fpr,meta_block_offset + DATA_START_OFFSET,SEEK_SET);
fread(&b_start,sizeof(short),1,fpr);
printf("data_block start block %u\n",b_start);
int root_dir_offset = (b_start + MBR_BLOCKS) * BLOCK_SIZE;
unsigned char filename[14];
unsigned short file_node;
int i = 0;
for(i=0;i<NUM_OF_FILE_ITEM_PER_BLOCK;i++){
fseek(fpr,root_dir_offset,SEEK_SET);
fread(filename,sizeof(char),14,fpr);
if(compare(filename,"loader")==0){
fseek(fpr,root_dir_offset + FILE_NAME_SIZE,SEEK_SET);
fread(&file_node,sizeof(short),1,fpr);
printf("filename %s , file_node %u \n", filename,file_node);
break;
}
root_dir_offset += FILE_ITEM_SIZE;
}
int data_block_offset = (i_start + MBR_BLOCKS) * BLOCK_SIZE + file_node * I_NODE_SIZE + DATA_INDEX_OFFSET;
FILE *readed_fpr = fopen("data","w+");
long loader_size = get_file_size("loader");
int LENGTH_INDEX_RECORD = 2;
// read direct index block
int direct_num = NUM_DIRECT_INDEX;
if(loader_size/BLOCK_SIZE<NUM_DIRECT_INDEX){
direct_num = loader_size/BLOCK_SIZE;
}
for(i=0;i<direct_num;i++){
unsigned char data[BLOCK_SIZE];
unsigned short data_block;
fseek(fpr,data_block_offset,SEEK_SET);
fread(&data_block,sizeof(short),1,fpr);
if(data_block!=0){
int data_offset = (data_block + MBR_BLOCKS) * BLOCK_SIZE;
fseek(fpr,data_offset,SEEK_SET);
fread(data,sizeof(char),BLOCK_SIZE,fpr);
fwrite(data,sizeof(char),BLOCK_SIZE,readed_fpr);
}
data_block_offset += LENGTH_INDEX_RECORD;
}
if(direct_num<NUM_DIRECT_INDEX){
fclose(readed_fpr);
compare_file("data","loader");
}
// read 1 indirect block
int left_size = loader_size - NUM_DIRECT_INDEX * BLOCK_SIZE;
int indirect_node_offset = data_block_offset;
int indirect_node_num = 2;
for(i=0;i<indirect_node_num;i++){
unsigned short indirect_node_block;
fseek(fpr,indirect_node_offset,SEEK_SET);
fread(&indirect_node_block,sizeof(short),1,fpr);
if(indirect_node_block!=0){
int j;
int indirect_data_offset = (indirect_node_block + MBR_BLOCKS) * BLOCK_SIZE;
for(j=0;j<256;j++){
unsigned char data[BLOCK_SIZE];
unsigned short indirect_data_block;
fseek(fpr,indirect_data_offset,SEEK_SET);
fread(&indirect_data_block,sizeof(short),1,fpr);
if(indirect_data_block!=0){
int data_offset = (indirect_data_block + MBR_BLOCKS) * BLOCK_SIZE;
fseek(fpr,data_offset,SEEK_SET);
if(left_size>=BLOCK_SIZE){
unsigned char data[BLOCK_SIZE];
fread(data,sizeof(char),BLOCK_SIZE,fpr);
fwrite(data,sizeof(char),BLOCK_SIZE,readed_fpr);
}else{
unsigned char data[left_size];
fread(data,sizeof(char),left_size,fpr);
fwrite(data,sizeof(char),left_size,readed_fpr);
}
left_size -= BLOCK_SIZE;
}
indirect_data_offset += INDEX_SIZE;
}
}
indirect_node_offset += INDEX_SIZE;
}
fclose(readed_fpr);
compare_file("data","loader");
fclose(fpr);
}
int compare(char *filename1, char *filename2){
while(*filename2!='\0'){
if(*filename1++ != *filename2++){
return -1;
}
}
return 0;
}
long get_file_size(char *filename){
FILE *fpr = fopen(filename,"rb");
if(fpr==NULL){
return -1;
}
fseek(fpr,0L,SEEK_END);
int size = ftell(fpr);
fclose(fpr);
return size;
}
int compare_file(char *file1, char *file2){
FILE *fpr1 = fopen(file1,"rb");
FILE *fpr2 = fopen(file2,"rb");
if(fpr1==NULL || fpr2==NULL){
printf("Oops,open file failure!");
exit(0);
}
long file1size = get_file_size(file1);
long file2size = get_file_size(file2);
printf("file1size: %lu file2size: %lu",file1size,file2size);
if(file1size<file2size || file1size==-1 || file2size==-1){
printf("Oops,the loader you have readed is not right!");
exit(0);
}
int i;
for(i=0;i<file2size;i++){
char a,b;
fseek(fpr1,i,SEEK_SET);
fread(&a,sizeof(char),1,fpr1);
fseek(fpr2,i,SEEK_SET);
fread(&b,sizeof(char),1,fpr2);
if(a!=b){
printf("Oops,the loader you have readed is not right!");
exit(0);
}
}
printf("Congratulations! You have successfully readed loader!\n");
exit(0);
}