summaryrefslogtreecommitdiff
path: root/packer.c
diff options
context:
space:
mode:
Diffstat (limited to 'packer.c')
-rw-r--r--packer.c82
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;
+}