xref: /dflybsd-src/contrib/libarchive/cat/bsdcat.c (revision 6b384f3989c11f4c0078ee986d3d85a2da3bf92a)
1*6b384f39SPeter Avalos /*-
2*6b384f39SPeter Avalos  * Copyright (c) 2011-2014, Mike Kazantsev
3*6b384f39SPeter Avalos  * All rights reserved.
4*6b384f39SPeter Avalos  *
5*6b384f39SPeter Avalos  * Redistribution and use in source and binary forms, with or without
6*6b384f39SPeter Avalos  * modification, are permitted provided that the following conditions
7*6b384f39SPeter Avalos  * are met:
8*6b384f39SPeter Avalos  * 1. Redistributions of source code must retain the above copyright
9*6b384f39SPeter Avalos  *    notice, this list of conditions and the following disclaimer.
10*6b384f39SPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
11*6b384f39SPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
12*6b384f39SPeter Avalos  *    documentation and/or other materials provided with the distribution.
13*6b384f39SPeter Avalos  *
14*6b384f39SPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15*6b384f39SPeter Avalos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*6b384f39SPeter Avalos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*6b384f39SPeter Avalos  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18*6b384f39SPeter Avalos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*6b384f39SPeter Avalos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*6b384f39SPeter Avalos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*6b384f39SPeter Avalos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*6b384f39SPeter Avalos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*6b384f39SPeter Avalos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*6b384f39SPeter Avalos  */
25*6b384f39SPeter Avalos 
26*6b384f39SPeter Avalos #include "bsdcat_platform.h"
27*6b384f39SPeter Avalos __FBSDID("$FreeBSD$");
28*6b384f39SPeter Avalos 
29*6b384f39SPeter Avalos #include <stdio.h>
30*6b384f39SPeter Avalos #ifdef HAVE_STDLIB_H
31*6b384f39SPeter Avalos #include <stdlib.h>
32*6b384f39SPeter Avalos #endif
33*6b384f39SPeter Avalos #ifdef HAVE_UNISTD_H
34*6b384f39SPeter Avalos #include <unistd.h>
35*6b384f39SPeter Avalos #endif
36*6b384f39SPeter Avalos #ifdef HAVE_STRING_H
37*6b384f39SPeter Avalos #include <string.h>
38*6b384f39SPeter Avalos #endif
39*6b384f39SPeter Avalos 
40*6b384f39SPeter Avalos #include "bsdcat.h"
41*6b384f39SPeter Avalos #include "err.h"
42*6b384f39SPeter Avalos 
43*6b384f39SPeter Avalos #define	BYTES_PER_BLOCK	(20*512)
44*6b384f39SPeter Avalos 
45*6b384f39SPeter Avalos struct archive *a;
46*6b384f39SPeter Avalos struct archive_entry *ae;
47*6b384f39SPeter Avalos char *bsdcat_current_path;
48*6b384f39SPeter Avalos int exit_status = 0;
49*6b384f39SPeter Avalos 
50*6b384f39SPeter Avalos 
51*6b384f39SPeter Avalos void
52*6b384f39SPeter Avalos usage(FILE *stream, int eval)
53*6b384f39SPeter Avalos {
54*6b384f39SPeter Avalos 	const char *p;
55*6b384f39SPeter Avalos 	p = lafe_getprogname();
56*6b384f39SPeter Avalos 	fprintf(stream,
57*6b384f39SPeter Avalos 	    "Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p);
58*6b384f39SPeter Avalos 	exit(eval);
59*6b384f39SPeter Avalos }
60*6b384f39SPeter Avalos 
61*6b384f39SPeter Avalos static void
62*6b384f39SPeter Avalos version(void)
63*6b384f39SPeter Avalos {
64*6b384f39SPeter Avalos 	printf("bsdcat %s - %s\n",
65*6b384f39SPeter Avalos 	    BSDCAT_VERSION_STRING,
66*6b384f39SPeter Avalos 	    archive_version_details());
67*6b384f39SPeter Avalos 	exit(0);
68*6b384f39SPeter Avalos }
69*6b384f39SPeter Avalos 
70*6b384f39SPeter Avalos void
71*6b384f39SPeter Avalos bsdcat_next()
72*6b384f39SPeter Avalos {
73*6b384f39SPeter Avalos 	a = archive_read_new();
74*6b384f39SPeter Avalos 	archive_read_support_filter_all(a);
75*6b384f39SPeter Avalos 	archive_read_support_format_empty(a);
76*6b384f39SPeter Avalos 	archive_read_support_format_raw(a);
77*6b384f39SPeter Avalos }
78*6b384f39SPeter Avalos 
79*6b384f39SPeter Avalos void
80*6b384f39SPeter Avalos bsdcat_print_error(void)
81*6b384f39SPeter Avalos {
82*6b384f39SPeter Avalos 	lafe_warnc(0, "%s: %s",
83*6b384f39SPeter Avalos 	    bsdcat_current_path, archive_error_string(a));
84*6b384f39SPeter Avalos 	exit_status = 1;
85*6b384f39SPeter Avalos }
86*6b384f39SPeter Avalos 
87*6b384f39SPeter Avalos void
88*6b384f39SPeter Avalos bsdcat_read_to_stdout(char* filename)
89*6b384f39SPeter Avalos {
90*6b384f39SPeter Avalos 	int r;
91*6b384f39SPeter Avalos 
92*6b384f39SPeter Avalos 	if (archive_read_open_filename(a, filename, BYTES_PER_BLOCK)
93*6b384f39SPeter Avalos 	    != ARCHIVE_OK)
94*6b384f39SPeter Avalos 		bsdcat_print_error();
95*6b384f39SPeter Avalos 	else if (r = archive_read_next_header(a, &ae),
96*6b384f39SPeter Avalos 		 r != ARCHIVE_OK && r != ARCHIVE_EOF)
97*6b384f39SPeter Avalos 		bsdcat_print_error();
98*6b384f39SPeter Avalos 	else if (r == ARCHIVE_EOF)
99*6b384f39SPeter Avalos 		/* for empty payloads don't try and read data */
100*6b384f39SPeter Avalos 		;
101*6b384f39SPeter Avalos 	else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK)
102*6b384f39SPeter Avalos 		bsdcat_print_error();
103*6b384f39SPeter Avalos 	if (archive_read_free(a) != ARCHIVE_OK)
104*6b384f39SPeter Avalos 		bsdcat_print_error();
105*6b384f39SPeter Avalos }
106*6b384f39SPeter Avalos 
107*6b384f39SPeter Avalos int
108*6b384f39SPeter Avalos main(int argc, char **argv)
109*6b384f39SPeter Avalos {
110*6b384f39SPeter Avalos 	struct bsdcat *bsdcat, bsdcat_storage;
111*6b384f39SPeter Avalos 	int c;
112*6b384f39SPeter Avalos 
113*6b384f39SPeter Avalos 	bsdcat = &bsdcat_storage;
114*6b384f39SPeter Avalos 	memset(bsdcat, 0, sizeof(*bsdcat));
115*6b384f39SPeter Avalos 
116*6b384f39SPeter Avalos 	lafe_setprogname(*argv, "bsdcat");
117*6b384f39SPeter Avalos 
118*6b384f39SPeter Avalos 	bsdcat->argv = argv;
119*6b384f39SPeter Avalos 	bsdcat->argc = argc;
120*6b384f39SPeter Avalos 
121*6b384f39SPeter Avalos 	while ((c = bsdcat_getopt(bsdcat)) != -1) {
122*6b384f39SPeter Avalos 		switch (c) {
123*6b384f39SPeter Avalos 		case 'h':
124*6b384f39SPeter Avalos 			usage(stdout, 0);
125*6b384f39SPeter Avalos 			break;
126*6b384f39SPeter Avalos 		case OPTION_VERSION:
127*6b384f39SPeter Avalos 			version();
128*6b384f39SPeter Avalos 			break;
129*6b384f39SPeter Avalos 		default:
130*6b384f39SPeter Avalos 			usage(stderr, 1);
131*6b384f39SPeter Avalos 		}
132*6b384f39SPeter Avalos 	}
133*6b384f39SPeter Avalos 
134*6b384f39SPeter Avalos 	bsdcat_next();
135*6b384f39SPeter Avalos 	if (*bsdcat->argv == NULL) {
136*6b384f39SPeter Avalos 		bsdcat_current_path = "<stdin>";
137*6b384f39SPeter Avalos 		bsdcat_read_to_stdout(NULL);
138*6b384f39SPeter Avalos 	} else
139*6b384f39SPeter Avalos 		while (*bsdcat->argv) {
140*6b384f39SPeter Avalos 			bsdcat_current_path = *bsdcat->argv++;
141*6b384f39SPeter Avalos 			bsdcat_read_to_stdout(bsdcat_current_path);
142*6b384f39SPeter Avalos 			bsdcat_next();
143*6b384f39SPeter Avalos 		}
144*6b384f39SPeter Avalos 
145*6b384f39SPeter Avalos 	exit(exit_status);
146*6b384f39SPeter Avalos }
147