libha: renamings to make names consistent
[libha.git] / src / main.c
bloba16d2034699081c9455a23eea50e0ad585539fad
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 libha_t asc = NULL;
35 static int fdi = -1;
36 static int fdo = -1;
38 static int dot_count = -1;
40 static uint64_t bytes_done = 0, bytes_total = 0;
41 static int packing;
44 static int bread (void *buf, int buf_len, void *udata) {
45 int res;
46 if (packing) {
47 if (pbar_dot_count(bytes_done, bytes_total) != dot_count) {
48 dot_count = pbar_dot_count(bytes_done, bytes_total);
49 pbar_draw(bytes_done, bytes_total);
52 res = read(fdi, buf, buf_len);
53 if (res > 0) bytes_done += res;
54 return res;
58 static int bwrite (const void *buf, int buf_len, void *udata) {
59 int res;
60 if (!packing) {
61 if (pbar_dot_count(bytes_done, bytes_total) != dot_count) {
62 dot_count = pbar_dot_count(bytes_done, bytes_total);
63 pbar_draw(bytes_done, bytes_total);
66 res = write(fdo, buf, buf_len);
67 if (res > 0) bytes_done += res;
68 return res;
72 static const libha_io_t haio = {
73 .bread = bread,
74 .bwrite = bwrite,
78 int main (int argc, char *argv[]) {
79 int res;
80 if (argc != 4) {
81 fprintf(stderr, "usage: %s <e|d> infile outfile\n", argv[0]);
82 return 1;
84 if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "c") == 0) packing = 1;
85 else if (strcmp(argv[1], "d") == 0 || strcmp(argv[1], "x") == 0) packing = 0;
86 else {
87 fprintf(stderr, "FATAL: unknown mode: '%s'\n", argv[1]);
88 return 1;
90 fdi = open(argv[2], O_RDONLY|O_CLOEXEC);
91 if (fdi < 0) {
92 fprintf(stderr, "FATAL: can't open file: '%s'\n", argv[2]);
93 return 1;
95 fdo = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0640);
96 if (fdo < 0) {
97 fprintf(stderr, "FATAL: can't create file: '%s'\n", argv[3]);
98 return 1;
100 bytes_total = lseek(fdi, 0, SEEK_END);
101 lseek(fdi, 0, SEEK_SET);
102 asc = libha_alloc(&haio, NULL);
103 if (packing) {
104 // hey, write signature
105 if (write(fdo, "LBHZ", 4) != 4) res = -1;
106 else if (write(fdo, &bytes_total, 8) != 8) res = -1;
107 else res = libha_pack(asc);
108 } else {
109 char sign[4];
110 if (read(fdi, sign, 4) != 4) res = -1;
111 else if (memcmp(sign, "LBHZ", 4) != 0) res = -1;
112 else if (read(fdi, &bytes_total, 8) != 8) res = -1;
113 else res = libha_unpack(asc);
115 libha_free(asc);
116 close(fdi);
117 close(fdo);
118 if (res == 0) pbar_clear();
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;