xref: /dflybsd-src/contrib/libarchive/cat/bsdcat.c (revision e95abc476b80ab0f6041c0123580ca7eee767083)
16b384f39SPeter Avalos /*-
26b384f39SPeter Avalos  * Copyright (c) 2011-2014, Mike Kazantsev
36b384f39SPeter Avalos  * All rights reserved.
46b384f39SPeter Avalos  *
56b384f39SPeter Avalos  * Redistribution and use in source and binary forms, with or without
66b384f39SPeter Avalos  * modification, are permitted provided that the following conditions
76b384f39SPeter Avalos  * are met:
86b384f39SPeter Avalos  * 1. Redistributions of source code must retain the above copyright
96b384f39SPeter Avalos  *    notice, this list of conditions and the following disclaimer.
106b384f39SPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
116b384f39SPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
126b384f39SPeter Avalos  *    documentation and/or other materials provided with the distribution.
136b384f39SPeter Avalos  *
146b384f39SPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
156b384f39SPeter Avalos  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
166b384f39SPeter Avalos  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
176b384f39SPeter Avalos  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
186b384f39SPeter Avalos  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
196b384f39SPeter Avalos  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
206b384f39SPeter Avalos  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
216b384f39SPeter Avalos  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
226b384f39SPeter Avalos  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
236b384f39SPeter Avalos  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
246b384f39SPeter Avalos  */
256b384f39SPeter Avalos 
266b384f39SPeter Avalos #include "bsdcat_platform.h"
276b384f39SPeter Avalos __FBSDID("$FreeBSD$");
286b384f39SPeter Avalos 
296b384f39SPeter Avalos #include <stdio.h>
306b384f39SPeter Avalos #ifdef HAVE_STDLIB_H
316b384f39SPeter Avalos #include <stdlib.h>
326b384f39SPeter Avalos #endif
336b384f39SPeter Avalos #ifdef HAVE_UNISTD_H
346b384f39SPeter Avalos #include <unistd.h>
356b384f39SPeter Avalos #endif
366b384f39SPeter Avalos #ifdef HAVE_STRING_H
376b384f39SPeter Avalos #include <string.h>
386b384f39SPeter Avalos #endif
396b384f39SPeter Avalos 
406b384f39SPeter Avalos #include "bsdcat.h"
416b384f39SPeter Avalos #include "err.h"
426b384f39SPeter Avalos 
436b384f39SPeter Avalos #define	BYTES_PER_BLOCK	(20*512)
446b384f39SPeter Avalos 
45*e95abc47Szrj static struct archive *a;
46*e95abc47Szrj static struct archive_entry *ae;
47*e95abc47Szrj static const char *bsdcat_current_path;
48*e95abc47Szrj static int exit_status = 0;
496b384f39SPeter Avalos 
506b384f39SPeter Avalos 
516b384f39SPeter Avalos void
usage(FILE * stream,int eval)526b384f39SPeter Avalos usage(FILE *stream, int eval)
536b384f39SPeter Avalos {
546b384f39SPeter Avalos 	const char *p;
556b384f39SPeter Avalos 	p = lafe_getprogname();
566b384f39SPeter Avalos 	fprintf(stream,
576b384f39SPeter Avalos 	    "Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p);
586b384f39SPeter Avalos 	exit(eval);
596b384f39SPeter Avalos }
606b384f39SPeter Avalos 
616b384f39SPeter Avalos static void
version(void)626b384f39SPeter Avalos version(void)
636b384f39SPeter Avalos {
646b384f39SPeter Avalos 	printf("bsdcat %s - %s \n",
656b384f39SPeter Avalos 	    BSDCAT_VERSION_STRING,
666b384f39SPeter Avalos 	    archive_version_details());
676b384f39SPeter Avalos 	exit(0);
686b384f39SPeter Avalos }
696b384f39SPeter Avalos 
706b384f39SPeter Avalos void
bsdcat_next(void)71*e95abc47Szrj bsdcat_next(void)
726b384f39SPeter Avalos {
73*e95abc47Szrj 	if (a != NULL) {
74*e95abc47Szrj 		if (archive_read_close(a) != ARCHIVE_OK)
75*e95abc47Szrj 			bsdcat_print_error();
76*e95abc47Szrj 		archive_read_free(a);
77*e95abc47Szrj 	}
78*e95abc47Szrj 
796b384f39SPeter Avalos 	a = archive_read_new();
806b384f39SPeter Avalos 	archive_read_support_filter_all(a);
816b384f39SPeter Avalos 	archive_read_support_format_empty(a);
826b384f39SPeter Avalos 	archive_read_support_format_raw(a);
836b384f39SPeter Avalos }
846b384f39SPeter Avalos 
856b384f39SPeter Avalos void
bsdcat_print_error(void)866b384f39SPeter Avalos bsdcat_print_error(void)
876b384f39SPeter Avalos {
886b384f39SPeter Avalos 	lafe_warnc(0, "%s: %s",
896b384f39SPeter Avalos 	    bsdcat_current_path, archive_error_string(a));
906b384f39SPeter Avalos 	exit_status = 1;
916b384f39SPeter Avalos }
926b384f39SPeter Avalos 
936b384f39SPeter Avalos void
bsdcat_read_to_stdout(const char * filename)94*e95abc47Szrj bsdcat_read_to_stdout(const char* filename)
956b384f39SPeter Avalos {
966b384f39SPeter Avalos 	int r;
976b384f39SPeter Avalos 
986b384f39SPeter Avalos 	if (archive_read_open_filename(a, filename, BYTES_PER_BLOCK)
996b384f39SPeter Avalos 	    != ARCHIVE_OK)
1006b384f39SPeter Avalos 		bsdcat_print_error();
1016b384f39SPeter Avalos 	else if (r = archive_read_next_header(a, &ae),
1026b384f39SPeter Avalos 		 r != ARCHIVE_OK && r != ARCHIVE_EOF)
1036b384f39SPeter Avalos 		bsdcat_print_error();
1046b384f39SPeter Avalos 	else if (r == ARCHIVE_EOF)
1056b384f39SPeter Avalos 		/* for empty payloads don't try and read data */
1066b384f39SPeter Avalos 		;
1076b384f39SPeter Avalos 	else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK)
1086b384f39SPeter Avalos 		bsdcat_print_error();
109*e95abc47Szrj 	if (archive_read_close(a) != ARCHIVE_OK)
1106b384f39SPeter Avalos 		bsdcat_print_error();
111*e95abc47Szrj 	archive_read_free(a);
112*e95abc47Szrj 	a = NULL;
1136b384f39SPeter Avalos }
1146b384f39SPeter Avalos 
1156b384f39SPeter Avalos int
main(int argc,char ** argv)1166b384f39SPeter Avalos main(int argc, char **argv)
1176b384f39SPeter Avalos {
1186b384f39SPeter Avalos 	struct bsdcat *bsdcat, bsdcat_storage;
1196b384f39SPeter Avalos 	int c;
1206b384f39SPeter Avalos 
1216b384f39SPeter Avalos 	bsdcat = &bsdcat_storage;
1226b384f39SPeter Avalos 	memset(bsdcat, 0, sizeof(*bsdcat));
1236b384f39SPeter Avalos 
1246b384f39SPeter Avalos 	lafe_setprogname(*argv, "bsdcat");
1256b384f39SPeter Avalos 
1266b384f39SPeter Avalos 	bsdcat->argv = argv;
1276b384f39SPeter Avalos 	bsdcat->argc = argc;
1286b384f39SPeter Avalos 
1296b384f39SPeter Avalos 	while ((c = bsdcat_getopt(bsdcat)) != -1) {
1306b384f39SPeter Avalos 		switch (c) {
1316b384f39SPeter Avalos 		case 'h':
1326b384f39SPeter Avalos 			usage(stdout, 0);
1336b384f39SPeter Avalos 			break;
1346b384f39SPeter Avalos 		case OPTION_VERSION:
1356b384f39SPeter Avalos 			version();
1366b384f39SPeter Avalos 			break;
1376b384f39SPeter Avalos 		default:
1386b384f39SPeter Avalos 			usage(stderr, 1);
1396b384f39SPeter Avalos 		}
1406b384f39SPeter Avalos 	}
1416b384f39SPeter Avalos 
1426b384f39SPeter Avalos 	bsdcat_next();
1436b384f39SPeter Avalos 	if (*bsdcat->argv == NULL) {
1446b384f39SPeter Avalos 		bsdcat_current_path = "<stdin>";
1456b384f39SPeter Avalos 		bsdcat_read_to_stdout(NULL);
146*e95abc47Szrj 	} else {
1476b384f39SPeter Avalos 		while (*bsdcat->argv) {
1486b384f39SPeter Avalos 			bsdcat_current_path = *bsdcat->argv++;
1496b384f39SPeter Avalos 			bsdcat_read_to_stdout(bsdcat_current_path);
1506b384f39SPeter Avalos 			bsdcat_next();
1516b384f39SPeter Avalos 		}
152*e95abc47Szrj 		archive_read_free(a); /* Help valgrind & friends */
153*e95abc47Szrj 	}
1546b384f39SPeter Avalos 
1556b384f39SPeter Avalos 	exit(exit_status);
1566b384f39SPeter Avalos }
157