home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win95 / ext2tool.exe / EXT2FS / OPENFS.C < prev    next >
C/C++ Source or Header  |  1995-05-10  |  4KB  |  140 lines

  1. /*
  2.  * openfs.c --- open an ext2 filesystem
  3.  * 
  4.  * Copyright (C) 1993, 1994 Theodore Ts'o.  This file may be redistributed
  5.  * under the terms of the GNU Public License.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <errno.h>
  15. #include <sys/stat.h>
  16. #include <sys/types.h>
  17.  
  18. #include <linux/ext2_fs.h>
  19.  
  20. #include "ext2fs.h"
  21.  
  22. /*
  23.  *  Note: if superblock is non-zero, block-size must also be non-zero.
  24.  *     Superblock and block_size can be zero to use the default size.
  25.  */
  26. errcode_t ext2fs_open(const char *name, int flags, int superblock,
  27.               int block_size, io_manager manager, ext2_filsys *ret_fs)
  28. {
  29.     ext2_filsys    fs;
  30.     errcode_t    retval;
  31.     int        i, group_block;
  32.     char        *dest;
  33.     
  34.     EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
  35.     
  36.     fs = (ext2_filsys) malloc(sizeof(struct struct_ext2_filsys));
  37.     if (!fs)
  38.         return ENOMEM;
  39.     
  40.     memset(fs, 0, sizeof(struct struct_ext2_filsys));
  41.     fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
  42.     fs->flags = flags;
  43.     retval = manager->open(name, (flags & EXT2_FLAG_RW) ? IO_FLAG_RW : 0,
  44.                    &fs->io);
  45.     if (retval)
  46.         goto cleanup;
  47.     fs->device_name = malloc(strlen(name)+1);
  48.     if (!fs->device_name) {
  49.         retval = ENOMEM;
  50.         goto cleanup;
  51.     }
  52.     strcpy(fs->device_name, name);
  53.     fs->super = malloc(SUPERBLOCK_SIZE);
  54.     if (!fs->super) {
  55.         retval = ENOMEM;
  56.         goto cleanup;
  57.     }
  58.  
  59.     /*
  60.      * If the user specifies a specific block # for the
  61.      * superblock, then he/she must also specify the block size!
  62.      * Otherwise, read the master superblock located at offset
  63.      * SUPERBLOCK_OFFSET from the start of the partition.
  64.      */
  65.     if (superblock) {
  66.         if (!block_size) {
  67.             retval = EINVAL;
  68.             goto cleanup;
  69.         }
  70.         io_channel_set_blksize(fs->io, block_size);
  71.         group_block = superblock + 1;
  72.     } else {
  73.         io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
  74.         superblock = 1;
  75.         group_block = 0;
  76.     }
  77.     retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
  78.                      fs->super);
  79.     if (retval)
  80.         goto cleanup;
  81.     
  82.     if (fs->super->s_magic != EXT2_SUPER_MAGIC) {
  83.         retval = EXT2_ET_BAD_MAGIC;
  84.         goto cleanup;
  85.     }
  86. #ifdef    EXT2_CURRENT_REV
  87.     if (fs->super->s_rev_level > EXT2_LIB_CURRENT_REV) {
  88.         retval = EXT2_ET_REV_TOO_HIGH;
  89.         goto cleanup;
  90.     }
  91. #endif
  92.     fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
  93.     fs->fragsize = EXT2_FRAG_SIZE(fs->super);
  94.     fs->inode_blocks_per_group = (fs->super->s_inodes_per_group /
  95.                       EXT2_INODES_PER_BLOCK(fs->super));
  96.     if (block_size) {
  97.         if (block_size != fs->blocksize) {
  98.             retval = EXT2_ET_UNEXPECTED_BLOCK_SIZE;
  99.             goto cleanup;
  100.         }
  101.     }
  102.     /*
  103.      * Set the blocksize to the filesystem's blocksize.
  104.      */
  105.     io_channel_set_blksize(fs->io, fs->blocksize);
  106.     
  107.     /*
  108.      * Read group descriptors
  109.      */
  110.     fs->group_desc_count = (fs->super->s_blocks_count -
  111.                 fs->super->s_first_data_block +
  112.                 EXT2_BLOCKS_PER_GROUP(fs->super) - 1)
  113.         / EXT2_BLOCKS_PER_GROUP(fs->super);
  114.     fs->desc_blocks = (fs->group_desc_count +
  115.                EXT2_DESC_PER_BLOCK(fs->super) - 1)
  116.         / EXT2_DESC_PER_BLOCK(fs->super);
  117.     fs->group_desc = malloc(fs->desc_blocks * fs->blocksize);
  118.     if (!fs->group_desc) {
  119.         retval = ENOMEM;
  120.         goto cleanup;
  121.     }
  122.     if (!group_block)
  123.         group_block = fs->super->s_first_data_block + 1;
  124.     dest = (char *) fs->group_desc;
  125.     for (i=0 ; i < fs->desc_blocks; i++) {
  126.         retval = io_channel_read_blk(fs->io, group_block, 1, dest);
  127.         if (retval)
  128.             goto cleanup;
  129.         group_block++;
  130.         dest += fs->blocksize;
  131.     }
  132.  
  133.     *ret_fs = fs;
  134.     return 0;
  135. cleanup:
  136.     ext2fs_free(fs);
  137.     return retval;
  138. }
  139.  
  140.