diff options
Diffstat (limited to 'packer.c')
-rw-r--r-- | packer.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/packer.c b/packer.c new file mode 100644 index 0000000..ca1cb4a --- /dev/null +++ b/packer.c @@ -0,0 +1,82 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "memory.h" +#include "pack.h" +#include "plat.h" + +char magic[4] = { 'P', 'A', 'C', 'K' }; +#define buffer_size 1024 + +int main(int argc, const char** argv) { + FILE* outfile; + const char* workingdir, * dsep = ""; + char buffer[buffer_size]; + int file_count = argc - 3, i; + uint32_t coff, table_size; + Pack_Entry* table; + Pack* pack; + if (file_count <= 0) return 0; + if (argc < 3) { + print_err("Usage: %s <outfile> <dir> infile...\n"); + return 3; + } + outfile = fopen(argv[1], "wb"); + if (!outfile) { + print_err("Failed to open %s\n", argv[1]); + return 6; + } + workingdir = argv[2]; + if (workingdir[strlen(workingdir) - 1] != '/') + dsep = "/"; + table_size = sizeof *table * file_count; + pack = malloc(get_pack_size(file_count)); + if (!pack) { + print_err("Out of memory.\n"); + return 1; + } + table = get_pack_table(pack); + for (i = 0; i < file_count; i++) { + table[i].name[0] = 0; + } + pack->filename = 0; + pack->file_count = file_count; + for (i = 0; i < file_count; i++) { + Pack_Entry* e; + e = pack_find_entry(pack, argv[i + 3]); + if (!e || e->name[0]) { + print_err("Hash table error.\n"); + return 5; + } + strcpy(e->name, argv[i + 3] + strlen(workingdir) + strlen(dsep)); + } + fwrite(magic, 1, 4, outfile); + fwrite(&pack->file_count, 1, 4, outfile); + fwrite(table, 1, table_size, outfile); + coff = ftell(outfile); + for (i = 0; i < file_count; i++) { + FILE* infile; + Pack_Entry* e = &table[i]; + uint32_t j; + infile = fopen(argv[i + 3], "rb"); + if (!infile) { + print_err("Failed to open %s.\n", argv[i + 3]); + return 6; + } + fseek(infile, 0, SEEK_END); + e->size = ftell(infile); + e->offset = coff; + rewind(infile); + fseek(outfile, e->offset, SEEK_SET); + for (j = 0; j < e->size; j += buffer_size) { + int read = fread(buffer, 1, buffer_size, infile); + fwrite(buffer, 1, read, outfile); + } + coff += e->size; + } + fseek(outfile, 8, SEEK_SET); + fwrite(table, 1, table_size, outfile); + fclose(outfile); + return 0; +} |