1*ae316d1dSXin LI#------------------------------------------------------------------------------ 2*ae316d1dSXin LI# $File: pack,v 1.1 2024/08/30 17:29:28 christos Exp $ 3*ae316d1dSXin LI# file(1) magic for things that have PACK as magic 4*ae316d1dSXin LI 5*ae316d1dSXin LI0 string PACK 6*ae316d1dSXin LI# Type: Git pack 7*ae316d1dSXin LI# From: Adam Buchbinder <adam.buchbinder@gmail.com> 8*ae316d1dSXin LI# Update: Joerg Jenderek 9*ae316d1dSXin LI# URL: http://fileformats.archiveteam.org/wiki/Git 10*ae316d1dSXin LI# reference: https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt 11*ae316d1dSXin LI# The actual magic is 'PACK', but that clashes with Doom/Quake packs. However, 12*ae316d1dSXin LI# those have a little-endian offset immediately following the magic 'PACK', 13*ae316d1dSXin LI# the first byte of which is never 0, while the first byte of the Git pack 14*ae316d1dSXin LI# version, since it's a tiny number stored in big-endian format, is always 0. 15*ae316d1dSXin LI# GRR: line above is too general as it matches also PackDir archive ./acorn 16*ae316d1dSXin LI# test for major version. Git 2017 accepts version number 2 or 3 17*ae316d1dSXin LI>4 ubelong <9 18*ae316d1dSXin LI# Acorn PackDir with method 0 compression has root like ADFS::HardDisc4.$.AsylumSrc 19*ae316d1dSXin LI# or SystemDevice::foobar 20*ae316d1dSXin LI>>9 search/13 :: 21*ae316d1dSXin LI# but in git binary 22*ae316d1dSXin LI>>9 default x Git pack 23*ae316d1dSXin LI!:mime application/x-git 24*ae316d1dSXin LI!:ext pack 25*ae316d1dSXin LI# 4 GB limit implies unsigned integer 26*ae316d1dSXin LI>>>4 ubelong x \b, version %u 27*ae316d1dSXin LI>>>8 ubelong x \b, %u objects 28*ae316d1dSXin LI 29*ae316d1dSXin LI# From: Joerg Jenderek 30*ae316d1dSXin LI# URL: https://www.kyzer.me.uk/pack/xad/#PackDir 31*ae316d1dSXin LI# reference: https://www.kyzer.me.uk/pack/xad/xad_PackDir.lha/PackDir.c 32*ae316d1dSXin LI# GRR: line below is too general as it matches also "Git pack" in ./revision 33*ae316d1dSXin LI# check for valid compression method 0-4 34*ae316d1dSXin LI>5 ulelong <5 35*ae316d1dSXin LI# https://www.riscosopen.org/wiki/documentation/show/Introduction%20To%20Filing%20Systems 36*ae316d1dSXin LI# To skip "Git pack" version 0 test for root directory object like 37*ae316d1dSXin LI# ADFS::RPC.$.websitezip.FONTFIX 38*ae316d1dSXin LI>>9 string >ADFS\ PackDir archive (RISC OS) 39*ae316d1dSXin LI# TrID labels above as "Acorn PackDir compressed Archive" 40*ae316d1dSXin LI# compression mode y (0 - 4) for GIF LZW with a maximum n bits 41*ae316d1dSXin LI# (y~n,0~12,1~13,2~14,3~15,4~16) 42*ae316d1dSXin LI>>>5 ulelong+12 x \b, LZW %u-bits compression 43*ae316d1dSXin LI# https://www.filebase.org.uk/filetypes 44*ae316d1dSXin LI# !Packdir compressed archive has three hexadecimal digits code 68E 45*ae316d1dSXin LI!:mime application/x-acorn-68E 46*ae316d1dSXin LI!:ext pkd/bin 47*ae316d1dSXin LI# null terminated root directory object like IDEFS::IDE-4.$.Apps.GRAPHICS.!XFMPdemo 48*ae316d1dSXin LI>>>9 string x \b, root "%s" 49*ae316d1dSXin LI# load address 0xFFFtttdd, ttt is the object filetype and dddddddddd is time 50*ae316d1dSXin LI>>>>&1 ulelong x \b, load address %#x 51*ae316d1dSXin LI# execution address 0xdddddddd dddddddddd is 40 bit unsigned centiseconds since 1.1.1900 UTC 52*ae316d1dSXin LI>>>>&5 ulelong x \b, exec address %#x 53*ae316d1dSXin LI# attributes (bits: 0~owner read,1~owner write,3~no delete,4~public read,5~public write) 54*ae316d1dSXin LI>>>>&9 ulelong x \b, attributes %#x 55*ae316d1dSXin LI# number of entries in this directory. for root dir 0 56*ae316d1dSXin LI#>>>&13 ulelong x \b, entries %#x 57*ae316d1dSXin LI# the entries start here with object name 58*ae316d1dSXin LI>>>>&17 string x \b, 1st object "%s" 59*ae316d1dSXin LI 60*ae316d1dSXin LI# Update: Joerg Jenderek 61*ae316d1dSXin LI# URL: http://fileformats.archiveteam.org/wiki/PAK 62*ae316d1dSXin LI# reference: https://quakewiki.org/wiki/.pak 63*ae316d1dSXin LI# GRR: line below is too general as it matches also Acorn PackDir compressed Archive 64*ae316d1dSXin LI# real Quake examples like pak0.pak have only some hundreds like 150 files 65*ae316d1dSXin LI# So test for few files 66*ae316d1dSXin LI>8 ulelong <0x01000000 67*ae316d1dSXin LI# in file version 5.32 test for null terminator is only true for 68*ae316d1dSXin LI# offset ~< FILE_BYTES_MAX = 1 MB defined in ../../src/file.h 69*ae316d1dSXin LI# look for null terminator of 1st entry name 70*ae316d1dSXin LI>>(4.l+55) ubyte 0 Quake I or II world or extension 71*ae316d1dSXin LI!:mime application/x-dzip 72*ae316d1dSXin LI!:ext pak 73*ae316d1dSXin LI#>>>8 ulelong x \b, table size %u 74*ae316d1dSXin LI# dividing this by entry size (64) gives number of files 75*ae316d1dSXin LI>>>8 ulelong/64 x \b, %u files 76*ae316d1dSXin LI# offset to the beginning of the file table 77*ae316d1dSXin LI>>>4 ulelong x \b, offset %#x 78*ae316d1dSXin LI# 1st file entry 79*ae316d1dSXin LI>>>(4.l) use pak-entry 80*ae316d1dSXin LI# 2nd file entry 81*ae316d1dSXin LI#>>>4 ulelong+64 x \b, offset %#x 82*ae316d1dSXin LI#>>>(4.l+64) use pak-entry 83*ae316d1dSXin LI# 84*ae316d1dSXin LI# display file table entry of Quake PAK archive 85*ae316d1dSXin LI0 name pak-entry 86*ae316d1dSXin LI# normally entry start after header which implies offset 12 or higher 87*ae316d1dSXin LI>56 ulelong >11 88*ae316d1dSXin LI# the offset from the beginning of pak to beginning of this entry file contents 89*ae316d1dSXin LI>>56 ulelong x at %#x 90*ae316d1dSXin LI# the size of file for this entry 91*ae316d1dSXin LI>>60 ulelong x %u bytes 92*ae316d1dSXin LI# 56 byte null-terminated entry name string includes path like maps/e1m1.bsp 93*ae316d1dSXin LI>>0 string x '%-.56s' 94*ae316d1dSXin LI# inspect entry content by jumping to entry offset 95*ae316d1dSXin LI>>(56) indirect x \b: 96*ae316d1dSXin LI 97*ae316d1dSXin LI#0 string -1\x0a Quake I demo 98*ae316d1dSXin LI#>30 string x version %.4s 99*ae316d1dSXin LI#>61 string x level %s 100*ae316d1dSXin LI 101*ae316d1dSXin LI#0 string 5\x0a Quake I save 102