standalone unpacker cosmetix
[libha.git] / src / main.c
blob9c0b289e5657f1a6b3a8f928a85ae81b43fec906
1 #include <fcntl.h>
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
11 #include "libha.h"
14 static asc_t asc = NULL;
15 static int fdi = -1;
16 static int fdo = -1;
18 #define INBUF_SIZE (1024*1024)
19 static uint8_t rdbuf[INBUF_SIZE];
20 static int rdpos = 0, rdmax = 0;
21 static int rdcur = 0, rdtotal = 0;
23 #define OUTBUF_SIZE (1024*1024)
24 static uint8_t wrbuf[OUTBUF_SIZE];
25 static int wrpos = 0;
28 static int get_byte (void *udata) {
29 if (rdpos >= rdmax) {
30 fprintf(stdout, "\r[%d/%d] %3d%%", rdcur, rdtotal, (int)((uint64_t)100*rdcur/rdtotal)); fflush(stdout);
31 rdmax = read(fdi, rdbuf, sizeof(rdbuf));
32 if (rdmax <= 0) return LIBHA_FEOF;
33 rdpos = 0;
34 rdcur += rdmax;
36 return rdbuf[rdpos++];
40 static int put_byte (int c, void *udata) {
41 if (wrpos >= sizeof(wrbuf)) {
42 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
43 wrpos = 0;
45 wrbuf[wrpos++] = c&0xff;
46 return LIBHA_FOK;
50 static int flush (void *udata) {
51 fprintf(stdout, "\r[%d/%d] %3d%%\n", rdtotal, rdtotal, 100); fflush(stdout);
52 if (wrpos > 0) {
53 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
54 wrpos = 0;
56 return LIBHA_FOK;
60 static const libha_io_t haio = {
61 .get_byte = get_byte,
62 .put_byte = put_byte,
63 .flush = flush
67 int main (int argc, char *argv[]) {
68 int dopack, res;
69 if (argc != 4) {
70 fprintf(stderr, "usage: %s <e|d> infile outfile\n", argv[0]);
71 return 1;
73 if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "c") == 0) dopack = 1;
74 else if (strcmp(argv[1], "d") == 0 || strcmp(argv[1], "x") == 0) dopack = 0;
75 else {
76 fprintf(stderr, "FATAL: unknown mode: '%s'\n", argv[1]);
77 return 1;
79 fdi = open(argv[2], O_RDONLY|O_CLOEXEC);
80 if (fdi < 0) {
81 fprintf(stderr, "FATAL: can't open file: '%s'\n", argv[2]);
82 return 1;
84 fdo = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0640);
85 if (fdo < 0) {
86 fprintf(stderr, "FATAL: can't create file: '%s'\n", argv[3]);
87 return 1;
89 rdtotal = lseek(fdi, 0, SEEK_END);
90 lseek(fdi, 0, SEEK_SET);
91 asc = asc_alloc(&haio, NULL);
92 if (dopack) {
93 res = asc_pack(asc);
94 } else {
95 res = asc_unpack(asc);
97 asc_free(asc);
98 close(fdi);
99 close(fdo);
100 switch (res) {
101 case 0: break;
102 case LIBHA_ERR_READ: fprintf(stderr, "\nREADING ERROR!\n"); break;
103 case LIBHA_ERR_WRITE: fprintf(stderr, "\nWRITING ERROR!\n"); break;
104 case LIBHA_ERR_MEMORY: fprintf(stderr, "\nMEMORY ERROR!\n"); break;
105 default: fprintf(stderr, "\nOTHER ERROR!\n"); break;
107 if (res != 0) unlink(argv[3]);
108 return res;