tests: added signature and size to packed files
[libha.git] / src / main.c
blob1aeda764073da98d58783f8a6d758779e94ca38d
1 /***********************************************************************
2 * This file is part of HA, a general purpose file archiver.
3 * Copyright (C) 1995 Harri Hirvola
4 * Modified by Ketmar // Invisible Vector
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ***********************************************************************/
20 #include <fcntl.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
30 #include "libha.h"
31 #include "pbar.h"
34 static asc_t asc = NULL;
35 static int fdi = -1;
36 static int fdo = -1;
38 #define INBUF_SIZE (1024*1024)
39 static uint8_t rdbuf[INBUF_SIZE];
40 static int rdpos = 0, rdmax = 0;
42 #define OUTBUF_SIZE (1024*1024)
43 static uint8_t wrbuf[OUTBUF_SIZE];
44 static int wrpos = 0;
46 static int dot_count = -1;
48 static uint64_t bytes_done = 0, bytes_total = 0;
49 static int packing;
52 static int get_byte (void *udata) {
53 if (rdpos >= rdmax) {
54 if (packing) {
55 if (pbar_dot_count(bytes_done, bytes_total) != dot_count) {
56 dot_count = pbar_dot_count(bytes_done, bytes_total);
57 pbar_draw(bytes_done, bytes_total);
60 rdmax = read(fdi, rdbuf, sizeof(rdbuf));
61 if (rdmax <= 0) return LIBHA_FEOF;
62 rdpos = 0;
63 bytes_done += rdmax;
65 return rdbuf[rdpos++];
69 static int put_byte (int c, void *udata) {
70 if (!packing) {
71 if (pbar_dot_count(bytes_done, bytes_total) != dot_count) {
72 dot_count = pbar_dot_count(bytes_done, bytes_total);
73 pbar_draw(bytes_done, bytes_total);
76 if (wrpos >= sizeof(wrbuf)) {
77 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
78 wrpos = 0;
80 wrbuf[wrpos++] = c&0xff;
81 return LIBHA_FOK;
85 static int flush (void *udata) {
86 if (wrpos > 0) {
87 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
88 wrpos = 0;
90 return LIBHA_FOK;
94 static const libha_io_t haio = {
95 .get_byte = get_byte,
96 .put_byte = put_byte,
97 .flush = flush
101 int main (int argc, char *argv[]) {
102 int dopack, res;
103 if (argc != 4) {
104 fprintf(stderr, "usage: %s <e|d> infile outfile\n", argv[0]);
105 return 1;
107 if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "c") == 0) dopack = 1;
108 else if (strcmp(argv[1], "d") == 0 || strcmp(argv[1], "x") == 0) dopack = 0;
109 else {
110 fprintf(stderr, "FATAL: unknown mode: '%s'\n", argv[1]);
111 return 1;
113 fdi = open(argv[2], O_RDONLY|O_CLOEXEC);
114 if (fdi < 0) {
115 fprintf(stderr, "FATAL: can't open file: '%s'\n", argv[2]);
116 return 1;
118 fdo = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0640);
119 if (fdo < 0) {
120 fprintf(stderr, "FATAL: can't create file: '%s'\n", argv[3]);
121 return 1;
123 bytes_total = lseek(fdi, 0, SEEK_END);
124 lseek(fdi, 0, SEEK_SET);
125 asc = asc_alloc(&haio, NULL);
126 if (dopack) {
127 // hey, write signature
128 if (write(fdo, "LBHZ", 4) != 4) res = -1;
129 else if (write(fdo, &bytes_total, 8) != 8) res = -1;
130 else res = asc_pack(asc);
131 } else {
132 char sign[4];
133 if (read(fdi, sign, 4) != 4) res = -1;
134 else if (memcmp(sign, "LBHZ", 4) != 0) res = -1;
135 else if (read(fdi, &bytes_total, 8) != 8) res = -1;
136 else res = asc_unpack(asc);
138 asc_free(asc);
139 close(fdi);
140 close(fdo);
141 if (res == 0) pbar_clear();
142 switch (res) {
143 case 0: break;
144 case LIBHA_ERR_READ: fprintf(stderr, "\nREADING ERROR!\n"); break;
145 case LIBHA_ERR_WRITE: fprintf(stderr, "\nWRITING ERROR!\n"); break;
146 case LIBHA_ERR_MEMORY: fprintf(stderr, "\nMEMORY ERROR!\n"); break;
147 default: fprintf(stderr, "\nOTHER ERROR!\n"); break;
149 if (res != 0) unlink(argv[3]);
150 return res;