00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "zlib.h"
00019 #include <stdio.h>
00020
00021 #ifdef STDC
00022 # include <string.h>
00023 # include <stdlib.h>
00024 #endif
00025
00026 #ifdef USE_MMAP
00027 # include <sys/types.h>
00028 # include <sys/mman.h>
00029 # include <sys/stat.h>
00030 #endif
00031
00032 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
00033 # include <fcntl.h>
00034 # include <io.h>
00035 # ifdef UNDER_CE
00036 # include <stdlib.h>
00037 # endif
00038 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
00039 #else
00040 # define SET_BINARY_MODE(file)
00041 #endif
00042
00043 #ifdef VMS
00044 # define unlink delete
00045 # define GZ_SUFFIX "-gz"
00046 #endif
00047 #ifdef RISCOS
00048 # define unlink remove
00049 # define GZ_SUFFIX "-gz"
00050 # define fileno(file) file->__file
00051 #endif
00052 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
00053 # include <unix.h>
00054 #endif
00055
00056 #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
00057 #ifndef WIN32
00058 extern int unlink OF((const char *));
00059 #endif
00060 #endif
00061
00062 #if defined(UNDER_CE)
00063 # include <windows.h>
00064 # define perror(s) pwinerror(s)
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static char *strwinerror (error)
00077 DWORD error;
00078 {
00079 static char buf[1024];
00080
00081 wchar_t *msgbuf;
00082 DWORD lasterr = GetLastError();
00083 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
00084 | FORMAT_MESSAGE_ALLOCATE_BUFFER,
00085 NULL,
00086 error,
00087 0,
00088 (LPVOID)&msgbuf,
00089 0,
00090 NULL);
00091 if (chars != 0) {
00092
00093 if (chars >= 2
00094 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
00095 chars -= 2;
00096 msgbuf[chars] = 0;
00097 }
00098
00099 if (chars > sizeof (buf) - 1) {
00100 chars = sizeof (buf) - 1;
00101 msgbuf[chars] = 0;
00102 }
00103
00104 wcstombs(buf, msgbuf, chars + 1);
00105 LocalFree(msgbuf);
00106 }
00107 else {
00108 sprintf(buf, "unknown win32 error (%ld)", error);
00109 }
00110
00111 SetLastError(lasterr);
00112 return buf;
00113 }
00114
00115 static void pwinerror (s)
00116 const char *s;
00117 {
00118 if (s && *s)
00119 fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
00120 else
00121 fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
00122 }
00123
00124 #endif
00125
00126 #ifndef GZ_SUFFIX
00127 # define GZ_SUFFIX ".gz"
00128 #endif
00129 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
00130
00131 #define BUFLEN 16384
00132 #define MAX_NAME_LEN 1024
00133
00134 #ifdef MAXSEG_64K
00135 # define local static
00136
00137 #else
00138 # define local
00139 #endif
00140
00141 char *prog;
00142
00143 void error OF((const char *msg));
00144 void gz_compress OF((FILE *in, gzFile out));
00145 #ifdef USE_MMAP
00146 int gz_compress_mmap OF((FILE *in, gzFile out));
00147 #endif
00148 void gz_uncompress OF((gzFile in, FILE *out));
00149 void file_compress OF((char *file, char *mode));
00150 void file_uncompress OF((char *file));
00151 int main OF((int argc, char *argv[]));
00152
00153
00154
00155
00156 void error(msg)
00157 const char *msg;
00158 {
00159 fprintf(stderr, "%s: %s\n", prog, msg);
00160 exit(1);
00161 }
00162
00163
00164
00165
00166
00167 void gz_compress(in, out)
00168 FILE *in;
00169 gzFile out;
00170 {
00171 local char buf[BUFLEN];
00172 int len;
00173 int err;
00174
00175 #ifdef USE_MMAP
00176
00177
00178
00179 if (gz_compress_mmap(in, out) == Z_OK) return;
00180 #endif
00181 for (;;) {
00182 len = (int)fread(buf, 1, sizeof(buf), in);
00183 if (ferror(in)) {
00184 perror("fread");
00185 exit(1);
00186 }
00187 if (len == 0) break;
00188
00189 if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
00190 }
00191 fclose(in);
00192 if (gzclose(out) != Z_OK) error("failed gzclose");
00193 }
00194
00195 #ifdef USE_MMAP
00196
00197
00198
00199
00200 int gz_compress_mmap(in, out)
00201 FILE *in;
00202 gzFile out;
00203 {
00204 int len;
00205 int err;
00206 int ifd = fileno(in);
00207 caddr_t buf;
00208 off_t buf_len;
00209 struct stat sb;
00210
00211
00212 if (fstat(ifd, &sb) < 0) return Z_ERRNO;
00213 buf_len = sb.st_size;
00214 if (buf_len <= 0) return Z_ERRNO;
00215
00216
00217 buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
00218 if (buf == (caddr_t)(-1)) return Z_ERRNO;
00219
00220
00221 len = gzwrite(out, (char *)buf, (unsigned)buf_len);
00222
00223 if (len != (int)buf_len) error(gzerror(out, &err));
00224
00225 munmap(buf, buf_len);
00226 fclose(in);
00227 if (gzclose(out) != Z_OK) error("failed gzclose");
00228 return Z_OK;
00229 }
00230 #endif
00231
00232
00233
00234
00235 void gz_uncompress(in, out)
00236 gzFile in;
00237 FILE *out;
00238 {
00239 local char buf[BUFLEN];
00240 int len;
00241 int err;
00242
00243 for (;;) {
00244 len = gzread(in, buf, sizeof(buf));
00245 if (len < 0) error (gzerror(in, &err));
00246 if (len == 0) break;
00247
00248 if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
00249 error("failed fwrite");
00250 }
00251 }
00252 if (fclose(out)) error("failed fclose");
00253
00254 if (gzclose(in) != Z_OK) error("failed gzclose");
00255 }
00256
00257
00258
00259
00260
00261
00262 void file_compress(file, mode)
00263 char *file;
00264 char *mode;
00265 {
00266 local char outfile[MAX_NAME_LEN];
00267 FILE *in;
00268 gzFile out;
00269
00270 if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
00271 fprintf(stderr, "%s: filename too long\n", prog);
00272 exit(1);
00273 }
00274
00275 strcpy(outfile, file);
00276 strcat(outfile, GZ_SUFFIX);
00277
00278 in = fopen(file, "rb");
00279 if (in == NULL) {
00280 perror(file);
00281 exit(1);
00282 }
00283 out = gzopen(outfile, mode);
00284 if (out == NULL) {
00285 fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
00286 exit(1);
00287 }
00288 gz_compress(in, out);
00289
00290 unlink(file);
00291 }
00292
00293
00294
00295
00296
00297 void file_uncompress(file)
00298 char *file;
00299 {
00300 local char buf[MAX_NAME_LEN];
00301 char *infile, *outfile;
00302 FILE *out;
00303 gzFile in;
00304 size_t len = strlen(file);
00305
00306 if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
00307 fprintf(stderr, "%s: filename too long\n", prog);
00308 exit(1);
00309 }
00310
00311 strcpy(buf, file);
00312
00313 if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
00314 infile = file;
00315 outfile = buf;
00316 outfile[len-3] = '\0';
00317 } else {
00318 outfile = file;
00319 infile = buf;
00320 strcat(infile, GZ_SUFFIX);
00321 }
00322 in = gzopen(infile, "rb");
00323 if (in == NULL) {
00324 fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
00325 exit(1);
00326 }
00327 out = fopen(outfile, "wb");
00328 if (out == NULL) {
00329 perror(file);
00330 exit(1);
00331 }
00332
00333 gz_uncompress(in, out);
00334
00335 unlink(infile);
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 int main(argc, argv)
00350 int argc;
00351 char *argv[];
00352 {
00353 int copyout = 0;
00354 int uncompr = 0;
00355 gzFile file;
00356 char *bname, outmode[20];
00357
00358 strcpy(outmode, "wb6 ");
00359
00360 prog = argv[0];
00361 bname = strrchr(argv[0], '/');
00362 if (bname)
00363 bname++;
00364 else
00365 bname = argv[0];
00366 argc--, argv++;
00367
00368 if (!strcmp(bname, "gunzip"))
00369 uncompr = 1;
00370 else if (!strcmp(bname, "zcat"))
00371 copyout = uncompr = 1;
00372
00373 while (argc > 0) {
00374 if (strcmp(*argv, "-c") == 0)
00375 copyout = 1;
00376 else if (strcmp(*argv, "-d") == 0)
00377 uncompr = 1;
00378 else if (strcmp(*argv, "-f") == 0)
00379 outmode[3] = 'f';
00380 else if (strcmp(*argv, "-h") == 0)
00381 outmode[3] = 'h';
00382 else if (strcmp(*argv, "-r") == 0)
00383 outmode[3] = 'R';
00384 else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
00385 (*argv)[2] == 0)
00386 outmode[2] = (*argv)[1];
00387 else
00388 break;
00389 argc--, argv++;
00390 }
00391 if (outmode[3] == ' ')
00392 outmode[3] = 0;
00393 if (argc == 0) {
00394 SET_BINARY_MODE(stdin);
00395 SET_BINARY_MODE(stdout);
00396 if (uncompr) {
00397 file = gzdopen(fileno(stdin), "rb");
00398 if (file == NULL) error("can't gzdopen stdin");
00399 gz_uncompress(file, stdout);
00400 } else {
00401 file = gzdopen(fileno(stdout), outmode);
00402 if (file == NULL) error("can't gzdopen stdout");
00403 gz_compress(stdin, file);
00404 }
00405 } else {
00406 if (copyout) {
00407 SET_BINARY_MODE(stdout);
00408 }
00409 do {
00410 if (uncompr) {
00411 if (copyout) {
00412 file = gzopen(*argv, "rb");
00413 if (file == NULL)
00414 fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
00415 else
00416 gz_uncompress(file, stdout);
00417 } else {
00418 file_uncompress(*argv);
00419 }
00420 } else {
00421 if (copyout) {
00422 FILE * in = fopen(*argv, "rb");
00423
00424 if (in == NULL) {
00425 perror(*argv);
00426 } else {
00427 file = gzdopen(fileno(stdout), outmode);
00428 if (file == NULL) error("can't gzdopen stdout");
00429
00430 gz_compress(in, file);
00431 }
00432
00433 } else {
00434 file_compress(*argv, outmode);
00435 }
00436 }
00437 } while (argv++, --argc);
00438 }
00439 return 0;
00440 }