aboutsummaryrefslogtreecommitdiff
path: root/analyze-gz.c
diff options
context:
space:
mode:
Diffstat (limited to 'analyze-gz.c')
-rw-r--r--analyze-gz.c280
1 files changed, 0 insertions, 280 deletions
diff --git a/analyze-gz.c b/analyze-gz.c
deleted file mode 100644
index a0c6d40..0000000
--- a/analyze-gz.c
+++ /dev/null
@@ -1,280 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <ctype.h>
-
-#define ID1 31
-#define ID2 139
-
-enum compression_method {
- DEFLATE = 8,
-};
-
-enum flag {
- FTEXT = 1 << 0,
- FHCRC = 1 << 1,
- FEXTRA = 1 << 2,
- FNAME = 1 << 3,
- FCOMMENT = 1 << 4,
-};
-
-enum operating_system {
- FAT = 0,
- AMIGA,
- VMS,
- UNIX,
- CMS,
- ATARI_TOS,
- HPFS,
- MACINTOSH,
- Z_SYSTEM,
- CP_M,
- TOPS20,
- NTFS,
- QDOS,
- ACORN_RISCOS,
-};
-
-const char *os_str(enum operating_system os) {
- switch (os) {
- case FAT: return "FAT filesystem (MS-DOS, OS/2, NT/Win32)";
- case AMIGA: return "Amiga";
- case VMS: return "VMS (or OpenVMS)";
- case UNIX: return "Unix";
- case CMS: return "VM/CMS";
- case ATARI_TOS: return "Atari TOS";
- case HPFS: return "HPFS filesystem (OS/2, NT)";
- case MACINTOSH: return "Macintosh";
- case Z_SYSTEM: return "Z-System";
- case CP_M: return "CP/M";
- case TOPS20: return "TOPS-20";
- case NTFS: return "NTFS filesystem (NT)";
- case QDOS: return "QDOS";
- case ACORN_RISCOS: return "Acorn RISCOS";
- default: return "unknown";
- }
-}
-
-struct member {
- uint8_t id1, id2, cm, flg;
- uint32_t mtime;
- uint8_t xfl, os;
-} __attribute__((packed));
-
-
-enum color {
- BLACK = 0,
- RED,
- GREEN,
- YELLOW,
- BLUE,
- PURPLE,
- CYAN,
- WHITE,
-};
-
-
-struct segment {
- enum color c;
- size_t len;
- uint8_t *data;
-};
-
-enum color next_color(void) {
- static uint8_t cc = 0;
- cc += 1;
- cc %= 6;
- return cc + 1;
-}
-
-void color_put(enum color c) {
- printf("\x1b[0;3%im", c);
-}
-
-void color_reset(void) {
- printf("\x1b[m");
-}
-
-#define LINELEN 0x8
-struct segment line_segments[LINELEN];
-size_t file_idx = 0;
-size_t line_idx = 0;
-size_t current_segment = 0;
-
-void cleanup_line(void) {
- for (int i = 0; i < current_segment; i++) {
- free(line_segments[i].data);
- }
-}
-
-void put_byte(uint8_t byte) {
- static bool flip = 0;
- printf("%02x", byte);
- flip = !flip;
- if (! flip) {
- printf(" ");
- }
-}
-
-void flush_line() {
- printf("%06lx: ", file_idx);
- file_idx += LINELEN;
- for (int i = 0; i < current_segment; i++) {
- color_put(line_segments[i].c);
- for (int b = 0; b < line_segments[i].len; b++) {
- put_byte(line_segments[i].data[b]);
- }
- color_reset();
- }
- for (int i = 0; i < current_segment; i++) {
- color_put(line_segments[i].c);
- for (int b = 0; b < line_segments[i].len; b++) {
- uint8_t ch = line_segments[i].data[b];
- if (isprint(ch)) {
- printf("%c", ch);
- } else {
- printf(".");
- }
- }
- color_reset();
- }
- printf("\n");
-}
-
-void add_segment(struct segment segment) {
- line_segments[current_segment++] = segment;
- line_idx += segment.len;
- if (line_idx == LINELEN) {
- flush_line();
- cleanup_line();
- current_segment = 0;
- line_idx = 0;
- }
-}
-
-/*
- * Buf MUST be a malloc:ed buffer, which is invalidated on this call.
- */
-void write_chunk(uint8_t *buf, size_t len) {
- if (line_idx + len >= LINELEN) {
- enum color c = next_color();
- size_t len1 = LINELEN - line_idx,
- len2 = len - len1;
- uint8_t *buf1 = malloc(len1),
- *buf2 = malloc(len2);
- memcpy(buf1, buf, len1);
- memcpy(buf2, buf + len1, len2);
- free(buf);
- struct segment
- seg1 = {
- .c = c,
- .len = len1,
- .data = buf1,
- },
- seg2 = {
- .c = c,
- .len = len2,
- .data = buf2,
- };
- add_segment(seg1);
- add_segment(seg2);
- } else {
- struct segment seg = {
- .c = next_color(),
- .len = len,
- .data = buf,
- };
- add_segment(seg);
- }
-}
-
-void write_chunk_s(uint8_t *buf, size_t len) {
- assert (len >= 0);
- uint8_t *true_buf = malloc(len);
- memcpy(true_buf, buf, len);
- write_chunk(true_buf, len);
-}
-
-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");
-
-
-}