annotate zlib/gzio.c @ 11:9fda93e18de5

Testing CVS in xEmacs
author darius
date Sat, 06 Dec 1997 04:46:49 +0000
parents 1040ca591f2e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
1 /* gzio.c -- IO on .gz files
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
2 * Copyright (C) 1995 Jean-loup Gailly.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
3 * For conditions of distribution and use, see copyright notice in zlib.h
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
4 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
5
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
6 /* $Id: gzio.c,v 1.1.1.1 1997/12/06 04:37:17 darius Exp $ */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
7
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
8 #include <stdio.h>
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
9
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
10 #include "zutil.h"
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
11
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
12 struct internal_state {int dummy;}; /* for buggy compilers */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
13
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
14 #define Z_BUFSIZE 4096
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
15
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
16 #define ALLOC(size) malloc(size)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
17 #define TRYFREE(p) {if (p) free(p);}
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
18
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
19 #define GZ_MAGIC_1 0x1f
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
20 #define GZ_MAGIC_2 0x8b
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
21
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
22 /* gzip flag byte */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
23 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
24 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
25 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
26 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
27 #define COMMENT 0x10 /* bit 4 set: file comment present */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
28 #define RESERVED 0xE0 /* bits 5..7: reserved */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
29
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
30 #ifndef SEEK_CUR
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
31 # define SEEK_CUR 1
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
32 #endif
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
33
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
34 typedef struct gz_stream {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
35 z_stream stream;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
36 int z_err; /* error code for last stream operation */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
37 int z_eof; /* set if end of input file */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
38 FILE *file; /* .gz file */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
39 Byte *inbuf; /* input buffer */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
40 Byte *outbuf; /* output buffer */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
41 uLong crc; /* crc32 of uncompressed data */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
42 char *msg; /* error message */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
43 char *path; /* path name for debugging only */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
44 int transparent; /* 1 if input file is not a .gz file */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
45 char mode; /* 'w' or 'r' */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
46 } gz_stream;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
47
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
48
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
49 local int destroy OF((gz_stream *s));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
50 local gzFile gz_open OF((char *path, char *mode, int fd));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
51 local void putLong OF((FILE *file, uLong x));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
52 local uLong getLong OF((Bytef *buf));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
53
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
54 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
55 * Cleanup then free the given gz_stream. Return a zlib error code.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
56 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
57 local int destroy (s)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
58 gz_stream *s;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
59 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
60 int err = Z_OK;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
61
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
62 if (!s) return Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
63
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
64 TRYFREE(s->inbuf);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
65 TRYFREE(s->outbuf);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
66 TRYFREE(s->path);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
67 TRYFREE(s->msg);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
68
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
69 if (s->stream.state != NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
70 if (s->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
71 err = deflateEnd(&(s->stream));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
72 } else if (s->mode == 'r') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
73 err = inflateEnd(&(s->stream));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
74 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
75 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
76 if (s->file != NULL && fclose(s->file)) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
77 err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
78 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
79 if (s->z_err < 0) err = s->z_err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
80 TRYFREE(s);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
81 return err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
82 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
83
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
84 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
85 Opens a gzip (.gz) file for reading or writing. The mode parameter
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
86 is as in fopen ("rb" or "wb"). The file is given either by file descritor
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
87 or path name (if fd == -1).
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
88 gz_open return NULL if the file could not be opened or if there was
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
89 insufficient memory to allocate the (de)compression state; errno
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
90 can be checked to distinguish the two cases (if errno is zero, the
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
91 zlib error is Z_MEM_ERROR).
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
92 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
93 local gzFile gz_open (path, mode, fd)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
94 char *path;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
95 char *mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
96 int fd;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
97 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
98 int err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
99 int level = Z_DEFAULT_COMPRESSION; /* compression level */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
100 char *p = mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
101 gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
102
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
103 if (!s) return Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
104
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
105 s->stream.zalloc = (alloc_func)0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
106 s->stream.zfree = (free_func)0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
107 s->stream.next_in = s->inbuf = Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
108 s->stream.next_out = s->outbuf = Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
109 s->stream.avail_in = s->stream.avail_out = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
110 s->file = NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
111 s->z_err = Z_OK;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
112 s->z_eof = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
113 s->crc = crc32(0L, Z_NULL, 0);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
114 s->msg = NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
115 s->transparent = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
116
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
117 s->path = (char*)ALLOC(strlen(path)+1);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
118 if (s->path == NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
119 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
120 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
121 strcpy(s->path, path); /* do this early for debugging */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
122
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
123 s->mode = '\0';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
124 do {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
125 if (*p == 'r') s->mode = 'r';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
126 if (*p == 'w') s->mode = 'w';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
127 if (*p >= '1' && *p <= '9') level = *p - '0';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
128 } while (*p++);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
129 if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
130
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
131 if (s->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
132 err = deflateInit2(&(s->stream), level,
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
133 DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
134 /* windowBits is passed < 0 to suppress zlib header */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
135
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
136 s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
137
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
138 if (err != Z_OK || s->outbuf == Z_NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
139 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
140 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
141 } else {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
142 err = inflateInit2(&(s->stream), -MAX_WBITS);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
143 s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
144
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
145 if (err != Z_OK || s->inbuf == Z_NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
146 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
147 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
148 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
149 s->stream.avail_out = Z_BUFSIZE;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
150
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
151 errno = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
152 s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
153
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
154 if (s->file == NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
155 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
156 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
157 if (s->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
158 /* Write a very simple .gz header:
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
159 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
160 fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2,
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
161 DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
162 } else {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
163 /* Check and skip the header:
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
164 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
165 Byte c1 = 0, c2 = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
166 Byte method = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
167 Byte flags = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
168 Byte xflags = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
169 Byte time[4];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
170 Byte osCode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
171 int c;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
172
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
173 s->stream.avail_in = fread(s->inbuf, 1, 2, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
174 if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
175 || s->inbuf[1] != GZ_MAGIC_2) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
176 s->transparent = 1;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
177 return (gzFile)s;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
178 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
179 s->stream.avail_in = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
180 fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
181
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
182 if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
183 s->z_err = Z_DATA_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
184 return (gzFile)s;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
185 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
186 if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
187 long len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
188 fscanf(s->file, "%c%c", &c1, &c2);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
189 len = c1 + ((long)c2<<8);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
190 fseek(s->file, len, SEEK_CUR);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
191 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
192 if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
193 while ((c = getc(s->file)) != 0 && c != EOF) ;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
194 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
195 if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
196 while ((c = getc(s->file)) != 0 && c != EOF) ;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
197 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
198 if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
199 fscanf(s->file, "%c%c", &c1, &c2);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
200 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
201 if (feof(s->file)) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
202 s->z_err = Z_DATA_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
203 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
204 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
205 return (gzFile)s;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
206 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
207
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
208 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
209 Opens a gzip (.gz) file for reading or writing.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
210 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
211 gzFile gzopen (path, mode)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
212 char *path;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
213 char *mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
214 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
215 return gz_open (path, mode, -1);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
216 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
217
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
218 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
219 Associate a gzFile with the file descriptor fd.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
220 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
221 gzFile gzdopen (fd, mode)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
222 int fd;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
223 char *mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
224 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
225 char name[20];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
226 sprintf(name, "<fd:%d>", fd); /* for debugging */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
227
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
228 return gz_open (name, mode, fd);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
229 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
230
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
231 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
232 Reads the given number of uncompressed bytes from the compressed file.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
233 gzread returns the number of bytes actually read (0 for end of file).
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
234 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
235 int gzread (file, buf, len)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
236 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
237 voidp buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
238 unsigned len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
239 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
240 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
241
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
242 if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
243
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
244 if (s->transparent) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
245 int n = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
246 Byte *b = (Byte*)buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
247 /* Copy the first two (non-magic) bytes if not done already */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
248 while (s->stream.avail_in > 0 && len > 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
249 *b++ = *s->stream.next_in++;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
250 s->stream.avail_in--;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
251 len--; n++;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
252 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
253 if (len == 0) return n;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
254 return n + fread(b, 1, len, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
255 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
256 if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
257 if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
258
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
259 s->stream.next_out = buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
260 s->stream.avail_out = len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
261
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
262 while (s->stream.avail_out != 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
263
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
264 if (s->stream.avail_in == 0 && !s->z_eof) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
265
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
266 errno = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
267 s->stream.avail_in =
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
268 fread(s->inbuf, 1, Z_BUFSIZE, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
269 if (s->stream.avail_in == 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
270 s->z_eof = 1;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
271 } else if (s->stream.avail_in == (uInt)EOF) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
272 s->stream.avail_in = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
273 s->z_eof = 1;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
274 s->z_err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
275 break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
276 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
277 s->stream.next_in = s->inbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
278 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
279 s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
280
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
281 if (s->z_err == Z_STREAM_END ||
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
282 s->z_err != Z_OK || s->z_eof) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
283 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
284 len -= s->stream.avail_out;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
285 s->crc = crc32(s->crc, buf, len);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
286 return (int)len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
287 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
288
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
289 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
290 Writes the given number of uncompressed bytes into the compressed file.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
291 gzwrite returns the number of bytes actually written (0 in case of error).
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
292 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
293 int gzwrite (file, buf, len)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
294 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
295 voidp buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
296 unsigned len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
297 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
298 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
299
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
300 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
301
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
302 s->stream.next_in = buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
303 s->stream.avail_in = len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
304
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
305 while (s->stream.avail_in != 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
306
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
307 if (s->stream.avail_out == 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
308
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
309 s->stream.next_out = s->outbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
310 if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
311 s->z_err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
312 break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
313 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
314 s->stream.avail_out = Z_BUFSIZE;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
315 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
316 s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
317 if (s->z_err != Z_OK) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
318 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
319 s->crc = crc32(s->crc, buf, len);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
320
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
321 return (int)(len - s->stream.avail_in);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
322 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
323
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
324 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
325 Flushes all pending output into the compressed file. The parameter
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
326 flush is as in the deflate() function.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
327 gzflush should be called only when strictly necessary because it can
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
328 degrade compression.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
329 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
330 int gzflush (file, flush)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
331 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
332 int flush;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
333 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
334 uInt len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
335 int done = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
336 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
337
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
338 if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
339
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
340 s->stream.avail_in = 0; /* should be zero already anyway */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
341
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
342 for (;;) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
343 len = Z_BUFSIZE - s->stream.avail_out;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
344
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
345 if (len != 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
346 if (fwrite(s->outbuf, 1, len, s->file) != len) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
347 s->z_err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
348 return Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
349 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
350 s->stream.next_out = s->outbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
351 s->stream.avail_out = Z_BUFSIZE;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
352 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
353 if (done) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
354 s->z_err = deflate(&(s->stream), flush);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
355
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
356 /* deflate has finished flushing only when it hasn't used up
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
357 * all the available space in the output buffer:
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
358 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
359 done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
360
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
361 if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
362 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
363 fflush(s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
364 return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
365 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
366
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
367 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
368 Outputs a long in LSB order to the given file
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
369 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
370 local void putLong (file, x)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
371 FILE *file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
372 uLong x;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
373 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
374 int n;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
375 for (n = 0; n < 4; n++) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
376 fputc((int)(x & 0xff), file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
377 x >>= 8;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
378 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
379 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
380
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
381 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
382 Reads a long in LSB order from the given buffer
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
383 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
384 local uLong getLong (buf)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
385 Bytef *buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
386 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
387 uLong x = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
388 Bytef *p = buf+4;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
389
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
390 do {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
391 x <<= 8;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
392 x |= *--p;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
393 } while (p != buf);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
394 return x;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
395 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
396
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
397 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
398 Flushes all pending output if necessary, closes the compressed file
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
399 and deallocates all the (de)compression state.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
400 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
401 int gzclose (file)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
402 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
403 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
404 uInt n;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
405 int err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
406 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
407
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
408 if (s == NULL) return Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
409
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
410 if (s->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
411 err = gzflush (file, Z_FINISH);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
412 if (err != Z_OK) return destroy(file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
413
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
414 putLong (s->file, s->crc);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
415 putLong (s->file, s->stream.total_in);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
416
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
417 } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
418
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
419 /* slide CRC and original size if they are at the end of inbuf */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
420 if ((n = s->stream.avail_in) < 8 && !s->z_eof) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
421 Byte *p = s->inbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
422 Bytef *q = s->stream.next_in;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
423 while (n--) { *p++ = *q++; };
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
424
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
425 n = s->stream.avail_in;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
426 n += fread(p, 1, 8, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
427 s->stream.next_in = s->inbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
428 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
429 /* check CRC and original size */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
430 if (n < 8 ||
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
431 getLong(s->stream.next_in) != s->crc ||
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
432 getLong(s->stream.next_in + 4) != s->stream.total_out) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
433
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
434 s->z_err = Z_DATA_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
435 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
436 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
437 return destroy(file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
438 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
439
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
440 /* ===========================================================================
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
441 Returns the error message for the last error which occured on the
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
442 given compressed file. errnum is set to zlib error number. If an
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
443 error occured in the file system and not in the compression library,
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
444 errnum is set to Z_ERRNO and the application may consult errno
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
445 to get the exact error code.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
446 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
447 char* gzerror (file, errnum)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
448 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
449 int *errnum;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
450 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
451 char *m;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
452 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
453
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
454 if (s == NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
455 *errnum = Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
456 return z_errmsg[1-Z_STREAM_ERROR];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
457 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
458 *errnum = s->z_err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
459 if (*errnum == Z_OK) return "";
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
460
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
461 m = *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
462
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
463 if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
464
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
465 TRYFREE(s->msg);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
466 s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
467 strcpy(s->msg, s->path);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
468 strcat(s->msg, ": ");
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
469 strcat(s->msg, m);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
470 return s->msg;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
471 }