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