added COPYING and 'modified by'
[libha.git] / src / main.c
blob81940128d3a3ec249d11d31e8709b421ed100091
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"
33 static asc_t asc = NULL;
34 static int fdi = -1;
35 static int fdo = -1;
37 #define INBUF_SIZE (1024*1024)
38 static uint8_t rdbuf[INBUF_SIZE];
39 static int rdpos = 0, rdmax = 0;
40 static int rdcur = 0, rdtotal = 0;
42 #define OUTBUF_SIZE (1024*1024)
43 static uint8_t wrbuf[OUTBUF_SIZE];
44 static int wrpos = 0;
47 static int get_byte (void *udata) {
48 if (rdpos >= rdmax) {
49 fprintf(stdout, "\r[%d/%d] %3d%%", rdcur, rdtotal, (int)((uint64_t)100*rdcur/rdtotal)); fflush(stdout);
50 rdmax = read(fdi, rdbuf, sizeof(rdbuf));
51 if (rdmax <= 0) return LIBHA_FEOF;
52 rdpos = 0;
53 rdcur += rdmax;
55 return rdbuf[rdpos++];
59 static int put_byte (int c, void *udata) {
60 if (wrpos >= sizeof(wrbuf)) {
61 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
62 wrpos = 0;
64 wrbuf[wrpos++] = c&0xff;
65 return LIBHA_FOK;
69 static int flush (void *udata) {
70 fprintf(stdout, "\r[%d/%d] %3d%%\n", rdtotal, rdtotal, 100); fflush(stdout);
71 if (wrpos > 0) {
72 if (write(fdo, wrbuf, wrpos) != wrpos) return LIBHA_FERR;
73 wrpos = 0;
75 return LIBHA_FOK;
79 static const libha_io_t haio = {
80 .get_byte = get_byte,
81 .put_byte = put_byte,
82 .flush = flush
86 int main (int argc, char *argv[]) {
87 int dopack, res;
88 if (argc != 4) {
89 fprintf(stderr, "usage: %s <e|d> infile outfile\n", argv[0]);
90 return 1;
92 if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "c") == 0) dopack = 1;
93 else if (strcmp(argv[1], "d") == 0 || strcmp(argv[1], "x") == 0) dopack = 0;
94 else {
95 fprintf(stderr, "FATAL: unknown mode: '%s'\n", argv[1]);
96 return 1;
98 fdi = open(argv[2], O_RDONLY|O_CLOEXEC);
99 if (fdi < 0) {
100 fprintf(stderr, "FATAL: can't open file: '%s'\n", argv[2]);
101 return 1;
103 fdo = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0640);
104 if (fdo < 0) {
105 fprintf(stderr, "FATAL: can't create file: '%s'\n", argv[3]);
106 return 1;
108 rdtotal = lseek(fdi, 0, SEEK_END);
109 lseek(fdi, 0, SEEK_SET);
110 asc = asc_alloc(&haio, NULL);
111 if (dopack) {
112 res = asc_pack(asc);
113 } else {
114 res = asc_unpack(asc);
116 asc_free(asc);
117 close(fdi);
118 close(fdo);
119 switch (res) {
120 case 0: break;
121 case LIBHA_ERR_READ: fprintf(stderr, "\nREADING ERROR!\n"); break;
122 case LIBHA_ERR_WRITE: fprintf(stderr, "\nWRITING ERROR!\n"); break;
123 case LIBHA_ERR_MEMORY: fprintf(stderr, "\nMEMORY ERROR!\n"); break;
124 default: fprintf(stderr, "\nOTHER ERROR!\n"); break;
126 if (res != 0) unlink(argv[3]);
127 return res;