From 7e111092d24ac80cfb29b3aa01ed5638246787d3 Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 17:34:28 -0400 Subject: [PATCH 1/7] Refactor MAGIC detection, add new formats, and cleanup main.c --- Makefile | 8 ++-- include/magic.h | 12 ------ src/license.h | 78 ++++++++++++++++++++++++++++++++++ src/magic.c | 87 +++++++++++++------------------------ src/magic.h | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 68 +++++++++++++---------------- 6 files changed, 252 insertions(+), 112 deletions(-) delete mode 100644 include/magic.h create mode 100644 src/license.h create mode 100644 src/magic.h diff --git a/Makefile b/Makefile index fd9e7be..aed9bf4 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,12 @@ CC = gcc CCFLAGS = -O3 -Wextra -Wall -Werror LDFLAGS = OUTPUT = data -CFILES = src/* -$(OUTPUT): - $(CC) $(CFILES) $(CCFLAGS) $(LDFLAGS) -o $(OUTPUT) +CMAIN = src/main.c +$(OUTPUT): clean + $(CC) $(CMAIN) $(CCFLAGS) $(LDFLAGS) -o $(OUTPUT) clean: rm -rf $(OUTPUT) install: cp $(OUTPUT) /bin/ remove: - rm /bin/$(OUTPUT) \ No newline at end of file + rm /bin/$(OUTPUT) diff --git a/include/magic.h b/include/magic.h deleted file mode 100644 index 6d2432b..0000000 --- a/include/magic.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MAGIC_H -#define MAGIC_H -#include -#include -extern char *type; -extern long b; -extern long kb; -extern long mb; -extern long gb; -int parse_magic(char *in); -int parse_size(char *in); -#endif \ No newline at end of file diff --git a/src/license.h b/src/license.h new file mode 100644 index 0000000..f292fe2 --- /dev/null +++ b/src/license.h @@ -0,0 +1,78 @@ +char LICENSE[] = { + 0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x66,0x72,0x65,0x65,0x20,0x61,0x6e,0x64, + 0x20,0x75,0x6e,0x65,0x6e,0x63,0x75,0x6d,0x62,0x65,0x72,0x65,0x64,0x20,0x73,0x6f, + 0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x64,0x20, + 0x69,0x6e,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x70,0x75,0x62,0x6c,0x69,0x63,0x20, + 0x64,0x6f,0x6d,0x61,0x69,0x6e,0x2e,0x0a,0x0a,0x41,0x6e,0x79,0x6f,0x6e,0x65,0x20, + 0x69,0x73,0x20,0x66,0x72,0x65,0x65,0x20,0x74,0x6f,0x20,0x63,0x6f,0x70,0x79,0x2c, + 0x20,0x6d,0x6f,0x64,0x69,0x66,0x79,0x2c,0x20,0x70,0x75,0x62,0x6c,0x69,0x73,0x68, + 0x2c,0x20,0x75,0x73,0x65,0x2c,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x2c,0x20, + 0x73,0x65,0x6c,0x6c,0x2c,0x20,0x6f,0x72,0x0a,0x64,0x69,0x73,0x74,0x72,0x69,0x62, + 0x75,0x74,0x65,0x20,0x74,0x68,0x69,0x73,0x20,0x73,0x6f,0x66,0x74,0x77,0x61,0x72, + 0x65,0x2c,0x20,0x65,0x69,0x74,0x68,0x65,0x72,0x20,0x69,0x6e,0x20,0x73,0x6f,0x75, + 0x72,0x63,0x65,0x20,0x63,0x6f,0x64,0x65,0x20,0x66,0x6f,0x72,0x6d,0x20,0x6f,0x72, + 0x20,0x61,0x73,0x20,0x61,0x20,0x63,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x64,0x0a,0x62, + 0x69,0x6e,0x61,0x72,0x79,0x2c,0x20,0x66,0x6f,0x72,0x20,0x61,0x6e,0x79,0x20,0x70, + 0x75,0x72,0x70,0x6f,0x73,0x65,0x2c,0x20,0x63,0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69, + 0x61,0x6c,0x20,0x6f,0x72,0x20,0x6e,0x6f,0x6e,0x2d,0x63,0x6f,0x6d,0x6d,0x65,0x72, + 0x63,0x69,0x61,0x6c,0x2c,0x20,0x61,0x6e,0x64,0x20,0x62,0x79,0x20,0x61,0x6e,0x79, + 0x0a,0x6d,0x65,0x61,0x6e,0x73,0x2e,0x0a,0x0a,0x49,0x6e,0x20,0x6a,0x75,0x72,0x69, + 0x73,0x64,0x69,0x63,0x74,0x69,0x6f,0x6e,0x73,0x20,0x74,0x68,0x61,0x74,0x20,0x72, + 0x65,0x63,0x6f,0x67,0x6e,0x69,0x7a,0x65,0x20,0x63,0x6f,0x70,0x79,0x72,0x69,0x67, + 0x68,0x74,0x20,0x6c,0x61,0x77,0x73,0x2c,0x20,0x74,0x68,0x65,0x20,0x61,0x75,0x74, + 0x68,0x6f,0x72,0x20,0x6f,0x72,0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x73,0x0a,0x6f, + 0x66,0x20,0x74,0x68,0x69,0x73,0x20,0x73,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20, + 0x64,0x65,0x64,0x69,0x63,0x61,0x74,0x65,0x20,0x61,0x6e,0x79,0x20,0x61,0x6e,0x64, + 0x20,0x61,0x6c,0x6c,0x20,0x63,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x69, + 0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,0x0a,0x73, + 0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x70, + 0x75,0x62,0x6c,0x69,0x63,0x20,0x64,0x6f,0x6d,0x61,0x69,0x6e,0x2e,0x20,0x57,0x65, + 0x20,0x6d,0x61,0x6b,0x65,0x20,0x74,0x68,0x69,0x73,0x20,0x64,0x65,0x64,0x69,0x63, + 0x61,0x74,0x69,0x6f,0x6e,0x20,0x66,0x6f,0x72,0x20,0x74,0x68,0x65,0x20,0x62,0x65, + 0x6e,0x65,0x66,0x69,0x74,0x0a,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x70,0x75,0x62, + 0x6c,0x69,0x63,0x20,0x61,0x74,0x20,0x6c,0x61,0x72,0x67,0x65,0x20,0x61,0x6e,0x64, + 0x20,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x74,0x72,0x69,0x6d,0x65,0x6e, + 0x74,0x20,0x6f,0x66,0x20,0x6f,0x75,0x72,0x20,0x68,0x65,0x69,0x72,0x73,0x20,0x61, + 0x6e,0x64,0x0a,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x6f,0x72,0x73,0x2e,0x20,0x57, + 0x65,0x20,0x69,0x6e,0x74,0x65,0x6e,0x64,0x20,0x74,0x68,0x69,0x73,0x20,0x64,0x65, + 0x64,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x74,0x6f,0x20,0x62,0x65,0x20,0x61, + 0x6e,0x20,0x6f,0x76,0x65,0x72,0x74,0x20,0x61,0x63,0x74,0x20,0x6f,0x66,0x0a,0x72, + 0x65,0x6c,0x69,0x6e,0x71,0x75,0x69,0x73,0x68,0x6d,0x65,0x6e,0x74,0x20,0x69,0x6e, + 0x20,0x70,0x65,0x72,0x70,0x65,0x74,0x75,0x69,0x74,0x79,0x20,0x6f,0x66,0x20,0x61, + 0x6c,0x6c,0x20,0x70,0x72,0x65,0x73,0x65,0x6e,0x74,0x20,0x61,0x6e,0x64,0x20,0x66, + 0x75,0x74,0x75,0x72,0x65,0x20,0x72,0x69,0x67,0x68,0x74,0x73,0x20,0x74,0x6f,0x20, + 0x74,0x68,0x69,0x73,0x0a,0x73,0x6f,0x66,0x74,0x77,0x61,0x72,0x65,0x20,0x75,0x6e, + 0x64,0x65,0x72,0x20,0x63,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x6c,0x61, + 0x77,0x2e,0x0a,0x0a,0x54,0x48,0x45,0x20,0x53,0x4f,0x46,0x54,0x57,0x41,0x52,0x45, + 0x20,0x49,0x53,0x20,0x50,0x52,0x4f,0x56,0x49,0x44,0x45,0x44,0x20,0x22,0x41,0x53, + 0x20,0x49,0x53,0x22,0x2c,0x20,0x57,0x49,0x54,0x48,0x4f,0x55,0x54,0x20,0x57,0x41, + 0x52,0x52,0x41,0x4e,0x54,0x59,0x20,0x4f,0x46,0x20,0x41,0x4e,0x59,0x20,0x4b,0x49, + 0x4e,0x44,0x2c,0x0a,0x45,0x58,0x50,0x52,0x45,0x53,0x53,0x20,0x4f,0x52,0x20,0x49, + 0x4d,0x50,0x4c,0x49,0x45,0x44,0x2c,0x20,0x49,0x4e,0x43,0x4c,0x55,0x44,0x49,0x4e, + 0x47,0x20,0x42,0x55,0x54,0x20,0x4e,0x4f,0x54,0x20,0x4c,0x49,0x4d,0x49,0x54,0x45, + 0x44,0x20,0x54,0x4f,0x20,0x54,0x48,0x45,0x20,0x57,0x41,0x52,0x52,0x41,0x4e,0x54, + 0x49,0x45,0x53,0x20,0x4f,0x46,0x0a,0x4d,0x45,0x52,0x43,0x48,0x41,0x4e,0x54,0x41, + 0x42,0x49,0x4c,0x49,0x54,0x59,0x2c,0x20,0x46,0x49,0x54,0x4e,0x45,0x53,0x53,0x20, + 0x46,0x4f,0x52,0x20,0x41,0x20,0x50,0x41,0x52,0x54,0x49,0x43,0x55,0x4c,0x41,0x52, + 0x20,0x50,0x55,0x52,0x50,0x4f,0x53,0x45,0x20,0x41,0x4e,0x44,0x20,0x4e,0x4f,0x4e, + 0x49,0x4e,0x46,0x52,0x49,0x4e,0x47,0x45,0x4d,0x45,0x4e,0x54,0x2e,0x0a,0x49,0x4e, + 0x20,0x4e,0x4f,0x20,0x45,0x56,0x45,0x4e,0x54,0x20,0x53,0x48,0x41,0x4c,0x4c,0x20, + 0x54,0x48,0x45,0x20,0x41,0x55,0x54,0x48,0x4f,0x52,0x53,0x20,0x42,0x45,0x20,0x4c, + 0x49,0x41,0x42,0x4c,0x45,0x20,0x46,0x4f,0x52,0x20,0x41,0x4e,0x59,0x20,0x43,0x4c, + 0x41,0x49,0x4d,0x2c,0x20,0x44,0x41,0x4d,0x41,0x47,0x45,0x53,0x20,0x4f,0x52,0x0a, + 0x4f,0x54,0x48,0x45,0x52,0x20,0x4c,0x49,0x41,0x42,0x49,0x4c,0x49,0x54,0x59,0x2c, + 0x20,0x57,0x48,0x45,0x54,0x48,0x45,0x52,0x20,0x49,0x4e,0x20,0x41,0x4e,0x20,0x41, + 0x43,0x54,0x49,0x4f,0x4e,0x20,0x4f,0x46,0x20,0x43,0x4f,0x4e,0x54,0x52,0x41,0x43, + 0x54,0x2c,0x20,0x54,0x4f,0x52,0x54,0x20,0x4f,0x52,0x20,0x4f,0x54,0x48,0x45,0x52, + 0x57,0x49,0x53,0x45,0x2c,0x0a,0x41,0x52,0x49,0x53,0x49,0x4e,0x47,0x20,0x46,0x52, + 0x4f,0x4d,0x2c,0x20,0x4f,0x55,0x54,0x20,0x4f,0x46,0x20,0x4f,0x52,0x20,0x49,0x4e, + 0x20,0x43,0x4f,0x4e,0x4e,0x45,0x43,0x54,0x49,0x4f,0x4e,0x20,0x57,0x49,0x54,0x48, + 0x20,0x54,0x48,0x45,0x20,0x53,0x4f,0x46,0x54,0x57,0x41,0x52,0x45,0x20,0x4f,0x52, + 0x20,0x54,0x48,0x45,0x20,0x55,0x53,0x45,0x20,0x4f,0x52,0x0a,0x4f,0x54,0x48,0x45, + 0x52,0x20,0x44,0x45,0x41,0x4c,0x49,0x4e,0x47,0x53,0x20,0x49,0x4e,0x20,0x54,0x48, + 0x45,0x20,0x53,0x4f,0x46,0x54,0x57,0x41,0x52,0x45,0x2e,0x0a,0x0a,0x46,0x6f,0x72, + 0x20,0x6d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72,0x6d,0x61,0x74,0x69,0x6f, + 0x6e,0x2c,0x20,0x70,0x6c,0x65,0x61,0x73,0x65,0x20,0x72,0x65,0x66,0x65,0x72,0x20, + 0x74,0x6f,0x20,0x3c,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x75,0x6e,0x6c,0x69, + 0x63,0x65,0x6e,0x73,0x65,0x2e,0x6f,0x72,0x67,0x3e,0x0a,0x00 +}; diff --git a/src/magic.c b/src/magic.c index f2366e1..15984c4 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1,4 +1,6 @@ -#include "../include/magic.h" +extern filetype_t * type; +extern filetype_t magic_table []; + int parse_magic(char *in) { unsigned char buffer[32]; FILE *target = fopen(in, "rb"); @@ -11,69 +13,38 @@ int parse_magic(char *in) { perror("Error"); return 1; } - // formats - if (buffer[0] == 0x89 && buffer[1] == 0x50 && buffer[2] == 0x4E && buffer[3] == 0x47) { - type = "PNG Image"; - } - else if (buffer[0] == 0x23 && buffer[1] == 0x21) { - type = "Script"; - } - else if (buffer[0] == 0x49 && buffer[1] == 0x44 && buffer[2] == 0x33) { - type = "MP3 Audio"; - } - else if (buffer[4] == 0x66 && buffer[5] == 0x74 && buffer[6] == 0x79) { - type = "MP4 Video"; - } - else if (buffer[0] == 0x7F && buffer[1] == 0x45 && buffer[2] == 0x4C && buffer[3] == 0x46) { - type = "ELF UNIX Binary"; - } - else if (buffer[0] == 0x4D && buffer[1] == 0x5A) { - type = "EXE Windows Binary"; - } - else if (buffer[0] == 0xFF && buffer[1] == 0xD8 && buffer[2] == 0xFF) { - type = "JPEG Image"; - } - else if (buffer[0] == 0x47 && buffer[1] == 0x49 && buffer[2] == 0x46) { - type = "GIF Image"; - } - else if (buffer[0] == 0x42 && buffer[1] == 0x4D) { - type = "BMP Image"; - } - else if (buffer[0] == 0x25 && buffer[1] == 0x50 && buffer[2] == 0x44 && buffer[3] == 0x46) { - type = "PDF Document"; - } - else if (buffer[0] == 0x50 && buffer[1] == 0x4B) { - type = "ZIP Archive"; - } - else if (buffer[0] == 0x1F && buffer[1] == 0x8B) { - type = "GZIP Archive"; - } - else if (buffer[0] == 0x52 && buffer[1] == 0x61 && buffer[2] == 0x72 && buffer[3] == 0x21) { - type = "RAR Archive"; - } - else if (buffer[0] == 0x37 && buffer[1] == 0x7A && buffer[2] == 0xBC && buffer[3] == 0xAF && buffer[4] == 0x27 && buffer[5] == 0x1C) { - type = "7z Archive"; - } else { - type = "Data"; - } + + type = NULL; + int i; for (i=0; i<(int)magic_table_size; i++) { + filetype_t * test = &magic_table[i]; + int max = test->len; + char * magic = ( test->magic ); + char * reference = (char *)( buffer + test->off ); + int status = strncmp(reference, magic, max); + if ( status == 0 ) { type = test; break; } + } + fclose(target); return 0; } + +long parse_size(char *in) { + FILE *target = fopen(in, "rb"); + if (target == NULL) { perror("Error"); return 0; } + long yield = get_size(target); + fclose(target); + return yield; +} + long get_size(FILE *f) { fseek(f, 0, SEEK_END); long size = ftell(f); rewind(f); return size; } -int parse_size(char *in) { - FILE *target = fopen(in, "rb"); - if (target == NULL) { - return 1; - } - b = get_size(target); - kb = b / 1024; - mb = kb / 1024; - gb = mb / 1024; - fclose(target); - return 0; -} \ No newline at end of file + +int parse_scale(long in) { + int i=0; + while(in >= 1024) { in >>= 10; i++; } + return i; +} diff --git a/src/magic.h b/src/magic.h new file mode 100644 index 0000000..8a91323 --- /dev/null +++ b/src/magic.h @@ -0,0 +1,111 @@ +#ifndef MAGIC_H +#define MAGIC_H +#include +#include + + // Allows overriding the default printer function for certain types +typedef void *type_parser(void *type, char *in); +void parser_default(void *type, char *in); +int parse_magic(char *in); +long parse_size(char *in); +long get_size(FILE *f); +int parse_scale(long in); + +typedef struct + { char * name; char * magic; char * ext; int off; int len; type_parser *printer; } + filetype_t; + +extern filetype_t * type; + +#define magic_table_size ( sizeof(magic_table) / sizeof(magic_table[0]) ) +filetype_t magic_table [] = { + // Easily-identifiable Text Files + { .name = "Shebang script", + .magic = "#!", .len = 2 }, + { .name = "SSH/Other Key File", + .magic = "-----BEGIN", .len = 10, .ext = "key" }, + { .name = "XML Document", + .magic = "\x0A", .len = 8, .ext = "deb" }, + // Device Image Formats + { .name = "qcow File Format", + .magic = "QFI", .len = 3, .ext = "qcow" }, + { .name = "ISO9660 CD Image", + .magic = "CD001", .len = 5, .ext = "iso" }, + { .name = "Compressed ISO Image", + .magic = "IsZ!", .len = 4, .ext = "isz" }, +}; + +#endif diff --git a/src/main.c b/src/main.c index 26ab9cb..37f46e2 100644 --- a/src/main.c +++ b/src/main.c @@ -1,46 +1,38 @@ -#include "../include/magic.h" -long b; -long mb; -long kb; -long gb; -char *type; +#include "magic.h" +#include "magic.c" +#include "license.h" + +filetype_t *type; int main(int argc, char* argv[]) { - if (argc > 2) { - printf("Too many options\n"); - return 1; - } - if (argc < 2) { - printf("Too few options\n"); - return 1; - } + if (argc > 2) { printf("Too many options\n"); return 1; } + if (argc < 2) { printf("Too few options\n"); return 1; } if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) { printf("Usage: data [target]\n"); printf("-h --help - Shows this message\n"); return 0; } - if (parse_magic(argv[1]) == 1) { - return 1; - } - if (parse_size(argv[1]) == 1) { - return 1; - } - printf("%s:%s\n", argv[1], type); // type print - if (kb >= 1024) { - if (gb < 1) { - printf("Size: %ld MB\n", mb); - } - } - if (mb < 1024) { - if (kb < 1024) { - if (b >= 1024) { - printf("Size: %ld KB\n", kb); - } - else { - printf("Size: %ld B\n", b); - } - } - } else { - printf("Size: %ld GB\n", gb); // size print + if (strcmp(argv[1], "--license") == 0 || strcmp(argv[1], "-l") == 0) { + printf("License:\n%s\n", LICENSE); + return 0; } + if (parse_magic(argv[1]) == 1) { return 1; } + if (parse_size(argv[1]) == 0) { return 1; } + // Truncate the input filename if too long + const long maxlen = 48; + char * outname = argv[1]; + int arglen = strlen(argv[1]); + if ( arglen > maxlen ) { + outname = (char *)(argv[1] + arglen - maxlen ); + outname[0] = '.'; outname[1] = '.'; outname[2] = '.'; } + if ( type == NULL ) { printf("%s: Unknown file type\n", outname); } + else { printf("%s: %s\n", outname, type->name); } + // Scale the filesize then print + char prefix[] = " MGTP"; + long size = parse_size(argv[1]); + int scale = parse_scale(size); if (scale > 4) { scale = 4; } + printf("Size: %ld %cB\n", + size >> (scale * 10), + prefix[scale] + ); return 0; -} \ No newline at end of file +} From 77ded3bbdd5c8c8db22ae831af352498e74976b3 Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 17:47:49 -0400 Subject: [PATCH 2/7] Update readme with new format support list and --license flag --- README.md | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 44cd45e..b024979 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ data [file] #lookup file data --help #show help data -h #show help +data --license #show license +data -l #show license ``` ### Building from source: ```bash @@ -23,23 +25,13 @@ make install #install into /bin/ make remove #remove from /bin/ ``` ### Format support: -| Status | Format | -|------------|-------| -| ✅ | ELF | -| ✅ | EXE | -| ✅ | PNG | -| ✅ | JPG | -| ✅ | GIF | -| ✅ | ZIP | -| ✅ | RAR | -| ✅ | GZIP | -| ✅ | 7z | -| ❌ | Mach-O | -| ✅ | PDF | -| ✅ | MP3 | -| ✅ | MP4 | -| ❌ | AVI | -| ❌ | MOV | -| ❌ | WAV | -| ❌ | ISO | -| ✅ | SH Script | +> See [./src/magic.h](src/magic.h) + +- Images: BMP, PNG, JPEG, QOI, GIF, TIFF, WEBP +- Audio: WAV, MP3, OGG, QOA, AIFF +- Video: MP4, AVI +- Multimedia: PDF, Blender, glTF +- Executables: ELF, EXE, WebAssembly +- Archives: ZIP, GZIP, LZIP, 7-Zip, RAR, BZip, CPIO, .deb +- Binary Data: qcow, ISO +- Other: XML, Shebang scripts, SSH keys From 30519d8c554c3b8f740ba41ddecc0d0e083bc11f Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 18:14:06 -0400 Subject: [PATCH 3/7] Fix typo in GIF, add MachO --- src/magic.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/magic.h b/src/magic.h index 8a91323..9f6656c 100644 --- a/src/magic.h +++ b/src/magic.h @@ -35,9 +35,9 @@ filetype_t magic_table [] = { { .name = "Quite-OK Image Format", .magic = "qoif", .len = 4, .ext = "qoi" }, { .name = "GIF Image (version 87)", - .magic = "GIF87a", .len = 4, .ext = "gif" }, + .magic = "GIF87a", .len = 6, .ext = "gif" }, { .name = "GIF Image (version 89)", - .magic = "GIF89a", .len = 4, .ext = "gif" }, + .magic = "GIF89a", .len = 6, .ext = "gif" }, { .name = "Bitmap Image", .magic = "BM", .ext = "bmp", .len = 2 }, { .name = "Tagged Image File (Little-Endian)", @@ -73,6 +73,12 @@ filetype_t magic_table [] = { .magic = "glTF", .len = 4, .ext = "glb" }, // Executable Formats // TODO: MachO Format + { .name = "MachO Binary (x86-32)", + .magic = "\xCE\xFA\xED\xFE\x07\x00\x00\x00", .len = 8, .ext = NULL }, + { .name = "MachO Binary (x86-64)", + .magic = "\xCF\xFA\xED\xFE\x07\x00\x00\x00", .len = 8, .ext = NULL }, + { .name = "MachO Binary (64-bit ARM)", + .magic = "\xCF\xFA\xED\xFE\x0C\x00\x00\x00", .len = 8, .ext = NULL }, // TODO: ELF Format Printer, checks header for subtype information { .name = "ELF Binary", .magic = "\x7F" "ELF", .len = 4, .ext = "bin" }, From dd74219fc418160743b80baca46ad7ffb67296fe Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 18:17:06 -0400 Subject: [PATCH 4/7] Fix scalar in main.c (add kilo) --- src/magic.h | 2 -- src/main.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/magic.h b/src/magic.h index 9f6656c..ac18818 100644 --- a/src/magic.h +++ b/src/magic.h @@ -27,7 +27,6 @@ filetype_t magic_table [] = { { .name = "XML Document", .magic = "name); } // Scale the filesize then print - char prefix[] = " MGTP"; + char prefix[] = " KMGTP"; long size = parse_size(argv[1]); int scale = parse_scale(size); if (scale > 4) { scale = 4; } printf("Size: %ld %cB\n", From 1cc129189998f525c594969e952e8296d7a65d91 Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 19:48:49 -0400 Subject: [PATCH 5/7] Patch PNG behavior, add some extra formats --- src/magic.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/magic.h b/src/magic.h index ac18818..28bbcd3 100644 --- a/src/magic.h +++ b/src/magic.h @@ -17,18 +17,28 @@ typedef struct extern filetype_t * type; +// https://en.wikipedia.org/wiki/List_of_file_formats #define magic_table_size ( sizeof(magic_table) / sizeof(magic_table[0]) ) filetype_t magic_table [] = { // Easily-identifiable Text Files { .name = "Shebang script", .magic = "#!", .len = 2 }, + { .name = "PostScript File", + .magic = "%!", .len = 2, .ext = "ps" }, { .name = "SSH/Other Key File", .magic = "-----BEGIN", .len = 10, .ext = "key" }, { .name = "XML Document", - .magic = "\x0A", .len = 8, .ext = "deb" }, + { .name = "RedHat RPM Linux Package", + .magic = "\x8E\xAD\xE8\x01\x00\x00\x00\x00", .len = 8, .ext = "rpm" }, + { .name = "eXtensible ARchive", + .magic = "xar!", .len = 4, .ext = "xar" }, + { .name = "Tar Archive", + .magic = "ustar", .len = 5, .ext = "tar" }, + { .name = "Quake WAD Archive", // https://github.com/id-Software/Quake/tree/master/WinQuake + .magic = "WAD2", .len = 4, .ext = "wad" }, + { .name = "Quake PACK Archive", + .magic = "PACK", .len = 4, .ext = "pak" }, // Device Image Formats { .name = "qcow File Format", .magic = "QFI", .len = 3, .ext = "qcow" }, From 5df7217d742dfd59e49cef6cf3771b8630ee6729 Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 19:56:11 -0400 Subject: [PATCH 6/7] Update readme --- README.md | 11 ++++++----- src/magic.h | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b024979..0904560 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,11 @@ make remove #remove from /bin/ > See [./src/magic.h](src/magic.h) - Images: BMP, PNG, JPEG, QOI, GIF, TIFF, WEBP -- Audio: WAV, MP3, OGG, QOA, AIFF +- Audio: WAV, MP3, OGG, QOA, AIFF, MIDI, FLAC - Video: MP4, AVI -- Multimedia: PDF, Blender, glTF -- Executables: ELF, EXE, WebAssembly -- Archives: ZIP, GZIP, LZIP, 7-Zip, RAR, BZip, CPIO, .deb +- Multimedia: PDF, Blender, glTF, MD2 +- Fonts: WOFF, WOFF2, OpenType +- Executables: ELF, EXE, WebAssembly, JAR, Luac +- Archives: Tar, ZIP, GZIP, XZ, LZIP, 7-Zip, RAR, BZip, CPIO, PAK, .deb, .rpm - Binary Data: qcow, ISO -- Other: XML, Shebang scripts, SSH keys +- Other: XML, Shebang scripts, SSH keys, Shortcuts diff --git a/src/magic.h b/src/magic.h index 28bbcd3..c2abf7d 100644 --- a/src/magic.h +++ b/src/magic.h @@ -102,9 +102,9 @@ filetype_t magic_table [] = { { .name = "Quake 2 Model", .magic = "IDP2\x08\x00\x00\x00", .len = 8, .ext = ".md2" }, // Executable Formats - { .name = "MachO Binary (x86-32)", + { .name = "MachO Binary (32-bit x86)", .magic = "\xCE\xFA\xED\xFE\x07\x00\x00\x00", .len = 8, .ext = NULL }, - { .name = "MachO Binary (x86-64)", + { .name = "MachO Binary (64-bit x86)", .magic = "\xCF\xFA\xED\xFE\x07\x00\x00\x00", .len = 8, .ext = NULL }, { .name = "MachO Binary (64-bit ARM)", .magic = "\xCF\xFA\xED\xFE\x0C\x00\x00\x00", .len = 8, .ext = NULL }, From 8e100609d4c856c55b08c7a3b4cf917b412c9d19 Mon Sep 17 00:00:00 2001 From: John Parker Date: Sun, 6 Sep 2026 22:46:51 -0400 Subject: [PATCH 7/7] Whoops! JAR overlaps ZIP. Fix --- src/magic.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/magic.h b/src/magic.h index c2abf7d..c181418 100644 --- a/src/magic.h +++ b/src/magic.h @@ -102,13 +102,13 @@ filetype_t magic_table [] = { { .name = "Quake 2 Model", .magic = "IDP2\x08\x00\x00\x00", .len = 8, .ext = ".md2" }, // Executable Formats + // TODO: ELF Format Printer, checks header for subtype information { .name = "MachO Binary (32-bit x86)", .magic = "\xCE\xFA\xED\xFE\x07\x00\x00\x00", .len = 8, .ext = NULL }, { .name = "MachO Binary (64-bit x86)", .magic = "\xCF\xFA\xED\xFE\x07\x00\x00\x00", .len = 8, .ext = NULL }, { .name = "MachO Binary (64-bit ARM)", .magic = "\xCF\xFA\xED\xFE\x0C\x00\x00\x00", .len = 8, .ext = NULL }, - // TODO: ELF Format Printer, checks header for subtype information { .name = "ELF Binary", .magic = "\x7F" "ELF", .len = 4, .ext = "bin" }, { .name = "Portable Executable Binary", @@ -117,10 +117,10 @@ filetype_t magic_table [] = { .magic = "\x00asm", .len = 4, .ext = "wasm" }, { .name = "Lua Bytecode", .magic = "\x1BLua", .len = 4, .ext = "luac" }, - { .name = "Java Archive", // Note: Must be before ZIP - .magic = "PK\x03\x04", .len = 4, .ext = "jar" }, { .name = "Java Class file", .magic = "\xFE\xCA\xBE\xBA", .len = 4, .ext = "class" }, + { .name = "PlayStation Package", + .magic = "\x7F\x50\x4B\x47\x80\x00", .len = 6, .ext = "pkg" }, // Archive Formats { .name = "ZIP Archive", .magic = "PK", .len = 2, .ext = "zip" },