source: branches/libc-0.6/src/gcc/zlib/minigzip.c

Last change on this file was 1477, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1476,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.3
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 7.7 KB
Line 
1/* minigzip.c -- simulate gzip using the zlib compression library
2 * Copyright (C) 1995-2002 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.1.2 2002/03/11 21:53:26 tromey Exp $ */
17
18#include <stdio.h>
19#include "zlib.h"
20
21#ifdef STDC
22# include <string.h>
23# include <stdlib.h>
24#else
25 extern void exit OF((int));
26#endif
27
28#ifdef USE_MMAP
29# include <sys/types.h>
30# include <sys/mman.h>
31# include <sys/stat.h>
32#endif
33
34#if defined(MSDOS) || defined(OS2) || defined(WIN32)
35# include <fcntl.h>
36# include <io.h>
37# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
38#else
39# define SET_BINARY_MODE(file)
40#endif
41
42#ifdef VMS
43# define unlink delete
44# define GZ_SUFFIX "-gz"
45#endif
46#ifdef RISCOS
47# define unlink remove
48# define GZ_SUFFIX "-gz"
49# define fileno(file) file->__file
50#endif
51#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
52# include <unix.h> /* for fileno */
53#endif
54
55#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
56 extern int unlink OF((const char *));
57#endif
58
59#ifndef GZ_SUFFIX
60# define GZ_SUFFIX ".gz"
61#endif
62#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
63
64#define BUFLEN 16384
65#define MAX_NAME_LEN 1024
66
67#ifdef MAXSEG_64K
68# define local static
69 /* Needed for systems with limitation on stack size. */
70#else
71# define local
72#endif
73
74char *prog;
75
76void error OF((const char *msg));
77void gz_compress OF((FILE *in, gzFile out));
78#ifdef USE_MMAP
79int gz_compress_mmap OF((FILE *in, gzFile out));
80#endif
81void gz_uncompress OF((gzFile in, FILE *out));
82void file_compress OF((char *file, char *mode));
83void file_uncompress OF((char *file));
84int main OF((int argc, char *argv[]));
85
86/* ===========================================================================
87 * Display error message and exit
88 */
89void error(msg)
90 const char *msg;
91{
92 fprintf(stderr, "%s: %s\n", prog, msg);
93 exit(1);
94}
95
96/* ===========================================================================
97 * Compress input to output then close both files.
98 */
99
100void gz_compress(in, out)
101 FILE *in;
102 gzFile out;
103{
104 local char buf[BUFLEN];
105 int len;
106 int err;
107
108#ifdef USE_MMAP
109 /* Try first compressing with mmap. If mmap fails (minigzip used in a
110 * pipe), use the normal fread loop.
111 */
112 if (gz_compress_mmap(in, out) == Z_OK) return;
113#endif
114 for (;;) {
115 len = fread(buf, 1, sizeof(buf), in);
116 if (ferror(in)) {
117 perror("fread");
118 exit(1);
119 }
120 if (len == 0) break;
121
122 if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
123 }
124 fclose(in);
125 if (gzclose(out) != Z_OK) error("failed gzclose");
126}
127
128#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
129
130/* Try compressing the input file at once using mmap. Return Z_OK if
131 * if success, Z_ERRNO otherwise.
132 */
133int gz_compress_mmap(in, out)
134 FILE *in;
135 gzFile out;
136{
137 int len;
138 int err;
139 int ifd = fileno(in);
140 caddr_t buf; /* mmap'ed buffer for the entire input file */
141 off_t buf_len; /* length of the input file */
142 struct stat sb;
143
144 /* Determine the size of the file, needed for mmap: */
145 if (fstat(ifd, &sb) < 0) return Z_ERRNO;
146 buf_len = sb.st_size;
147 if (buf_len <= 0) return Z_ERRNO;
148
149 /* Now do the actual mmap: */
150 buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
151 if (buf == (caddr_t)(-1)) return Z_ERRNO;
152
153 /* Compress the whole file at once: */
154 len = gzwrite(out, (char *)buf, (unsigned)buf_len);
155
156 if (len != (int)buf_len) error(gzerror(out, &err));
157
158 munmap(buf, buf_len);
159 fclose(in);
160 if (gzclose(out) != Z_OK) error("failed gzclose");
161 return Z_OK;
162}
163#endif /* USE_MMAP */
164
165/* ===========================================================================
166 * Uncompress input to output then close both files.
167 */
168void gz_uncompress(in, out)
169 gzFile in;
170 FILE *out;
171{
172 local char buf[BUFLEN];
173 int len;
174 int err;
175
176 for (;;) {
177 len = gzread(in, buf, sizeof(buf));
178 if (len < 0) error (gzerror(in, &err));
179 if (len == 0) break;
180
181 if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
182 error("failed fwrite");
183 }
184 }
185 if (fclose(out)) error("failed fclose");
186
187 if (gzclose(in) != Z_OK) error("failed gzclose");
188}
189
190
191/* ===========================================================================
192 * Compress the given file: create a corresponding .gz file and remove the
193 * original.
194 */
195void file_compress(file, mode)
196 char *file;
197 char *mode;
198{
199 local char outfile[MAX_NAME_LEN];
200 FILE *in;
201 gzFile out;
202
203 strcpy(outfile, file);
204 strcat(outfile, GZ_SUFFIX);
205
206 in = fopen(file, "rb");
207 if (in == NULL) {
208 perror(file);
209 exit(1);
210 }
211 out = gzopen(outfile, mode);
212 if (out == NULL) {
213 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
214 exit(1);
215 }
216 gz_compress(in, out);
217
218 unlink(file);
219}
220
221
222/* ===========================================================================
223 * Uncompress the given file and remove the original.
224 */
225void file_uncompress(file)
226 char *file;
227{
228 local char buf[MAX_NAME_LEN];
229 char *infile, *outfile;
230 FILE *out;
231 gzFile in;
232 int len = strlen(file);
233
234 strcpy(buf, file);
235
236 if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
237 infile = file;
238 outfile = buf;
239 outfile[len-3] = '\0';
240 } else {
241 outfile = file;
242 infile = buf;
243 strcat(infile, GZ_SUFFIX);
244 }
245 in = gzopen(infile, "rb");
246 if (in == NULL) {
247 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
248 exit(1);
249 }
250 out = fopen(outfile, "wb");
251 if (out == NULL) {
252 perror(file);
253 exit(1);
254 }
255
256 gz_uncompress(in, out);
257
258 unlink(infile);
259}
260
261
262/* ===========================================================================
263 * Usage: minigzip [-d] [-f] [-h] [-1 to -9] [files...]
264 * -d : decompress
265 * -f : compress with Z_FILTERED
266 * -h : compress with Z_HUFFMAN_ONLY
267 * -1 to -9 : compression level
268 */
269
270int main(argc, argv)
271 int argc;
272 char *argv[];
273{
274 int uncompr = 0;
275 gzFile file;
276 char outmode[20];
277
278 strcpy(outmode, "wb6 ");
279
280 prog = argv[0];
281 argc--, argv++;
282
283 while (argc > 0) {
284 if (strcmp(*argv, "-d") == 0)
285 uncompr = 1;
286 else if (strcmp(*argv, "-f") == 0)
287 outmode[3] = 'f';
288 else if (strcmp(*argv, "-h") == 0)
289 outmode[3] = 'h';
290 else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
291 (*argv)[2] == 0)
292 outmode[2] = (*argv)[1];
293 else
294 break;
295 argc--, argv++;
296 }
297 if (argc == 0) {
298 SET_BINARY_MODE(stdin);
299 SET_BINARY_MODE(stdout);
300 if (uncompr) {
301 file = gzdopen(fileno(stdin), "rb");
302 if (file == NULL) error("can't gzdopen stdin");
303 gz_uncompress(file, stdout);
304 } else {
305 file = gzdopen(fileno(stdout), outmode);
306 if (file == NULL) error("can't gzdopen stdout");
307 gz_compress(stdin, file);
308 }
309 } else {
310 do {
311 if (uncompr) {
312 file_uncompress(*argv);
313 } else {
314 file_compress(*argv, outmode);
315 }
316 } while (argv++, --argc);
317 }
318 exit(0);
319 return 0; /* to avoid warning */
320}
Note: See TracBrowser for help on using the repository browser.