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