annotate src/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:16 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) zcalloc((voidp)0, 1, size)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
17 #define TRYFREE(p) {if (p) zcfree((voidp)0, 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 __P((gz_stream *s));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
50 local gzFile gz_open __P((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 __P((FILE *file, uLong x));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
52 local uLong getLong __P((Byte *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 zcfree((voidp)0, 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 char *p = mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
100 gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream));
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
101
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
102 if (!s) return Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
103
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
104 s->stream.zalloc = (alloc_func)0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
105 s->stream.zfree = (free_func)0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
106 s->stream.next_in = s->inbuf = Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
107 s->stream.next_out = s->outbuf = Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
108 s->stream.avail_in = s->stream.avail_out = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
109 s->file = NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
110 s->z_err = Z_OK;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
111 s->z_eof = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
112 s->crc = crc32(0L, Z_NULL, 0);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
113 s->msg = NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
114 s->transparent = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
115
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
116 s->path = (char*)ALLOC(strlen(path)+1);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
117 if (s->path == NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
118 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
119 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
120 strcpy(s->path, path); /* do this early for debugging */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
121
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
122 s->mode = '\0';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
123 do {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
124 if (*p == 'r') s->mode = 'r';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
125 if (*p == 'w') s->mode = 'w';
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
126 } while (*p++);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
127 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
128
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
129 if (s->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
130 err = deflateInit2(&(s->stream), Z_DEFAULT_COMPRESSION,
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
131 DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
132 /* windowBits is passed < 0 to suppress zlib header */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
133
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
134 s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE);
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 if (err != Z_OK || s->outbuf == Z_NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
137 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
138 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
139 } else {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
140 err = inflateInit2(&(s->stream), -MAX_WBITS);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
141 s->stream.next_in = s->inbuf = ALLOC(Z_BUFSIZE);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
142
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
143 if (err != Z_OK || s->inbuf == Z_NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
144 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
145 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
146 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
147 s->stream.avail_out = Z_BUFSIZE;
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 errno = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
150 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
151
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
152 if (s->file == NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
153 return destroy(s), (gzFile)Z_NULL;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
154 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
155 if (s->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
156 /* Write a very simple .gz header:
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
157 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
158 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
159 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
160 } else {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
161 /* Check and skip the header:
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
162 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
163 Byte c1 = 0, c2 = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
164 Byte method = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
165 Byte flags = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
166 Byte xflags = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
167 Byte time[4];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
168 Byte osCode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
169 int c;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
170
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
171 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
172 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
173 || s->inbuf[1] != GZ_MAGIC_2) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
174 s->transparent = 1;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
175 return (gzFile)s;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
176 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
177 s->stream.avail_in = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
178 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
179
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
180 if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
181 s->z_err = Z_DATA_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
182 return (gzFile)s;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
183 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
184 if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
185 long len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
186 fscanf(s->file, "%c%c", &c1, &c2);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
187 len = c1 + ((long)c2<<8);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
188 fseek(s->file, len, SEEK_CUR);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
189 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
190 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
191 while ((c = getc(s->file)) != 0 && c != EOF) ;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
192 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
193 if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
194 while ((c = getc(s->file)) != 0 && c != EOF) ;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
195 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
196 if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
197 fscanf(s->file, "%c%c", &c1, &c2);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
198 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
199 if (feof(s->file)) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
200 s->z_err = Z_DATA_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
201 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
202 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
203 return (gzFile)s;
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
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 Opens a gzip (.gz) file for reading or writing.
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 gzFile gzopen (path, mode)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
210 char *path;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
211 char *mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
212 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
213 return gz_open (path, mode, -1);
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
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 Associate a gzFile with the file descriptor fd.
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 gzFile gzdopen (fd, mode)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
220 int fd;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
221 char *mode;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
222 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
223 char name[20];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
224 sprintf(name, "<fd:%d>", fd); /* for debugging */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
225
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
226 return gz_open (name, mode, fd);
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
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 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
231 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
232 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
233 int gzread (file, buf, len)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
234 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
235 voidp buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
236 unsigned len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
237 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
238 gz_stream *s = (gz_stream*)file;
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 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
241
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
242 if (s->transparent) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
243 unsigned n = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
244 Byte *b = (Byte*)buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
245 /* 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
246 while (s->stream.avail_in > 0 && len > 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
247 *b++ = *s->stream.next_in++;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
248 s->stream.avail_in--;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
249 len--; n++;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
250 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
251 if (len == 0) return n;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
252 return n + fread(b, 1, len, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
253 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
254 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
255 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
256
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
257 s->stream.next_out = buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
258 s->stream.avail_out = len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
259
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
260 while (s->stream.avail_out != 0) {
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 if (s->stream.avail_in == 0 && !s->z_eof) {
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 errno = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
265 s->stream.avail_in =
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
266 fread(s->inbuf, 1, Z_BUFSIZE, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
267 if (s->stream.avail_in == 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
268 s->z_eof = 1;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
269 } else if (s->stream.avail_in == (uInt)EOF) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
270 s->stream.avail_in = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
271 s->z_eof = 1;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
272 s->z_err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
273 break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
274 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
275 s->stream.next_in = s->inbuf;
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->z_err = inflate(&(s->stream), Z_NO_FLUSH);
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 if (s->z_err == Z_STREAM_END ||
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
280 s->z_err != Z_OK || s->z_eof) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
281 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
282 len -= s->stream.avail_out;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
283 s->crc = crc32(s->crc, buf, len);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
284 return len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
285 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
286
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 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
289 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
290 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
291 int gzwrite (file, buf, len)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
292 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
293 voidp buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
294 unsigned len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
295 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
296 gz_stream *s = (gz_stream*)file;
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 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
299
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
300 s->stream.next_in = buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
301 s->stream.avail_in = len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
302
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
303 while (s->stream.avail_in != 0) {
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 if (s->stream.avail_out == 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 s->stream.next_out = s->outbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
308 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
309 s->z_err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
310 break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
311 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
312 s->stream.avail_out = Z_BUFSIZE;
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->z_err = deflate(&(s->stream), Z_NO_FLUSH);
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 if (s->z_err != Z_OK) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
317 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
318 s->crc = crc32(s->crc, buf, len);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
319
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
320 return len - s->stream.avail_in;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
321 }
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 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
325 flush is as in the deflate() function.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
326 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
327 degrade compression.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
328 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
329 int gzflush (file, flush)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
330 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
331 int flush;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
332 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
333 uInt len;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
334 int done = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
335 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
336
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
337 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
338
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
339 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
340
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
341 for (;;) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
342 len = Z_BUFSIZE - s->stream.avail_out;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
343
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
344 if (len != 0) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
345 if (fwrite(s->outbuf, 1, len, s->file) != len) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
346 s->z_err = Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
347 return Z_ERRNO;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
348 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
349 s->stream.next_out = s->outbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
350 s->stream.avail_out = Z_BUFSIZE;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
351 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
352 if (done) break;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
353 s->z_err = deflate(&(s->stream), flush);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
354
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
355 /* 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
356 * all the available space in the output buffer:
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
357 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
358 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
359
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
360 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
361 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
362 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
363 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
364
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 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
367 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
368 local void putLong (file, x)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
369 FILE *file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
370 uLong x;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
371 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
372 int n;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
373 for (n = 0; n < 4; n++) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
374 fputc((int)(x & 0xff), file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
375 x >>= 8;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
376 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
377 }
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 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
381 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
382 local uLong getLong (buf)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
383 Byte *buf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
384 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
385 uLong x = 0;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
386 Byte *p = buf+4;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
387
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
388 do {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
389 x <<= 8;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
390 x |= *--p;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
391 } while (p != buf);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
392 return x;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
393 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
394
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 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
397 and deallocates all the (de)compression state.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
398 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
399 int gzclose (file)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
400 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
401 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
402 uInt n;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
403 int err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
404 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
405
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
406 if (s == NULL) return Z_STREAM_ERROR;
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->mode == 'w') {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
409 err = gzflush (file, Z_FINISH);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
410 if (err != Z_OK) return destroy(file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
411
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
412 putLong (s->file, s->crc);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
413 putLong (s->file, s->stream.total_in);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
414
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
415 } 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
416
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
417 /* 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
418 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
419 Byte *p = s->inbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
420 Byte *q = s->stream.next_in;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
421 while (n--) { *p++ = *q++; };
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
422
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
423 n = s->stream.avail_in;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
424 n += fread(p, 1, 8, s->file);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
425 s->stream.next_in = s->inbuf;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
426 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
427 /* check CRC and original size */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
428 if (n < 8 ||
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
429 getLong(s->stream.next_in) != s->crc ||
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
430 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
431
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
432 s->z_err = Z_DATA_ERROR;
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 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
435 return destroy(file);
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
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 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
440 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
441 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
442 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
443 to get the exact error code.
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
444 */
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
445 char* gzerror (file, errnum)
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
446 gzFile file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
447 int *errnum;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
448 {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
449 char *m;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
450 gz_stream *s = (gz_stream*)file;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
451
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
452 if (s == NULL) {
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
453 *errnum = Z_STREAM_ERROR;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
454 return z_errmsg[1-Z_STREAM_ERROR];
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
455 }
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
456 *errnum = s->z_err;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
457 if (*errnum == Z_OK) return "";
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
458
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
459 m = *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg;
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 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
462
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
463 TRYFREE(s->msg);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
464 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
465 strcpy(s->msg, s->path);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
466 strcat(s->msg, ": ");
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
467 strcat(s->msg, m);
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
468 return s->msg;
1040ca591f2e First entry of Paradise Server 2.9 patch 10 Beta
darius
parents:
diff changeset
469 }