xref: /netbsd/distrib/utils/zcat/zcat.c (revision bc4ff4ca)
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