为Ext2文件系统实现我自己的Read,Write,Open,Close函数

时间:2015-03-23 18:58:44

标签: c ext2

干杯, 所以基本上我需要创建一个名为my_open,my_read,my_write和my_close的函数来操作Ext2文件系统映像。这一切都需要用C语言(我所知道的唯一语言)来完成。 我编写了一些代码来打印源自文件系统中根目录的所有目录和文件,但我希望能够使用此代码来操作文件系统。这是我的代码:


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "/include/ext2.h"

#define BASE_OFFSET 1024
#define BLOCK_OFFSET(block) (BASE_OFFSET+(block-1)*block_size)
#define NAMELEN     255

unsigned int block_size = 0;

void read_inode(int, int, const struct ext2_group_desc*, struct ext2_inode*);
void read_dir(int, struct ext2_inode*, const struct ext2_group_desc*, char *);

int main(int argc, char *argv[]) {

  char imgname[BASE_OFFSET];
  struct ext2_super_block super_block;
  struct ext2_group_desc block_group;
  struct ext2_inode inode;
  int fd;

  if (argc > 1)
    strcpy(imgname, argv[1]);
  else
    fprintf(stderr, " Command Usage: step1 %s ", imgname);

  if ((fd = open(imgname, O_RDONLY)) < 0) {
    fprintf(stderr, "Usage: step1 %s", argv[1]);
    exit(1);
  }

  fd = open(imgname, O_RDONLY);
  if(lseek(fd, BASE_OFFSET, SEEK_SET) < 0) {
    fprintf(stderr,"unable to seek\n");
    exit(0);
  }

  /* read super-block */

  lseek(fd, BASE_OFFSET, SEEK_SET);
  read(fd, &super_block, sizeof(super_block));

   block_size = 1024 << super_block.s_log_block_size;

  /* read group descriptor */

  lseek(fd, BASE_OFFSET + block_size, SEEK_SET);
  read(fd, &block_group, sizeof(block_group));

  /* show entries in the root directory */

  read_inode(fd, 2, &block_group, &inode);   /* read inode 2 (root directory) */
  read_dir(fd, &inode, &block_group, "/");

  close(fd);
  exit(0);
}

 void read_inode(int fd, int inode_no, const struct ext2_group_desc *block_group, struct ext2_inode *inode)
{
  lseek(fd, BLOCK_OFFSET(block_group->bg_inode_table)+(inode_no-1)*sizeof(struct ext2_inode),
    SEEK_SET);
  read(fd, inode, sizeof(struct ext2_inode));
}

void read_dir(int fd, struct ext2_inode *inode, const struct ext2_group_desc *block_group, char *prefix)
{
  void *block;

  if (S_ISDIR(inode->i_mode)) {
    struct ext2_dir_entry_2 *entry;
     unsigned int size = 0;
    char *tmpprefix;

    //prefix = malloc (siozeof(char) * BASE_OFFSET);                                                                                        


    if ((block = malloc(block_size)) == NULL) {
      fprintf(stderr, "Not enough Memory.\n");
       close(fd);
       exit(1);
     }

    lseek(fd, BLOCK_OFFSET(inode->i_block[0]), SEEK_SET);
    read(fd, block, block_size);
    entry = (struct ext2_dir_entry_2 *) block;  /* first entry in the directory */
       //entry (entry->inode == NULL)                                                                                                       
    while((size < inode->i_size) && entry->inode) {
      char file_name[NAMELEN+1];
      memcpy(file_name, entry->name, entry->name_len);
      file_name[entry->name_len] = 0;     /* append null character */
      if (*file_name != '.')
      //if (strcmp(file_name,".") == 0 || strcmp(file_name,"..")== 0) continue;                                                             
      if (entry->file_type == 2) {
        printf("%10u %s%s/\n", entry->inode, prefix,file_name);
        read_inode(fd, entry->inode, block_group, inode);
        tmpprefix = (char *)malloc(strlen(file_name)+strlen(prefix)+2);
        sprintf(tmpprefix, "%s%s/",prefix,file_name);
        read_dir(fd, inode, block_group, tmpprefix);
        free(tmpprefix);
      }
      else {
        printf("%10u %s%s\n", entry->inode, prefix, file_name);
      }
      entry = (void*) entry + entry->rec_len;
      size += entry->rec_len;
    }
    free(block);
  }
}


/*                                                                                                                                          
 my_open(char *fn, int mode)                                                                                                                 
 {                                                                                                                                           

 }                                                                                                                                           

 my_close(char *fn, descriptor)                                                                                                              
 {                                                                                                                                           

 }                                                                                                                                           

 my_read()                                                                                                                                   
 {                                                                                                                                           

 }        
 my_write()                                                                                                                                  
 {                                                                                                                                           

 }                                                                                                                                           

*/

这是我的Header文件,其结构为:

/*
   __u32     * Structure of the super block
*/
#include <linux/types.h>

#define EXT2_NDIR_BLOCKS  12
#define EXT2_IND_BLOCK    EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK  (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK  (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS    (EXT2_TIND_BLOCK + 1)
#define EXT2_NAME_LEN     255

struct ext2_super_block
{
  __u32 s_inodes_count;         /* Inodes count */
  __u32 s_blocks_count;         /* Blocks count */
  __u32 s_r_blocks_count;       /* Reserved blocks count */
  __u32 s_free_blocks_count;    /* Free blocks count */
  __u32 s_free_inodes_count;    /* Free inodes */
  __u32 s_first_data_block;     /* First Data Block */
  __u32 s_log_block_size;       /* Block size */
  __u32 s_log_frag_size;        /* Fragment size */
  __u32 s_blocks_per_group;     /* # Blocks per group */
  __s32 s_frags_per_group;      /* # Fragments per group */
  __u32 s_inodes_per_group;     /* # Inodes per group */
  __u32 s_mtime;                /* Mount time */
  __u32 s_wtime;                /* Write time */
  __u16 s_mnt_count;            /* Mount count */
  __s16 s_max_mnt_count;        /* Maximal mount count */
  __u16 s_magic;                /* Magic signature */
  __u16 s_state;                /* File system state */
  __u16 s_errors;               /* Behaviour when detecting errors */
  __u16 s_minor_rev_level;      /* minor revision level */
  __u32 s_lastcheck;            /* time of last check */
  __u32 s_checkinterval;        /* max. time between checks */
  __u32 s_creator_os;           /* OS */
  __u32 s_rev_level;            /* Revision level */
  __u16 s_def_resuid;           /* Default uid for reserved blocks */
  __u16 s_def_resgid;           /* Default gid for reserved blocks */
  __u32 s_first_ino;            /* First non-reserved inode */
  __u16 s_inode_size;           /* size of inode structure */
  __u16 s_block_group_nr;       /* block group # of this superblock */
  __u32 s_feature_compat;       /* compatible feature set */
  __u32 s_feature_incompat;     /* incompatible feature set */

/*
  __u32     * Structure of the super block
*/
#include <linux/types.h>

#define EXT2_NDIR_BLOCKS  12
#define EXT2_IND_BLOCK    EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK  (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK  (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS    (EXT2_TIND_BLOCK + 1)
#define EXT2_NAME_LEN     255

struct ext2_super_block
{
  __u32 s_inodes_count;         /* Inodes count */
  __u32 s_blocks_count;         /* Blocks count */
  __u32 s_r_blocks_count;       /* Reserved blocks count */
  __u32 s_free_blocks_count;    /* Free blocks count */
  __u32 s_free_inodes_count;    /* Free inodes */
  __u32 s_first_data_block;     /* First Data Block */
  __u32 s_log_block_size;       /* Block size */
  __u32 s_log_frag_size;        /* Fragment size */
  __u32 s_blocks_per_group;     /* # Blocks per group */
  __s32 s_frags_per_group;      /* # Fragments per group */
  __u32 s_inodes_per_group;     /* # Inodes per group */
  __u32 s_mtime;                /* Mount time */
  __u32 s_wtime;                /* Write time */
  __u16 s_mnt_count;            /* Mount count */
  __s16 s_max_mnt_count;        /* Maximal mount count */
  __u16 s_magic;                /* Magic signature */
  __u16 s_state;                /* File system state */
  __u16 s_errors;               /* Behaviour when detecting errors */
  __u16 s_minor_rev_level;      /* minor revision level */
  __u32 s_lastcheck;            /* time of last check */
  __u32 s_checkinterval;        /* max. time between checks */
  __u32 s_creator_os;           /* OS */
  __u32 s_rev_level;            /* Revision level */
  __u16 s_def_resuid;           /* Default uid for reserved blocks */
  __u16 s_def_resgid;           /* Default gid for reserved blocks */
  __u32 s_first_ino;            /* First non-reserved inode */
  __u16 s_inode_size;           /* size of inode structure */
  __u16 s_block_group_nr;       /* block group # of this superblock */
  __u32 s_feature_compat;       /* compatible feature set */
  __u32 s_feature_incompat;     /* incompatible feature set */
  __u32 s_feature_ro_compat;    /* readonly-compatible feature set */
  __u8 s_uuid[16];              /* 128-bit uuid for volume */
  char s_volume_name[16];       /* volume name */
  char s_last_mounted[64];      /* directory where last mounted */
  __u32 s_algorithm_usage_bitmap;       /* For compression */
  __u8 s_prealloc_blocks;       /* Nr of blocks to try to preallocate */
  __u8 s_prealloc_dir_blocks;   /* Nr to preallocate for dirs */
  __u16 s_padding1;
  __u32 s_reserved[204];        /* Padding to the end of the block */
};

struct ext2_group_desc
{
  __u32 bg_block_bitmap;        /* Blocks bitmap block */
  __u32 bg_inode_bitmap;        /* Inodes bitmap block */
  __u32 bg_inode_table;         /* Inodes table block */
  __u16 bg_free_blocks_count;   /* Free blocks count */
  __u16 bg_free_inodes_count;   /* Free inodes count */
  __u16 bg_used_dirs_count;     /* Directories count */
  __u16 bg_pad;
  __u32 bg_reserved[3];
};

struct ext2_inode
{
  __u16 i_mode;                 /* File mode */
  __u16 i_uid;                  /* Low 16 bits of Owner Uid */
  __u32 i_size;                 /* Size in bytes */
  __u32 i_atime;                /* Access time */
  __u32 i_ctime;                /* Creation time */
  __u32 i_mtime;                /* Modification time */
  __u32 i_dtime;                /* Deletion Time */
  __u16 i_gid;                  /* Low 16 bits of Group Id */
  __u16 i_links_count;          /* Links count */
  __u32 i_blocks;               /* Blocks count */
  __u32 i_flags;                /* File flags */
  union
  {
    struct {
       __u32 l_i_reserved1;
    } linux1;
    struct {
      __u32 h_i_translator;
    } hurd1;
    struct {
      __u32 m_i_reserved1;
    } masix1;
  } osd1;                       /* OS dependent 1 */
  __u32 i_block[EXT2_N_BLOCKS]; /* Pointers to blocks */
  __u32 i_generation;           /* File version (for NFS) */
  __u32 i_file_acl;             /* File ACL */
  __u32 i_dir_acl;              /* Directory ACL */
  __u32 i_faddr;                /* Fragment address */
  union {
    struct {
      __u8 l_i_frag;            /* Fragment number */
      __u8 l_i_fsize;           /* Fragment size */
      __u16 i_pad1;
      __u16 l_i_uid_high;       /* these 2 fields    */
      __u16 l_i_gid_high;       /* were reserved2[0] */
      __u32 l_i_reserved2;
    } linux2;
    struct {
      __u8 h_i_frag;            /* Fragment number */
      __u8 h_i_fsize;           /* Fragment size */
      __u16 h_i_mode_high;
      __u16 h_i_uid_high;
      __u16 h_i_gid_high;
      __u32 h_i_author;
    } hurd2;
    struct {
      __u8 m_i_frag;            /* Fragment number */
      __u8 m_i_fsize;           /* Fragment size */
      __u16 m_pad1;
      __u32 m_i_reserved2[2];
    } masix2;
  } osd2;
};

struct ext2_dir_entry_2
{
  __u32 inode;                  /* Inode number */
  __u16 rec_len;                /* Directory entry length */
  __u8 name_len;                /* Name length */
  __u8 file_type;
  char name[EXT2_NAME_LEN];     /* File name */
};

任何帮助将不胜感激!提前谢谢!

0 个答案:

没有答案