Add 'r' raw command to unpack.

r dumps the raw format as seen in the file to stdout as readable text.
This commit is contained in:
James Bowes 2012-09-06 11:12:54 -03:00
parent e0245db498
commit 8d59720195
3 changed files with 82 additions and 10 deletions

View file

@ -73,7 +73,8 @@ huffman_build_tree(void **values, int count)
} }
void * void *
huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read) huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read,
bool print)
{ {
struct huffman_node *node = tree; struct huffman_node *node = tree;
@ -88,8 +89,14 @@ huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read)
if ((bits[0] << *bits_read % 8 & 0x80) == 0) { if ((bits[0] << *bits_read % 8 & 0x80) == 0) {
node = node->left; node = node->left;
if (print) {
putchar ('0');
}
} else { } else {
node = node->right; node = node->right;
if (print) {
putchar ('1');
}
} }
(*bits_read)++; (*bits_read)++;

View file

@ -1,3 +1,4 @@
#include <stdbool.h>
struct huffman_node { struct huffman_node {
int weight; int weight;
@ -9,4 +10,4 @@ struct huffman_node {
struct huffman_node *huffman_build_tree(void **values, int count); struct huffman_node *huffman_build_tree(void **values, int count);
void *huffman_lookup (struct huffman_node *tree, unsigned char *bits, void *huffman_lookup (struct huffman_node *tree, unsigned char *bits,
int *bits_read); int *bits_read, bool print);

View file

@ -129,9 +129,9 @@ load_dictionary(FILE *source, char ***dictionary, int *dictionary_size,
} }
static int static int
load_content_sets(FILE *stream, struct node **list, load_content_sets(FILE *stream, struct node **list, int *node_count,
struct huffman_node *dictionary_tree, bool stats) { struct huffman_node *dictionary_tree, bool stats, bool raw)
{
unsigned char *buf = malloc (sizeof (char *) * CHUNK); unsigned char *buf = malloc (sizeof (char *) * CHUNK);
size_t read; size_t read;
struct node **nodes; struct node **nodes;
@ -141,8 +141,10 @@ load_content_sets(FILE *stream, struct node **list,
fread(&count, sizeof (unsigned char), 1, stream); fread(&count, sizeof (unsigned char), 1, stream);
if (stats) { if (stats) {
printf("node stats:\n"); printf ("node stats:\n");
printf("\tnumber of nodes: %hd\n", count); printf ("\tnumber of nodes: %hd\n", count);
} else if (raw) {
printf ("Nodes (%d entries):\n", count);
} }
@ -173,19 +175,40 @@ load_content_sets(FILE *stream, struct node **list,
node->paths = malloc (sizeof (char *) * 64); node->paths = malloc (sizeof (char *) * 64);
node->children = malloc (sizeof (struct node *) * 64); node->children = malloc (sizeof (struct node *) * 64);
if (raw) {
printf ("\tNode:\n");
}
while (true) { while (true) {
if (raw) {
printf("\t\t");
}
char *path = (char *) huffman_lookup (dictionary_tree, char *path = (char *) huffman_lookup (dictionary_tree,
buf, &bits_read); buf, &bits_read,
raw);
buf = buf + bits_read / 8; buf = buf + bits_read / 8;
bits_read = bits_read % 8; bits_read = bits_read % 8;
if (path[0] == '\0') { if (path[0] == '\0') {
if (raw) {
printf("\n");
}
break; break;
} }
if (raw) {
printf (" :: ");
}
struct node *child = struct node *child =
(struct node *) huffman_lookup (tree, buf, (struct node *) huffman_lookup (tree, buf,
&bits_read); &bits_read,
raw);
if (raw) {
printf ("\n");
}
buf = buf + bits_read / 8; buf = buf + bits_read / 8;
bits_read = bits_read % 8; bits_read = bits_read % 8;
@ -330,14 +353,46 @@ check_content_set (struct node *content_sets, const char *path)
} }
} }
static void
print_dictionary (char **dictionary, int dictionary_size)
{
int i;
printf ("Path Dictionary (%d entries):\n", dictionary_size);
for (i = 0; i < dictionary_size; i++) {
printf ("\t%s\n", dictionary[i]);
}
}
static void
print_node (struct node *content_set)
{
int i;
printf ("\tNode:\n");
for (i = 0; i < content_set->count; i++) {
printf ("\t\t%s\n", content_set->paths[i]);
}
}
static void
print_nodes (struct node **content_sets, int content_set_size)
{
int i;
printf ("Node Dictionary (%d entries):\n", content_set_size);
for (i = 0; i < content_set_size; i++) {
print_node (content_sets[i]);
}
}
int int
main(int argc, char **argv) { main(int argc, char **argv) {
FILE *fp; FILE *fp;
char **dictionary; char **dictionary;
int dictionary_size; int dictionary_size;
struct node *content_sets; struct node *content_sets;
int content_set_size;
bool stats = false; bool stats = false;
bool raw = false;
bool dump = false; bool dump = false;
bool check = false; bool check = false;
@ -345,6 +400,7 @@ main(int argc, char **argv) {
printf("usage: unpack [mode] [bin file]\n"); printf("usage: unpack [mode] [bin file]\n");
printf("mode is one of:\n"); printf("mode is one of:\n");
printf("s - print stats for the binary content set blob\n"); printf("s - print stats for the binary content set blob\n");
printf("r - display the raw binary as text\n");
printf("d - dump the blob contents to stdout\n"); printf("d - dump the blob contents to stdout\n");
printf("c - check if a path is allowed by the blob\n"); printf("c - check if a path is allowed by the blob\n");
printf("\n"); printf("\n");
@ -361,6 +417,9 @@ main(int argc, char **argv) {
case 'd': case 'd':
dump = true; dump = true;
break; break;
case 'r':
raw = true;
break;
case 'c': case 'c':
check = true; check = true;
if (argc != 4) { if (argc != 4) {
@ -385,7 +444,12 @@ main(int argc, char **argv) {
struct huffman_node *dictionary_tree = struct huffman_node *dictionary_tree =
huffman_build_tree ((void **) dictionary, dictionary_size); huffman_build_tree ((void **) dictionary, dictionary_size);
if (load_content_sets(fp, &content_sets, dictionary_tree, stats)) { if (raw) {
print_dictionary (dictionary, dictionary_size);
}
if (load_content_sets(fp, &content_sets, &content_set_size,
dictionary_tree, stats, raw)) {
printf("node list parsing failed. exiting\n"); printf("node list parsing failed. exiting\n");
return -1; return -1;
} }