diff options
Diffstat (limited to 'minigzip.c')
-rw-r--r-- | minigzip.c | 210 |
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 | |||
37 | char *prog; | ||
38 | |||
39 | /* =========================================================================== | ||
40 | * Display error message and exit | ||
41 | */ | ||
42 | void 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 | */ | ||
52 | void 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 | */ | ||
77 | void 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 | */ | ||
102 | void 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 | */ | ||
131 | void 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 | |||
172 | void 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 | } | ||