tests: added funny 'secondary progress' and final reports
[libha.git] / src / main_unp.c
blobf0d06fec373b50db091f6221cccca226acd044e8
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 "libhaunp.h"
31 #include "pbar.h"
33 #include "intio.c"
36 static int fdi = -1;
37 static int fdo = -1;
38 static uint64_t bytes_done = 0, bytes_total = 0, bytes_res = 0, left;
40 static unsigned int crc_cur, crc;
42 #ifdef NDEBUG
43 # define OUTBUF_SIZE (1024*1024)
44 #else
45 # define OUTBUF_SIZE 1
46 #endif
47 static uint8_t *wrbuf;
50 static int dot_count = -1;
53 static int bread (void *buf, int buf_len, void *udata) {
54 int res = read(fdi, buf, buf_len);
55 if (res > 0) bytes_res += res;
56 return res;
60 int main (int argc, char *argv[]) {
61 haunp_t hup;
62 int res = 0;
63 char sign[4];
64 #ifndef NDEBUG
65 if (argc != 3) {
66 argc = 3;
67 argv[1] = "egatiles.dd2.haz";
68 argv[2] = "z01";
70 #endif
71 if (argc != 3) {
72 fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
73 return 1;
75 fdi = open(argv[1], O_RDONLY|O_CLOEXEC);
76 if (fdi < 0) {
77 fprintf(stderr, "FATAL: can't open file: '%s'\n", argv[1]);
78 return 1;
80 if (read(fdi, sign, 4) != 4) res = -1;
81 else if (memcmp(sign, "LBHZ", 4) != 0) res = -1;
82 else if (read(fdi, &crc, 4) != 4) res = -1;
83 else if (iio_read_integer_fd(fdi, &bytes_total, 8) < 0) res = -1;
84 if (res == -1) {
85 close(fdi);
86 fprintf(stderr, "FATAL: not libha file!\n");
87 return 1;
89 fdo = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0640);
90 if (fdo < 0) {
91 fprintf(stderr, "FATAL: can't create file: '%s'\n", argv[2]);
92 return 1;
94 hup = haunp_open_io(bread, NULL);
95 wrbuf = malloc(OUTBUF_SIZE);
96 //printf("output buffer size: %d\n", OUTBUF_SIZE);
97 crc_cur = haunp_crc32_begin();
98 left = bytes_total;
99 while (left > 0) {
100 int rd = (left > OUTBUF_SIZE ? OUTBUF_SIZE : left);
101 if (pbar_dot_count(bytes_done, bytes_total, bytes_res) != dot_count) {
102 dot_count = pbar_dot_count(bytes_done, bytes_total, bytes_res);
103 pbar_draw(bytes_done, bytes_total, bytes_res);
105 rd = haunp_read(hup, wrbuf, rd);
106 if (rd <= 0) {
107 pbar_clear();
108 if (rd < 0 || left > 0) {
109 fprintf(stdout, "READ ERROR!\n");
110 res = -1;
112 break;
114 crc_cur = haunp_crc32_part(crc_cur, wrbuf, rd);
115 if (write(fdo, wrbuf, rd) != rd) {
116 pbar_clear();
117 fprintf(stdout, "WRITE ERROR!\n");
118 res = -1;
119 break;
121 bytes_done += rd;
122 left -= rd;
124 free(wrbuf);
125 pbar_clear();
126 haunp_close(hup);
127 close(fdi);
128 close(fdo);
129 if (res == 0) {
130 crc_cur = haunp_crc32_end(crc_cur);
131 if (crc_cur != crc) {
132 fprintf(stdout, "CRC ERROR!\n");
133 res = -1;
136 if (res != 0) {
137 unlink(argv[2]);
138 } else {
139 char stot[92], sres[92];
140 pbar_u2s(stot, bytes_total);
141 pbar_u2s(sres, bytes_res);
142 printf("%s bytes unpacked to %s bytes\n", sres, stot);
144 return res;