summaryrefslogtreecommitdiff
path: root/packer.c
blob: 283c11f386d0907abdc4945ad75c09adec385fbe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#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]);
	}
	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++) {
		char fname[1024] = { 0 };
		FILE* infile;
		Pack_Entry* e = &table[i];
		uint32_t j;
		strcat(fname, workingdir);
		strcat(fname, dsep);
		strcat(fname, e->name);
		infile = fopen(fname, "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;
}