1299425Smm/*- 2299425Smm * Copyright (c) 2011-2014, Mike Kazantsev 3299425Smm * All rights reserved. 4299425Smm * 5299425Smm * Redistribution and use in source and binary forms, with or without 6299425Smm * modification, are permitted provided that the following conditions 7299425Smm * are met: 8299425Smm * 1. Redistributions of source code must retain the above copyright 9299425Smm * notice, this list of conditions and the following disclaimer. 10299425Smm * 2. Redistributions in binary form must reproduce the above copyright 11299425Smm * notice, this list of conditions and the following disclaimer in the 12299425Smm * documentation and/or other materials provided with the distribution. 13299425Smm * 14299425Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15299425Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16299425Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17299425Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18299425Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19299425Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20299425Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21299425Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22299425Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23299425Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24299425Smm */ 25299425Smm 26299425Smm#include "bsdcat_platform.h" 27299425Smm__FBSDID("$FreeBSD: stable/11/contrib/libarchive/cat/bsdcat.c 337351 2018-08-05 14:35:30Z mm $"); 28299425Smm 29299425Smm#include <stdio.h> 30299425Smm#ifdef HAVE_STDLIB_H 31299425Smm#include <stdlib.h> 32299425Smm#endif 33299425Smm#ifdef HAVE_UNISTD_H 34299425Smm#include <unistd.h> 35299425Smm#endif 36299425Smm#ifdef HAVE_STRING_H 37299425Smm#include <string.h> 38299425Smm#endif 39299425Smm 40299425Smm#include "bsdcat.h" 41299425Smm#include "err.h" 42299425Smm 43299425Smm#define BYTES_PER_BLOCK (20*512) 44299425Smm 45299529Smmstatic struct archive *a; 46299529Smmstatic struct archive_entry *ae; 47299529Smmstatic const char *bsdcat_current_path; 48299529Smmstatic int exit_status = 0; 49299425Smm 50299425Smm 51299425Smmvoid 52299425Smmusage(FILE *stream, int eval) 53299425Smm{ 54299425Smm const char *p; 55299425Smm p = lafe_getprogname(); 56299425Smm fprintf(stream, 57299425Smm "Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p); 58299425Smm exit(eval); 59299425Smm} 60299425Smm 61299425Smmstatic void 62299425Smmversion(void) 63299425Smm{ 64337351Smm printf("bsdcat %s - %s \n", 65299425Smm BSDCAT_VERSION_STRING, 66299425Smm archive_version_details()); 67299425Smm exit(0); 68299425Smm} 69299425Smm 70299425Smmvoid 71299529Smmbsdcat_next(void) 72299425Smm{ 73328827Smm if (a != NULL) { 74328827Smm if (archive_read_close(a) != ARCHIVE_OK) 75328827Smm bsdcat_print_error(); 76328827Smm archive_read_free(a); 77328827Smm } 78328827Smm 79299425Smm a = archive_read_new(); 80299425Smm archive_read_support_filter_all(a); 81299425Smm archive_read_support_format_empty(a); 82299425Smm archive_read_support_format_raw(a); 83299425Smm} 84299425Smm 85299425Smmvoid 86299425Smmbsdcat_print_error(void) 87299425Smm{ 88299425Smm lafe_warnc(0, "%s: %s", 89299425Smm bsdcat_current_path, archive_error_string(a)); 90299425Smm exit_status = 1; 91299425Smm} 92299425Smm 93299425Smmvoid 94299529Smmbsdcat_read_to_stdout(const char* filename) 95299425Smm{ 96299425Smm int r; 97299425Smm 98299425Smm if (archive_read_open_filename(a, filename, BYTES_PER_BLOCK) 99299425Smm != ARCHIVE_OK) 100299425Smm bsdcat_print_error(); 101299425Smm else if (r = archive_read_next_header(a, &ae), 102299425Smm r != ARCHIVE_OK && r != ARCHIVE_EOF) 103299425Smm bsdcat_print_error(); 104299425Smm else if (r == ARCHIVE_EOF) 105299425Smm /* for empty payloads don't try and read data */ 106299425Smm ; 107299425Smm else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK) 108299425Smm bsdcat_print_error(); 109328827Smm if (archive_read_close(a) != ARCHIVE_OK) 110299425Smm bsdcat_print_error(); 111328827Smm archive_read_free(a); 112328827Smm a = NULL; 113299425Smm} 114299425Smm 115299425Smmint 116299425Smmmain(int argc, char **argv) 117299425Smm{ 118299425Smm struct bsdcat *bsdcat, bsdcat_storage; 119299425Smm int c; 120299425Smm 121299425Smm bsdcat = &bsdcat_storage; 122299425Smm memset(bsdcat, 0, sizeof(*bsdcat)); 123299425Smm 124299425Smm lafe_setprogname(*argv, "bsdcat"); 125299425Smm 126299425Smm bsdcat->argv = argv; 127299425Smm bsdcat->argc = argc; 128299425Smm 129299425Smm while ((c = bsdcat_getopt(bsdcat)) != -1) { 130299425Smm switch (c) { 131299425Smm case 'h': 132299425Smm usage(stdout, 0); 133299425Smm break; 134299425Smm case OPTION_VERSION: 135299425Smm version(); 136299425Smm break; 137299425Smm default: 138299425Smm usage(stderr, 1); 139299425Smm } 140299425Smm } 141299425Smm 142299425Smm bsdcat_next(); 143299425Smm if (*bsdcat->argv == NULL) { 144299425Smm bsdcat_current_path = "<stdin>"; 145299425Smm bsdcat_read_to_stdout(NULL); 146328827Smm } else { 147299425Smm while (*bsdcat->argv) { 148299425Smm bsdcat_current_path = *bsdcat->argv++; 149299425Smm bsdcat_read_to_stdout(bsdcat_current_path); 150299425Smm bsdcat_next(); 151299425Smm } 152328827Smm archive_read_free(a); /* Help valgrind & friends */ 153328827Smm } 154299425Smm 155299425Smm exit(exit_status); 156299425Smm} 157