/* version 2023-10-04 */ /* gcc -Wall -o zunlib zunlib.c -lz */ /* typical usage: ./zunlib file.z > file */ #include #include #include #include int main(int n, char **v) { char *filename; FILE *f; struct stat statbuf; unsigned char *buf; int ret; if (n != 2) { fprintf(stderr, "gimme file.z to unzip\n"); return 1; } filename = v[1]; f = fopen(v[1], "r"); if (f == NULL) { perror(filename); return 1; } if (fstat(fileno(f), &statbuf)) { perror(filename); return 1; } buf = malloc(statbuf.st_size); if (buf == NULL) abort(); fread(buf, statbuf.st_size, 1, f); fclose(f); z_stream s; s.next_in = buf; s.avail_in = statbuf.st_size; s.zalloc = NULL; s.zfree = NULL; s.opaque = NULL; ret = inflateInit(&s); if (ret != Z_OK) { fprintf(stderr, "zlib error\n"); return 1; } unsigned char output[4096]; while (1) { s.next_out = output; s.avail_out = 4096; ret = inflate(&s, Z_NO_FLUSH); if (ret == Z_OK || ret == Z_STREAM_END) { int n = 4096-s.avail_out; if (n > 0) if (fwrite(output, n, 1, stdout) != 1) { fprintf(stderr, "output error\n"); return 1; } } if (ret == Z_STREAM_END) break; if (ret != Z_OK) { fprintf(stderr, "error in input\n"); return 1; } } ret = inflateEnd(&s); if (ret != Z_OK) { fprintf(stderr, "error with zlib closing\n"); return 1; } if (fflush(stdout)) { fprintf(stderr, "fflush failed, output is bad\n"); return 1; } return 0; }