00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <stdio.h>
00019 #include "zlib.h"
00020
00021 #ifdef STDC
00022 # include <string.h>
00023 # include <stdlib.h>
00024 #else
00025 extern void exit OF((int));
00026 #endif
00027
00028 #ifdef USE_MMAP
00029 # include <sys/types.h>
00030 # include <sys/mman.h>
00031 # include <sys/stat.h>
00032 #endif
00033
00034 #if defined(MSDOS) || defined(OS2) || defined(WIN32)
00035 # include <fcntl.h>
00036 # include <io.h>
00037 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
00038 #else
00039 # define SET_BINARY_MODE(file)
00040 #endif
00041
00042 #ifdef VMS
00043 # define unlink delete
00044 # define GZ_SUFFIX "-gz"
00045 #endif
00046 #ifdef RISCOS
00047 # define unlink remove
00048 # define GZ_SUFFIX "-gz"
00049 # define fileno(file) file->__file
00050 #endif
00051 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
00052 # include <unix.h>
00053 #endif
00054
00055 #ifndef WIN32
00056 extern int unlink OF((const char *));
00057 #endif
00058
00059 #ifndef GZ_SUFFIX
00060 # define GZ_SUFFIX ".gz"
00061 #endif
00062 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
00063
00064 #define BUFLEN 16384
00065 #define MAX_NAME_LEN 1024
00066
00067 #ifdef MAXSEG_64K
00068 # define local static
00069
00070 #else
00071 # define local
00072 #endif
00073
00074 char *prog;
00075
00076 void error OF((const char *msg));
00077 void gz_compress OF((FILE *in, gzFile out));
00078 #ifdef USE_MMAP
00079 int gz_compress_mmap OF((FILE *in, gzFile out));
00080 #endif
00081 void gz_uncompress OF((gzFile in, FILE *out));
00082 void file_compress OF((char *file, char *mode));
00083 void file_uncompress OF((char *file));
00084 int main OF((int argc, char *argv[]));
00085
00086
00087
00088
00089 void error(msg)
00090 const char *msg;
00091 {
00092 fprintf(stderr, "%s: %s\n", prog, msg);
00093 exit(1);
00094 }
00095
00096
00097
00098
00099
00100 void gz_compress(in, out)
00101 FILE *in;
00102 gzFile out;
00103 {
00104 local char buf[BUFLEN];
00105 int len;
00106 int err;
00107
00108 #ifdef USE_MMAP
00109
00110
00111
00112 if (gz_compress_mmap(in, out) == Z_OK) return;
00113 #endif
00114 for (;;) {
00115 len = fread(buf, 1, sizeof(buf), in);
00116 if (ferror(in)) {
00117 perror("fread");
00118 exit(1);
00119 }
00120 if (len == 0) break;
00121
00122 if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
00123 }
00124 fclose(in);
00125 if (gzclose(out) != Z_OK) error("failed gzclose");
00126 }
00127
00128 #ifdef USE_MMAP
00129
00130
00131
00132
00133 int gz_compress_mmap(in, out)
00134 FILE *in;
00135 gzFile out;
00136 {
00137 int len;
00138 int err;
00139 int ifd = fileno(in);
00140 caddr_t buf;
00141 off_t buf_len;
00142 struct stat sb;
00143
00144
00145 if (fstat(ifd, &sb) < 0) return Z_ERRNO;
00146 buf_len = sb.st_size;
00147 if (buf_len <= 0) return Z_ERRNO;
00148
00149
00150 buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
00151 if (buf == (caddr_t)(-1)) return Z_ERRNO;
00152
00153
00154 len = gzwrite(out, (char *)buf, (unsigned)buf_len);
00155
00156 if (len != (int)buf_len) error(gzerror(out, &err));
00157
00158 munmap(buf, buf_len);
00159 fclose(in);
00160 if (gzclose(out) != Z_OK) error("failed gzclose");
00161 return Z_OK;
00162 }
00163 #endif
00164
00165
00166
00167
00168 void gz_uncompress(in, out)
00169 gzFile in;
00170 FILE *out;
00171 {
00172 local char buf[BUFLEN];
00173 int len;
00174 int err;
00175
00176 for (;;) {
00177 len = gzread(in, buf, sizeof(buf));
00178 if (len < 0) error (gzerror(in, &err));
00179 if (len == 0) break;
00180
00181 if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
00182 error("failed fwrite");
00183 }
00184 }
00185 if (fclose(out)) error("failed fclose");
00186
00187 if (gzclose(in) != Z_OK) error("failed gzclose");
00188 }
00189
00190
00191
00192
00193
00194
00195 void file_compress(file, mode)
00196 char *file;
00197 char *mode;
00198 {
00199 local char outfile[MAX_NAME_LEN];
00200 FILE *in;
00201 gzFile out;
00202
00203 strcpy(outfile, file);
00204 strcat(outfile, GZ_SUFFIX);
00205
00206 in = fopen(file, "rb");
00207 if (in == NULL) {
00208 perror(file);
00209 exit(1);
00210 }
00211 out = gzopen(outfile, mode);
00212 if (out == NULL) {
00213 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
00214 exit(1);
00215 }
00216 gz_compress(in, out);
00217
00218 unlink(file);
00219 }
00220
00221
00222
00223
00224
00225 void file_uncompress(file)
00226 char *file;
00227 {
00228 local char buf[MAX_NAME_LEN];
00229 char *infile, *outfile;
00230 FILE *out;
00231 gzFile in;
00232 int len = strlen(file);
00233
00234 strcpy(buf, file);
00235
00236 if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
00237 infile = file;
00238 outfile = buf;
00239 outfile[len-3] = '\0';
00240 } else {
00241 outfile = file;
00242 infile = buf;
00243 strcat(infile, GZ_SUFFIX);
00244 }
00245 in = gzopen(infile, "rb");
00246 if (in == NULL) {
00247 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
00248 exit(1);
00249 }
00250 out = fopen(outfile, "wb");
00251 if (out == NULL) {
00252 perror(file);
00253 exit(1);
00254 }
00255
00256 gz_uncompress(in, out);
00257
00258 unlink(infile);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 int main(argc, argv)
00271 int argc;
00272 char *argv[];
00273 {
00274 int uncompr = 0;
00275 gzFile file;
00276 char outmode[20];
00277
00278 strcpy(outmode, "wb6 ");
00279
00280 prog = argv[0];
00281 argc--, argv++;
00282
00283 while (argc > 0) {
00284 if (strcmp(*argv, "-d") == 0)
00285 uncompr = 1;
00286 else if (strcmp(*argv, "-f") == 0)
00287 outmode[3] = 'f';
00288 else if (strcmp(*argv, "-h") == 0)
00289 outmode[3] = 'h';
00290 else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
00291 (*argv)[2] == 0)
00292 outmode[2] = (*argv)[1];
00293 else
00294 break;
00295 argc--, argv++;
00296 }
00297 if (argc == 0) {
00298 SET_BINARY_MODE(stdin);
00299 SET_BINARY_MODE(stdout);
00300 if (uncompr) {
00301 file = gzdopen(fileno(stdin), "rb");
00302 if (file == NULL) error("can't gzdopen stdin");
00303 gz_uncompress(file, stdout);
00304 } else {
00305 file = gzdopen(fileno(stdout), outmode);
00306 if (file == NULL) error("can't gzdopen stdout");
00307 gz_compress(stdin, file);
00308 }
00309 } else {
00310 do {
00311 if (uncompr) {
00312 file_uncompress(*argv);
00313 } else {
00314 file_compress(*argv, outmode);
00315 }
00316 } while (argv++, --argc);
00317 }
00318 exit(0);
00319 return 0;
00320 }