diff --git a/huffman.c b/huffman.c index 43e7019..edbbfd5 100644 --- a/huffman.c +++ b/huffman.c @@ -73,7 +73,8 @@ huffman_build_tree(void **values, int count) } 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; @@ -88,8 +89,14 @@ huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read) if ((bits[0] << *bits_read % 8 & 0x80) == 0) { node = node->left; + if (print) { + putchar ('0'); + } } else { node = node->right; + if (print) { + putchar ('1'); + } } (*bits_read)++; diff --git a/huffman.h b/huffman.h index c767ec3..c4b499d 100644 --- a/huffman.h +++ b/huffman.h @@ -1,3 +1,4 @@ +#include struct huffman_node { int weight; @@ -9,4 +10,4 @@ struct huffman_node { struct huffman_node *huffman_build_tree(void **values, int count); void *huffman_lookup (struct huffman_node *tree, unsigned char *bits, - int *bits_read); + int *bits_read, bool print); diff --git a/unpack.c b/unpack.c index 944cf47..77ccbfd 100644 --- a/unpack.c +++ b/unpack.c @@ -129,9 +129,9 @@ load_dictionary(FILE *source, char ***dictionary, int *dictionary_size, } static int -load_content_sets(FILE *stream, struct node **list, - struct huffman_node *dictionary_tree, bool stats) { - +load_content_sets(FILE *stream, struct node **list, int *node_count, + struct huffman_node *dictionary_tree, bool stats, bool raw) +{ unsigned char *buf = malloc (sizeof (char *) * CHUNK); size_t read; struct node **nodes; @@ -141,8 +141,10 @@ load_content_sets(FILE *stream, struct node **list, fread(&count, sizeof (unsigned char), 1, stream); if (stats) { - printf("node stats:\n"); - printf("\tnumber of nodes: %hd\n", count); + printf ("node stats:\n"); + 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->children = malloc (sizeof (struct node *) * 64); + if (raw) { + printf ("\tNode:\n"); + } + while (true) { + if (raw) { + printf("\t\t"); + } + char *path = (char *) huffman_lookup (dictionary_tree, - buf, &bits_read); + buf, &bits_read, + raw); buf = buf + bits_read / 8; bits_read = bits_read % 8; if (path[0] == '\0') { + if (raw) { + printf("\n"); + } break; } + if (raw) { + printf (" :: "); + } + struct node *child = (struct node *) huffman_lookup (tree, buf, - &bits_read); + &bits_read, + raw); + if (raw) { + printf ("\n"); + } + buf = buf + 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 main(int argc, char **argv) { FILE *fp; char **dictionary; int dictionary_size; struct node *content_sets; + int content_set_size; bool stats = false; + bool raw = false; bool dump = false; bool check = false; @@ -345,6 +400,7 @@ main(int argc, char **argv) { printf("usage: unpack [mode] [bin file]\n"); printf("mode is one of:\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("c - check if a path is allowed by the blob\n"); printf("\n"); @@ -361,6 +417,9 @@ main(int argc, char **argv) { case 'd': dump = true; break; + case 'r': + raw = true; + break; case 'c': check = true; if (argc != 4) { @@ -385,7 +444,12 @@ main(int argc, char **argv) { struct huffman_node *dictionary_tree = 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"); return -1; }