1 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://sam.zoy.org/wtfpl/COPYING for more details.
23 #include <sys/types.h>
25 #include "libwdx/libwdx.h"
28 static void reportError (void) {
29 fprintf(stderr
, "ERROR: %s\n", strerror(errno
));
33 static void *loadWholeFile (const char *fname
, int *fsize
) {
36 int fd
= open(fname
, O_RDONLY
);
38 if (fd
< 0) goto error
;
39 fsz
= lseek(fd
, 0, SEEK_END
);
40 if (fsz
<= (off_t
)-1) goto error
;
41 if (fsz
> 0x7fffffff) { fprintf(stderr
, "ERROR: file too big\n"); goto error1
; }
42 if (lseek(fd
, 0, SEEK_SET
) <= (off_t
)-1) goto error
;
46 if (read(fd
, res
, fsz
) != fsz
) goto error
;
48 if (close(fd
) < 0) { fd
= -1; goto error
; }
54 if (fd
>= 0) close(fd
);
60 static int writeUInt (int fd
, uint32_t i
) {
61 uint32_t v
= htole32(i
);
63 if (write(fd
, &v
, 4) != 4) { reportError(); return -1; }
68 static uint32_t getUInt (const void *buf
) {
76 static int writeWDX (const char *fname
, const void *pbuf
, int pSize
, int origSize
, uint32_t crc
) {
77 static char *sign
= "WDX0";
80 if (pSize
< 0) return -1;
81 fd
= open(fname
, O_CREAT
| O_WRONLY
| O_TRUNC
, 0644);
82 if (fd
< 0) goto error
;
83 if (write(fd
, sign
, 4) != 4) goto error
;
84 if (writeUInt(fd
, (uint32_t)origSize
)) goto error1
;
85 if (writeUInt(fd
, crc
)) goto error1
;
86 if (writeUInt(fd
, (uint32_t)pSize
)) goto error1
;
87 if (write(fd
, pbuf
, pSize
) != pSize
) goto error1
;
88 if (close(fd
) < 0) { unlink(fname
); fd
= -1; goto error
; }
101 static int pack (const char *fin
, const char *fout
) {
106 if (!(ibuf
= loadWholeFile(fin
, &isz
))) {
107 fprintf(stderr
, "ERROR: can't read input file: %s\n", fin
);
110 osz
= wdxPackBufferSize(isz
);
114 fprintf(stderr
, "ERROR: out of memory!\n");
117 crc
= wdxCRC32(ibuf
, isz
);
118 fprintf(stdout
, "packing %d bytes ... ", isz
); fflush(stdout
);
119 psz
= wdxPack(obuf
, osz
, ibuf
, isz
);
123 fprintf(stdout
, "FAILED!\n");
124 fprintf(stderr
, "ERROR: can't pack!\n");
127 fprintf(stdout
, "got %d packed bytes\n", psz
); fflush(stdout
);
128 osz
= writeWDX(fout
, obuf
, psz
, isz
, crc
);
131 fprintf(stderr
, "ERROR: can't write output file: %s\n", fout
);
138 static int unpack (const char *fin
, const char *fout
) {
140 uint8_t *ibuf
, *obuf
, *origBuf
;
141 int isz
, osz
, psz
, xsz
;
144 if (!(ibuf
= loadWholeFile(fin
, &isz
))) {
145 fprintf(stderr
, "ERROR: can't read input file: %s\n", fin
);
148 if (isz
< 16 || ibuf
[0] != 'W' || ibuf
[1] != 'D' || ibuf
[2] != 'X' || ibuf
[3] != '0') {
149 fprintf(stderr
, "ERROR: invalid input file: %s\n", fin
);
153 ibuf
+= 4; /* skip signature */
154 osz
= getUInt(ibuf
); ibuf
+= 4; /* unpacked size */
155 crc
= getUInt(ibuf
); ibuf
+= 4; /* crc */
156 psz
= getUInt(ibuf
); ibuf
+= 4; /* packed size */
160 fprintf(stderr
, "ERROR: out of memory!\n");
163 fprintf(stdout
, "unpacking %d bytes to %d bytes ... ", psz
, osz
); fflush(stdout
);
164 xsz
= wdxUnpack(obuf
, osz
, ibuf
, psz
);
166 if (xsz
< 0 || xsz
!= osz
) {
168 fprintf(stdout
, "FAILED!\n");
169 fprintf(stderr
, "ERROR: can't unpack! (%d)\n", xsz
);
172 ncrc
= wdxCRC32(obuf
, xsz
);
175 fprintf(stdout
, "FAILED!\n");
176 fprintf(stderr
, "ERROR: CRC check failed!\n");
179 fprintf(stdout
, "OK\n");
180 fo
= open(fout
, O_CREAT
| O_WRONLY
| O_TRUNC
, 0644);
183 fprintf(stderr
, "ERROR: can't write output file: %s\n", fout
);
186 if (write(fo
, obuf
, xsz
) != xsz
) {
188 fprintf(stderr
, "ERROR: can't write output file (1): %s\n", fout
);
193 fprintf(stderr
, "ERROR: can't write output file (2): %s\n", fout
);
210 int main (int argc
, char *argv
[]) {
211 const char *inname
= NULL
, *outname
= NULL
;
216 } else if (argc
> 3) {
220 fprintf(stderr
, "usage: %s <c|d> infile [outfile]\n", argv
[0]);
223 if (!strcmp("c", argv
[1]) || !strcmp("-c", argv
[1])) return pack(inname
, outname
);
224 return unpack(inname
, outname
);