| 156 | } |
| 157 | |
| 158 | static int receiveAndDecompress(int sock, FILE* fh, size_t filesize) |
| 159 | { |
| 160 | static unsigned char in[ZLIB_CHUNK]; |
| 161 | static unsigned char out[ZLIB_CHUNK]; |
| 162 | |
| 163 | int ret; |
| 164 | unsigned have; |
| 165 | z_stream strm; |
| 166 | size_t chunksize; |
| 167 | |
| 168 | /* allocate inflate state */ |
| 169 | strm.zalloc = Z_NULL; |
| 170 | strm.zfree = Z_NULL; |
| 171 | strm.opaque = Z_NULL; |
| 172 | strm.avail_in = 0; |
| 173 | strm.next_in = Z_NULL; |
| 174 | ret = inflateInit(&strm); |
| 175 | if (ret != Z_OK) |
| 176 | { |
| 177 | netloaderError("inflateInit", ret); |
| 178 | return ret; |
| 179 | } |
| 180 | |
| 181 | size_t total = 0; |
| 182 | // decompress until deflate stream ends or end of file |
| 183 | do |
| 184 | { |
| 185 | int len = recvall(sock, &chunksize, 4, 0); |
| 186 | |
| 187 | if (len != 4) |
| 188 | { |
| 189 | inflateEnd(&strm); |
| 190 | netloaderError("chunksize", len); |
| 191 | return Z_DATA_ERROR; |
| 192 | } |
| 193 | |
| 194 | strm.avail_in = recvall(sock,in,chunksize,0); |
| 195 | |
| 196 | if (strm.avail_in == 0) |
| 197 | { |
| 198 | inflateEnd(&strm); |
| 199 | netloaderError("closed", 0); |
| 200 | return Z_DATA_ERROR; |
| 201 | } |
| 202 | |
| 203 | strm.next_in = in; |
| 204 | |
| 205 | // run inflate() on input until output buffer not full |
| 206 | do |
| 207 | { |
| 208 | strm.avail_out = ZLIB_CHUNK; |
| 209 | strm.next_out = out; |
| 210 | ret = inflate(&strm, Z_NO_FLUSH); |
| 211 | |
| 212 | switch (ret) |
| 213 | { |
| 214 | case Z_NEED_DICT: |
| 215 | ret = Z_DATA_ERROR; // and fall through |
no test coverage detected