Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libarchive/cat/bsdcat.c
39478 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2011-2014, Mike Kazantsev
5
* All rights reserved.
6
*/
7
8
#include "bsdcat_platform.h"
9
10
#include <stdio.h>
11
#ifdef HAVE_STDLIB_H
12
#include <stdlib.h>
13
#endif
14
#ifdef HAVE_UNISTD_H
15
#include <unistd.h>
16
#endif
17
#ifdef HAVE_STRING_H
18
#include <string.h>
19
#endif
20
21
#include <archive.h>
22
#include <archive_entry.h>
23
24
#include "bsdcat.h"
25
#include "err.h"
26
27
#define BYTES_PER_BLOCK (20*512)
28
29
static struct archive *a;
30
static struct archive_entry *ae;
31
static const char *bsdcat_current_path;
32
static int exit_status = 0;
33
34
35
static __LA_NORETURN void
36
usage(FILE *stream, int eval)
37
{
38
const char *p;
39
p = lafe_getprogname();
40
fprintf(stream,
41
"Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p);
42
exit(eval);
43
}
44
45
static __LA_NORETURN void
46
version(void)
47
{
48
printf("bsdcat %s - %s \n",
49
BSDCAT_VERSION_STRING,
50
archive_version_details());
51
exit(0);
52
}
53
54
static void
55
bsdcat_print_error(void)
56
{
57
lafe_warnc(0, "%s: %s",
58
bsdcat_current_path, archive_error_string(a));
59
exit_status = 1;
60
}
61
62
static void
63
bsdcat_next(void)
64
{
65
if (a != NULL) {
66
if (archive_read_close(a) != ARCHIVE_OK)
67
bsdcat_print_error();
68
archive_read_free(a);
69
}
70
71
a = archive_read_new();
72
archive_read_support_filter_all(a);
73
archive_read_support_format_empty(a);
74
archive_read_support_format_raw(a);
75
}
76
77
static void
78
bsdcat_read_to_stdout(const char* filename)
79
{
80
int r;
81
82
if (archive_read_open_filename(a, filename, BYTES_PER_BLOCK)
83
!= ARCHIVE_OK)
84
bsdcat_print_error();
85
else if (r = archive_read_next_header(a, &ae),
86
r != ARCHIVE_OK && r != ARCHIVE_EOF)
87
bsdcat_print_error();
88
else if (r == ARCHIVE_EOF)
89
/* for empty payloads don't try and read data */
90
;
91
else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK)
92
bsdcat_print_error();
93
if (archive_read_close(a) != ARCHIVE_OK)
94
bsdcat_print_error();
95
archive_read_free(a);
96
a = NULL;
97
}
98
99
int
100
main(int argc, char **argv)
101
{
102
struct bsdcat *bsdcat, bsdcat_storage;
103
int c;
104
105
bsdcat = &bsdcat_storage;
106
memset(bsdcat, 0, sizeof(*bsdcat));
107
108
lafe_setprogname(*argv, "bsdcat");
109
110
bsdcat->argv = argv;
111
bsdcat->argc = argc;
112
113
while ((c = bsdcat_getopt(bsdcat)) != -1) {
114
switch (c) {
115
case 'h':
116
usage(stdout, 0);
117
/* NOTREACHED */
118
/* Fallthrough */
119
case OPTION_VERSION:
120
version();
121
/* NOTREACHED */
122
/* Fallthrough */
123
default:
124
usage(stderr, 1);
125
/* Fallthrough */
126
/* NOTREACHED */
127
}
128
}
129
130
bsdcat_next();
131
if (*bsdcat->argv == NULL) {
132
bsdcat_current_path = "<stdin>";
133
bsdcat_read_to_stdout(NULL);
134
} else {
135
while (*bsdcat->argv) {
136
bsdcat_current_path = *bsdcat->argv++;
137
bsdcat_read_to_stdout(bsdcat_current_path);
138
bsdcat_next();
139
}
140
archive_read_free(a); /* Help valgrind & friends */
141
}
142
143
exit(exit_status);
144
}
145
146