Changeset a8e1aae in mainline


Ignore:
Timestamp:
2011-02-24T21:03:42Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9ffbdf1
Parents:
102d400
Message:

Add support for reading directories to libext2

Location:
uspace
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/ext2info/ext2info.c

    r102d400 ra8e1aae  
    5656static void print_block_groups(ext2_filesystem_t *);
    5757static void print_block_group(ext2_block_group_t *);
    58 static void print_inode_by_number(ext2_filesystem_t *, uint32_t, bool, uint32_t);
     58static void print_inode_by_number(ext2_filesystem_t *, uint32_t, bool, uint32_t,
     59    bool);
     60static void print_data(unsigned char *, size_t);
    5961static void print_inode(ext2_filesystem_t *, ext2_inode_t *);
    6062static void print_inode_data(ext2_filesystem_t *, ext2_inode_t *, uint32_t);
     63static void print_directory_contents(ext2_filesystem_t *, ext2_inode_ref_t *);
    6164
    6265#define ARG_SUPERBLOCK 1
     
    6568#define ARG_STRICT_CHECK 8
    6669#define ARG_INODE_DATA 16
     70#define ARG_INODE_LIST 32
    6771#define ARG_COMMON (ARG_SUPERBLOCK | ARG_BLOCK_GROUPS)
    6872#define ARG_ALL (ARG_COMMON | ARG_INODE)
     
    141145                        --argc; ++argv;
    142146                }
     147               
     148                if (str_cmp(*argv, "--list") == 0) {
     149                        --argc; ++argv;
     150                        arg_flags |= ARG_INODE_LIST;
     151                }
    143152        }
    144153
     
    186195        if (arg_flags & ARG_INODE) {
    187196                print_inode_by_number(&filesystem, inode, arg_flags & ARG_INODE_DATA,
    188                     inode_data);
     197                    inode_data, arg_flags & ARG_INODE_LIST);
    189198        }
    190199
     
    198207{
    199208        printf("syntax: ext2info [--strict-check] [--superblock] [--block-groups] "
    200             "[--inode <i-number> [--inode-data <block-number>]] <device_name>\n");
     209            "[--inode <i-number> [--inode-data <block-number>] [--list]] <device_name>\n");
    201210}
    202211
     
    346355
    347356void print_inode_by_number(ext2_filesystem_t *fs, uint32_t inode,
    348     bool print_data, uint32_t data)
     357    bool print_data, uint32_t data, bool list)
    349358{
    350359        int rc;
     
    362371        if (print_data) {
    363372                print_inode_data(fs, inode_ref->inode, data);
     373        }
     374       
     375        if (list && ext2_inode_is_type(fs->superblock, inode_ref->inode,
     376            EXT2_INODE_MODE_DIRECTORY)) {
     377                print_directory_contents(fs, inode_ref);
    364378        }
    365379       
     
    444458}
    445459
     460void print_data(unsigned char *data, size_t size)
     461{
     462        unsigned char c;
     463        size_t i;
     464       
     465        for (i = 0; i < size; i++) {
     466                c = data[i];
     467                if (c >= 32 && c < 127) {
     468                        putchar(c);
     469                }
     470                else {
     471                        putchar('.');
     472                }
     473        }
     474}
     475
    446476void print_inode_data(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t data)
    447477{
     
    449479        uint32_t data_block_index;
    450480        block_t *block;
    451         size_t i;
    452         unsigned char c;
    453481       
    454482        rc = ext2_filesystem_get_inode_data_block_index(fs, inode, data,
     
    471499        }
    472500       
    473         for (i = 0; i < block->size; i++) {
    474                 c = ((unsigned char *)block->data)[i];
    475                 if (c >= 32 && c < 127) {
    476                         putchar(c);
    477                 }
    478                 else {
    479                         putchar('.');
    480                 }
    481         }
    482        
     501        print_data(block->data, block->size);
    483502        printf("\n");   
    484503       
     
    486505        if (rc != EOK) {
    487506                printf("Failed putting filesystem block\n");
     507        }
     508       
     509}
     510
     511void print_directory_contents(ext2_filesystem_t *fs,
     512    ext2_inode_ref_t *inode_ref)
     513{
     514        int rc;
     515        ext2_directory_iterator_t it;
     516        size_t name_size;
     517       
     518        printf("  Directory contents:\n");
     519       
     520        rc = ext2_directory_iterator_init(&it, fs, inode_ref);
     521        if (rc != EOK) {
     522                printf("Failed initializing directory iterator\n");
     523                return;
     524        }
     525       
     526        while (it.current != NULL) {
     527                name_size = ext2_directory_entry_ll_get_name_length(fs->superblock,
     528                    it.current);
     529                printf("    ");
     530                print_data(&it.current->name, name_size);
     531                printf(" --> %u\n", it.current->inode);
     532               
     533                rc = ext2_directory_iterator_next(&it);
     534                if (rc != EOK) {
     535                        printf("Failed reading directory contents\n");
     536                        goto cleanup;
     537                }
     538        }
     539
     540cleanup:
     541        rc = ext2_directory_iterator_fini(&it);
     542        if (rc != EOK) {
     543                printf("Failed cleaning-up directory iterator\n");
    488544        }
    489545       
  • uspace/lib/ext2/libext2_directory.c

    r102d400 ra8e1aae  
    3737#include "libext2_directory.h"
    3838#include <byteorder.h>
     39#include <errno.h>
     40#include <assert.h>
    3941
    4042/**
     
    7577}
    7678
     79/**
     80 * Initialize a directory iterator
     81 *
     82 * @param it pointer to iterator to initialize
     83 * @param fs pointer to filesystem structure
     84 * @param inode pointer to inode reference structure
     85 * @return EOK on success or negative error code on failure
     86 */
     87int ext2_directory_iterator_init(ext2_directory_iterator_t *it,
     88    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref)
     89{
     90        int rc;
     91        uint32_t block_id;
     92        it->inode_ref = inode_ref;
     93        it->fs = fs;
     94       
     95        // Get the first data block, so we can get first entry
     96        rc = ext2_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0,
     97            &block_id);
     98        if (rc != EOK) {
     99                return rc;
     100        }
     101       
     102        rc = block_get(&it->current_block, fs->device, block_id, 0);
     103        if (rc != EOK) {
     104                return rc;
     105        }
     106       
     107        it->current = it->current_block->data;
     108        it->current_offset = 0;
     109       
     110        return EOK;
     111}
     112
     113/**
     114 * Advance the directory iterator to the next entry
     115 *
     116 * @param it pointer to iterator to initialize
     117 * @return EOK on success or negative error code on failure
     118 */
     119int ext2_directory_iterator_next(ext2_directory_iterator_t *it)
     120{
     121        int rc;
     122        uint16_t skip;
     123        uint64_t size;
     124        aoff64_t current_block_idx;
     125        aoff64_t next_block_idx;
     126        uint32_t next_block_phys_idx;
     127        uint32_t block_size;
     128        uint32_t offset_in_block;
     129       
     130        assert(it->current != NULL);
     131       
     132        skip = ext2_directory_entry_ll_get_entry_length(it->current);
     133        size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode);
     134       
     135        // Are we at the end?
     136        if (it->current_offset + skip >= size) {
     137                rc = block_put(it->current_block);
     138                it->current_block = NULL;
     139                it->current = NULL;
     140                if (rc != EOK) {
     141                        return rc;
     142                }
     143               
     144                it->current_offset += skip;
     145                return EOK;
     146        }
     147       
     148        block_size = ext2_superblock_get_block_size(it->fs->superblock);
     149        current_block_idx = it->current_offset / block_size;
     150        next_block_idx = (it->current_offset + skip) / block_size;
     151       
     152        // If we are moving accross block boundary,
     153        // we need to get another block
     154        if (current_block_idx != next_block_idx) {
     155                rc = block_put(it->current_block);
     156                it->current_block = NULL;
     157                it->current = NULL;
     158                if (rc != EOK) {
     159                        return rc;
     160                }
     161               
     162                rc = ext2_filesystem_get_inode_data_block_index(it->fs,
     163                    it->inode_ref->inode, next_block_idx, &next_block_phys_idx);
     164                if (rc != EOK) {
     165                        return rc;
     166                }
     167               
     168                rc = block_get(&it->current_block, it->fs->device, next_block_phys_idx,
     169                    BLOCK_FLAGS_NONE);
     170                if (rc != EOK) {
     171                        it->current_block = NULL;
     172                        return rc;
     173                }
     174        }
     175       
     176        offset_in_block = (it->current_offset + skip) % block_size;
     177       
     178        // Ensure proper alignment
     179        if ((offset_in_block % 4) != 0) {
     180                it->current = NULL;
     181                return EIO;
     182        }
     183       
     184        // Ensure that the core of the entry does not overflow the block
     185        if (offset_in_block > block_size - 8) {
     186                it->current = NULL;
     187                return EIO;
     188        }
     189               
     190        it->current = it->current_block->data + offset_in_block;
     191        it->current_offset += skip;
     192       
     193        // Ensure that the whole entry does not overflow the block
     194        skip = ext2_directory_entry_ll_get_entry_length(it->current);
     195        if (offset_in_block + skip > block_size) {
     196                it->current = NULL;
     197                return EIO;
     198        }
     199       
     200        // Ensure the name length is not too large
     201        if (ext2_directory_entry_ll_get_name_length(it->fs->superblock,
     202            it->current) > skip-8) {
     203                it->current = NULL;
     204                return EIO;
     205        }
     206       
     207        return EOK;
     208}
     209
     210/**
     211 * Release all resources asociated with the directory iterator
     212 *
     213 * @param it pointer to iterator to initialize
     214 * @return EOK on success or negative error code on failure
     215 */
     216int ext2_directory_iterator_fini(ext2_directory_iterator_t *it)
     217{
     218        int rc;
     219       
     220        it->fs = NULL;
     221        it->inode_ref = NULL;
     222        it->current = NULL;
     223       
     224        if (it->current_block) {
     225                rc = block_put(it->current_block);
     226                if (rc != EOK) {
     227                        return rc;
     228                }
     229        }
     230       
     231        return EOK;
     232}
     233
    77234/** @}
    78235 */
  • uspace/lib/ext2/libext2_directory.h

    r102d400 ra8e1aae  
    3838
    3939#include <libblock.h>
     40#include "libext2_filesystem.h"
     41#include "libext2_inode.h"
    4042
    4143/**
     
    5355} __attribute__ ((packed)) ext2_directory_entry_ll_t;
    5456
     57typedef struct ext2_directory_iterator {
     58        ext2_filesystem_t *fs;
     59        ext2_inode_ref_t *inode_ref;
     60        block_t *current_block;
     61        aoff64_t current_offset;
     62        ext2_directory_entry_ll_t *current;
     63} ext2_directory_iterator_t;
     64
    5565
    5666inline uint32_t ext2_directory_entry_ll_get_inode(ext2_directory_entry_ll_t *);
     
    6070    ext2_superblock_t *, ext2_directory_entry_ll_t *);
    6171
     72extern int ext2_directory_iterator_init(ext2_directory_iterator_t *,
     73    ext2_filesystem_t *, ext2_inode_ref_t *);
     74extern int ext2_directory_iterator_next(ext2_directory_iterator_t *);
     75extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *);
     76
    6277#endif
    6378
Note: See TracChangeset for help on using the changeset viewer.