From ff291bdc716769edab04e70ccbd8ceffe73a9336 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 20 Jan 2020 00:16:25 +0100 Subject: An attempt at cleaning sqfsbrowse a little and adding explanations Signed-off-by: David Oberhollenzer --- extras/browse.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/extras/browse.c b/extras/browse.c index 79042eb..6992a4b 100644 --- a/extras/browse.c +++ b/extras/browse.c @@ -5,6 +5,7 @@ #include "sqfs/inode.h" #include "sqfs/super.h" #include "sqfs/error.h" +#include "sqfs/block.h" #include "sqfs/dir.h" #include "sqfs/io.h" @@ -23,6 +24,8 @@ static sqfs_inode_generic_t *working_dir; static sqfs_id_table_t *idtbl; static sqfs_data_reader_t *data; +/*****************************************************************************/ + static void change_directory(const char *dirname) { sqfs_inode_generic_t *inode; @@ -43,6 +46,8 @@ static void change_directory(const char *dirname) } } +/*****************************************************************************/ + static void list_directory(const char *dirname) { sqfs_inode_generic_t *root, *inode; @@ -50,6 +55,7 @@ static void list_directory(const char *dirname) sqfs_dir_entry_t *ent; int ret; + /* Get the directory inode we want to dump and open the directory */ if (dirname == NULL) { ret = sqfs_dir_reader_open_dir(dr, working_dir); if (ret) @@ -78,6 +84,7 @@ static void list_directory(const char *dirname) goto fail_open; } + /* first pass over the directory to figure out column count/length */ for (max_len = 0; ; max_len = len > max_len ? len : max_len) { ret = sqfs_dir_reader_read(dr, &ent); if (ret > 0) @@ -92,12 +99,13 @@ static void list_directory(const char *dirname) free(ent); } - sqfs_dir_reader_rewind(dr); - col_count = 79 / (max_len + 1); col_count = col_count < 1 ? 1 : col_count; i = 0; + /* second pass for printing directory contents */ + sqfs_dir_reader_rewind(dr); + for (;;) { ret = sqfs_dir_reader_read(dr, &ent); if (ret > 0) @@ -108,6 +116,7 @@ static void list_directory(const char *dirname) break; } + /* entries always use basic types only */ switch (ent->type) { case SQFS_INODE_DIR: fputs("\033[01;34m", stdout); @@ -158,6 +167,8 @@ fail_resolve: return; } +/*****************************************************************************/ + static void mode_to_str(sqfs_u16 mode, char *p) { *(p++) = (mode & SQFS_INODE_OWNER_R) ? 'r' : '-'; @@ -205,6 +216,7 @@ static void stat_cmd(const char *filename) size_t i; int ret; + /* get the inode we are interested in */ if (filename == NULL) { printf("Missing argument: file name\n"); return; @@ -223,8 +235,7 @@ static void stat_cmd(const char *filename) goto fail_resolve; } - printf("Stat: %s\n", filename); - + /* some basic information */ switch (inode->base.type) { case SQFS_INODE_DIR: type = "directory"; break; case SQFS_INODE_FILE: type = "file"; break; @@ -243,6 +254,7 @@ static void stat_cmd(const char *filename) default: type = "UNKNOWN"; break; } + printf("Stat: %s\n", filename); printf("Type: %s\n", type); printf("Inode number: %u\n", inode->base.inode_number); @@ -250,6 +262,7 @@ static void stat_cmd(const char *filename) printf("Access: 0%o/%s\n", inode->base.mode & ~SQFS_INODE_MODE_MASK, buffer); + /* resolve and print UID/GID */ if (sqfs_id_table_index_to_id(idtbl, inode->base.uid_idx, &uid)) { strcpy(buffer, "-- error --"); } else { @@ -266,11 +279,13 @@ static void stat_cmd(const char *filename) printf("GID: %s (index = %u)\n", buffer, inode->base.gid_idx); + /* last modification time stamp */ timeval = inode->base.mod_time; tm = gmtime(&timeval); strftime(buffer, sizeof(buffer), "%a, %d %b %Y %T %z", tm); printf("Last modified: %s (%u)\n", buffer, inode->base.mod_time); + /* inode type specific data */ switch (inode->base.type) { case SQFS_INODE_BDEV: case SQFS_INODE_CDEV: @@ -315,9 +330,9 @@ static void stat_cmd(const char *filename) for (i = 0; i < inode->num_file_blocks; ++i) { printf("\tBlock #%lu size: %u (%s)\n", (unsigned long)i, - inode->extra[i] & 0x00FFFFFF, - inode->extra[i] & (1 << 24) ? - "uncompressed" : "compressed"); + SQFS_ON_DISK_BLOCK_SIZE(inode->extra[i]), + SQFS_IS_BLOCK_COMPRESSED(inode->extra[i]) ? + "compressed" : "uncompressed"); } break; case SQFS_INODE_EXT_FILE: @@ -336,8 +351,8 @@ static void stat_cmd(const char *filename) for (i = 0; i < inode->num_file_blocks; ++i) { printf("\tBlock #%lu size: %u (%s)\n", (unsigned long)i, - inode->extra[i] & 0x00FFFFFF, - inode->extra[i] & (1 << 24) ? + SQFS_ON_DISK_BLOCK_SIZE(inode->extra[i]), + SQFS_IS_BLOCK_COMPRESSED(inode->extra[i]) ? "compressed" : "uncompressed"); } break; @@ -361,6 +376,7 @@ static void stat_cmd(const char *filename) if (inode->data.dir_ext.size == 0) break; + /* dump the extended directories fast-lookup index */ for (i = 0; ; ++i) { ret = sqfs_inode_unpack_dir_index_entry(inode, &idx, i); if (ret == SQFS_ERROR_OUT_OF_BOUNDS) @@ -388,6 +404,8 @@ fail_resolve: return; } +/*****************************************************************************/ + static void cat_cmd(const char *filename) { sqfs_inode_generic_t *inode, *root; @@ -396,6 +414,7 @@ static void cat_cmd(const char *filename) sqfs_s32 diff; int ret; + /* get the inode of the file */ if (filename == NULL) { printf("Missing argument: file name\n"); return; @@ -415,6 +434,10 @@ static void cat_cmd(const char *filename) return; } + /* Use the high level read-like function that uses the data-reader + * internal cache. There are also other functions for direct block + * or fragment access. + */ for (;;) { diff = sqfs_data_reader_read(data, inode, offset, buffer, sizeof(buffer)); @@ -431,6 +454,7 @@ static void cat_cmd(const char *filename) } } +/*****************************************************************************/ static const struct { const char *cmd; -- cgit v1.2.3