summaryrefslogtreecommitdiff
path: root/minigzip.c
diff options
context:
space:
mode:
Diffstat (limited to 'minigzip.c')
-rw-r--r--minigzip.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/minigzip.c b/minigzip.c
new file mode 100644
index 0000000..688b3a1
--- /dev/null
+++ b/minigzip.c
@@ -0,0 +1,210 @@
1/* minigzip.c -- simulate gzip using the zlib compression library
2 * Copyright (C) 1995 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/*
7 * minigzip is a minimal implementation of the gzip utility. This is
8 * only an example of using zlib and isn't meant to replace the
9 * full-featured gzip. No attempt is made to deal with file systems
10 * limiting names to 14 or 8+3 characters, etc... Error checking is
11 * very limited. So use minigzip only for testing; use gzip for the
12 * real thing. On MSDOS, use only on file names without extension
13 * or in pipe mode.
14 */
15
16/* $Id: minigzip.c,v 1.1 1995/04/14 13:35:59 jloup Exp $ */
17
18#include <stdio.h>
19#include "zlib.h"
20
21#ifdef MSDOS
22# include <fcntl.h>
23# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
24#else
25# define SET_BINARY_MODE(file)
26#endif
27
28#define BUFLEN 4096
29#define MAX_NAME_LEN 1024
30
31#define local static
32/* For MSDOS and other systems with limitation on stack size. For Unix,
33 #define local
34 works also.
35 */
36
37char *prog;
38
39/* ===========================================================================
40 * Display error message and exit
41 */
42void error(msg)
43 char *msg;
44{
45 fprintf(stderr, "%s: %s\n", prog, msg);
46 exit(1);
47}
48
49/* ===========================================================================
50 * Compress input to output then close both files.
51 */
52void gz_compress(in, out)
53 FILE *in;
54 gzFile out;
55{
56 local char buf[BUFLEN];
57 int len;
58 int err;
59
60 for (;;) {
61 len = fread(buf, 1, sizeof(buf), in);
62 if (ferror(in)) {
63 perror("fread");
64 exit(1);
65 }
66 if (len == 0) break;
67
68 if (gzwrite(out, buf, len) != len) error(gzerror(out, &err));
69 }
70 fclose(in);
71 if (gzclose(out) != Z_OK) error("failed gzclose");
72}
73
74/* ===========================================================================
75 * Uncompress input to output then close both files.
76 */
77void gz_uncompress(in, out)
78 gzFile in;
79 FILE *out;
80{
81 local char buf[BUFLEN];
82 int len;
83 int err;
84
85 for (;;) {
86 len = gzread(in, buf, sizeof(buf));
87 if (len < 0) error (gzerror(in, &err));
88 if (len == 0) break;
89
90 if (fwrite(buf, 1, len, out) != len) error("failed fwrite");
91 }
92 if (fclose(out)) error("failed fclose");
93
94 if (gzclose(in) != Z_OK) error("failed gzclose");
95}
96
97
98/* ===========================================================================
99 * Compress the given file: create a corresponding .gz file and remove the
100 * original.
101 */
102void file_compress(file)
103 char *file;
104{
105 local char outfile[MAX_NAME_LEN];
106 FILE *in;
107 gzFile out;
108
109 strcpy(outfile, file);
110 strcat(outfile, ".gz");
111
112 in = fopen(file, "rb");
113 if (in == NULL) {
114 perror(file);
115 exit(1);
116 }
117 out = gzopen(outfile, "wb");
118 if (out == NULL) {
119 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
120 exit(1);
121 }
122 gz_compress(in, out);
123
124 unlink(file);
125}
126
127
128/* ===========================================================================
129 * Uncompress the given file and remove the original.
130 */
131void file_uncompress(file)
132 char *file;
133{
134 local char buf[MAX_NAME_LEN];
135 char *infile, *outfile;
136 FILE *out;
137 gzFile in;
138 int len = strlen(file);
139
140 strcpy(buf, file);
141
142 if (len > 3 && strcmp(file+len-3, ".gz") == 0) {
143 infile = file;
144 outfile = buf;
145 outfile[len-3] = '\0';
146 } else {
147 outfile = file;
148 infile = buf;
149 strcat(infile, ".gz");
150 }
151 in = gzopen(infile, "rb");
152 if (in == NULL) {
153 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
154 exit(1);
155 }
156 out = fopen(outfile, "wb");
157 if (out == NULL) {
158 perror(file);
159 exit(1);
160 }
161
162 gz_uncompress(in, out);
163
164 unlink(infile);
165}
166
167
168/* ===========================================================================
169 * Usage: minigzip [-d] [files...]
170 */
171
172void main(argc, argv)
173 int argc;
174 char *argv[];
175{
176 int uncompr = 0;
177 gzFile file;
178
179 prog = argv[0];
180 argc--, argv++;
181
182 if (argc > 0) {
183 uncompr = (strcmp(*argv, "-d") == 0);
184 if (uncompr) {
185 argc--, argv++;
186 }
187 }
188 if (argc == 0) {
189 SET_BINARY_MODE(stdin);
190 SET_BINARY_MODE(stdout);
191 if (uncompr) {
192 file = gzdopen(fileno(stdin), "rb");
193 if (file == NULL) error("can't gzdopen stdin");
194 gz_uncompress(file, stdout);
195 } else {
196 file = gzdopen(fileno(stdout), "wb");
197 if (file == NULL) error("can't gzdopen stdout");
198 gz_compress(stdin, file);
199 }
200 } else {
201 do {
202 if (uncompr) {
203 file_uncompress(*argv);
204 } else {
205 file_compress(*argv);
206 }
207 } while (argv++, --argc);
208 }
209 exit(0);
210}