// $Id: ex3b.c,v 1.3 2006/12/21 01:14:35 kaiya Exp kaiya $ /* Spec Get dirent data in n'th block from standard input Usage ./a.out block_number < filesystem_file Output List of information of each file in the directory Limit block_number: natural number and it should specify directory block. 0<=block_number<1440 filesytem_file should be simple ext2 file system dump; i.e. block size=1024B, number of blocks=1440. Compile gcc thisfile.c using ext2_os2006.h Platform gcc in PPC */ #include #include #include #include // #include #include "ext2_os2006.h" // 1024*1440 = 1474560 #define ALLBLOCKSIZE 1474560 #define BLOCKSIZE 1024 #define BLOCKNUMBER 1440 // data in all blocks are stored here. unsigned char blocks[ALLBLOCKSIZE]; /* Get the beginning of n'th block. Argument: n ro: specify the number of block. (0, 1, 2, ...) Return: pointer to the beginning of the block. NULL if fail. */ unsigned char* nth_block(int n){ if(n<0 || BLOCKNUMBER<=n) return NULL; // out of range return blocks+(n*BLOCKSIZE); } /* Get dir_entry from byte array. Arguments: *block ro: begin of byte array *de rw: begin address of gotten dir_entry. de->name is terminated. *resta rw: number of bytes still remained. Return: pointer to the next dir entry. NULL if fail. */ unsigned char* get_dir_entry( struct ext2_dir_entry_2* de, unsigned char* block, int* resta ){ if(*resta<=0) return NULL; memcpy(de, block, sizeof(*de)); de->name[de->name_len]='\0'; *resta -= (int)rev16(de->rec_len); return block+(int)rev16(de->rec_len); } main(int argc, char* argv[]){ int nb; unsigned char* blockptr; struct ext2_dir_entry_2 dirent2; int rest=BLOCKSIZE; // check argument if(argc<2) exit(1); nb=atoi(argv[1]); if(nb<0 || nb>1440) exit(2); // load all blocks in the file system. if(read(0, blocks, ALLBLOCKSIZE)!=ALLBLOCKSIZE){ fprintf(stderr, "Can not read all blocks!\n"); exit(1); } // seek a block. if((blockptr=nth_block(nb))==NULL){ fprintf(stderr, "Block number overrun!\n"); exit(3); } // parse the block. while((blockptr=get_dir_entry(&dirent2, blockptr, &rest))!=NULL){ printf("inode = %d, file type = %d, file name =(%s)\n", rev32(dirent2.inode), dirent2.file_type, dirent2.name ); } }