00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <assert.h>
00018 #include "zlib.h"
00019
00020 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
00021 # include <fcntl.h>
00022 # include <io.h>
00023 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
00024 #else
00025 # define SET_BINARY_MODE(file)
00026 #endif
00027
00028 #define CHUNK 16384
00029
00030
00031
00032
00033
00034
00035
00036 int def(FILE *source, FILE *dest, int level)
00037 {
00038 int ret, flush;
00039 unsigned have;
00040 z_stream strm;
00041 unsigned char in[CHUNK];
00042 unsigned char out[CHUNK];
00043
00044
00045 strm.zalloc = Z_NULL;
00046 strm.zfree = Z_NULL;
00047 strm.opaque = Z_NULL;
00048 ret = deflateInit(&strm, level);
00049 if (ret != Z_OK)
00050 return ret;
00051
00052
00053 do {
00054 strm.avail_in = fread(in, 1, CHUNK, source);
00055 if (ferror(source)) {
00056 (void)deflateEnd(&strm);
00057 return Z_ERRNO;
00058 }
00059 flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
00060 strm.next_in = in;
00061
00062
00063
00064 do {
00065 strm.avail_out = CHUNK;
00066 strm.next_out = out;
00067 ret = deflate(&strm, flush);
00068 assert(ret != Z_STREAM_ERROR);
00069 have = CHUNK - strm.avail_out;
00070 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
00071 (void)deflateEnd(&strm);
00072 return Z_ERRNO;
00073 }
00074 } while (strm.avail_out == 0);
00075 assert(strm.avail_in == 0);
00076
00077
00078 } while (flush != Z_FINISH);
00079 assert(ret == Z_STREAM_END);
00080
00081
00082 (void)deflateEnd(&strm);
00083 return Z_OK;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 int inf(FILE *source, FILE *dest)
00093 {
00094 int ret;
00095 unsigned have;
00096 z_stream strm;
00097 unsigned char in[CHUNK];
00098 unsigned char out[CHUNK];
00099
00100
00101 strm.zalloc = Z_NULL;
00102 strm.zfree = Z_NULL;
00103 strm.opaque = Z_NULL;
00104 strm.avail_in = 0;
00105 strm.next_in = Z_NULL;
00106 ret = inflateInit(&strm);
00107 if (ret != Z_OK)
00108 return ret;
00109
00110
00111 do {
00112 strm.avail_in = fread(in, 1, CHUNK, source);
00113 if (ferror(source)) {
00114 (void)inflateEnd(&strm);
00115 return Z_ERRNO;
00116 }
00117 if (strm.avail_in == 0)
00118 break;
00119 strm.next_in = in;
00120
00121
00122 do {
00123 strm.avail_out = CHUNK;
00124 strm.next_out = out;
00125 ret = inflate(&strm, Z_NO_FLUSH);
00126 assert(ret != Z_STREAM_ERROR);
00127 switch (ret) {
00128 case Z_NEED_DICT:
00129 ret = Z_DATA_ERROR;
00130 case Z_DATA_ERROR:
00131 case Z_MEM_ERROR:
00132 (void)inflateEnd(&strm);
00133 return ret;
00134 }
00135 have = CHUNK - strm.avail_out;
00136 if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
00137 (void)inflateEnd(&strm);
00138 return Z_ERRNO;
00139 }
00140 } while (strm.avail_out == 0);
00141
00142
00143 } while (ret != Z_STREAM_END);
00144
00145
00146 (void)inflateEnd(&strm);
00147 return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
00148 }
00149
00150
00151 void zerr(int ret)
00152 {
00153 fputs("zpipe: ", stderr);
00154 switch (ret) {
00155 case Z_ERRNO:
00156 if (ferror(stdin))
00157 fputs("error reading stdin\n", stderr);
00158 if (ferror(stdout))
00159 fputs("error writing stdout\n", stderr);
00160 break;
00161 case Z_STREAM_ERROR:
00162 fputs("invalid compression level\n", stderr);
00163 break;
00164 case Z_DATA_ERROR:
00165 fputs("invalid or incomplete deflate data\n", stderr);
00166 break;
00167 case Z_MEM_ERROR:
00168 fputs("out of memory\n", stderr);
00169 break;
00170 case Z_VERSION_ERROR:
00171 fputs("zlib version mismatch!\n", stderr);
00172 }
00173 }
00174
00175
00176 int main(int argc, char **argv)
00177 {
00178 int ret;
00179
00180
00181 SET_BINARY_MODE(stdin);
00182 SET_BINARY_MODE(stdout);
00183
00184
00185 if (argc == 1) {
00186 ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
00187 if (ret != Z_OK)
00188 zerr(ret);
00189 return ret;
00190 }
00191
00192
00193 else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
00194 ret = inf(stdin, stdout);
00195 if (ret != Z_OK)
00196 zerr(ret);
00197 return ret;
00198 }
00199
00200
00201 else {
00202 fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
00203 return 1;
00204 }
00205 }