1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include <stdlib.h>
#include <stdio.h>
#include <zlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#define CHUNK (16384)
#define GZIP_WBITS (16)
/* Input
* 1: filepath
* 2: offset
* 3: length
*
* Reads in buffer,
* decompresses to buffer
* prints out buffer
*/
int main(int argc, char **argv) {
const char *f_name = argv[1];
long offset = atol(argv[2]);
long size = atol(argv[3]);
z_stream strm;
int ret;
size_t n_cur = 0;
uint8_t *out = NULL;
int fd;
if ((fd = open(f_name, O_RDONLY)) == -1) {
printf("open error\n");
return EXIT_FAILURE;
}
uint8_t *data = malloc(size);
if (data == NULL) {
printf("malloc data error\n");
return EXIT_FAILURE;
}
ssize_t read;
if ((read = pread(fd, data, size, offset)) != size) {
printf("pread error: returned %zu\n", read);
return EXIT_FAILURE;
}
close(fd);
/*
fwrite(data, 1, len, stdout);
printf("\n");
*/
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = size;
strm.next_in = data;
if (inflateInit2(&strm, GZIP_WBITS) != Z_OK) {
printf("inflate init error\n");
return EXIT_FAILURE;
}
do {
out = (uint8_t *) realloc(out, n_cur + CHUNK);
if (out == NULL) {
printf("realloc out error\n");
return EXIT_FAILURE;
}
strm.avail_out = CHUNK;
strm.next_out = out + n_cur;
ret = inflate(&strm, Z_NO_FLUSH);
switch (ret) {
case Z_MEM_ERROR:
fprintf(stderr, "zlib mem error\n");
break;
case Z_BUF_ERROR:
fprintf(stderr, "zlib buf error\n");
break;
case Z_DATA_ERROR:
fprintf(stderr, "zlib data error\n");
break;
case Z_OK:
fprintf(stderr, "zlib ok\n");
break;
case Z_STREAM_END:
fprintf(stderr, "zlib stream end\n");
break;
}
n_cur += CHUNK - strm.avail_out;
} while (strm.avail_out == 0);
fwrite(out, 1, n_cur, stdout);
free(out);
free(data);
if (ret == Z_OK || ret == Z_STREAM_END) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
}
|