tests: using 64-bit offsets
[libha.git] / src / main.c
blob6ab096067e230b1358e25153c7e5ed6912ed4f99
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;
41 static uint64_t rdcur = 0, rdtotal = 0;
43 #define OUTBUF_SIZE (1024*1024)
44 static uint8_t wrbuf[OUTBUF_SIZE];
45 static int wrpos = 0;
47 static int dot_count = -1;
50 static int get_byte (void *udata) {
51 if (rdpos >= rdmax) {
52 if (pbar_dot_count(rdcur, rdtotal) != dot_count) {
53 dot_count = pbar_dot_count(rdcur, rdtotal);
54 pbar_draw(rdcur, rdtotal);
56 rdmax = read(fdi, rdbuf, sizeof(rdbuf));
57 if (rdmax <= 0) return LIBHA_FEOF;
58 rdpos = 0;
59 rdcur += rdmax;
61 return rdbuf[rdpos++];
65 static int put_byte (int c, void *udata) {
66 if (wrpos >= sizeof(wrbuf)) {
67 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
68 wrpos = 0;
70 wrbuf[wrpos++] = c&0xff;
71 return LIBHA_FOK;
75 static int flush (void *udata) {
76 pbar_clear();
77 if (wrpos > 0) {
78 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
79 wrpos = 0;
81 return LIBHA_FOK;
85 static const libha_io_t haio = {
86 .get_byte = get_byte,
87 .put_byte = put_byte,
88 .flush = flush
92 int main (int argc, char *argv[]) {
93 int dopack, res;
94 if (argc != 4) {
95 fprintf(stderr, "usage: %s <e|d> infile outfile\n", argv[0]);
96 return 1;
98 if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "c") == 0) dopack = 1;
99 else if (strcmp(argv[1], "d") == 0 || strcmp(argv[1], "x") == 0) dopack = 0;
100 else {
101 fprintf(stderr, "FATAL: unknown mode: '%s'\n", argv[1]);
102 return 1;
104 fdi = open(argv[2], O_RDONLY|O_CLOEXEC);
105 if (fdi < 0) {
106 fprintf(stderr, "FATAL: can't open file: '%s'\n", argv[2]);
107 return 1;
109 fdo = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0640);
110 if (fdo < 0) {
111 fprintf(stderr, "FATAL: can't create file: '%s'\n", argv[3]);
112 return 1;
114 rdtotal = lseek(fdi, 0, SEEK_END);
115 lseek(fdi, 0, SEEK_SET);
116 asc = asc_alloc(&haio, NULL);
117 if (dopack) {
118 res = asc_pack(asc);
119 } else {
120 res = asc_unpack(asc);
122 asc_free(asc);
123 close(fdi);
124 close(fdo);
125 if (res < 0) pbar_clear();
126 switch (res) {
127 case 0: break;
128 case LIBHA_ERR_READ: fprintf(stderr, "\nREADING ERROR!\n"); break;
129 case LIBHA_ERR_WRITE: fprintf(stderr, "\nWRITING ERROR!\n"); break;
130 case LIBHA_ERR_MEMORY: fprintf(stderr, "\nMEMORY ERROR!\n"); break;
131 default: fprintf(stderr, "\nOTHER ERROR!\n"); break;
133 if (res != 0) unlink(argv[3]);
134 return res;