// $Id: ex3c.c,v 1.1 2006/12/21 01:16:20 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 #include "ext2_os2006.h" #define BLOCKSIZE 1024 #define BLOCKNUMBER 1440 /* 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; unsigned char block[BLOCKSIZE]; 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); // seek a block. if(lseek(0, nb*BLOCKSIZE, SEEK_SET)<0){ fprintf(stderr, "Seek failed!\n"); exit(3); } // get indented block. if(read(0, block, BLOCKSIZE)!=BLOCKSIZE){ fprintf(stderr, "block read failed!\n"); exit(4); } // parse the block. for( blockptr=block; (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 ); } }