aboutsummaryrefslogtreecommitdiff
path: root/analyze_gz.c
blob: 1ea0d78254a440c03e53f3d77f92b1ca809f671f (plain)
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
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "hexdump_pretty.h"

#include "gzip.h"

int main(int argc, char *argv[]) {
	if (argc == 1) {
		fprintf(stderr, "Usage: %s <filename.gz>\n", argv[0]);
		return 1;
	}

	FILE *f = fopen(argv[1], "rb");
	size_t len;

	struct member header;
	uint8_t *extra_fields = NULL;
	uint16_t crc16 = 0;
	char *filename = NULL;
	char *file_comment = NULL;

	len = fread(&header, sizeof(header), 1, f);

	if (len != 1) {
		fprintf(stderr, "Unexpected end of header\n");
		return 1;
	}

	write_chunk_s((uint8_t[2]) {header.id1, header.id2}, 2);
	write_chunk_s(&header.cm, 1);
	write_chunk_s(&header.flg, 1);
	{
		size_t s = sizeof(header.mtime);
		uint8_t *buf = malloc(s);
		memcpy(buf, &header.mtime, s);
		write_chunk(buf, s);
	}
	write_chunk_s(&header.xfl, 1);
	write_chunk_s(&header.os, 1);

	if (header.flg & FEXTRA) {
		uint16_t xlen;
		len = fread(&xlen, sizeof(xlen), 1, f);
		{
			uint8_t *buf = malloc(len);
			memcpy(buf, &xlen, len);
			write_chunk(buf, len);
		}
		extra_fields = malloc(xlen);
		len = fread(extra_fields, 1, xlen, f);
		write_chunk(extra_fields, xlen);
	}

	if (header.flg & FNAME) {
		size_t n;
		len = getdelim(&filename, &n, '\0', f);
		write_chunk((uint8_t*) filename, n);
	}

	if (header.flg & FCOMMENT) {
		size_t n;
		len = getdelim(&file_comment, &n, '\0', f);
		write_chunk((uint8_t*) file_comment, n);
	}

	if (header.flg & FHCRC) {
		len = fread(&crc16, sizeof(crc16), 1, f);
		{
			uint8_t *buf = malloc(len);
			memcpy(buf, &crc16, len);
			write_chunk(buf, len);
		}
	}

// cleanup:
	if (extra_fields) free(extra_fields);
	if (filename) free(filename);
	if (file_comment) free(file_comment);
	flush_line();
	cleanup_line();

	printf("\n");


}