-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgrpex.c
More file actions
115 lines (96 loc) · 2.82 KB
/
grpex.c
File metadata and controls
115 lines (96 loc) · 2.82 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCKSIZE (32768)
typedef struct {
char name[13];
unsigned int size;
} Entry;
const char magic[] = "KenSilverman";
int main(int argc, char **argv) {
char buffer[BLOCKSIZE];
char entry[16];
int nEntries;
Entry *entries;
FILE *in, *out;
int i;
unsigned int j;
unsigned int dataRead;
unsigned int remainder;
if(argc < 2) {
fprintf(stderr, "%s <GRP file>\n", argv[0]);
goto error0;
}
in = fopen(argv[1], "rb");
if(in == NULL) {
fprintf(stderr, "Failed to open %s for reading.\n", argv[1]);
goto error0;
}
if(fread(entry, 1, sizeof(entry), in) < sizeof(entry)) {
fprintf(stderr, "Failed to read entry.\n");
goto error1;
}
if(memcmp(entry, magic, 12) != 0) {
fprintf(stderr, "Bad magic.\n");
goto error1;
}
nEntries = ((int *)entry)[3];
entries = malloc(sizeof(Entry) * nEntries);
if(entries == NULL) {
fprintf(stderr, "Failed to allocate memory");
goto error1;
}
for(i = 0; i < nEntries; i++) {
if(fread(entry, 1, sizeof(entry), in) < sizeof(entry)) {
fprintf(stderr, "Failed to read entry.\n");
goto error2;
}
memcpy(entries[i].name, entry, 12);
entries[i].name[12] = '\0';
entries[i].size = ((unsigned int *)entry)[3];
}
for(i = 0; i < nEntries; i++) {
fprintf(stderr, "%s (%u)... ", entries[i].name, entries[i].size);
out = fopen(entries[i].name, "wb");
if(out == NULL) {
fprintf(stderr, "Failed to open %s for writing.\n", entries[i].name);
goto error2;
}
for(j = 0; BLOCKSIZE < entries[i].size - j; j += BLOCKSIZE) {
dataRead = fread(buffer, 1, BLOCKSIZE, in);
if(dataRead < BLOCKSIZE) {
fprintf(stderr, "Failed to read block.\n");
goto error3;
}
if(fwrite(buffer, 1, dataRead, out) < dataRead) {
fprintf(stderr, "Failed to write block.\n");
goto error3;
}
}
remainder = entries[i].size % BLOCKSIZE;
if(remainder > 0) {
dataRead = fread(buffer, 1, remainder, in);
if(dataRead < remainder) {
fprintf(stderr, "Failed to read block.\n");
goto error3;
}
if(fwrite(buffer, 1, dataRead, out) < dataRead) {
fprintf(stderr, "Failed to write block.\n");
goto error3;
}
}
fclose(out);
fprintf(stderr, "\n");
}
free(entries);
fclose(in);
exit(EXIT_SUCCESS);
error3:
fclose(out);
error2:
free(entries);
error1:
fclose(in);
error0:
exit(EXIT_FAILURE);
}