display container, tag, and extent details in query command

This commit is contained in:
2025-02-04 12:58:01 +00:00
parent d94edfa8ee
commit d174baf97e

View File

@@ -1,17 +1,127 @@
#include "commands.h"
#include "misc.h"
#include "read.h"
#include "status.h"
#include <blue/cmd.h>
#include <blue/core/endian.h>
#include <blue/term.h>
#include <errno.h>
enum {
ARG_CONTAINER,
OPT_VERBOSE,
};
static void tag_type_string(unsigned long in, char out[5])
{
b_i32 v = b_i32_htob(in);
out[0] = v.i_bytes[0];
out[1] = v.i_bytes[1];
out[2] = v.i_bytes[2];
out[3] = v.i_bytes[3];
out[4] = 0;
}
static int query(
const b_command *self,
const b_arglist *opt,
const b_array *args)
{
const char *in_path = NULL;
b_arglist_get_string(
opt,
B_COMMAND_INVALID_ID,
ARG_CONTAINER,
0,
&in_path);
FILE *fp = fopen(in_path, "rb");
if (!fp) {
b_err("cannot open container '%s'", in_path);
b_i("reason: %s", strerror(errno));
return -1;
}
struct ec3_reader *reader = NULL;
enum ec3_status status = ec3_reader_create(fp, &reader);
if (status != EC3_SUCCESS) {
fclose(fp);
b_err("cannot open container '%s'", in_path);
return -1;
}
const struct ec3_container_info *c_info
= ec3_reader_get_container_info(reader);
char container_id[32];
ec3_identifier_to_string(
c_info->c_id,
container_id,
sizeof container_id);
printf("container details:\n");
printf(" %-20s: %04x\n", "format version", c_info->c_version);
printf(" %-20s: %s\n", "identifier", container_id);
printf(" %-20s: %u\n", "cluster size", c_info->c_cluster_size);
printf(" %-20s: 0x%zx\n",
"tag table offset",
c_info->c_tag_table_offset);
printf(" %-20s: 0x%zx\n",
"extent table offset",
c_info->c_extent_table_offset);
printf(" %-20s: 0x%zx\n",
"cluster table offset",
c_info->c_cluster_table_offset);
printf(" %-20s: %u\n", "tag count", c_info->c_nr_tags);
printf(" %-20s: %u\n", "extent count", c_info->c_nr_extents);
printf(" %-20s: %u\n",
"cluster group count",
c_info->c_nr_cluster_groups);
printf("\ntags:\n");
const struct ec3_tag_info *tags = ec3_reader_get_tags(reader);
for (unsigned int i = 0; i < c_info->c_nr_tags; i++) {
char tag_type[5];
tag_type_string(tags[i].tag_type, tag_type);
char tag_id[32];
ec3_identifier_to_string(
tags[i].tag_ident,
tag_id,
sizeof tag_id);
printf(" (%lx/%s) %s\n", tags[i].tag_type, tag_type, tag_id);
printf(" %-8s: %08lx\n", "flags", tags[i].tag_flags);
printf(" %-8s: %08lx\n", "checksum", tags[i].tag_checksum);
}
printf("\nextents:\n");
const struct ec3_extent_info *extents = ec3_reader_get_extents(reader);
for (unsigned int i = 0; i < c_info->c_nr_tags; i++) {
char tag_id[32];
ec3_identifier_to_string(
extents[i].ex_owner,
tag_id,
sizeof tag_id);
size_t physical_base = extents[i].ex_physical_cluster;
size_t physical_limit = physical_base + extents[i].ex_count - 1;
size_t logical_base = extents[i].ex_logical_cluster;
size_t logical_limit = logical_base + extents[i].ex_count - 1;
printf(" (%16s) %lu clusters", tag_id, extents[i].ex_count);
printf(" [%05lx-%05lx] -> [%05lx-%05lx]\n",
logical_base,
logical_limit,
physical_base,
physical_limit);
}
ec3_reader_finish(reader);
fclose(fp);
return 0;
}