-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfpack.c
More file actions
130 lines (118 loc) · 3.81 KB
/
Copy pathfpack.c
File metadata and controls
130 lines (118 loc) · 3.81 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _MSC_VER
#include <unistd.h>
#include <getopt.h>
#endif
#include "fpack.h"
#include "lzss.h"
int main(int ac, char** av)
{
char* filename = NULL;
int encode = 0;
int opt = -1;
#ifndef _MSC_VER
while((opt = getopt(ac, av, "e")) != -1) {
switch(opt) {
case 'e':
encode = 1;
break;
default:
fprintf(stderr, "Usage: %s [-e] archive.fpk files...\n", av[0]);
return 1;
}
}
#else
// Simple argument parsing for MSVC
int optind = 1;
for(int i = 1; i < ac; i++) {
if(strcmp(av[i], "-e") == 0) {
encode = 1;
} else {
optind = i;
break;
}
}
#endif
if(optind < ac) {
filename = av[optind];
}
if(!filename || optind + 1 >= ac) {
fprintf(stderr, "Usage: %s [-e] archive.fpk files...\n", av[0]);
return 1;
}
FILE* fpk = fopen(filename, "wb");
if(!fpk) {
perror("Failed to open archive");
return 1;
}
fpack_header_t header;
memcpy(header.signature, "KAPF", 4);
header.files_count = ac - optind - 1; // Number of files to pack
fwrite(&header, sizeof(header), 1, fpk);
fpack_file_entry_t* entries = malloc(header.files_count * sizeof(fpack_file_entry_t));
if(!entries) {
perror("Failed to allocate memory for file entries");
fclose(fpk);
return 1;
}
memset(entries, 0, header.files_count * sizeof(fpack_file_entry_t));
fwrite(entries, sizeof(fpack_file_entry_t), header.files_count, fpk);
fpack_file_entry_t* entry;
for(int i = optind + 1; i < ac; i++) {
int index = i - optind - 1; // Adjust index for entries array
entry = &entries[index];
strncpy(entry->filename, av[i], sizeof(entry->filename) - 1);
entry->filename[sizeof(entry->filename) - 1] = '\0'; // Ensure null termination
FILE* in_file = fopen(av[i], "rb");
if(!in_file) {
perror("Failed to open input file");
free(entries);
fclose(fpk);
return 1;
}
fseek(in_file, 0, SEEK_END);
entry->size = ftell(in_file);
fseek(in_file, 0, SEEK_SET);
entry->offset = ftell(fpk);
if(encode) {
uint8_t* buffer = malloc(entry->size);
if(!buffer) {
perror("Failed to allocate memory for file data");
fclose(in_file);
free(entries);
fclose(fpk);
return 1;
}
fread(buffer, 1, entry->size, in_file);
uint32_t encodedSize = entry->size * 2;
uint8_t* encodedData = malloc(encodedSize); // Allocate more than enough space
encodeLZSS(buffer, entry->size, encodedData, &encodedSize);
fwrite(encodedData, 1, encodedSize, fpk);
free(encodedData);
free(buffer);
entry->size = encodedSize; // Update size to the encoded size
} else {
char* buffer = malloc(entry->size);
if(!buffer) {
perror("Failed to allocate memory for file data");
fclose(in_file);
free(entries);
fclose(fpk);
return 1;
}
fread(buffer, 1, entry->size, in_file);
fwrite(buffer, 1, entry->size, fpk);
free(buffer);
}
fclose(in_file);
}
fseek(fpk, 0, SEEK_SET);
fwrite(&header, sizeof(header), 1, fpk); // Write header again with updated file count
fwrite(entries, sizeof(fpack_file_entry_t), header.files_count, fpk); // Write entries again
free(entries);
fclose(fpk);
printf("Archive created successfully: %s\n", filename);
return 0;
}