1 /* $NetBSD: zcat.c,v 1.5 2017/01/12 01:58:03 christos Exp $ */
2
3 /* mini zcat.c -- a minimal zcat using the zlib compression library
4 * Copyright (C) 1995-1996 Jean-loup Gailly.
5 * For conditions of distribution and use, see copyright notice in zlib.h
6 */
7
8 /*
9 * Credits, History:
10 * This program is a reduced version of the minigzip.c
11 * program originally written by Jean-loup Gailly.
12 * This reduction is the work of Gordon Ross.
13 */
14
15 #include <stdio.h>
16 #include <stdarg.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21
22 #include "zlib.h"
23
24 #define BUFLEN 4096
25
26 char *prog;
27
28 static void error(const char *, ...) __printflike(1, 2);
29 static void gz_uncompress(gzFile, int);
30
31 /* ===========================================================================
32 * Display error message and exit
33 */
34 static void
error(const char * fmt,...)35 error(const char *fmt, ...)
36 {
37 char buf[1024];
38 va_list ap;
39 int l;
40
41 l = snprintf_ss(buf, sizeof(buf), "%s: ", prog);
42 write(STDERR_FILENO, buf, l);
43 va_start(ap, fmt);
44 l = vsnprintf_ss(buf, sizeof(buf), fmt, ap);
45 va_end(ap);
46 write(STDERR_FILENO, buf, l);
47 _exit(EXIT_SUCCESS);
48 }
49
50 /* ===========================================================================
51 * Uncompress input to output then close both files.
52 */
53 static void
gz_uncompress(gzFile in,int out)54 gz_uncompress(gzFile in, int out)
55 {
56 char buf[BUFLEN];
57 int len;
58 int err;
59
60 for (;;) {
61 len = gzread(in, buf, sizeof(buf));
62 if (len < 0)
63 error ("%s", gzerror(in, &err));
64 if (len == 0)
65 break;
66
67 if ((int)write(out, buf, (size_t)len) != len) {
68 error("failed fwrite");
69 }
70 }
71 if (close(out))
72 error("failed fclose");
73
74 if (gzclose(in) != Z_OK)
75 error("failed gzclose");
76 }
77
78
79 /* ===========================================================================
80 * Usage: zcat [files...]
81 */
82
83 int
main(int argc,char * argv[])84 main(int argc, char *argv[])
85 {
86 gzFile zfp;
87
88 /* save program name and skip */
89 prog = argv[0];
90 argc--, argv++;
91
92 /* ignore any switches */
93 while (*argv && (**argv == '-')) {
94 argc--, argv++;
95 }
96
97 if (argc == 0) {
98 zfp = gzdopen(STDIN_FILENO, "rb");
99 if (zfp == NULL)
100 error("can't gzdopen stdin");
101 gz_uncompress(zfp, STDOUT_FILENO);
102 return 0;
103 }
104
105 do {
106 /* file_uncompress(*argv); */
107 zfp = gzopen(*argv, "rb");
108 if (zfp == NULL) {
109 error("can't gzopen `%s'", *argv);
110 _exit(EXIT_FAILURE);
111 }
112 gz_uncompress(zfp, STDOUT_FILENO);
113 } while (argv++, --argc);
114 return 0; /* to avoid warning */
115 }
116
117
118 /*
119 * XXX: hacks to keep gzio.c from pulling in deflate stuff
120 */
121
deflateInit2_(z_streamp strm,int level,int method,int windowBits,int memLevel,int strategy,const char * version,int stream_size)122 int deflateInit2_(z_streamp strm, int level, int method,
123 int windowBits, int memLevel, int strategy,
124 const char *version, int stream_size)
125 {
126
127 return -1;
128 }
129
deflate(z_streamp strm,int flush)130 int deflate(z_streamp strm, int flush)
131 {
132
133 return -1;
134 }
135
deflateEnd(z_streamp strm)136 int deflateEnd(z_streamp strm)
137 {
138
139 return -1;
140 }
141
deflateParams(z_streamp strm,int level,int strategy)142 int deflateParams(z_streamp strm, int level, int strategy)
143 {
144
145 return Z_STREAM_ERROR;
146 }
147