-
Notifications
You must be signed in to change notification settings - Fork 1
/
chmdump.c
90 lines (81 loc) · 1.77 KB
/
chmdump.c
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
/* CHMDump was written by Matthew T. Russotto, who hereby
places this source file in the public domain. */
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include "chmlib.h"
static void usage(char *pname)
{
fprintf(stderr, "Usage: %s chmfile outdir\n", pname);
}
main(int argc, char *argv[])
{
ubyte *buf;
ulong length;
chmfile *c;
char *infname;
char *outdirname;
int i;
ubyte *outbuf;
int namelen;
char *rel;
char dirname[PATH_MAX];
int err;
FILE *f;
if (3 != argc) {
usage(argv[0]);
exit(-1);
}
infname = argv[1];
outdirname = argv[2];
err = mkdir(outdirname, 0777);
if (err) {
if (errno == EEXIST) {
fprintf(stderr, "Directory %s already exists; you must specify a new directory.\n", outdirname);
}
else
perror("mkdir");
exit(-1);
}
c = chm_openfile(infname);
if (!c) {
perror("chm_openfile");
exit(-1);
}
err = chdir(outdirname);
if (err != 0) {
perror("chdir");
rmdir(outdirname);
exit(-1);
}
for (i = 0; i < c->dir->nentries; i++) {
if (c->dir->entry[i].name[0] == '/') {
namelen = strlen(c->dir->entry[i].name);
if (namelen == 1) continue; /* skip the slash */
rel = c->dir->entry[i].name + 1;
if (c->dir->entry[i].name[namelen-1] == '/') {
strncpy(dirname, rel, namelen-2);
dirname[namelen-2] = 0;
err = mkdir(dirname, 0777);
if (err != 0) {
fprintf(stderr, "mkdir failed on %s\n", dirname);
perror("mkdir");
exit(-1);
}
}
else {
chm_getfile(c, c->dir->entry[i].name, &length, &outbuf);
f = fopen(rel, "wb");
if (!f) {
fprintf(stderr, "Couldn't open %s\n", rel);
perror("fopen");
exit(-1);
}
fwrite(outbuf, 1, length, f);
fclose(f);
if (outbuf) free(outbuf);
}
}
}
chm_close(c);
}