Imported Upstream version 5.37 58/233658/1 upstream/5.37
authorHyunjee Kim <hj0426.kim@samsung.com>
Mon, 18 May 2020 05:15:41 +0000 (14:15 +0900)
committerHyunjee Kim <hj0426.kim@samsung.com>
Mon, 18 May 2020 05:16:47 +0000 (14:16 +0900)
Change-Id: I447bb8875c45e98aa701193009f35a3fc07b1a23
Signed-off-by: Hyunjee Kim <hj0426.kim@samsung.com>
465 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
MAINT [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
README.DEVELOPER [new file with mode: 0644]
RELEASE-PROCEDURE [new file with mode: 0644]
TODO [new file with mode: 0644]
acinclude.m4 [new file with mode: 0644]
configure.ac [new file with mode: 0644]
doc/.cvsignore [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
doc/file.man [new file with mode: 0644]
doc/libmagic.man [new file with mode: 0644]
doc/magic.man [new file with mode: 0644]
fuzz/Dockerfile [new file with mode: 0644]
fuzz/build.sh [new file with mode: 0755]
fuzz/magic_fuzzer.c [new file with mode: 0644]
fuzz/project.yaml [new file with mode: 0644]
m4/.cvsignore [new file with mode: 0644]
magic/.cvsignore [new file with mode: 0644]
magic/Header [new file with mode: 0644]
magic/Localstuff [new file with mode: 0644]
magic/Magdir/acorn [new file with mode: 0644]
magic/Magdir/adi [new file with mode: 0644]
magic/Magdir/adventure [new file with mode: 0644]
magic/Magdir/algol68 [new file with mode: 0644]
magic/Magdir/allegro [new file with mode: 0644]
magic/Magdir/alliant [new file with mode: 0644]
magic/Magdir/alpha [new file with mode: 0644]
magic/Magdir/amanda [new file with mode: 0644]
magic/Magdir/amigaos [new file with mode: 0644]
magic/Magdir/android [new file with mode: 0644]
magic/Magdir/animation [new file with mode: 0644]
magic/Magdir/aout [new file with mode: 0644]
magic/Magdir/apache [new file with mode: 0755]
magic/Magdir/apl [new file with mode: 0644]
magic/Magdir/apple [new file with mode: 0644]
magic/Magdir/application [new file with mode: 0644]
magic/Magdir/applix [new file with mode: 0644]
magic/Magdir/apt [new file with mode: 0644]
magic/Magdir/archive [new file with mode: 0644]
magic/Magdir/assembler [new file with mode: 0644]
magic/Magdir/asterix [new file with mode: 0644]
magic/Magdir/att3b [new file with mode: 0644]
magic/Magdir/audio [new file with mode: 0644]
magic/Magdir/basis [new file with mode: 0644]
magic/Magdir/beetle [new file with mode: 0644]
magic/Magdir/ber [new file with mode: 0644]
magic/Magdir/bflt [new file with mode: 0644]
magic/Magdir/bhl [new file with mode: 0644]
magic/Magdir/bioinformatics [new file with mode: 0644]
magic/Magdir/biosig [new file with mode: 0644]
magic/Magdir/blackberry [new file with mode: 0644]
magic/Magdir/blcr [new file with mode: 0644]
magic/Magdir/blender [new file with mode: 0644]
magic/Magdir/blit [new file with mode: 0644]
magic/Magdir/bout [new file with mode: 0644]
magic/Magdir/bsdi [new file with mode: 0644]
magic/Magdir/bsi [new file with mode: 0644]
magic/Magdir/btsnoop [new file with mode: 0644]
magic/Magdir/c-lang [new file with mode: 0644]
magic/Magdir/c64 [new file with mode: 0644]
magic/Magdir/cad [new file with mode: 0644]
magic/Magdir/cafebabe [new file with mode: 0644]
magic/Magdir/cbor [new file with mode: 0644]
magic/Magdir/cddb [new file with mode: 0644]
magic/Magdir/chord [new file with mode: 0644]
magic/Magdir/cisco [new file with mode: 0644]
magic/Magdir/citrus [new file with mode: 0644]
magic/Magdir/clarion [new file with mode: 0644]
magic/Magdir/claris [new file with mode: 0644]
magic/Magdir/clipper [new file with mode: 0644]
magic/Magdir/clojure [new file with mode: 0644]
magic/Magdir/coff [new file with mode: 0644]
magic/Magdir/commands [new file with mode: 0644]
magic/Magdir/communications [new file with mode: 0644]
magic/Magdir/compress [new file with mode: 0644]
magic/Magdir/console [new file with mode: 0644]
magic/Magdir/convex [new file with mode: 0644]
magic/Magdir/coverage [new file with mode: 0644]
magic/Magdir/cracklib [new file with mode: 0644]
magic/Magdir/ctags [new file with mode: 0644]
magic/Magdir/ctf [new file with mode: 0644]
magic/Magdir/cubemap [new file with mode: 0644]
magic/Magdir/cups [new file with mode: 0644]
magic/Magdir/dact [new file with mode: 0644]
magic/Magdir/database [new file with mode: 0644]
magic/Magdir/dataone [new file with mode: 0644]
magic/Magdir/dbpf [new file with mode: 0644]
magic/Magdir/der [new file with mode: 0644]
magic/Magdir/diamond [new file with mode: 0644]
magic/Magdir/diff [new file with mode: 0644]
magic/Magdir/digital [new file with mode: 0644]
magic/Magdir/dolby [new file with mode: 0644]
magic/Magdir/dump [new file with mode: 0644]
magic/Magdir/dyadic [new file with mode: 0644]
magic/Magdir/ebml [new file with mode: 0644]
magic/Magdir/edid [new file with mode: 0644]
magic/Magdir/editors [new file with mode: 0644]
magic/Magdir/efi [new file with mode: 0644]
magic/Magdir/elf [new file with mode: 0644]
magic/Magdir/encore [new file with mode: 0644]
magic/Magdir/epoc [new file with mode: 0644]
magic/Magdir/erlang [new file with mode: 0644]
magic/Magdir/espressif [new file with mode: 0644]
magic/Magdir/esri [new file with mode: 0644]
magic/Magdir/etf [new file with mode: 0644]
magic/Magdir/fcs [new file with mode: 0644]
magic/Magdir/filesystems [new file with mode: 0644]
magic/Magdir/finger [new file with mode: 0644]
magic/Magdir/flash [new file with mode: 0644]
magic/Magdir/flif [new file with mode: 0644]
magic/Magdir/fonts [new file with mode: 0644]
magic/Magdir/fortran [new file with mode: 0644]
magic/Magdir/frame [new file with mode: 0644]
magic/Magdir/freebsd [new file with mode: 0644]
magic/Magdir/fsav [new file with mode: 0644]
magic/Magdir/fusecompress [new file with mode: 0644]
magic/Magdir/games [new file with mode: 0644]
magic/Magdir/gcc [new file with mode: 0644]
magic/Magdir/gconv [new file with mode: 0644]
magic/Magdir/geo [new file with mode: 0644]
magic/Magdir/geos [new file with mode: 0644]
magic/Magdir/gimp [new file with mode: 0644]
magic/Magdir/glibc [new file with mode: 0644]
magic/Magdir/gnome [new file with mode: 0644]
magic/Magdir/gnu [new file with mode: 0644]
magic/Magdir/gnumeric [new file with mode: 0644]
magic/Magdir/gpt [new file with mode: 0644]
magic/Magdir/gpu [new file with mode: 0644]
magic/Magdir/grace [new file with mode: 0644]
magic/Magdir/graphviz [new file with mode: 0644]
magic/Magdir/gringotts [new file with mode: 0644]
magic/Magdir/guile [new file with mode: 0644]
magic/Magdir/hardware [new file with mode: 0644]
magic/Magdir/hitachi-sh [new file with mode: 0644]
magic/Magdir/hp [new file with mode: 0644]
magic/Magdir/human68k [new file with mode: 0644]
magic/Magdir/ibm370 [new file with mode: 0644]
magic/Magdir/ibm6000 [new file with mode: 0644]
magic/Magdir/icc [new file with mode: 0644]
magic/Magdir/iff [new file with mode: 0644]
magic/Magdir/images [new file with mode: 0644]
magic/Magdir/inform [new file with mode: 0644]
magic/Magdir/intel [new file with mode: 0644]
magic/Magdir/interleaf [new file with mode: 0644]
magic/Magdir/island [new file with mode: 0644]
magic/Magdir/ispell [new file with mode: 0644]
magic/Magdir/isz [new file with mode: 0644]
magic/Magdir/java [new file with mode: 0644]
magic/Magdir/javascript [new file with mode: 0644]
magic/Magdir/jpeg [new file with mode: 0644]
magic/Magdir/karma [new file with mode: 0644]
magic/Magdir/kde [new file with mode: 0644]
magic/Magdir/keepass [new file with mode: 0644]
magic/Magdir/kerberos [new file with mode: 0644]
magic/Magdir/kicad [new file with mode: 0644]
magic/Magdir/kml [new file with mode: 0644]
magic/Magdir/lecter [new file with mode: 0644]
magic/Magdir/lex [new file with mode: 0644]
magic/Magdir/lif [new file with mode: 0644]
magic/Magdir/linux [new file with mode: 0644]
magic/Magdir/lisp [new file with mode: 0644]
magic/Magdir/llvm [new file with mode: 0644]
magic/Magdir/lua [new file with mode: 0644]
magic/Magdir/luks [new file with mode: 0644]
magic/Magdir/m4 [new file with mode: 0644]
magic/Magdir/mach [new file with mode: 0644]
magic/Magdir/macintosh [new file with mode: 0644]
magic/Magdir/macos [new file with mode: 0644]
magic/Magdir/magic [new file with mode: 0644]
magic/Magdir/mail.news [new file with mode: 0644]
magic/Magdir/make [new file with mode: 0644]
magic/Magdir/map [new file with mode: 0644]
magic/Magdir/maple [new file with mode: 0644]
magic/Magdir/marc21 [new file with mode: 0644]
magic/Magdir/mathcad [new file with mode: 0644]
magic/Magdir/mathematica [new file with mode: 0644]
magic/Magdir/matroska [new file with mode: 0644]
magic/Magdir/mcrypt [new file with mode: 0644]
magic/Magdir/measure [new file with mode: 0644]
magic/Magdir/mercurial [new file with mode: 0644]
magic/Magdir/metastore [new file with mode: 0644]
magic/Magdir/meteorological [new file with mode: 0644]
magic/Magdir/microfocus [new file with mode: 0644]
magic/Magdir/mime [new file with mode: 0644]
magic/Magdir/mips [new file with mode: 0644]
magic/Magdir/mirage [new file with mode: 0644]
magic/Magdir/misctools [new file with mode: 0644]
magic/Magdir/mkid [new file with mode: 0644]
magic/Magdir/mlssa [new file with mode: 0644]
magic/Magdir/mmdf [new file with mode: 0644]
magic/Magdir/modem [new file with mode: 0644]
magic/Magdir/motorola [new file with mode: 0644]
magic/Magdir/mozilla [new file with mode: 0644]
magic/Magdir/msdos [new file with mode: 0644]
magic/Magdir/msooxml [new file with mode: 0644]
magic/Magdir/msvc [new file with mode: 0644]
magic/Magdir/msx [new file with mode: 0644]
magic/Magdir/mup [new file with mode: 0644]
magic/Magdir/music [new file with mode: 0644]
magic/Magdir/nasa [new file with mode: 0644]
magic/Magdir/natinst [new file with mode: 0644]
magic/Magdir/ncr [new file with mode: 0644]
magic/Magdir/neko [new file with mode: 0644]
magic/Magdir/netbsd [new file with mode: 0644]
magic/Magdir/netscape [new file with mode: 0644]
magic/Magdir/netware [new file with mode: 0644]
magic/Magdir/news [new file with mode: 0644]
magic/Magdir/nitpicker [new file with mode: 0644]
magic/Magdir/numpy [new file with mode: 0644]
magic/Magdir/oasis [new file with mode: 0644]
magic/Magdir/ocaml [new file with mode: 0644]
magic/Magdir/octave [new file with mode: 0644]
magic/Magdir/ole2compounddocs [new file with mode: 0644]
magic/Magdir/olf [new file with mode: 0644]
magic/Magdir/os2 [new file with mode: 0644]
magic/Magdir/os400 [new file with mode: 0644]
magic/Magdir/os9 [new file with mode: 0644]
magic/Magdir/osf1 [new file with mode: 0644]
magic/Magdir/palm [new file with mode: 0644]
magic/Magdir/parix [new file with mode: 0644]
magic/Magdir/parrot [new file with mode: 0644]
magic/Magdir/pascal [new file with mode: 0644]
magic/Magdir/pbf [new file with mode: 0644]
magic/Magdir/pbm [new file with mode: 0644]
magic/Magdir/pc88 [new file with mode: 0644]
magic/Magdir/pc98 [new file with mode: 0644]
magic/Magdir/pdf [new file with mode: 0644]
magic/Magdir/pdp [new file with mode: 0644]
magic/Magdir/perl [new file with mode: 0644]
magic/Magdir/pgf [new file with mode: 0644]
magic/Magdir/pgp [new file with mode: 0644]
magic/Magdir/pkgadd [new file with mode: 0644]
magic/Magdir/plan9 [new file with mode: 0644]
magic/Magdir/plus5 [new file with mode: 0644]
magic/Magdir/polyml [new file with mode: 0644]
magic/Magdir/printer [new file with mode: 0644]
magic/Magdir/project [new file with mode: 0644]
magic/Magdir/psdbms [new file with mode: 0644]
magic/Magdir/psl [new file with mode: 0644]
magic/Magdir/pulsar [new file with mode: 0644]
magic/Magdir/pwsafe [new file with mode: 0644]
magic/Magdir/pyramid [new file with mode: 0644]
magic/Magdir/python [new file with mode: 0644]
magic/Magdir/qt [new file with mode: 0644]
magic/Magdir/revision [new file with mode: 0644]
magic/Magdir/riff [new file with mode: 0644]
magic/Magdir/rinex [new file with mode: 0644]
magic/Magdir/rpi [new file with mode: 0644]
magic/Magdir/rpm [new file with mode: 0644]
magic/Magdir/rpmsg [new file with mode: 0644]
magic/Magdir/rtf [new file with mode: 0644]
magic/Magdir/ruby [new file with mode: 0644]
magic/Magdir/sc [new file with mode: 0644]
magic/Magdir/sccs [new file with mode: 0644]
magic/Magdir/scientific [new file with mode: 0644]
magic/Magdir/securitycerts [new file with mode: 0644]
magic/Magdir/selinux [new file with mode: 0644]
magic/Magdir/sendmail [new file with mode: 0644]
magic/Magdir/sequent [new file with mode: 0644]
magic/Magdir/sereal [new file with mode: 0644]
magic/Magdir/sgi [new file with mode: 0644]
magic/Magdir/sgml [new file with mode: 0644]
magic/Magdir/sharc [new file with mode: 0644]
magic/Magdir/sinclair [new file with mode: 0644]
magic/Magdir/sisu [new file with mode: 0644]
magic/Magdir/sketch [new file with mode: 0644]
magic/Magdir/smalltalk [new file with mode: 0644]
magic/Magdir/smile [new file with mode: 0644]
magic/Magdir/sniffer [new file with mode: 0644]
magic/Magdir/softquad [new file with mode: 0644]
magic/Magdir/spec [new file with mode: 0644]
magic/Magdir/spectrum [new file with mode: 0644]
magic/Magdir/sql [new file with mode: 0644]
magic/Magdir/ssh [new file with mode: 0644]
magic/Magdir/ssl [new file with mode: 0644]
magic/Magdir/sun [new file with mode: 0644]
magic/Magdir/symbos [new file with mode: 0644]
magic/Magdir/sysex [new file with mode: 0644]
magic/Magdir/tcl [new file with mode: 0644]
magic/Magdir/teapot [new file with mode: 0644]
magic/Magdir/terminfo [new file with mode: 0644]
magic/Magdir/tex [new file with mode: 0644]
magic/Magdir/tgif [new file with mode: 0644]
magic/Magdir/ti-8x [new file with mode: 0644]
magic/Magdir/timezone [new file with mode: 0644]
magic/Magdir/tplink [new file with mode: 0644]
magic/Magdir/troff [new file with mode: 0644]
magic/Magdir/tuxedo [new file with mode: 0644]
magic/Magdir/typeset [new file with mode: 0644]
magic/Magdir/unicode [new file with mode: 0644]
magic/Magdir/unknown [new file with mode: 0644]
magic/Magdir/uterus [new file with mode: 0644]
magic/Magdir/uuencode [new file with mode: 0644]
magic/Magdir/vacuum-cleaner [new file with mode: 0644]
magic/Magdir/varied.out [new file with mode: 0644]
magic/Magdir/varied.script [new file with mode: 0644]
magic/Magdir/vax [new file with mode: 0644]
magic/Magdir/vicar [new file with mode: 0644]
magic/Magdir/virtual [new file with mode: 0644]
magic/Magdir/virtutech [new file with mode: 0644]
magic/Magdir/visx [new file with mode: 0644]
magic/Magdir/vms [new file with mode: 0644]
magic/Magdir/vmware [new file with mode: 0644]
magic/Magdir/vorbis [new file with mode: 0644]
magic/Magdir/vxl [new file with mode: 0644]
magic/Magdir/warc [new file with mode: 0644]
magic/Magdir/weak [new file with mode: 0644]
magic/Magdir/webassembly [new file with mode: 0644]
magic/Magdir/windows [new file with mode: 0644]
magic/Magdir/wireless [new file with mode: 0644]
magic/Magdir/wordprocessors [new file with mode: 0644]
magic/Magdir/wsdl [new file with mode: 0644]
magic/Magdir/x68000 [new file with mode: 0644]
magic/Magdir/xdelta [new file with mode: 0644]
magic/Magdir/xenix [new file with mode: 0644]
magic/Magdir/xilinx [new file with mode: 0644]
magic/Magdir/xo65 [new file with mode: 0644]
magic/Magdir/xwindows [new file with mode: 0644]
magic/Magdir/yara [new file with mode: 0644]
magic/Magdir/zfs [new file with mode: 0644]
magic/Magdir/zilog [new file with mode: 0644]
magic/Magdir/zip [new file with mode: 0644]
magic/Magdir/zyxel [new file with mode: 0644]
magic/Makefile.am [new file with mode: 0644]
magic/scripts/create_filemagic_flac [new file with mode: 0755]
python/.cvsignore [new file with mode: 0644]
python/CHANGELOG.md [new file with mode: 0644]
python/LICENSE [new file with mode: 0644]
python/Makefile.am [new file with mode: 0644]
python/README.md [new file with mode: 0644]
python/example.py [new file with mode: 0644]
python/file_magic/__init__.py [new file with mode: 0644]
python/magic.py [new file with mode: 0644]
python/setup.py [new file with mode: 0644]
python/tests.py [new file with mode: 0644]
src/.cvsignore [new file with mode: 0644]
src/BNF [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/Makefile.std [new file with mode: 0644]
src/apprentice.c [new file with mode: 0644]
src/apptype.c [new file with mode: 0644]
src/ascmagic.c [new file with mode: 0644]
src/asctime_r.c [new file with mode: 0644]
src/asprintf.c [new file with mode: 0644]
src/buffer.c [new file with mode: 0644]
src/cdf.c [new file with mode: 0644]
src/cdf.h [new file with mode: 0644]
src/cdf.mk [new file with mode: 0644]
src/cdf_time.c [new file with mode: 0644]
src/compress.c [new file with mode: 0644]
src/ctime_r.c [new file with mode: 0644]
src/der.c [new file with mode: 0644]
src/der.h [new file with mode: 0644]
src/dprintf.c [new file with mode: 0644]
src/elfclass.h [new file with mode: 0644]
src/encoding.c [new file with mode: 0644]
src/file.c [new file with mode: 0644]
src/file.h [new file with mode: 0644]
src/file_opts.h [new file with mode: 0644]
src/fmtcheck.c [new file with mode: 0644]
src/fsmagic.c [new file with mode: 0644]
src/funcs.c [new file with mode: 0644]
src/getline.c [new file with mode: 0644]
src/getopt_long.c [new file with mode: 0644]
src/gmtime_r.c [new file with mode: 0644]
src/is_json.c [new file with mode: 0644]
src/is_tar.c [new file with mode: 0644]
src/localtime_r.c [new file with mode: 0644]
src/magic.c [new file with mode: 0644]
src/magic.h.in [new file with mode: 0644]
src/mygetopt.h [new file with mode: 0644]
src/patchlevel.h [new file with mode: 0644]
src/pread.c [new file with mode: 0644]
src/print.c [new file with mode: 0644]
src/readcdf.c [new file with mode: 0644]
src/readelf.c [new file with mode: 0644]
src/readelf.h [new file with mode: 0644]
src/seccomp.c [new file with mode: 0644]
src/softmagic.c [new file with mode: 0644]
src/strcasestr.c [new file with mode: 0644]
src/strlcat.c [new file with mode: 0644]
src/strlcpy.c [new file with mode: 0644]
src/tar.h [new file with mode: 0644]
src/teststrchr.c [new file with mode: 0644]
src/vasprintf.c [new file with mode: 0644]
tests/.cvsignore [new file with mode: 0644]
tests/CVE-2014-1943.result [new file with mode: 0644]
tests/CVE-2014-1943.testfile [new file with mode: 0644]
tests/JW07022A.mp3.result [new file with mode: 0644]
tests/JW07022A.mp3.testfile [new file with mode: 0644]
tests/Makefile.am [new file with mode: 0644]
tests/README [new file with mode: 0644]
tests/escapevel.result [new file with mode: 0644]
tests/escapevel.testfile [new file with mode: 0644]
tests/fit-map-data.result [new file with mode: 0644]
tests/fit-map-data.testfile [new file with mode: 0644]
tests/gedcom.result [new file with mode: 0644]
tests/gedcom.testfile [new file with mode: 0644]
tests/hddrawcopytool.result [new file with mode: 0644]
tests/hddrawcopytool.testfile [new file with mode: 0644]
tests/issue311docx.result [new file with mode: 0644]
tests/issue311docx.testfile [new file with mode: 0644]
tests/issue359xlsx.result [new file with mode: 0644]
tests/issue359xlsx.testfile [new file with mode: 0644]
tests/json1.result [new file with mode: 0644]
tests/json1.testfile [new file with mode: 0644]
tests/json2.result [new file with mode: 0644]
tests/json2.testfile [new file with mode: 0644]
tests/json3.result [new file with mode: 0644]
tests/json3.testfile [new file with mode: 0644]
tests/regex-eol.magic [new file with mode: 0644]
tests/regex-eol.result [new file with mode: 0644]
tests/regex-eol.testfile [new file with mode: 0644]
tests/test.c [new file with mode: 0644]
tests/zstd-3-skippable-frames.result [new file with mode: 0644]
tests/zstd-dictionary-0.result [new file with mode: 0644]
tests/zstd-dictionary-1.result [new file with mode: 0644]
tests/zstd-dictionary-2.result [new file with mode: 0644]
tests/zstd-skippable-frame-0.result [new file with mode: 0644]
tests/zstd-skippable-frame-4.result [new file with mode: 0644]
tests/zstd-skippable-frame-8.result [new file with mode: 0644]
tests/zstd-skippable-frame-C.result [new file with mode: 0644]
tests/zstd-v0.2-FF.result [new file with mode: 0644]
tests/zstd-v0.2-FF.testfile [new file with mode: 0644]
tests/zstd-v0.3-FF.result [new file with mode: 0644]
tests/zstd-v0.3-FF.testfile [new file with mode: 0644]
tests/zstd-v0.4-FF.result [new file with mode: 0644]
tests/zstd-v0.4-FF.testfile [new file with mode: 0644]
tests/zstd-v0.5-FF.result [new file with mode: 0644]
tests/zstd-v0.5-FF.testfile [new file with mode: 0644]
tests/zstd-v0.6-FF.result [new file with mode: 0644]
tests/zstd-v0.6-FF.testfile [new file with mode: 0644]
tests/zstd-v0.7-00.result [new file with mode: 0644]
tests/zstd-v0.7-21.result [new file with mode: 0644]
tests/zstd-v0.7-21.testfile [new file with mode: 0644]
tests/zstd-v0.7-22.result [new file with mode: 0644]
tests/zstd-v0.7-22.testfile [new file with mode: 0644]
tests/zstd-v0.8-00.result [new file with mode: 0644]
tests/zstd-v0.8-01.result [new file with mode: 0644]
tests/zstd-v0.8-01.testfile [new file with mode: 0644]
tests/zstd-v0.8-02.result [new file with mode: 0644]
tests/zstd-v0.8-02.testfile [new file with mode: 0644]
tests/zstd-v0.8-03.result [new file with mode: 0644]
tests/zstd-v0.8-03.testfile [new file with mode: 0644]
tests/zstd-v0.8-16.result [new file with mode: 0644]
tests/zstd-v0.8-16.testfile [new file with mode: 0644]
tests/zstd-v0.8-20.result [new file with mode: 0644]
tests/zstd-v0.8-20.testfile [new file with mode: 0644]
tests/zstd-v0.8-21.result [new file with mode: 0644]
tests/zstd-v0.8-21.testfile [new file with mode: 0644]
tests/zstd-v0.8-22.result [new file with mode: 0644]
tests/zstd-v0.8-22.testfile [new file with mode: 0644]
tests/zstd-v0.8-23.result [new file with mode: 0644]
tests/zstd-v0.8-23.testfile [new file with mode: 0644]
tests/zstd-v0.8-F4.result [new file with mode: 0644]
tests/zstd-v0.8-F4.testfile [new file with mode: 0644]
tests/zstd-v0.8-FF.result [new file with mode: 0644]
tests/zstd-v0.8-FF.testfile [new file with mode: 0644]
visibility.m4 [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..bac5d5b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+See COPYING.
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..16410a1
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,29 @@
+$File: COPYING,v 1.2 2018/09/09 20:33:28 christos Exp $
+Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
+Software written by Ian F. Darwin and others;
+maintained 1994- Christos Zoulas.
+
+This software is not subject to any export provision of the United States
+Department of Commerce, and may be exported to any country or planet.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice immediately at the beginning of the file, without modification,
+   this list of conditions, and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..482a5f7
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1825 @@
+2019-05-14  22:26  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.37
+
+2019-05-09  22:27  Christos Zoulas <christos@zoulas.com>
+       
+       * Make sure that continuation separators are printed
+         with -k within softmagic
+
+2019-05-06  22:27  Christos Zoulas <christos@zoulas.com>
+
+       * Change SIGPIPE saving and restoring during compression to use
+         sigaction(2) instead of signal(3) and cache it. (Denys Vlasenko)
+       * Cache stat(2) calls more to reduce number of calls (Denys Vlasenko)
+
+2019-05-06  17:25  Christos Zoulas <christos@zoulas.com>
+
+       * PR/77: Handle --mime-type and -k correctly.
+
+2019-05-03  15:26  Christos Zoulas <christos@zoulas.com>
+
+       * Switch decompression code to use vfork() because
+         tools like rpmdiff and rpmbuild call libmagic
+         with large process footprints (Denys Vlasenko)
+
+2019-04-07  14:05  Christos Zoulas <christos@zoulas.com>
+
+       * PR/75: --enable-zlib, did not work.
+
+2019-02-27  11:54  Christos Zoulas <christos@zoulas.com>
+
+       * Improve regex efficiency (Michael Schroeder) by:
+               1. Prefixing regex searches with regular search
+                  for keywords where possible
+               2. Using memmem(3) where available
+
+2019-02-20  10:16  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.36
+
+2019-02-19  15:30  Christos Zoulas <christos@zoulas.com>
+
+       * Fix cast to use cast macros
+       * Add UCS-32 builtin detection (PR/61) reported by tmc
+
+2019-02-18  18:24  Christos Zoulas <christos@zoulas.com>
+
+       * Fix stack read (PR/62) and write (PR/64) stack overflows
+         reported by spinpx 
+
+2018-10-18  19:32  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.35
+
+2018-09-10  20:38  Christos Zoulas <christos@zoulas.com>
+
+       * Add FreeBSD ELF core file support (John Baldwin)
+
+2018-08-20  18:40  Christos Zoulas <christos@zoulas.com>
+
+       * PR/30: Allow all parameter values to be set (don't treat 0 specially)
+       * handle default annotations on the softmagic match instead at the
+         end.
+
+2018-07-25  10:17  Christos Zoulas <christos@zoulas.com>
+
+       * PR/23: Recognize JSON files
+
+2018-07-25  10:17  Christos Zoulas <christos@zoulas.com>
+
+       * PR/18: file --mime-encoding should not print mime-type
+
+2018-07-25   8:50  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.34
+
+2018-06-22  16:38  Christos Zoulas <christos@zoulas.com>
+
+       * Add Quad indirect offsets
+
+2018-05-24  14:10  Christos Zoulas <christos@zoulas.com>
+
+       * Enable parsing of ELF dynamic sections to handle PIE better
+
+2018-04-15  14:52  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.33
+
+2018-02-24  14:50  Christos Zoulas <christos@zoulas.com>
+
+       * extend the support for ${x?:} expansions for magic descriptions
+
+2018-02-21  16:25  Christos Zoulas <christos@zoulas.com>
+
+       * add support for ${x?:} in mime types to handle
+         pie binaries.
+
+2017-11-03   9:23  Christos Zoulas <christos@zoulas.com>
+
+       * add support for negative offsets (offsets from the end of file)
+
+2017-09-26   8:22  Christos Zoulas <christos@zoulas.com>
+
+       * close the file on error when writing magic (Steve Grubb)
+
+2017-09-24  12:02  Christos Zoulas <christos@zoulas.com>
+
+       * seccomp support (Paul Moore)
+
+2017-09-02  11:53  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.32
+
+2017-08-28  16:37  Christos Zoulas <christos@zoulas.com>
+
+       * Always reset state in {file,buffer}_apprentice (Krzysztof Wilczynski)
+
+2017-08-27  03:55  Christos Zoulas <christos@zoulas.com>
+
+       * Fix always true condition (Thomas Jarosch)
+
+2017-05-24  17:30  Christos Zoulas <christos@zoulas.com>
+
+       * pickier parsing of numeric values in magic files.
+
+2017-05-23  17:55  Christos Zoulas <christos@zoulas.com>
+
+       * PR/615 add magic_getflags()
+
+2017-05-23  13:55  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.31
+
+2017-03-17  20:32  Christos Zoulas <christos@zoulas.com>
+
+       * remove trailing spaces from magic files
+       * refactor is_tar
+       * better bounds checks for cdf
+
+2017-02-10  12:24  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.30
+
+2017-02-07  23:27  Christos Zoulas <christos@zoulas.com>
+
+       * If we exceeded the offset in a search return no match
+         (Christoph Biedl)
+       * Be more lenient on corrupt CDF files (Christoph Biedl)
+
+2017-02-04  16:46  Christos Zoulas <christos@zoulas.com>
+
+       * pacify ubsan sign extension (oss-fuzz/524)
+
+2017-02-01  12:42  Christos Zoulas <christos@zoulas.com>
+
+       * off by one in cdf parsing (PR/593)
+       * report debugging sections in elf (PR/591)
+
+2016-11-06  10:52  Christos Zoulas <christos@zoulas.com>
+
+       * Allow @@@ in extensions
+       * Add missing overflow check in der magic (Jonas Wagner)
+
+2016-10-25  10:40  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.29
+
+2016-10-24  11:20  Christos Zoulas <christos@zoulas.com>
+
+       * der getlength overflow (Jonas Wagner)
+       * multiple magic file load failure (Christoph Biedl)
+
+2016-10-17  11:26  Christos Zoulas <christos@zoulas.com>
+
+       * CDF parsing improvements (Guy Helmer)
+
+2016-07-20   7:26  Christos Zoulas <christos@zoulas.com>
+
+       * Add support for signed indirect offsets
+
+2016-07-18   7:41  Christos Zoulas <christos@zoulas.com>
+
+       * cat /dev/null | file - should print empty (Christoph Biedl)
+
+2016-07-05  15:20  Christos Zoulas <christos@zoulas.com>
+
+       * Bump string size from 64 to 96.
+
+2016-06-13  20:20  Christos Zoulas <christos@zoulas.com>
+
+       * PR/556: Fix separators on annotations.
+
+2016-06-13  19:40  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.28
+       * fix leak on allocation failure
+
+2016-06-01   1:20  Christos Zoulas <christos@zoulas.com>
+
+       * PR/555: Avoid overflow for offset > nbytes
+       * PR/550: Segv on DER parsing:
+           - use the correct variable for length
+           - set offset to 0 on failure.
+
+2016-05-13  12:00  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.27
+
+2016-04-18   9:35  Christos Zoulas <christos@zoulas.com>
+
+       * Errors comparing DER entries or computing offsets
+         are just indications of malformed non-DER files.
+         Don't print them.
+       * Offset comparison was off-by-one.
+       * Fix compression code (Werner Fink)
+       * Put new bytes constant in the right file (not the generated one)
+
+2016-04-16  18:34  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.26
+
+2016-03-31  13:50  Christos Zoulas <christos@zoulas.com>
+
+       * make the number of bytes read from files configurable.
+
+2016-03-21  13:40  Christos Zoulas <christos@zoulas.com>
+
+       * Add bounds checks for DER code (discovered by Thomas Jarosch)
+       * Change indirect recursion limit to indirect use count and
+         bump from 15 to 50 to prevent abuse.
+
+2016-03-13  20:39  Christos Zoulas <christos@zoulas.com>
+
+       * Add -00 which prints filename\0description\0
+
+2016-03-01  13:28  Christos Zoulas <christos@zoulas.com>
+
+       * Fix ID3 indirect parsing
+
+2016-01-19  10:18  Christos Zoulas <christos@zoulas.com>
+
+       * add DER parsing capability
+
+2015-11-13  10:35  Christos Zoulas <christos@zoulas.com>
+
+       * provide dprintf(3) for the OS's that don't have it.
+
+2015-11-11  16:25  Christos Zoulas <christos@zoulas.com>
+
+       * redo the compression code report decompression errors
+
+2015-11-10  23:25  Christos Zoulas <christos@zoulas.com>
+
+       * REG_STARTEND code is not working as expected, delete it.
+
+2015-11-09  16:05  Christos Zoulas <christos@zoulas.com>
+
+       * Add zlib support if we have it.
+
+2015-11-05  11:22  Christos Zoulas <christos@zoulas.com>
+
+       * PR/492: compression forking was broken with magic_buffer.
+
+2015-09-16   9:50  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.25
+
+2015-09-11  13:25  Christos Zoulas <christos@zoulas.com>
+
+       * add a limit to the length of regex searches
+
+2015-09-08   9:50  Christos Zoulas <christos@zoulas.com>
+
+       * fix problems with --parameter (Christoph Biedl)
+
+2015-07-11  10:35  Christos Zoulas <christos@zoulas.com>
+
+       * Windows fixes PR/466 (Jason Hood)
+
+2015-07-09  10:35  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.24
+
+2015-06-11   8:52  Christos Zoulas <christos@zoulas.com>
+
+       * redo long option encoding to fix off-by-one in 5.23
+
+2015-06-10  13:50  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.23
+
+2015-06-09  16:10  Christos Zoulas <christos@zoulas.com>
+
+       * Fix issue with regex range for magic with offset
+       * Always return true from mget with USE (success to mget not match
+         indication). Fixes mime evaluation after USE magic
+       * PR/459: Don't insert magic entries to the list if there are parsing
+         errors for them.
+
+2015-06-03  16:00  Christos Zoulas <christos@zoulas.com>
+
+       * PR/455: Add utf-7 encoding
+
+2015-06-03  14:30  Christos Zoulas <christos@zoulas.com>
+
+       * PR/455: Implement -Z, look inside, but don't report on compression
+       * PR/454: Fix allocation error on bad magic.
+
+2015-05-29  10:30  Christos Zoulas <christos@zoulas.com>
+
+       * handle MAGIC_CONTINUE everywhere, not just in softmagic
+
+2015-05-21  14:30  Christos Zoulas <christos@zoulas.com>
+
+       * don't print descriptions for NAME types when mime.
+
+2015-04-09  15:59  Christos Zoulas <christos@zoulas.com>
+
+       * Add --extension to list the known extensions for this file type
+         Idea by Andrew J Roazen
+
+2015-02-14  12:23  Christos Zoulas <christos@zoulas.com>
+
+       * Bump file search buffer size to 1M.
+
+2015-01-09  14:35  Christos Zoulas <christos@zoulas.com>
+
+       * Fix multiple issues with date formats reported by Christoph Biedl:
+               - T_LOCAL meaning was reversed
+               - Arithmetic did not work
+         Also stop adjusting daylight savings for gmt printing.
+
+2015-01-05  13:00  Christos Zoulas <christos@zoulas.com>
+
+       * PR/411: Fix memory corruption from corrupt cdf file.
+
+2015-01-02  15:15  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.22
+
+2015-01-01  12:01  Christos Zoulas <christos@zoulas.com>
+
+       * add indirect relative for TIFF/Exif
+
+2014-12-16  18:10  Christos Zoulas <christos@zoulas.com>
+
+       * restructure elf note printing to avoid repeated messages
+       * add note limit, suggested by Alexander Cherepanov
+
+2014-12-16  16:53  Christos Zoulas <christos@zoulas.com>
+
+       * Bail out on partial pread()'s (Alexander Cherepanov)
+       * Fix incorrect bounds check in file_printable (Alexander Cherepanov)
+
+2014-12-11  20:01  Christos Zoulas <christos@zoulas.com>
+
+       * PR/405: ignore SIGPIPE from uncompress programs
+       * change printable -> file_printable and use it in
+         more places for safety
+       * in ELF, instead of "(uses dynamic libraries)" when PT_INTERP
+         is present print the interpreter name.
+
+2014-12-10  20:01  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.21
+
+2014-11-27  18:40  Christos Zoulas <christos@zoulas.com>
+
+       * Allow setting more parameters from the command line.
+       * Split name/use and indirect magic recursion limits.
+
+2014-11-27  11:12  Christos Zoulas <christos@zoulas.com>
+
+       * Adjust ELF parameters and the default recursion
+         level.
+       * Allow setting the recursion level dynamically.
+
+2014-11-24   8:55  Christos Zoulas <christos@zoulas.com>
+
+       * The following fixes resulted from Thomas Jarosch's fuzzing
+         tests that revealed severe performance issues on pathological
+         input:
+           - limit number of elf program and sections processing
+           - abort elf note processing quickly
+           - reduce the number of recursion levels from 20 to 10
+           - preserve error messages in indirect magic handling
+
+       This is tracked as CVE-2014-8116 and CVE-2014-8117
+
+2014-11-12  10:30  Christos Zoulas <christos@zoulas.com>
+
+       * fix bogus free in the user buffer case.
+
+2014-11-11  12:35  Christos Zoulas <christos@zoulas.com>
+
+       * fix out of bounds read for pascal strings
+       * fix memory leak (not freeing the head of each mlist)
+
+2014-11-07  10:25  Christos Zoulas <christos@zoulas.com>
+
+       * When printing strings from a file, convert them to printable
+         on a byte by byte basis, so that we don't get issues with
+         locale's trying to interpret random byte streams as UTF-8 and
+         having printf error out with EILSEQ.
+
+2014-10-17  11:48  Christos Zoulas <christos@zoulas.com>
+
+       * fix bounds in note reading (Francisco Alonso / Red Hat)
+
+2014-10-11  15:02  Christos Zoulas <christos@zoulas.com>
+
+       * fix autoconf glue for setlocale and locale_t; some OS's
+         have locale_t in xlocale.h
+
+2014-10-10  15:01  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.20
+
+2014-08-17  10:01  Christos Zoulas <christos@zoulas.com>
+
+       * recognize encrypted CDF documents
+
+2014-08-04   9:18  Christos Zoulas <christos@zoulas.com>
+
+       * add magic_load_buffers from Brooks Davis
+
+2014-07-24  16:40  Christos Zoulas <christos@zoulas.com>
+
+       * add thumbs.db support
+
+2014-06-12  12:28  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.19
+
+2014-06-09   9:04  Christos Zoulas <christos@zoulas.com>
+
+       * Misc buffer overruns and missing buffer size tests in cdf parsing
+         (Francisco Alonso, Jan Kaluza)
+
+2014-06-02  14:50  Christos Zoulas <christos@zoulas.com>
+
+       * Enforce limit of 8K on regex searches that have no limits
+       * Allow the l modifier for regex to mean line count. Default
+         to byte count. If line count is specified, assume a max
+         of 80 characters per line to limit the byte count.
+       * Don't allow conversions to be used for dates, allowing
+         the mask field to be used as an offset.
+
+2014-05-30  12:51  Christos Zoulas <christos@zoulas.com>
+
+       * Make the range operator limit the length of the
+         regex search.
+
+2014-05-14  19:23  Christos Zoulas <christos@zoulas.com>
+
+       * PR/347: Windows fixes
+       * PR/352: Hangul word processor recognition
+       * PR/354: Encoding irregularities in text files
+
+2014-05-06  6:12  Christos Zoulas <christos@zoulas.com>
+
+       * Fix uninitialized title in CDF files (Jan Kaluza)
+
+2014-05-04  14:55  Christos Zoulas <christos@zoulas.com>
+
+       * PR/351: Fix compilation of empty files
+
+2014-04-30  17:39  Christos Zoulas <christos@zoulas.com>
+
+       * Fix integer formats: We don't specify 'l' or
+         'h' and 'hh' specifiers anymore, only 'll' for
+         quads and nothing for the rest. This is so that
+         magic writing is simpler.
+
+2014-04-01  15:25  Christos Zoulas <christos@zoulas.com>
+
+       * PR/341: Jan Kaluza, fix memory leak
+       * PR/342: Jan Kaluza, fix out of bounds read
+
+2014-03-28  15:25  Christos Zoulas <christos@zoulas.com>
+
+       * Fix issue with long formats not matching fmtcheck
+
+2014-03-26  11:25  Christos Zoulas <christos@zoulas.com>
+
+       * release 5.18
+
+2014-03-15  17:45  Christos Zoulas <christos@zoulas.com>
+
+       * add fmtcheck(3) for those who don't have it
+
+2014-03-14  15:12  Christos Zoulas <christos@zoulas.com>
+
+       * prevent mime entries from being attached to magic
+         entries with no descriptions
+
+       * adjust magic strength for regex type
+
+       * remove superfluous ascmagic with encoding test
+
+2014-03-06  12:01  Christos Zoulas <christos@zoulas.com>
+
+       * fix regression fix echo -ne "\012\013\014" | file -i -
+         which printed "binary" instead of "application/octet-stream"
+
+       * add size_t overflow check for magic file size
+
+2014-02-27  16:01  Christos Zoulas <christos@zoulas.com>
+
+       * experimental support for matching with CFD CLSID
+
+2014-02-18  13:04  Kimmo Suominen (kimmo@suominen.com)
+
+       * Cache old LC_CTYPE locale before setting it to "C", so
+         we can use it to restore LC_CTYPE instead of asking
+         setlocale() to scan the environment variables.
+
+2014-02-12  18:21  Christos Zoulas <christos@zoulas.com>
+
+       * Count recursion levels through indirect magic
+
+2014-02-11  10:40  Christos Zoulas <christos@zoulas.com>
+
+       * Prevent infinite recursion on files with indirect offsets of 0
+
+2014-01-30  21:00  Christos Zoulas <christos@zoulas.com>
+
+       * Add -E flag that makes file print filesystem errors to stderr
+         and exit.
+
+2014-01-08  17:20  Christos Zoulas <christos@zoulas.com>
+
+       * mime printing could print results from multiple magic entries
+         if there were multiple matches.
+       * in some cases overflow was not detected when computing offsets
+         in softmagic.
+
+2013-12-05  12:00  Christos Zoulas <christos@zoulas.com>
+
+       * use strcasestr() to for cdf strings
+       * reset to the "C" locale while doing regex operations, or case
+         insensitive comparisons; this is provisional
+
+2013-11-19  20:10  Christos Zoulas <christos@zoulas.com>
+
+       * always leave magic file loaded, don't unload for magic_check, etc.
+       * fix default encoding to binary instead of unknown which broke recently
+       * handle empty and one byte files, less specially so that
+         --mime-encoding does not break completely.
+               `
+2013-11-06  14:40  Christos Zoulas <christos@zoulas.com>
+
+       * fix erroneous non-zero exit code from non-existent file and message
+
+2013-10-29  14:25  Christos Zoulas <christos@zoulas.com>
+
+       * add CDF MSI file detection (Guy Helmer)
+
+2013-09-03  11:56  Christos Zoulas <christos@zoulas.com>
+
+       * Don't mix errors and regular output if there was an error
+       * in magic_descriptor() don't close the file and try to restore
+         its position
+
+2013-05-30  17:25  Christos Zoulas <christos@zoulas.com>
+
+       * Don't treat magic as an error if offset was past EOF (Christoph Biedl)
+
+2013-05-28  17:25  Christos Zoulas <christos@zoulas.com>
+
+       * Fix spacing issues in softmagic and elf (Jan Kaluza)
+
+2013-05-02  18:00  Christos Zoulas <christos@zoulas.com>
+
+       * Fix segmentation fault with multiple magic_load commands.
+
+2013-04-22  11:20  Christos Zoulas <christos@zoulas.com>
+
+       * The way "default" was implemented was not very useful
+         because the "if something was printed at that level"
+         was not easily controlled by the user, and the format
+         was bound to a string which is too restrictive. Add
+         a "clear" for that level keyword and make "default"
+         void. This way one can do:
+
+               >>13    clear   x
+               >>13    lelong  1       foo
+               >>13    lelong  2       bar
+               >>13    default x
+               >>>13   lelong  x       unknown %x
+
+2013-03-25  13:20  Christos Zoulas <christos@zoulas.com>
+
+       * disallow strength setting in "name" entries
+
+2013-03-06  21:24  Christos Zoulas <christos@zoulas.com>
+
+       * fix recursive magic separator printing
+
+2013-02-26  19:28  Christos Zoulas <christos@zoulas.com>
+
+       * limit recursion level for mget
+       * fix pread() related breakage in cdf
+       * handle offsets properly in recursive "use"
+
+2013-02-18  10:39  Christos Zoulas <christos@zoulas.com>
+
+       * add elf reading of debug info to determine if file is stripped
+         (Jan Kaluza)
+       * use pread()
+
+2013-01-25  18:05  Christos Zoulas <christos@zoulas.com>
+
+       * change mime description size from 64 to 80 to accommodate OOXML.
+
+2013-01-11  14:50  Christos Zoulas <christos@zoulas.com>
+
+       * Warn about inconsistent continuation levels.
+       * Change fsmagic to add a space after it prints.
+
+2013-01-10  21:00  Christos Zoulas <christos@zoulas.com>
+
+       * Make getline public so that file can link against it.
+         Perhaps it is better to rename it, or hide it differently.
+         Fixes builds on platforms that do not provide it.
+
+2013-01-07  16:30  Christos Zoulas <christos@zoulas.com>
+
+       * Add SuS d{,1,2,4,8}, u{,1,2,4,8} and document
+         what long, int, short, etc is (Guy Harris)
+
+2013-01-06  11:20  Christos Zoulas <christos@zoulas.com>
+
+       * add magic_version function and constant
+       * Redo memory allocation and de-allocation.
+         (prevents double frees on non mmap platforms)
+       * Fix bug with name/use having to do with passing
+         found state from the parent to the child and back.
+
+2012-12-19   8:47  Christos Zoulas <christos@zoulas.com>
+
+       * Only print elf capabilities for archs we know (Jan Kaluza)
+
+2012-10-30  19:14  Christos Zoulas <christos@zoulas.com>
+
+       * Add "name" and "use" file types in order to look
+         inside mach-o files.
+
+2012-09-06  10:40  Christos Zoulas <christos@zoulas.com>
+
+       * make --version exit 0 (Matthew Schultz)
+       * add string/T (Jan Kaluza)
+
+2012-08-09  2:15  Christos Zoulas <christos@zoulas.com>
+
+       * add z and t modifiers for our own vasprintf
+       * search for $HOME/.magic.mgc if it is there first
+       * fix reads from a pipe, and preserve errno
+
+2012-05-15  13:12  Christos Zoulas <christos@zoulas.com>
+
+       * use ctime_r, asctime_r
+
+2012-04-06  17:18  Christos Zoulas <christos@zoulas.com>
+
+       * Fixes for indirect offsets to handle apple disk formats
+
+2012-04-03  18:26  Christos Zoulas <christos@zoulas.com>
+
+       * Add windows date field types
+       * More info for windows shortcuts (incomplete)
+
+2012-02-20  17:33  Christos Zoulas <christos@zoulas.com>
+
+       * Fix CDF parsing issues found by CERT's fuzzing tool (Will Dormann)
+
+2011-12-15  12:17  Chris Metcalf <cmetcalf@tilera.com>
+
+       * Support Tilera architectures (tile64, tilepro, tilegx).
+
+2011-12-16  16:33  Reuben Thomas <rrt@sc3d.org>
+
+       * Add magic for /usr/bin/env Perl scripts
+       * Weaken generic script magic to avoid clashing with
+       language-specific magic.
+
+2011-12-08  13:37  Reuben Thomas <rrt@sc3d.org>
+
+       * Simplify if (p) free(p) to free(p).
+
+2011-12-08  13:07  Reuben Thomas <rrt@sc3d.org>
+
+       * Remove hardwired token finding (names.h), turning it into soft
+       magic. Patterns are either anchored regexs or search/8192. English
+       language detection and PL/1 detection have been removed as they
+       were too fragile. -e tokens is still accepted for backwards
+       compatibility.
+       * Move 3ds patterns (which are commented out anyway) into autodesk
+       (they were, oddly, in c-lang).
+
+2011-12-06  00:16  Reuben Thomas <rrt@sc3d.org>
+
+       * Tweak strength of generic hash-bang detectors to be less than
+       specific ones.
+       * Make an inconsistent description of Python scripts consistent.
+
+2011-12-05  23:58  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix minor error in file(1).
+
+2011-11-05  00:00  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix issue #150 (I hope).
+
+2011-09-22  12:57  Christos Zoulas <christos@zoulas.com>
+
+       * Python3 binding fixes from Kelly Anderson
+
+2011-09-20  11:32  Christos Zoulas <christos@zoulas.com>
+
+       * If a string type magic entry is marked as text or binary
+         only match text files against text entries and binary
+         files against binary entries.
+
+2011-09-01  12:12  Christos Zoulas <christos@zoulas.com>
+
+       * Don't wait for any subprocess, just the one we forked.
+
+2011-08-26  16:40  Christos Zoulas <christos@zoulas.com>
+
+       * If the application name is not set in a cdf file, try to see
+         if it has a directory with the application name on it.
+
+2011-08-17  14:32  Christos Zoulas <christos@zoulas.com>
+
+       * Fix ELF lseek(2) madness. Inspired by PR/134 by Jan Kaluza
+
+2011-08-14  09:03  Christos Zoulas <christos@zoulas.com>
+
+       * Don't use variable string formats.
+
+2011-07-12  12:32  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix detection of Zip files (Mantis #128).
+       * Make some minor improvements to file(1).
+       * Rename MIME types for filesystem objects for consistency with
+         xdg-utils. Typically this means that application/x-foo becomes
+         inode/foo, but some names also change slightly, e.g.
+         application/x-character-device becomes inode/chardevice.
+
+2011-05-10  20:57  Christos Zoulas <christos@zoulas.com>
+
+       * fix mingw compilation (Abradoks)
+
+2011-05-10  20:57  Christos Zoulas <christos@zoulas.com>
+
+       * remove patchlevel.h
+       * Fix read past allocated memory caused by double-incrementing
+         a pointer in a loop (reported by Roberto Maar)
+
+2011-03-30  15:45  Christos Zoulas <christos@zoulas.com>
+
+       * Fix cdf string buffer setting (Sven Anders)
+
+2011-03-20  16:35  Christos Zoulas <christos@zoulas.com>
+
+       * Eliminate MAXPATHLEN and use dynamic allocation for
+         path and file buffers.
+
+2011-03-15  18:15  Christos Zoulas <christos@zoulas.com>
+
+       * binary tests on magic entries with masks could spuriously
+         get converted to ascii.
+
+2011-03-12  18:06  Reuben Thomas <rrt@sc3d.org>
+
+       * Improve file.man (remove BUGS, present email addresses consistently).
+
+2011-03-07  19:38  Christos Zoulas <christos@zoulas.com>
+
+       * add lrzip support (from Ville Skytta)
+
+2011-02-10  16:36  Christos Zoulas <christos@zoulas.com>
+
+       * fix CDF bounds checking (Guy Helmer)
+
+2011-02-10  12:03  Christos Zoulas <christos@zoulas.com>
+
+       * add cdf_ctime() that prints a meaningful error when time cannot
+         be converted.
+
+2011-02-02  20:40  Christos Zoulas <christos@zoulas.com>
+
+       * help and version output to stdout.
+
+       * When matching softmagic for ascii files, don't just print
+         the softmagic classification, keep going and print the
+         text classification too. This fixes broken troff files when
+         we moved them from keyword recognition to softmagic
+         (they stopped printing "with CRLF" etc.)
+         Reported by Doug McIlroy.
+
+2011-01-16  19:31  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix two potential buffer overruns in apprentice_list.
+
+2011-01-14  22:33  Reuben Thomas <rrt@sc3d.org>
+
+       * New Python binding in pure Python.
+       * Update libmagic(3).
+
+2011-01-06  21:40  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix Python bindings (including recent Python 3 compatibility
+         update).
+
+2011-01-04  18:43  Reuben Thomas <rrt@sc3d.org>
+
+       * magic/Makefile.am: make it easier to recover from magic build failures.
+       * Fix pstring length specifier parsing to avoid generating invalid
+         magic files.
+       * Add pstring length "J" (for "JPEG") to specify that the length
+         include itself.
+       * Fix JPEG comment parsing at last using pstring/HJ!
+       * Ignore section 5 man pages in doc/.cvsignore.
+
+2010-12-22  13:12  Christos Zoulas <christos@zoulas.com>
+
+       * Add pstring/BHhLl to specify the type of the length of pascal
+         strings.
+
+2010-11-26  18:39  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix "-e soft": it was ignored when softmagic was called
+         during asciimagic.
+       * Improve comments and use "unsigned char" in tar.h/is_tar.c.
+
+2010-11-05  17:26  Reuben Thomas <rrt@sc3d.org>
+
+       * Make bug reporting addresses more visible.
+
+2010-11-01  18:35  Reuben Thomas <rrt@sc3d.org>
+
+       * Add tcl magic from Gustaf Neumann
+
+2010-10-24  10:42  Christos Zoulas <christos@zoulas.com>
+
+       * Fix the whitespace comparing code (Christopher Chittleborough)
+
+2010-10-06  21:05  Christos Zoulas <christos@zoulas.com>
+
+       * allow string/t to work (Jan Kaluza)
+
+2010-09-20  22:11  Reuben Thomas <rrt@sc3d.org>
+
+       * Apply some patches from Ubuntu and Fedora.
+
+2010-09-20  21:16  Reuben Thomas <rrt@sc3d.org>
+
+       * Apply all patches from Debian package 5.04-6 which have not
+         already been applied and are not Debian-specific.
+
+2010-09-20  15:24  Reuben Thomas <rrt@sc3d.org>
+
+       * Minor security fix to softmagic.c (don't use untrusted
+         string as printf format).
+
+2010-07-21  12:20  Christos Zoulas <christos@zoulas.com>
+
+       * MINGW32 portability from LRN
+
+       * Don't warn about escaping magic regex chars when we are in a regex.
+
+2010-07-19  10:55  Christos Zoulas <christos@zoulas.com>
+
+       * Only try to print prpsinfo for core files. (Jan Kaluza)
+
+2010-04-22  12:55  Christos Zoulas <christos@zoulas.com>
+
+       * Try more elf offsets for Debian core files.  (Arnaud Giersch)
+
+2010-02-20  15:18  Reuben Thomas <rrt@sc3d.org>
+
+       * Clarify which sort of CDF we mean.
+
+2010-02-14  22:58  Reuben Thomas <rrt@sc3d.org>
+
+       * Re-jig Zip file type magic so that unsupported special
+         Zip types (those with "mimetype" at offset 30) can be
+         recognized.
+
+2010-02-02  21:50  Reuben Thomas <rrt@sc3d.org>
+
+       * Add support for OCF (EPUB) files (application/epub+zip)
+
+2010-01-28  18:25  Christos Zoulas <christos@zoulas.com>
+
+       * Fix core-dump from unbound loop:
+         https://bugzilla.redhat.com/show_bug.cgi?id=533245
+
+2010-01-22  15:45  Christos Zoulas <christos@zoulas.com>
+
+       * print proper mime for crystal reports file
+
+       * print the last summary information of a cdf document, not the
+         first so that nested documents print the right info
+
+2010-01-16  18:42  Charles Longeau <chl@tuxfamily.org>
+
+       * bring back some fixes from OpenBSD:
+               - make gcc2 builds file
+               - fix typos in a magic file comment
+
+2009-11-17  18:35  Christos Zoulas <christos@zoulas.com>
+
+       * ctime/asctime can return NULL on some OS's although
+         they should not (Toshit Antani)
+
+2009-09-14  13:49  Christos Zoulas <christos@zoulas.com>
+
+       * Centralize magic path handling routines and remove the
+         special-casing from file.c so that the python module for
+         example comes up with the same magic path (Fixes ~/.magic
+         handling) (from Gab)
+
+2009-09-11  23:38  Reuben Thomas <rrt@sc3d.org>
+
+       * When magic argument is a directory, read the files in
+         strcmp-sorted order (fixes Debian bug #488562 and our own FIXME).
+
+2009-09-11  13:11  Reuben Thomas <rrt@sc3d.org>
+
+       * Combine overlapping epoc and psion magic files into one (epoc).
+
+       * Add some more EPOC MIME types.
+
+2009-08-19  15:55  Christos Zoulas <christos@zoulas.com>
+
+       * Fix 3 bugs (From Ian Darwin):
+           - file_showstr could move one past the end of the array
+           - parse_apple did not nul terminate the string in the overflow case
+           - parse_mime truncated the wrong string in the overflow case
+
+2009-08-12  12:28  Robert Byrnes  <byrnes@wildpumpkin.net>
+
+       * Include Localstuff when compiling magic.
+
+2009-07-15  10:05  Christos Zoulas <christos@zoulas.com>
+
+       * Fix logic for including mygetopts.h
+
+       * Make cdf.c compile again with debugging
+
+       * Add the necessary field handling for crystal reports files to work
+
+2009-06-23 01:34  Reuben Thomas <rrt@sc3d.org>
+
+       * Stop "(if" identifying Lisp files, that's plain dumb!
+
+2009-06-09 22:13  Reuben Thomas <rrt@sc3d.org>
+
+       * Add a couple of missing MP3 MIME types.
+
+2009-05-27 23:00  Reuben Thomas <rrt@sc3d.org>
+
+       * Add full range of hash-bang tests for Python and Ruby.
+
+       * Add MIME types for Python and Ruby scripts.
+
+2009-05-13  10:44  Christos Zoulas <christos@zoulas.com>
+
+       * off by one in parsing hw capabilities in elf
+         (Cheng Renquan)
+
+2009-05-08  13:40  Christos Zoulas <christos@zoulas.com>
+
+       * lint fixes and more from NetBSD
+
+2009-05-06  10:25  Christos Zoulas <christos@zoulas.com>
+
+       * Avoid null dereference in cdf code (Drew Yao)
+
+       * More cdf bounds checks and overflow checks
+
+2009-05-01  18:37  Christos Zoulas <christos@zoulas.com>
+
+       * Buffer overflow fixes from Drew Yao
+
+2009-04-30  17:10  Christos Zoulas <christos@zoulas.com>
+
+       * Fix more cdf lossage. All the documents I have
+         right now print the correct information.
+
+2009-03-27  18:43  Christos Zoulas <christos@zoulas.com>
+
+       * don't print \012- separators in the same magic entry
+         if it consists of multiple magic printing lines.
+
+2009-03-23  10:20  Christos Zoulas <christos@zoulas.com>
+
+       * Avoid file descriptor leak in compress code from
+         (Daniel Novotny)
+
+2009-03-18  16:50  Christos Zoulas <christos@zoulas.com>
+
+       * Allow escaping of relation characters, so that we can say \^[A-Z]
+         and the ^ is not eaten as a relation char.
+
+       * Fix troff and fortran to their previous glory using
+         regex. This was broken since their removel from ascmagic.
+
+2009-03-10  16:50  Christos Zoulas <christos@zoulas.com>
+
+       * don't use strlen in strndup() (Toby Peterson)
+
+2009-03-10  7:45  Christos Zoulas <christos@zoulas.com>
+
+       * avoid c99 syntax.
+
+2009-02-23 15:45  Christos Zoulas <christos@zoulas.com>
+
+       * make the cdf code use the buffer first if available,
+         and then the fd code.
+
+2009-02-13 13:45  Christos Zoulas <christos@zoulas.com>
+
+       * look for struct option to determine if getopt.h is usable for IRIX.
+
+       * sanitize cdf document strings
+
+2009-02-04 13:25  Christos Zoulas <christos@zoulas.com>
+
+       * fix OS/2 warnings.
+
+2008-12-12 15:50  Christos Zoulas <christos@zoulas.com>
+
+       * fix initial offset calculation for non 4K sector files
+
+       * add loop limits to avoid DoS attacks by constructing
+         looping sector references.
+
+2008-12-03 13:05  Christos Zoulas <christos@zoulas.com>
+
+       * fix memory botches on cdf file parsing.
+
+       * exit with non-zero value for any error, not just for the last
+         file processed.
+
+2008-11-09 20:42  Charles Longeau <chl@tuxfamily.org>
+
+       * Replace all str{cpy,cat} functions with strl{cpy,cat}
+       * Ensure that strl{cpy,cat} are included in libmagic,
+         as needed.
+
+2008-11-06 18:18  Christos Zoulas <christos@zoulas.com>
+
+       * Handle ID3 format files.
+
+2008-11-06 23:00  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix --mime, --mime-type and --mime-encoding under new scheme.
+
+       * Rename "ascii" to "text" and add "encoding" test.
+
+       * Return a precise ("utf-16le" or "utf-16be") MIME charset for
+         UTF-16.
+
+       * Fix error in comment caused by automatic indentation adding
+         words!
+
+2008-11-06 10:35  Christos Zoulas <christos@astron.com>
+
+       * use memchr instead of strchr because the string
+         might not be NUL terminated (Scott MacVicar)
+
+2008-11-03 07:31  Reuben Thomas <rrt@sc3d.org>
+
+       * Fix a printf with a non-literal format string.
+
+       * Fix formatting and punctuation of help for "--apple".
+
+2008-10-30 11:00  Reuben Thomas <rrt@sc3d.org>
+
+       * Correct words counts in comments of struct magic.
+
+       * Fix handle_annotation to allow both Apple and MIME types to be
+         printed, and to return correct code if MIME type is
+         printed (1, not 0) or if there's an error (-1 not 1).
+
+       * Fix output of charset for MIME type (precede with semi-colon;
+         fixes Debian bug #501460).
+
+       * Fix potential attacks via conversion specifications in magic
+         strings.
+
+       * Add a FIXME for Debian bug #488562 (magic files should be
+         read in a defined order, by sorting the names).
+
+2008-10-18 16:45  Christos Zoulas <christos@astron.com>
+
+       * Added APPLE file creator/type
+
+2008-10-12 10:20  Christos Zoulas <christos@astron.com>
+
+       * Added CDF parsing
+
+2008-10-09 16:40  Christos Zoulas <christos@astron.com>
+
+       * filesystem and msdos patches (Joerg Jenderek)
+
+2008-10-09 13:20  Christos Zoulas <christos@astron.com>
+
+       * correct --exclude documentation issues: remove troff and fortran
+         and rename "token" to "tokens". (Randy McMurchy)
+
+2008-10-01 10:30  Christos Zoulas <christos@astron.com>
+
+       * Read ~/.magic in addition to the default magic file not instead
+         of, as documented in the man page.
+
+2008-09-10 21:30  Reuben Thomas  <rrt@sc3d.org>
+
+       * Comment out graphviz patterns, as they match too many files.
+
+2008-08-30 12:54  Christos Zoulas <christos@astron.com>
+
+       * Don't eat trailing \n in magic enties.
+
+       * Cast defines to allow compilation using a c++ compiler.
+
+2008-08-25 23:56  Reuben Thomas  <rrt@sc3d.org>
+
+       * Add text/x-lua MIME type for Lua scripts.
+
+       * Escape { in regex in graphviz patterns.
+
+2008-07-26 00:59  Reuben Thomas  <rrt@sc3d.org>
+
+       * Add MIME types for special files.
+
+       * Use access to give more accurate information for files that
+         can't be opened.
+
+       * Add a TODO list.
+
+2008-07-02 11:15  Christos Zoulas  <christos@astron.com>
+
+       * add !:strength op to adjust magic strength (experimental)
+
+2008-06-16 21:41  Reuben Thomas  <rrt@sc3d.org>
+
+       * Fix automake error in configure.ac.
+
+       * Add MIME type for Psion Sketch files.
+
+2008-06-05 08:59  Christos Zoulas  <christos@astron.com>
+
+       * Don't print warnings about bad namesize in stripped
+         binaries with PT_NOTE is still there, and the actual
+         note is gone (Jakub Jelinek)
+
+2008-05-28 15:12  Robert Byrnes  <byrnes@wildpumpkin.net>
+
+       * magic/Magdir/elf:
+         Note invalid byte order for little-endian SPARC32PLUS.
+         Add SPARC V9 vendor extensions and memory model.
+
+       * src/elfclass.h:
+         Pass target machine to doshn (for Solaris hardware capabilities).
+
+       * src/readelf.c (doshn):
+         Add support for Solaris hardware/software capabilities.
+
+       * src/readelf.h:
+         Ditto.
+
+       * src/vasprintf.c (dispatch):
+         Add support for ll modifier.
+
+2008-05-16 10:25  Christos Zoulas  <christos@astron.com>
+
+       * Fix compiler warnings.
+
+       * remove stray printf, and fix a vprintf bug. (Martin Dorey)
+
+2008-05-06 00:13  Robert Byrnes  <byrnes@wildpumpkin.net>
+
+       * src/Makefile.am:
+         Ensure that getopt_long and [v]asprintf are included in libmagic,
+         as needed.
+
+         Remove unnecessary EXTRA_DIST.
+
+       * src/Makefile.in:
+         Rerun automake.
+
+       * src/vasprintf.c (dispatch):
+         Fix variable precision bug: be sure to step past '*'.
+
+       * src/vasprintf.c (core):
+         Remove unreachable code.
+
+       * src/apprentice.c (set_test_type):
+         Add cast to avoid compiler warning.
+
+2008-04-22 23:45  Christos Zoulas  <christos@astron.com>
+
+       * Add magic submission guidelines (Abel Cheung)
+
+       * split msdos and windows magic (Abel Cheung)
+
+2008-04-04 11:00  Christos Zoulas  <christos@astron.com>
+
+       * >= <= is not supported, so fix the magic and warn about it.
+         reported by: Thien-Thi Nguyen <ttn@gnuvola.org>
+
+2008-03-27 16:16  Robert Byrnes  <byrnes@wildpumpkin.net>
+
+       * src/readelf.c (donote):
+         ELF core file command name/line bug fixes and enhancements:
+
+         Try larger offsets first to avoid false matches
+         from earlier data that happen to look like strings;
+         this primarily affected SunOS 5.x 32-bit Intel core files.
+
+         Add support for command line (instead of just short name)
+         for SunOS 5.x.
+
+         Add information about NT_PSINFO for SunOS 5.x.
+
+         Only trim whitespace from end of command line.
+
+2007-02-11 01:36 Reuben Thomas <rrt@sc3d.org>
+
+       * Change strength of ! from MULT to 0, as it matches almost
+                 anything (Reuben Thomas)
+
+       * Debian fixes (Reuben Thomas)
+
+2007-02-11 00:17 Reuben Thomas <rrt@sc3d.org>
+
+       * Clarify UTF-8 BOM message (Reuben Thomas)
+
+       * Add HTML comment to token list in names.h
+
+2007-02-04 15:50 Christos Zoulas <christos@astron.com>
+
+       * Debian fixes (Reuben Thomas)
+
+2007-02-04 11:31 Christos Zoulas <christos@astron.com>
+
+       * !:mime annotations in magic files (Reuben Thomas)
+
+2007-01-29 15:35 Christos Zoulas <christos@astron.com>
+
+       * zero out utime/utimes structs (Gavin Atkinson)
+
+2007-01-26 13:45 Christos Zoulas <christos@astron.com>
+
+       * reduce writable data from Diego "Flameeyes" Petten
+
+2007-12-28 15:06 Christos Zoulas <christos@astron.com>
+
+       * strtof detection
+
+       * remove bogus regex magic that could cause a DoS
+
+       * better mismatch version message
+
+2007-12-27 11:35 Christos Zoulas <christos@astron.com>
+
+       * bring back some fixes from OpenBSD
+
+       * treat ELF dynamic objects as executables
+
+       * fix gcc warnings
+
+2007-12-01 19:55 Christos Zoulas <christos@astron.com>
+
+       * make sure we have zlib.h and libz to compile the builtin
+         decompress code
+
+2007-10-28 20:48 Christos Zoulas <christos@astron.com>
+
+       * float and double magic support (Behan Webster)
+
+2007-10-28 20:48 Christos Zoulas <christos@astron.com>
+
+       * Convert fortran to a soft test (Reuben Thomas)
+
+2007-10-23  5:25 Christos Zoulas <christos@astron.com>
+
+       * Add --with-filename, and --no-filename (Reuben Thomas)
+
+2007-10-23  3:59 Christos Zoulas <christos@astron.com>
+
+       * Rest of the mime split (Reuben Thomas)
+
+       * Make usage message generated from the flags so that
+         they stay consistent (Reuben Thomas)
+
+2007-10-20  3:06 Christos Zoulas <christos@astron.com>
+
+       * typo in comment, missing ifdef QUICK, remove unneeded code
+               (Charles Longeau)
+
+2007-10-17  3:33 Christos Zoulas <christos@astron.com>
+
+       * Fix problem printing -\012 in some entries
+
+       * Separate magic type and encoding flags (Reuben Thomas)
+
+2007-10-09  3:55 Christos Zoulas <christos@astron.com>
+
+       * configure fix for int64 and strndup (Reuben Thomas)
+
+2007-09-26  4:45 Christos Zoulas <christos@astron.com>
+
+       * Add magic_descriptor() function.
+
+       * Fix regression in elf reading code where the core name was
+         not being printed.
+
+       * Don't convert NUL's to spaces in {l,b}estring16 (Daniel Dawson)
+
+2007-08-19  6:30 Christos Zoulas <christos@astron.com>
+
+       * Make mime format consistent so that it can
+         be easily parsed:
+             mimetype [charset=character-set] [encoding=encoding-mime-type]
+
+         Remove spurious extra text from some MIME type printouts
+         (mostly in is_tar).
+
+         Fix one case where -i produced nothing at all (for a 1-byte file,
+         which is now classed as application/octet-stream).
+
+         Remove 7/8bit classifications, since they were arbitrary
+         and not based on the file data.
+
+         This work was done by Reuben Thomas
+
+2007-05-24 10:00 Christos Zoulas <christos@astron.com>
+
+       * Fix another integer overflow (Colin Percival)
+
+2007-03-26 13:58 Christos Zoulas <christos@astron.com>
+
+       * make sure that all of struct magic_set is initialized appropriately
+         (Brett)
+
+2007-03-25 17:44 Christos Zoulas <christos@astron.com>
+
+       * reset left bytes in the buffer (Dmitry V. Levin)
+
+       * compilation failed with COMPILE_ONLY and ENABLE_CONDITIONALS
+         (Peter Avalos)
+
+2007-03-15 10:51 Christos Zoulas <christos@astron.com>
+
+       * fix fortran and nroff reversed tests (Dmitry V. Levin)
+
+       * fix exclude option (Dmitry V. Levin)
+
+2007-02-08 17:30 Christos Zoulas <christos@astron.com>
+
+       * fix integer underflow in file_printf which can lead to
+         to exploitable heap overflow (Jean-Sebastien Guay-Lero)
+
+2007-02-05 11:35 Christos Zoulas <christos@astron.com>
+
+       * make socket/pipe reading more robust
+
+2007-01-25 16:01 Christos Zoulas <christos@astron.com>
+
+       * Centralize all the tests in file_buffer.
+
+       * Add exclude flag.
+
+2007-01-18 05:29 Anon Ymous <do@not.spam.me>
+
+       * Move the "type" detection code from parse() into its own table
+         driven routine.  This avoids maintaining multiple lists in
+         file.h.
+
+       * Add an optional conditional field (ust before the type field).
+         This code is wrapped in "#ifdef ENABLE_CONDITIONALS" as it is
+         likely to go away.
+
+2007-01-16 23:24 Anon Ymous <do@not.spam.me>
+
+       * Fix an initialization bug in check_mem().
+
+2007-01-16 14:58 Anon Ymous <do@not.spam.me>
+
+       * Add a "default" type to print a message if nothing previously
+         matched at that level or since the last default at that
+         level.  This is useful for setting up switch-like statements.
+         It can also be used to do if/else constructions without a
+         redundant second test.
+
+       * Fix the "x" special case test so that one can test for that
+         string with "=x".
+
+       * Allow "search" to search the entire buffer if the "/N"
+         search count is missing.
+
+       * Make "regex" work!  It now starts its search at the
+         specified offset and takes an (optional) "/N" line count to
+         specify the search range; otherwise it searches to the end
+         of the file.  The match is now grabbed correctly for format
+         strings and the offset set to the end of the match.
+
+       * Add a "/s" flag to "regex" and "search" to set the offset to
+         the start of the match.  By default the offset is set to the
+         end of the match, as it is with other tests.  This is mostly
+         useful for "regex".
+
+       * Make "search", "string" and "pstring" use the same
+         file_strncmp() routine so that they support the same flags;
+         "bestring16" and "lestring16" call the same routine, but
+         with flags = 0.  Also add a "/C" flag (in analogy to "/c")
+         to ignore the case on uppercase (lowercase) characters in
+         the test string.
+
+       * Strict adherence to C style string escapes.  A warnings are
+         printed when compiling.  Note: previously "\a" was
+         incorrectly translated to 'a' instead of an <alert> (i.e.,
+         BELL, typically 0x07).
+
+       * Make this compile with "-Wall -Wextra" and all the warning
+         flags used with WARNS=4 in the NetBSD source.  Also make it
+         pass lint.
+
+       * Many "cleanups" and hopefully not too many new bugs!
+
+2007-01-16 14:56 Anon Ymous <do@not.spam.me>
+
+       * make several more files compile with gcc warnings
+         on and also make them pass lint.
+
+2007-01-16 14:54 Anon Ymous <do@not.spam.me>
+
+       * fix a puts()/putc() usage goof in file.c
+
+       * make file.c compile with gcc warnings and pass lint
+
+2006-12-11 16:49 Christos Zoulas <christos@astron.com>
+
+       * fix byteswapping issue
+
+       * report the number of bytes we tried to
+         allocate when allocation fails
+
+       * add a few missed cases in the strength routine
+
+2006-12-08 16:32 Christos Zoulas <christos@astron.com>
+
+       * store and print the line number of the magic
+         entry for debugging.
+
+       * if the magic entry did not print anything,
+         don't treat it as a match
+
+       * change the magic strength algorithm to take
+         into account the relationship op.
+
+       * fix a bug in search where we could accidentally
+         return a match.
+
+       * propagate the error return from match to
+         file_softmagic.
+
+2006-11-25 13:35 Christos Zoulas <christos@astron.com>
+
+       * Don't store the current offset in the magic
+         struct, because it needs to be restored and
+         it was not done properly all the time. Bug
+         found by: Arkadiusz Miskiewicz
+
+       * Fix problem in the '\0' separator; and don't
+         print it as an additional separator; print
+         it as the only separator.
+
+2006-11-17 10:51 Christos Zoulas <christos@astron.com>
+
+       * Added a -0 option to print a '\0' separator
+         Etienne Buira <etienne.buira@free.fr>
+
+2006-10-31 15:14 Christos Zoulas <christos@astron.com>
+
+       * Check offset before copying (Mike Frysinger)
+
+       * merge duplicated code
+
+       * add quad date support
+
+       * make sure that we nul terminate desc (Ryoji Kanai)
+
+       * don't process elf notes multiple times
+
+       * allow -z to report empty compressed files
+
+       * use calloc to initialize the ascii buffers (Jos van den Oever)
+
+2006-06-08 11:11 Christos Zoulas <christos@astron.com>
+
+       * QNX fixes (Mike Gorchak)
+
+       * Add quad support.
+
+       * FIFO checks (Dr. Werner Fink)
+
+       * Linux ELF fixes (Dr. Werner Fink)
+
+       * Magic format checks (Dr. Werner Fink)
+
+       * Magic format function improvent (Karl Chen)
+
+2006-05-03 11:11 Christos Zoulas <christos@astron.com>
+
+       * Pick up some elf changes and some constant fixes from SUSE
+
+       * Identify gnu tar vs. posix tar
+
+       * When keep going, don't print spurious newlines (Radek Vokal)
+
+2006-04-01 12:02 Christos Zoulas <christos@astron.com>
+
+       * Use calloc instead of malloc (Mike Frysinger)
+
+       * Fix configure script to detect wctypes.h (Mike Frysinger)
+
+2006-03-02 16:06 Christos Zoulas <christos@astron.com>
+
+       * Print empty if the file is (Mike Frysinger)
+
+       * Don't try to read past the end of the buffer (Mike Frysinger)
+
+       * Sort magic entries by strength [experimental]
+
+2005-11-29 13:26 Christos Zoulas <christos@astron.com>
+
+       * Use iswprint() to convert the output string.
+           (Bastien Nocera)
+
+2005-10-31 8:54 Christos Zoulas <christos@astron.com>
+
+       * Fix regression where the core info was not completely processed
+           (Radek Vokal)
+
+2005-10-20 11:15 Christos Zoulas <christos@astron.com>
+
+       * Middle Endian magic (Diomidis Spinellis)
+
+2005-10-17 11:15 Christos Zoulas <christos@astron.com>
+
+       * Open with O_BINARY for CYGWIN (Corinna Vinschen)
+
+       * Don't close stdin (Arkadiusz Miskiewicz)
+
+       * Look for note sections in non executables.
+
+2005-09-20 13:33 Christos Zoulas <christos@astron.com>
+
+       * Don't print SVR4 Style in core files multiple times
+           (Radek Vokal)
+
+2005-08-27 04:09 Christos Zoulas <christos@astron.com>
+
+       * Cygwin changes Corinna Vinschen
+
+2005-08-18 09:53 Christos Zoulas <christos@astron.com>
+
+       * Remove erroreous mention of /etc/magic in the file man page
+         This is gentoo bug 101639. (Mike Frysinger)
+
+       * Cross-compile support and detection (Mike Frysinger)
+
+2005-08-12 10:17 Christos Zoulas <christos@astron.com>
+
+       * Add -h flag and dereference symlinks if POSIXLY_CORRECT
+         is set.
+
+2005-07-29 13:57 Christos Zoulas <christos@astron.com>
+
+       * Avoid search and regex buffer overflows (Kelledin)
+
+2005-07-12 11:48 Christos Zoulas <christos@astron.com>
+
+       * Provide stub implementations for {v,}nsprintf() for older
+         OS's that don't have them.
+       * Change mbstate_t autoconf detection macro from AC_MBSTATE_T
+         to AC_TYPE_MBSTATE_T.
+
+2005-06-25 11:48 Christos Zoulas <christos@astron.com>
+
+       * Dynamically allocate the string buffers and make the
+         default read size 256K.
+
+2005-06-01 00:00 Joerg Sonnenberger <joerg@britannica.bec.de>
+
+       * Dragonfly ELF note support
+
+2005-03-14 00:00 Giuliano Bertoletti <gb@symbolic.it>
+
+       * Avoid NULL pointer dereference in time conversion.
+
+2005-03-06 00:00  Joerg Walter <jwalt@mail.garni.ch>
+
+       * Add indirect magic offset support, and search mode.
+
+2005-01-12 00:00  Stepan Kasal  <kasal@ucw.cz>
+
+       * src/ascmagic.c (file_ascmagic): Fix three bugs about text files:
+         If a CRLF text file happens to have CR at offset HOWMANY - 1
+         (currently 0xffff), it should not be counted as CR line
+         terminator.
+         If a line has length exactly MAXLINELEN, it should not yet be
+         treated as a ``very long line'', as MAXLINELEN is ``longest sane
+         line length''.
+         With CRLF, the line length was not computed correctly, and even
+         lines of length MAXLINELEN - 1 were treated as ``very long''.
+
+2004-12-07 14:15  Christos Zoulas  <christos@astron.com>
+
+       * bzip2 needs a lot of input buffer space on some files
+         before it can begin uncompressing. This makes file -z
+         fail on some bz2 files. Fix it by giving it a copy of
+         the file descriptor to read as much as it wants if we
+         have access to it. <christos@astron.com>
+
+2004-11-24 12:39  Christos Zoulas  <christos@astron.com>
+
+       * Stack smash fix, and ELF more conservative reading.
+         Jakub Bogusz <qboosh@pld-linux.org>
+
+2004-11-20 18:50  Christos Zoulas  <christos@astron.com>
+
+       * New FreeBSD version parsing code:
+         Jon Noack <noackjr@alumni.rice.edu>
+
+       * Hackish support for ucs16 strings <christos@astron.com>
+
+2004-11-13 03:07  Christos Zoulas  <christos@astron.com>
+
+       * print the file name and line number in syntax errors.
+
+2004 10-12 10:50  Christos Zoulas  <christos@astron.com>
+
+       * Fix stack overwriting on 0 length strings: Tim Waugh
+           <twaugh@redhat.com> Ned Ludd <solar@gentoo.org>
+
+2004-09-27 11:30  Christos Zoulas  <christos@astron.com>
+
+       * Remove 3rd and 4th copyright clause; approved by Ian Darwin.
+
+       * Fix small memory leaks; caught by: Tamas Sarlos
+           <stamas@csillag.ilab.sztaki.hu>
+
+2004-07-24 16:33  Christos Zoulas  <christos@astron.com>
+
+       * magic.mime update Danny Milosavljevic <danny.milo@gmx.net>
+
+       * FreeBSD version update Oliver Eikemeier <eikemeier@fillmore-labs.com>
+
+       * utime/utimes detection Ian Lance Taylor <ian@wasabisystems.com>
+
+       * errors reading elf magic Jakub Bogusz <qboosh@pld-linux.org>
+
+2004-04-12 10:55  Christos Zoulas  <christos@astron.com>
+
+       * make sure that magic formats match magic types during compilation
+
+       * fix broken sgi magic file
+
+2004-04-06 20:36  Christos Zoulas  <christos@astron.com>
+
+       * detect present of mbstate_t Petter Reinholdtsen <pere@hungry.com>
+
+       * magic fixes
+
+2004-03-22 15:25  Christos Zoulas  <christos@astron.com>
+
+       * Lots of mime fixes
+         (Joerg Ostertag) <ostertag@rechengilde.de>
+
+       * FreeBSD ELF version handling
+         (Edwin Groothuis) <edwin@mavetju.org>
+
+       * correct cleanup in all cases; don't just close the file.
+         (Christos Zoulas) <christos@astron.com>
+
+       * add gettext message catalogue support
+         (Michael Piefel) <piefel@debian.org>
+
+       * better printout for unreadable files
+         (Michael Piefel) <piefel@debian.org>
+
+       * compensate for missing MAXPATHLEN
+         (Michael Piefel) <piefel@debian.org>
+
+       * add wide character string length computation
+         (Michael Piefel) <piefel@debian.org>
+
+       * Avoid infinite loops caused by bad elf alignments
+         or name and description note sizes. Reported by
+         (Mikael Magnusson) <mmikael@comhem.se>
+
+2004-03-09 13:55  Christos Zoulas  <christos@astron.com>
+
+       * Fix possible memory leak on error and add missing regfree
+         (Dmitry V. Levin) <ldv@altlinux.org>
+
+2003-12-23 12:12  Christos Zoulas  <christos@astron.com>
+
+       * fix -k flag (Maciej W. Rozycki)
+
+2003-11-18 14:10  Christos Zoulas  <christos@astron.com>
+
+       * Try to give us much info as possible on corrupt elf files.
+         (Willy Tarreau) <willy@w.ods.org>
+       * Updated python bindings (Brett Funderburg)
+          <brettf@deepfile.com>
+
+2003-11-11 15:03  Christos Zoulas  <christos@astron.com>
+
+       * Include file.h first, because it includes config.h
+         breaks largefile test macros otherwise.
+         (Paul Eggert <eggert@CS.UCLA.EDU> via
+          Lars Hecking <lhecking@nmrc.ie>)
+
+2003-10-14 21:39  Christos Zoulas  <christos@astron.com>
+
+       * Python bindings (Brett Funderburg) <brettf@deepfile.com>
+       * Don't lookup past the end of the buffer
+         (Chad Hanson) <chanson@tcs-sec.com>
+       * Add MAGIC_ERROR and api on magic_errno()
+
+2003-10-08 12:40  Christos Zoulas  <christos@astron.com>
+
+       * handle error conditions from compile as fatal
+         (Antti Kantee) <pooka@netbsd.org>
+       * handle magic filename parsing sanely
+       * more magic fixes.
+       * fix a memory leak (Illes Marton) <illes.marton@balabit.hu>
+       * describe magic file handling
+         (Bryan Henderson) <bryanh@giraffe-data.com>
+
+2003-09-12 15:09  Christos Zoulas  <christos@astron.com>
+
+       * update magic files.
+       * remove largefile support from file.h; it breaks things on most OS's
+
+2003-08-10 10:25  Christos Zoulas  <christos@astron.com>
+
+       * fix unmapping'ing of mmaped files.
+
+2003-07-10 12:03  Christos Zoulas  <christos@astron.com>
+
+       * don't exit with -1 on error; always exit 1 (Marty Leisner)
+       * restore utimes code.
+
+2003-06-10 17:03  Christos Zoulas  <christos@astron.com>
+
+       * make sure we don't access uninitialized memory.
+       * pass lint
+       * #ifdef __cplusplus in magic.h
+
+2003-05-25 19:23  Christos Zoulas  <christos@astron.com>
+
+       * rename cvs magic file to revision to deal with
+         case insensitive filesystems.
+
+2003-05-23 17:03  Christos Zoulas  <christos@astron.com>
+
+       * documentation fixes from Michael Piefel <piefel@debian.org>
+       * magic fixes (various)
+       * revert basename magic in .mgc name determination
+       * buffer protection in uncompress,
+         signness issues,
+         close files
+         Maciej W. Rozycki <macro@ds2.pg.gda.pl
+
+2003-04-21 20:12  Christos Zoulas  <christos@astron.com>
+
+       * fix zsh magic
+
+2003-04-04 16:59  Christos Zoulas  <christos@astron.com>
+
+       * fix operand sort order in string.
+
+2003-04-02 17:30  Christos Zoulas  <christos@astron.com>
+
+       * cleanup namespace in magic.h
+
+2003-04-02 13:50  Christos Zoulas  <christos@astron.com>
+
+       * Magic additions (Alex Ott)
+       * Fix bug that broke VPATH compilation (Peter Breitenlohner)
+
+2003-03-28 16:03  Christos Zoulas  <christos@astron.com>
+
+       * remove packed attribute from magic struct.
+       * make the magic struct properly aligned.
+       * bump version number of compiled files to 2.
+
+2003-03-27 13:10  Christos Zoulas  <christos@astron.com>
+
+       * separate tar detection and run it before softmagic.
+       * fix reversed symlink test.
+       * fix version printing.
+       * make separator a string instead of a char.
+       * update manual page and sort options.
+
+2003-03-26 11:00  Christos Zoulas  <christos@astron.com>
+
+       * Pass lint
+       * make NULL in magic_file mean stdin
+       * Fix "-" argument to file to pass NULL to magic_file
+       * avoid pointer casts by using memcpy
+       * rename magic_buf -> magic_buffer
+       * keep only the first error
+       * manual page: new sentence, new line
+       * fix typo in api function (magic_buf -> magic_buffer)
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..7d1c323
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,365 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+   Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.  Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+   The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package, generally using the just-built uninstalled binaries.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the `make install' phase executed with root
+     privileges.
+
+  5. Optionally, type `make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior `make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  7. Often, you can also type `make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide `make
+     distcheck', which can by used by developers to test that all other
+     targets like `make install' and `make uninstall' work correctly.
+     This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.  This
+is known as a "VPATH" build.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.  In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'.  Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated.  The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the `DESTDIR' variable.  For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names.  The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+   Some packages offer the ability to configure how verbose the
+execution of `make' will be.  For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
+
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/MAINT b/MAINT
new file mode 100644 (file)
index 0000000..6820306
--- /dev/null
+++ b/MAINT
@@ -0,0 +1,44 @@
+$File: MAINT,v 1.9 2007/01/19 21:15:27 christos Exp $
+
+Maintenance notes:
+
+I am continuing to maintain the file command. I welcome your help,
+but to make my life easier I'd like to request the following:
+
+- Do not distribute changed versions.
+
+People trying to be helpful occasionally put up their hacked versions
+of the file command for anonymous FTP, and people all over the
+world get copies of the hacked versions.  Within a day or two I am
+getting email from around the world asking me why "my" file command
+won't compile!!! Needless to say this detracts from the limited
+time I have available to work on the actual software. Therefore I
+ask you again to please NOT distribute your changed version. If
+you need to make changes, please add a patch file next to the
+distribution tar, and a README file that clearly explains what you
+are trying to fix.
+
+Thank you for your assistance and cooperation.
+
+Code Overview
+
+This is a rough idea of the control flow from the main program:
+
+file.c main()
+file.c process (called for each file)
+               printf file name
+magic.c                magic_file()
+fsmagic.c              file_fsmagic()
+                               (handles statbuf modes for DEV)
+                       (handles statbuf modes for executable &c.
+                       reads data from file.
+funcs.c:               file_buffer()
+compress.c                     file_zmagic()
+is_tar.c                       file_is_tar()
+softmagic.c                    file_softmagic()
+                                               match() - looks for match against main magic database
+ascmagic.c                     file_ascmagic()
+readelf.c              file_tryelf()
+                               "unknown"
+
+Christos Zoulas (see README for email address)
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..8bd927d
--- /dev/null
@@ -0,0 +1,5 @@
+ACLOCAL_AMFLAGS = -I m4
+
+EXTRA_DIST = MAINT
+
+SUBDIRS = src magic tests doc python
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..898a3da
--- /dev/null
+++ b/NEWS
@@ -0,0 +1 @@
+See ChangeLog.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..bb29a46
--- /dev/null
+++ b/README
@@ -0,0 +1,154 @@
+## README for file(1) Command and the libmagic(3) library ##
+
+    @(#) $File: README,v 1.57 2019/02/06 00:20:56 christos Exp $
+
+Mailing List: file@astron.com
+Mailing List archives: http://mailman.astron.com/pipermail/file/
+Bug tracker: http://bugs.astron.com/
+E-mail: christos@astron.com
+Build Status: https://travis-ci.org/file/file
+
+Phone: Do not even think of telephoning me about this program. Send cash first!
+
+This is Release 5.x of Ian Darwin's (copyright but distributable)
+file(1) command, an implementation of the Unix File(1) command.
+It knows the 'magic number' of several thousands of file types.
+This version is the standard "file" command for Linux,
+*BSD, and other systems. (See "patchlevel.h" for the exact release number).
+
+You can download the latest version of the original sources for file from:
+
+       ftp://ftp.astron.com/pub/file/
+
+A public read-only git repository of the same sources is available at:
+
+       https://github.com/file/file
+
+The major changes for 5.x are CDF file parsing, indirect magic, name/use
+(recursion) and overhaul in mime and ascii encoding handling.
+
+The major feature of 4.x is the refactoring of the code into a library,
+and the re-write of the file command in terms of that library. The library
+itself, libmagic can be used by 3rd party programs that wish to identify
+file types without having to fork() and exec() file. The prime contributor
+for 4.0 was Mans Rullgard.
+
+UNIX is a trademark of UNIX System Laboratories.
+
+The prime contributor to Release 3.8 was Guy Harris, who put in megachanges
+including byte-order independence.
+
+The prime contributor to Release 3.0 was Christos Zoulas, who put
+in hundreds of lines of source code changes, including his own
+ANSIfication of the code (I liked my own ANSIfication better, but
+his (__P()) is the "Berkeley standard" way of doing it, and I wanted UCB
+to include the code...), his HP-like "indirection" (a feature of
+the HP file command, I think), and his mods that finally got the
+uncompress (-z) mode finished and working.
+
+This release has compiled in numerous environments; see PORTING
+for a list and problems.
+
+This fine freeware file(1) follows the USG (System V) model of the file
+command, rather than the Research (V7) version or the V7-derived 4.[23]
+Berkeley one. That is, the file /etc/magic contains much of the ritual
+information that is the source of this program's power. My version
+knows a little more magic (including tar archives) than System V; the
+/etc/magic parsing seems to be compatible with the (poorly documented)
+System V /etc/magic format (with one exception; see the man page).
+
+In addition, the /etc/magic file is built from a subdirectory
+for easier(?) maintenance.  I will act as a clearinghouse for
+magic numbers assigned to all sorts of data files that
+are in reasonable circulation. Send your magic numbers,
+in magic(5) format please, to the maintainer, Christos Zoulas.
+
+COPYING - read this first.
+README - read this second (you are currently reading this file).
+INSTALL - read on how to install
+src/apprentice.c - parses /etc/magic to learn magic
+src/apptype.c - used for OS/2 specific application type magic
+src/ascmagic.c - third & last set of tests, based on hardwired assumptions.
+src/asctime_r.c - replacement for OS's that don't have it.
+src/asprintf.c - replacement for OS's that don't have it.
+src/asctime_r.c - replacement for OS's that don't have it.
+src/asprintf.c - replacement for OS's that don't have it.
+src/buffer.c - buffer handling functions.
+src/cdf.[ch] - parser for Microsoft Compound Document Files
+src/cdf_time.c - time converter for CDF.
+src/compress.c - handles decompressing files to look inside.
+src/ctime_r.c - replacement for OS's that don't have it.
+src/der.[ch] - parser for Distinguished Encoding Rules
+src/dprintf.c - replacement for OS's that don't have it.
+src/elfclass.h - common code for elf 32/64.
+src/encoding.c - handles unicode encodings
+src/file.c - the main program
+src/file.h - header file
+src/file_opts.h - list of options
+src/fmtcheck.c - replacement for OS's that don't have it.
+src/fsmagic.c - first set of tests the program runs, based on filesystem info
+src/funcs.c - utilility functions
+src/getline.c - replacement for OS's that don't have it.
+src/getopt_long.c - replacement for OS's that don't have it.
+src/gmtime_r.c - replacement for OS's that don't have it.
+src/is_json.c - knows about JavaScript Object Notation format (RFC 8259).
+src/is_tar.c, tar.h - knows about Tape ARchive format (courtesy John Gilmore).
+src/localtime_r.c - replacement for OS's that don't have it.
+src/magic.h.in - source file for magic.h
+src/mygetopt.h - replacement for OS's that don't have it.
+src/magic.c - the libmagic api
+src/names.h - header file for ascmagic.c
+src/pread.c - replacement for OS's that don't have it.
+src/print.c - print results, errors, warnings.
+src/readcdf.c - CDF wrapper.
+src/readelf.[ch] - Stand-alone elf parsing code.
+src/softmagic.c - 2nd set of tests, based on /etc/magic
+src/mygetopt.h - replacement for OS's that don't have it.
+src/strcasestr.c - replacement for OS's that don't have it.
+src/strlcat.c - replacement for OS's that don't have it.
+src/strlcpy.c - replacement for OS's that don't have it.
+src/strndup.c - replacement for OS's that don't have it.
+src/tar.h - tar file definitions
+src/vasprintf.c - for systems that don't have it.
+doc/file.man - man page for the command
+doc/magic.man - man page for the magic file, courtesy Guy Harris.
+       Install as magic.4 on USG and magic.5 on V7 or Berkeley; cf Makefile.
+
+Magdir - directory of /etc/magic pieces
+------------------------------------------------------------------------------
+
+If you submit a new magic entry please make sure you read the following
+guidelines:
+
+- Initial match is preferably at least 32 bits long, and is a _unique_ match
+- If this is not feasible, use additional check
+- Match of <= 16 bits are not accepted
+- Delay printing string as much as possible, don't print output too early
+- Avoid printf arbitrary byte as string, which can be a source of
+  crash and buffer overflow
+
+- Provide complete information with entry:
+  * One line short summary
+  * Optional long description
+  * File extension, if applicable
+  * Full name and contact method (for discussion when entry has problem)
+  * Further reference, such as documentation of format
+
+------------------------------------------------------------------------------
+
+gpg for dummies:
+
+$ gpg --verify file-X.YY.tar.gz.asc file-X.YY.tar.gz
+gpg: assuming signed data in `file-X.YY.tar.gz'
+gpg: Signature made WWW MMM DD HH:MM:SS YYYY ZZZ using DSA key ID KKKKKKKK
+
+To download the key:
+
+$ gpg --keyserver hkp://keys.gnupg.net --recv-keys KKKKKKKK
+
+------------------------------------------------------------------------------
+
+
+Parts of this software were developed at SoftQuad Inc., developers
+of SGML/HTML/XML publishing software, in Toronto, Canada.
+SoftQuad was swallowed up by Corel in 2002 and does not exist any longer.
diff --git a/README.DEVELOPER b/README.DEVELOPER
new file mode 100644 (file)
index 0000000..9b23b46
--- /dev/null
@@ -0,0 +1,40 @@
+# How to get started developing
+
+@(#) $File: README.DEVELOPER,v 1.5 2014/03/10 12:38:08 kim Exp $
+
+## Auto files
+
+After checking out the source, run the following:
+
+       autoreconf -f -i
+       ./configure --disable-silent-rules
+       make -j4
+       make -C tests check
+
+If you see errors, make sure you have the latest libtool and autoconf
+This has been tested with autoconf-2.69 and libtool-2.4.2
+
+## Installing dependencies
+
+If your platform doesn't have the above tools, install the following
+packages first.
+
+### Debian
+
+       apt-get install \
+           automake \
+           gcc \
+           libtool \
+           make \
+           python \
+           zlib1g-dev \
+
+See also `.travis.yml`.
+
+### Mac OS X (MacPorts)
+
+       port install \
+           autoconf \
+           automake \
+           libtool \
+
diff --git a/RELEASE-PROCEDURE b/RELEASE-PROCEDURE
new file mode 100644 (file)
index 0000000..c2c0855
--- /dev/null
@@ -0,0 +1,29 @@
+# HOW TO RELEASE FILE
+
+@(#) $File: RELEASE-PROCEDURE,v 1.6 2018/07/25 06:17:15 christos Exp $
+
+1)  Update version number in configure.ac
+2)  Note the new version in ChangeLog
+3)  Update README if applicable
+4)  Commit changes into CVS
+5)  Rebuild and run tests (see README.DEVELOPER)
+6)  Tag the release with FILEx_yy
+7)  Create the source tarball: make distcheck
+7a) Sign the source tarball.
+       gpg --armor --detach-sign mysoftware-0.4.tar.gz
+8)  Make the source tarball available on ftp
+9)  Add the new version to bugs.astron.com:
+    - Click: Manage > Manage Projects > file
+    - Scroll down to "Versions"
+    - Click on "Edit" next to the HEAD version
+    - Change the "Version" from HEAD to the newly released version
+    - Change the "Date Order" to the current time
+    - Check the "Released" box
+    - Click on "Update Version"
+    - Type HEAD into the box at the bottom of the version list and
+      click on "Add and Edit Version"
+    - Set the "Date Order" to 2030-01-01 (i.e. far in the future)
+    - Click on "Update Version"
+10) Mail an announcement to file@astron.com containing a summary of the
+    ChangeLog changes. Historically we don't mention magic changes in the
+    ChangeLog or the mail message, only source changes.
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..836d6b5
--- /dev/null
+++ b/TODO
@@ -0,0 +1,49 @@
+Most TODOs live in the TODO section of doc/file.man (i.e. file(1)).
+They are more visible there, so please add any further TODOs to that
+file, not here. More speculative material can live here.
+
+(This change was made when Reuben Thomas noticed that all the bugs
+listed in the BUGS section of the man page had been fixed!)
+
+---
+It would be nice to simplify file considerably. For example,
+reimplement the apprentice and non-pattern magic methods in Python,
+and compile the magic patterns to a giant regex (or something similar;
+maybe using Ragel (http://www.complang.org/ragel/)) so that only a
+small amount of C is needed (because fast execution is typically only
+required for soft magic, not the more detailed information given by
+hard-wired routines). In this regard, note that hplip, which is
+BSD-licensed, has a magic reimplementation in Python.
+---
+Read the kerberos magic entry for more ideas.
+---
+Write a string merger to make magic entry sizes dynamic.
+Strings will be converted to offsets from the string table.
+---
+Programming language support, we can introduce the concept of a group
+of rules where n rules need to match before the rule is positive. This
+could require structural changes to the matching code :-(
+
+0      group   2       # require 2 matches
+# rule 1
+>0     ....
+...
+# rule 2
+>0     ....
+...
+---
+- Merge the stat code dance in one place and keep it in one place
+  (perhaps struct buffer).
+- Enable seeking around if offset > nbytes if possible (the fd
+  is seekable).
+- We could use file_pipe2file more (for EOF offsets, CDF documents),
+  but that is expensive; perhaps we should provide a way to disable it
+- The implementation of struct buffer needs re-thinking and more work.
+  For example we don't always pass the fd in the child. This is not
+  important yet as we don't have yet cases where use/indirect magic
+  needs negative offsets.
+- Really the whole thing just needs here's an (offset, buffer, size)
+  you have (filebuffer, filebuffersize &&|| fd), fill the buffer with
+  data from offset. The buffer API should be changed to just do that.
+
+christos
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644 (file)
index 0000000..dcbf92f
--- /dev/null
@@ -0,0 +1,58 @@
+dnl from autoconf 2.13 acspecific.m4, with changes to check for daylight
+
+AC_DEFUN([AC_STRUCT_TIMEZONE_DAYLIGHT],
+[AC_REQUIRE([AC_STRUCT_TM])dnl
+AC_CACHE_CHECK([for tm_zone in struct tm], ac_cv_struct_tm_zone,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <$ac_cv_struct_tm>], [struct tm tm; tm.tm_zone;],
+  ac_cv_struct_tm_zone=yes, ac_cv_struct_tm_zone=no)])
+if test "$ac_cv_struct_tm_zone" = yes; then
+  AC_DEFINE(HAVE_TM_ZONE,1,[HAVE_TM_ZONE])
+fi
+
+# On SGI, apparently tzname is a #define, but that's ok, AC_CHECK_DECL will
+# consider it declared and we won't give our own extern.
+AC_CHECK_DECLS([tzname], , , [#include <time.h>])
+AC_CACHE_CHECK(for tzname, ac_cv_var_tzname,
+[AC_TRY_LINK(
+[#include <time.h>
+#if !HAVE_DECL_TZNAME
+extern char *tzname[];
+#endif],
+[return tzname[0][0];], [ac_cv_var_tzname=yes], [ac_cv_var_tzname=no])])
+  if test $ac_cv_var_tzname = yes; then
+    AC_DEFINE(HAVE_TZNAME,1,[HAVE_TZNAME])
+  fi
+
+AC_CACHE_CHECK([for tm_isdst in struct tm], ac_cv_struct_tm_isdst,
+[AC_TRY_COMPILE([#include <sys/types.h>
+#include <$ac_cv_struct_tm>], [struct tm tm; tm.tm_isdst;],
+  ac_cv_struct_tm_isdst=yes, ac_cv_struct_tm_isdst=no)])
+if test "$ac_cv_struct_tm_isdst" = yes; then
+  AC_DEFINE(HAVE_TM_ISDST,1,[HAVE_TM_ISDST])
+fi
+
+
+AC_CHECK_DECLS([daylight], , , [#include <time.h>])
+AC_CACHE_CHECK(for daylight, ac_cv_var_daylight,
+[AC_TRY_LINK(
+changequote(<<, >>)dnl
+<<#include <time.h>
+#if !HAVE_DECL_DAYLIGHT
+extern int daylight;
+#endif>>,
+changequote([, ])dnl
+[atoi(daylight);], ac_cv_var_daylight=yes, ac_cv_var_daylight=no)])
+  if test $ac_cv_var_daylight = yes; then
+    AC_DEFINE(HAVE_DAYLIGHT,1,[HAVE_DAYLIGHT])
+  fi
+])
+
+AC_DEFUN([AC_STRUCT_OPTION_GETOPT_H],
+[AC_CACHE_CHECK([for struct option in getopt], ac_cv_struct_option_getopt_h,
+[AC_TRY_COMPILE([#include <getopt.h>], [struct option op; op.name;],
+  ac_cv_struct_option_getopt_h=yes, ac_cv_struct_option_getopt_h=no)])
+if test "$ac_cv_struct_option_getopt_h" = yes; then
+  AC_DEFINE(HAVE_STRUCT_OPTION,1,[HAVE_STRUCT_OPTION])
+fi
+])
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..7da62aa
--- /dev/null
@@ -0,0 +1,184 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT([file],[5.37],[christos@astron.com])
+AM_INIT_AUTOMAKE([subdir-objects foreign])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_MSG_CHECKING(for builtin ELF support)
+AC_ARG_ENABLE(elf,
+[  --disable-elf            disable builtin ELF support],
+[if test "${enableval}" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE([BUILTIN_ELF], 1, [Define if built-in ELF support is used])
+else
+  AC_MSG_RESULT(no)
+fi], [
+  # enable by default
+  AC_MSG_RESULT(yes)
+  AC_DEFINE([BUILTIN_ELF], 1, [Define in built-in ELF support is used])
+])
+
+AC_MSG_CHECKING(for ELF core file support)
+AC_ARG_ENABLE(elf-core,
+[  --disable-elf-core       disable ELF core file support],
+[if test "${enableval}" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE([ELFCORE], 1, [Define for ELF core file support])
+else
+  AC_MSG_RESULT(no)
+fi], [
+  # enable by default
+  AC_MSG_RESULT(yes)
+  AC_DEFINE([ELFCORE], 1, [Define for ELF core file support])
+])
+
+AC_MSG_CHECKING(for zlib support)
+AC_ARG_ENABLE([zlib],
+[AS_HELP_STRING([--disable-zlib], [disable zlib compression support @<:@default=auto@:>@])])
+AC_MSG_RESULT($enable_zlib)
+
+AC_MSG_CHECKING(for libseccomp support)
+AC_ARG_ENABLE([libseccomp],
+[AS_HELP_STRING([--disable-libseccomp], [disable libseccomp sandboxing @<:@default=auto@:>@])])
+AC_MSG_RESULT($enable_libseccomp)
+
+AC_MSG_CHECKING(for file formats in man section 5)
+AC_ARG_ENABLE(fsect-man5,
+[  --enable-fsect-man5      enable file formats in man section 5],
+[if test "${enableval}" = yes; then
+  AC_MSG_RESULT(yes)
+  fsect=5
+else
+  AC_MSG_RESULT(no)
+  fsect=4
+fi], [
+  # disable by default
+  AC_MSG_RESULT(no)
+  fsect=4
+])
+
+AC_CANONICAL_HOST
+case "$host_os" in
+   mingw32*)
+      MINGW=1
+      ;;
+   *)
+      MINGW=0
+      ;;
+esac
+AC_SUBST(MINGW)
+AM_CONDITIONAL(MINGW, test "$MINGW" = 1)
+
+AC_SUBST([pkgdatadir], ['$(datadir)/misc'])
+AC_SUBST(fsect)
+AM_CONDITIONAL(FSECT5, test x$fsect = x5)
+
+AC_SUBST(WARNINGS)
+
+dnl Checks for programs.
+AC_PROG_CC_STDC
+AC_USE_SYSTEM_EXTENSIONS
+AM_PROG_CC_C_O
+AC_C_BIGENDIAN
+AC_PROG_INSTALL
+AC_PROG_LN_S
+LT_INIT([disable-static pic-only])
+gl_VISIBILITY
+dnl Checks for headers
+AC_HEADER_STDC
+AC_HEADER_MAJOR
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(stdint.h fcntl.h inttypes.h unistd.h)
+AC_CHECK_HEADERS(utime.h wchar.h wctype.h)
+AC_CHECK_HEADERS(getopt.h err.h xlocale.h)
+AC_CHECK_HEADERS(sys/mman.h sys/stat.h sys/types.h sys/utime.h sys/time.h sys/sysmacros.h)
+if test "$enable_zlib" != "no"; then
+  AC_CHECK_HEADERS(zlib.h)
+fi
+AC_CHECK_TYPE([sig_t],[AC_DEFINE([HAVE_SIG_T],1,[Have sig_t type])],,[#include <signal.h>])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_CHECK_MEMBERS([struct stat.st_rdev])
+
+AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[#include <time.h>])
+AC_STRUCT_TIMEZONE
+AC_STRUCT_TIMEZONE_DAYLIGHT
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+AC_TYPE_MBSTATE_T
+
+AC_STRUCT_OPTION_GETOPT_H
+AC_TYPE_PID_T
+AC_TYPE_UINT8_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_INT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_INT64_T
+AC_TYPE_INTPTR_T
+AC_TYPE_UINTPTR_T
+AC_FUNC_MMAP
+AC_FUNC_FORK
+AC_FUNC_MBRTOWC
+
+AC_MSG_CHECKING(for gcc compiler warnings)
+AC_ARG_ENABLE(warnings,
+[  --disable-warnings  disable compiler warnings],
+[if test "${enableval}" = no -o "$GCC" = no; then
+   AC_MSG_RESULT(no)
+   WARNINGS=
+else
+   AC_MSG_RESULT(yes)
+   WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+       -Wmissing-declarations -Wredundant-decls -Wnested-externs \
+       -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
+       -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter -Wformat=2"
+fi], [
+if test "$GCC" = yes; then
+   AC_MSG_RESULT(yes)
+   WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
+       -Wmissing-declarations -Wredundant-decls -Wnested-externs \
+       -Wsign-compare -Wreturn-type -Wswitch -Wshadow \
+       -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter -Wformat=2"
+else
+   WARNINGS=
+   AC_MSG_RESULT(no)
+fi])
+
+dnl Checks for functions
+AC_CHECK_FUNCS(strndup mkstemp mkostemp utimes utime wcwidth strtof newlocale uselocale freelocale memmem)
+
+dnl Provide implementation of some required functions if necessary
+AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline ctime_r asctime_r localtime_r gmtime_r pread strcasestr fmtcheck dprintf)
+
+dnl Checks for libraries
+if test "$enable_zlib" != "no"; then
+  AC_CHECK_LIB(z, gzopen)
+fi
+if test "$enable_libseccomp" != "no"; then
+    AC_CHECK_LIB(seccomp, seccomp_init)
+fi
+if test "$MINGW" = 1; then
+  AC_CHECK_LIB(gnurx,regexec,,AC_MSG_ERROR([libgnurx is required to build file(1) with MinGW]))
+fi
+
+dnl See if we are cross-compiling
+AM_CONDITIONAL(IS_CROSS_COMPILE, test "$cross_compiling" = yes)
+
+dnl Final sanity checks
+if test "$enable_zlib" = "yes"; then
+  if test "$ac_cv_header_zlib_h$ac_cv_lib_z_gzopen" != "yesyes"; then
+    AC_MSG_ERROR([zlib support requested but not found])
+  fi
+fi
+if  test "$ac_cv_header_zlib_h$ac_cv_lib_z_gzopen" = "yesyes"; then
+  AC_DEFINE([ZLIBSUPPORT], 1, [Enable zlib compression support])
+fi
+
+AC_CONFIG_FILES([Makefile src/Makefile magic/Makefile tests/Makefile doc/Makefile python/Makefile])
+AC_OUTPUT
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644 (file)
index 0000000..d3f8107
--- /dev/null
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.1
+*.3
+*.4
+*.5
+.gitignore
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..4a78589
--- /dev/null
@@ -0,0 +1,32 @@
+MAGIC   = $(pkgdatadir)/magic
+if FSECT5
+man_MAGIC = magic.5
+else
+man_MAGIC = magic.4
+endif
+fsect = @fsect@
+man_MANS = file.1 $(man_MAGIC) libmagic.3
+
+EXTRA_DIST = file.man magic.man libmagic.man
+CLEANFILES = $(man_MANS)
+
+file.1:        Makefile file.man
+       @rm -f $@
+       sed -e s@__CSECTION__@1@g \
+           -e s@__FSECTION__@${fsect}@g \
+           -e s@__VERSION__@${VERSION}@g \
+           -e s@__MAGIC__@${MAGIC}@g $(srcdir)/file.man > $@
+
+magic.${fsect}: Makefile magic.man
+       @rm -f $@
+       sed -e s@__CSECTION__@1@g \
+           -e s@__FSECTION__@${fsect}@g \
+           -e s@__VERSION__@${VERSION}@g \
+           -e s@__MAGIC__@${MAGIC}@g $(srcdir)/magic.man > $@
+
+libmagic.3: Makefile libmagic.man
+       @rm -f $@
+       sed -e s@__CSECTION__@1@g \
+           -e s@__FSECTION__@${fsect}@g \
+           -e s@__VERSION__@${VERSION}@g \
+           -e s@__MAGIC__@${MAGIC}@g $(srcdir)/libmagic.man > $@
diff --git a/doc/file.man b/doc/file.man
new file mode 100644 (file)
index 0000000..63e95f1
--- /dev/null
@@ -0,0 +1,717 @@
+.\" $File: file.man,v 1.135 2019/03/03 02:32:40 christos Exp $
+.Dd February 18, 2019
+.Dt FILE __CSECTION__
+.Os
+.Sh NAME
+.Nm file
+.Nd determine file type
+.Sh SYNOPSIS
+.Nm
+.Bk -words
+.Op Fl bcdEhiklLNnprsSvzZ0
+.Op Fl Fl apple
+.Op Fl Fl extension
+.Op Fl Fl mime-encoding
+.Op Fl Fl mime-type
+.Op Fl e Ar testname
+.Op Fl F Ar separator
+.Op Fl f Ar namefile
+.Op Fl m Ar magicfiles
+.Op Fl P Ar name=value
+.Ar
+.Ek
+.Nm
+.Fl C
+.Op Fl m Ar magicfiles
+.Nm
+.Op Fl Fl help
+.Sh DESCRIPTION
+This manual page documents version __VERSION__ of the
+.Nm
+command.
+.Pp
+.Nm
+tests each argument in an attempt to classify it.
+There are three sets of tests, performed in this order:
+filesystem tests, magic tests, and language tests.
+The
+.Em first
+test that succeeds causes the file type to be printed.
+.Pp
+The type printed will usually contain one of the words
+.Em text
+(the file contains only
+printing characters and a few common control
+characters and is probably safe to read on an
+.Dv ASCII
+terminal),
+.Em executable
+(the file contains the result of compiling a program
+in a form understandable to some
+.Tn UNIX
+kernel or another),
+or
+.Em data
+meaning anything else (data is usually
+.Dq binary
+or non-printable).
+Exceptions are well-known file formats (core files, tar archives)
+that are known to contain binary data.
+When modifying magic files or the program itself, make sure to
+.Em "preserve these keywords" .
+Users depend on knowing that all the readable files in a directory
+have the word
+.Dq text
+printed.
+Don't do as Berkeley did and change
+.Dq shell commands text
+to
+.Dq shell script .
+.Pp
+The filesystem tests are based on examining the return from a
+.Xr stat 2
+system call.
+The program checks to see if the file is empty,
+or if it's some sort of special file.
+Any known file types appropriate to the system you are running on
+(sockets, symbolic links, or named pipes (FIFOs) on those systems that
+implement them)
+are intuited if they are defined in the system header file
+.In sys/stat.h .
+.Pp
+The magic tests are used to check for files with data in
+particular fixed formats.
+The canonical example of this is a binary executable (compiled program)
+.Dv a.out
+file, whose format is defined in
+.In elf.h ,
+.In a.out.h
+and possibly
+.In exec.h
+in the standard include directory.
+These files have a
+.Dq "magic number"
+stored in a particular place
+near the beginning of the file that tells the
+.Tn UNIX
+operating system
+that the file is a binary executable, and which of several types thereof.
+The concept of a
+.Dq "magic"
+has been applied by extension to data files.
+Any file with some invariant identifier at a small fixed
+offset into the file can usually be described in this way.
+The information identifying these files is read from the compiled
+magic file
+.Pa __MAGIC__.mgc ,
+or the files in the directory
+.Pa __MAGIC__
+if the compiled file does not exist.
+In addition, if
+.Pa $HOME/.magic.mgc
+or
+.Pa $HOME/.magic
+exists, it will be used in preference to the system magic files.
+.Pp
+If a file does not match any of the entries in the magic file,
+it is examined to see if it seems to be a text file.
+ASCII, ISO-8859-x, non-ISO 8-bit extended-ASCII character sets
+(such as those used on Macintosh and IBM PC systems),
+UTF-8-encoded Unicode, UTF-16-encoded Unicode, and EBCDIC
+character sets can be distinguished by the different
+ranges and sequences of bytes that constitute printable text
+in each set.
+If a file passes any of these tests, its character set is reported.
+ASCII, ISO-8859-x, UTF-8, and extended-ASCII files are identified
+as
+.Dq text
+because they will be mostly readable on nearly any terminal;
+UTF-16 and EBCDIC are only
+.Dq character data
+because, while
+they contain text, it is text that will require translation
+before it can be read.
+In addition,
+.Nm
+will attempt to determine other characteristics of text-type files.
+If the lines of a file are terminated by CR, CRLF, or NEL, instead
+of the Unix-standard LF, this will be reported.
+Files that contain embedded escape sequences or overstriking
+will also be identified.
+.Pp
+Once
+.Nm
+has determined the character set used in a text-type file,
+it will
+attempt to determine in what language the file is written.
+The language tests look for particular strings (cf.
+.In names.h )
+that can appear anywhere in the first few blocks of a file.
+For example, the keyword
+.Em .br
+indicates that the file is most likely a
+.Xr troff 1
+input file, just as the keyword
+.Em struct
+indicates a C program.
+These tests are less reliable than the previous
+two groups, so they are performed last.
+The language test routines also test for some miscellany
+(such as
+.Xr tar 1
+archives, JSON files).
+.Pp
+Any file that cannot be identified as having been written
+in any of the character sets listed above is simply said to be
+.Dq data .
+.Sh OPTIONS
+.Bl -tag -width indent
+.It Fl Fl apple
+Causes the file command to output the file type and creator code as
+used by older MacOS versions.
+The code consists of eight letters,
+the first describing the file type, the latter the creator.
+This option works properly only for file formats that have the
+apple-style output defined.
+.It Fl b , Fl Fl brief
+Do not prepend filenames to output lines (brief mode).
+.It Fl C , Fl Fl compile
+Write a
+.Pa magic.mgc
+output file that contains a pre-parsed version of the magic file or directory.
+.It Fl c , Fl Fl checking-printout
+Cause a checking printout of the parsed form of the magic file.
+This is usually used in conjunction with the
+.Fl m
+flag to debug a new magic file before installing it.
+.It Fl d
+Prints internal debugging information to stderr.
+.It Fl E
+On filesystem errors (file not found etc), instead of handling the error
+as regular output as POSIX mandates and keep going, issue an error message
+and exit.
+.It Fl e , Fl Fl exclude Ar testname
+Exclude the test named in
+.Ar testname
+from the list of tests made to determine the file type.
+Valid test names are:
+.Bl -tag -width compress
+.It apptype
+.Dv EMX
+application type (only on EMX).
+.It ascii
+Various types of text files (this test will try to guess the text
+encoding, irrespective of the setting of the
+.Sq encoding
+option).
+.It encoding
+Different text encodings for soft magic tests.
+.It tokens
+Ignored for backwards compatibility.
+.It cdf
+Prints details of Compound Document Files.
+.It compress
+Checks for, and looks inside, compressed files.
+.It elf
+Prints ELF file details, provided soft magic tests are enabled and the
+elf magic is found.
+.It json
+Examines JSON (RFC-7159) files by parsing them for compliance.
+.It soft
+Consults magic files.
+.It tar
+Examines tar files by verifying the checksum of the 512 byte tar header.
+Excluding this test can provide more detailed content description by using
+the soft magic method.
+.It text
+A synonym for
+.Sq ascii .
+.El
+.It Fl Fl extension
+Print a slash-separated list of valid extensions for the file type found.
+.It Fl F , Fl Fl separator Ar separator
+Use the specified string as the separator between the filename and the
+file result returned.
+Defaults to
+.Sq \&: .
+.It Fl f , Fl Fl files-from Ar namefile
+Read the names of the files to be examined from
+.Ar namefile
+(one per line)
+before the argument list.
+Either
+.Ar namefile
+or at least one filename argument must be present;
+to test the standard input, use
+.Sq -
+as a filename argument.
+Please note that
+.Ar namefile
+is unwrapped and the enclosed filenames are processed when this option is
+encountered and before any further options processing is done.
+This allows one to process multiple lists of files with different command line
+arguments on the same
+.Nm
+invocation.
+Thus if you want to set the delimiter, you need to do it before you specify
+the list of files, like:
+.Dq Fl F Ar @ Fl f Ar namefile ,
+instead of:
+.Dq Fl f Ar namefile Fl F Ar @ .
+.It Fl h , Fl Fl no-dereference
+option causes symlinks not to be followed
+(on systems that support symbolic links).
+This is the default if the environment variable
+.Dv POSIXLY_CORRECT
+is not defined.
+.It Fl i , Fl Fl mime
+Causes the file command to output mime type strings rather than the more
+traditional human readable ones.
+Thus it may say
+.Sq text/plain; charset=us-ascii
+rather than
+.Dq ASCII text .
+.It Fl Fl mime-type , Fl Fl mime-encoding
+Like
+.Fl i ,
+but print only the specified element(s).
+.It Fl k , Fl Fl keep-going
+Don't stop at the first match, keep going.
+Subsequent matches will be
+have the string
+.Sq "\[rs]012\- "
+prepended.
+(If you want a newline, see the
+.Fl r
+option.)
+The magic pattern with the highest strength (see the
+.Fl l
+option) comes first.
+.It Fl l , Fl Fl list
+Shows a list of patterns and their strength sorted descending by
+.Xr magic 4
+strength
+which is used for the matching (see also the
+.Fl k
+option).
+.It Fl L , Fl Fl dereference
+option causes symlinks to be followed, as the like-named option in
+.Xr ls 1
+(on systems that support symbolic links).
+This is the default if the environment variable
+.Ev POSIXLY_CORRECT
+is defined.
+.It Fl m , Fl Fl magic-file Ar magicfiles
+Specify an alternate list of files and directories containing magic.
+This can be a single item, or a colon-separated list.
+If a compiled magic file is found alongside a file or directory,
+it will be used instead.
+.It Fl N , Fl Fl no-pad
+Don't pad filenames so that they align in the output.
+.It Fl n , Fl Fl no-buffer
+Force stdout to be flushed after checking each file.
+This is only useful if checking a list of files.
+It is intended to be used by programs that want filetype output from a pipe.
+.It Fl p , Fl Fl preserve-date
+On systems that support
+.Xr utime 3
+or
+.Xr utimes 2 ,
+attempt to preserve the access time of files analyzed, to pretend that
+.Nm
+never read them.
+.It Fl P , Fl Fl parameter Ar name=value
+Set various parameter limits.
+.Bl -column "elf_phnum" "Default" "XXXXXXXXXXXXXXXXXXXXXXXXXXX" -offset indent
+.It Sy "Name" Ta Sy "Default" Ta Sy "Explanation"
+.It Li indir Ta 15 Ta recursion limit for indirect magic
+.It Li name Ta 30 Ta use count limit for name/use magic
+.It Li elf_notes Ta 256 Ta max ELF notes processed
+.It Li elf_phnum Ta 128 Ta max ELF program sections processed
+.It Li elf_shnum Ta 32768 Ta max ELF sections processed
+.It Li regex Ta 8192 Ta length limit for regex searches
+.It Li bytes Ta 1048576 Ta max number of bytes to read from file
+.El
+.It Fl r , Fl Fl raw
+Don't translate unprintable characters to \eooo.
+Normally
+.Nm
+translates unprintable characters to their octal representation.
+.It Fl s , Fl Fl special-files
+Normally,
+.Nm
+only attempts to read and determine the type of argument files which
+.Xr stat 2
+reports are ordinary files.
+This prevents problems, because reading special files may have peculiar
+consequences.
+Specifying the
+.Fl s
+option causes
+.Nm
+to also read argument files which are block or character special files.
+This is useful for determining the filesystem types of the data in raw
+disk partitions, which are block special files.
+This option also causes
+.Nm
+to disregard the file size as reported by
+.Xr stat 2
+since on some systems it reports a zero size for raw disk partitions.
+.It Fl S , Fl Fl no-sandbox
+On systems where libseccomp
+.Pa ( https://github.com/seccomp/libseccomp )
+is available, the
+.Fl S
+flag disables sandboxing which is enabled by default.
+This option is needed for file to execute external descompressing programs,
+i.e. when the
+.Fl z
+flag is specified and the built-in decompressors are not available.
+.It Fl v , Fl Fl version
+Print the version of the program and exit.
+.It Fl z , Fl Fl uncompress
+Try to look inside compressed files.
+.It Fl Z , Fl Fl uncompress-noreport
+Try to look inside compressed files, but report information about the contents
+only not the compression.
+.It Fl 0 , Fl Fl print0
+Output a null character
+.Sq \e0
+after the end of the filename.
+Nice to
+.Xr cut 1
+the output.
+This does not affect the separator, which is still printed.
+.Pp
+If this option is repeated more than once, then
+.Nm
+prints just the filename followed by a NUL followed by the description
+(or ERROR: text) followed by a second NUL for each entry.
+.It Fl -help
+Print a help message and exit.
+.El
+.Sh ENVIRONMENT
+The environment variable
+.Ev MAGIC
+can be used to set the default magic file name.
+If that variable is set, then
+.Nm
+will not attempt to open
+.Pa $HOME/.magic .
+.Nm
+adds
+.Dq Pa .mgc
+to the value of this variable as appropriate.
+The environment variable
+.Ev POSIXLY_CORRECT
+controls (on systems that support symbolic links), whether
+.Nm
+will attempt to follow symlinks or not.
+If set, then
+.Nm
+follows symlink, otherwise it does not.
+This is also controlled by the
+.Fl L
+and
+.Fl h
+options.
+.Sh FILES
+.Bl -tag -width __MAGIC__.mgc -compact
+.It Pa __MAGIC__.mgc
+Default compiled list of magic.
+.It Pa __MAGIC__
+Directory containing default magic files.
+.El
+.Sh EXIT STATUS
+.Nm
+will exit with
+.Dv 0
+if the operation was successful or
+.Dv >0
+if an error was encountered.
+The following errors cause diagnostic messages, but don't affect the program
+exit code (as POSIX requires), unless
+.Fl E
+is specified:
+.Bl -bullet -compact -offset indent
+.It
+A file cannot be found
+.It
+There is no permission to read a file
+.It
+The file type cannot be determined
+.El
+.Sh EXAMPLES
+.Bd -literal -offset indent
+$ file file.c file /dev/{wd0a,hda}
+file.c:   C program text
+file:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
+          dynamically linked (uses shared libs), stripped
+/dev/wd0a: block special (0/0)
+/dev/hda: block special (3/0)
+
+$ file -s /dev/wd0{b,d}
+/dev/wd0b: data
+/dev/wd0d: x86 boot sector
+
+$ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
+/dev/hda:   x86 boot sector
+/dev/hda1:  Linux/i386 ext2 filesystem
+/dev/hda2:  x86 boot sector
+/dev/hda3:  x86 boot sector, extended partition table
+/dev/hda4:  Linux/i386 ext2 filesystem
+/dev/hda5:  Linux/i386 swap file
+/dev/hda6:  Linux/i386 swap file
+/dev/hda7:  Linux/i386 swap file
+/dev/hda8:  Linux/i386 swap file
+/dev/hda9:  empty
+/dev/hda10: empty
+
+$ file -i file.c file /dev/{wd0a,hda}
+file.c:      text/x-c
+file:        application/x-executable
+/dev/hda:    application/x-not-regular-file
+/dev/wd0a:   application/x-not-regular-file
+
+.Ed
+.Sh SEE ALSO
+.Xr hexdump 1 ,
+.Xr od 1 ,
+.Xr strings 1 ,
+.Xr magic __FSECTION__
+.Sh STANDARDS CONFORMANCE
+This program is believed to exceed the System V Interface Definition
+of FILE(CMD), as near as one can determine from the vague language
+contained therein.
+Its behavior is mostly compatible with the System V program of the same name.
+This version knows more magic, however, so it will produce
+different (albeit more accurate) output in many cases.
+.\" URL: http://www.opengroup.org/onlinepubs/009695399/utilities/file.html
+.Pp
+The one significant difference
+between this version and System V
+is that this version treats any white space
+as a delimiter, so that spaces in pattern strings must be escaped.
+For example,
+.Bd -literal -offset indent
+\*[Gt]10       string  language impress\       (imPRESS data)
+.Ed
+.Pp
+in an existing magic file would have to be changed to
+.Bd -literal -offset indent
+\*[Gt]10       string  language\e impress      (imPRESS data)
+.Ed
+.Pp
+In addition, in this version, if a pattern string contains a backslash,
+it must be escaped.
+For example
+.Bd -literal -offset indent
+0      string          \ebegindata     Andrew Toolkit document
+.Ed
+.Pp
+in an existing magic file would have to be changed to
+.Bd -literal -offset indent
+0      string          \e\ebegindata   Andrew Toolkit document
+.Ed
+.Pp
+SunOS releases 3.2 and later from Sun Microsystems include a
+.Nm
+command derived from the System V one, but with some extensions.
+This version differs from Sun's only in minor ways.
+It includes the extension of the
+.Sq \*[Am]
+operator, used as,
+for example,
+.Bd -literal -offset indent
+\*[Gt]16       long\*[Am]0x7fffffff    \*[Gt]0         not stripped
+.Ed
+.Sh SECURITY
+On systems where libseccomp
+.Pa ( https://github.com/seccomp/libseccomp )
+is available,
+.Nm
+is enforces limiting system calls to only the ones necessary for the
+operation of the program.
+This enforcement does not provide any security benefit when
+.Nm
+is asked to decompress input files running external programs with
+the
+.Fl z
+option.
+To enable execution of external decompressors, one needs to disable
+sandboxing using the
+.Fl S
+flag.
+.Sh MAGIC DIRECTORY
+The magic file entries have been collected from various sources,
+mainly USENET, and contributed by various authors.
+Christos Zoulas (address below) will collect additional
+or corrected magic file entries.
+A consolidation of magic file entries
+will be distributed periodically.
+.Pp
+The order of entries in the magic file is significant.
+Depending on what system you are using, the order that
+they are put together may be incorrect.
+If your old
+.Nm
+command uses a magic file,
+keep the old magic file around for comparison purposes
+(rename it to
+.Pa __MAGIC__.orig ) .
+.Sh HISTORY
+There has been a
+.Nm
+command in every
+.Dv UNIX since at least Research Version 4
+(man page dated November, 1973).
+The System V version introduced one significant major change:
+the external list of magic types.
+This slowed the program down slightly but made it a lot more flexible.
+.Pp
+This program, based on the System V version,
+was written by Ian Darwin
+.Aq ian@darwinsys.com
+without looking at anybody else's source code.
+.Pp
+John Gilmore revised the code extensively, making it better than
+the first version.
+Geoff Collyer found several inadequacies
+and provided some magic file entries.
+Contributions of the
+.Sq \*[Am]
+operator by Rob McMahon,
+.Aq cudcv@warwick.ac.uk ,
+1989.
+.Pp
+Guy Harris,
+.Aq guy@netapp.com ,
+made many changes from 1993 to the present.
+.Pp
+Primary development and maintenance from 1990 to the present by
+Christos Zoulas
+.Aq christos@astron.com .
+.Pp
+Altered by Chris Lowth
+.Aq chris@lowth.com ,
+2000: handle the
+.Fl i
+option to output mime type strings, using an alternative
+magic file and internal logic.
+.Pp
+Altered by Eric Fischer
+.Aq enf@pobox.com ,
+July, 2000,
+to identify character codes and attempt to identify the languages
+of non-ASCII files.
+.Pp
+Altered by Reuben Thomas
+.Aq rrt@sc3d.org ,
+2007-2011, to improve MIME support, merge MIME and non-MIME magic,
+support directories as well as files of magic, apply many bug fixes,
+update and fix a lot of magic, improve the build system, improve the
+documentation, and rewrite the Python bindings in pure Python.
+.Pp
+The list of contributors to the
+.Sq magic
+directory (magic files)
+is too long to include here.
+You know who you are; thank you.
+Many contributors are listed in the source files.
+.Sh LEGAL NOTICE
+Copyright (c) Ian F. Darwin, Toronto, Canada, 1986-1999.
+Covered by the standard Berkeley Software Distribution copyright; see the file
+COPYING in the source distribution.
+.Pp
+The files
+.Pa tar.h
+and
+.Pa is_tar.c
+were written by John Gilmore from his public-domain
+.Xr tar 1
+program, and are not covered by the above license.
+.Sh BUGS
+Please report bugs and send patches to the bug tracker at
+.Pa https://bugs.astron.com/
+or the mailing list at
+.Aq file@astron.com
+(visit
+.Pa https://mailman.astron.com/mailman/listinfo/file
+first to subscribe).
+.Sh TODO
+Fix output so that tests for MIME and APPLE flags are not needed all
+over the place, and actual output is only done in one place.
+This needs a design.
+Suggestion: push possible outputs on to a list, then pick the
+last-pushed (most specific, one hopes) value at the end, or
+use a default if the list is empty.
+This should not slow down evaluation.
+.Pp
+The handling of
+.Dv MAGIC_CONTINUE
+and printing \e012- between entries is clumsy and complicated; refactor
+and centralize.
+.Pp
+Some of the encoding logic is hard-coded in encoding.c and can be moved
+to the magic files if we had a !:charset annotation
+.Pp
+Continue to squash all magic bugs.
+See Debian BTS for a good source.
+.Pp
+Store arbitrarily long strings, for example for %s patterns, so that
+they can be printed out.
+Fixes Debian bug #271672.
+This can be done by allocating strings in a string pool, storing the
+string pool at the end of the magic file and converting all the string
+pointers to relative offsets from the string pool.
+.Pp
+Add syntax for relative offsets after current level (Debian bug #466037).
+.Pp
+Make file -ki work, i.e. give multiple MIME types.
+.Pp
+Add a zip library so we can peek inside Office2007 documents to
+print more details about their contents.
+.Pp
+Add an option to print URLs for the sources of the file descriptions.
+.Pp
+Combine script searches and add a way to map executable names to MIME
+types (e.g. have a magic value for !:mime which causes the resulting
+string to be looked up in a table).
+This would avoid adding the same magic repeatedly for each new
+hash-bang interpreter.
+.Pp
+When a file descriptor is available, we can skip and adjust the buffer
+instead of the hacky buffer management we do now.
+.Pp
+Fix
+.Dq name
+and
+.Dq use
+to check for consistency at compile time (duplicate
+.Dq name ,
+.Dq use
+pointing to undefined
+.Dq name
+).
+Make
+.Dq name
+/
+.Dq use
+more efficient by keeping a sorted list of names.
+Special-case ^ to flip endianness in the parser so that it does not
+have to be escaped, and document it.
+.Pp
+If the offsets specified internally in the file exceed the buffer size
+(
+.Dv HOWMANY
+variable in file.h), then we don't seek to that offset, but we give up.
+It would be better if buffer managements was done when the file descriptor
+is available so move around the file.
+One must be careful though because this has performance (and thus security
+considerations).
+.Sh AVAILABILITY
+You can obtain the original author's latest version by anonymous FTP
+on
+.Pa ftp.astron.com
+in the directory
+.Pa /pub/file/file-X.YZ.tar.gz .
diff --git a/doc/libmagic.man b/doc/libmagic.man
new file mode 100644 (file)
index 0000000..086f065
--- /dev/null
@@ -0,0 +1,413 @@
+.\" $File: libmagic.man,v 1.44 2018/09/09 20:33:28 christos Exp $
+.\"
+.\" Copyright (c) Christos Zoulas 2003, 2018.
+.\" All Rights Reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice immediately at the beginning of the file, without modification,
+.\"    this list of conditions, and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd August 18, 2018
+.Dt LIBMAGIC 3
+.Os
+.Sh NAME
+.Nm magic_open ,
+.Nm magic_close ,
+.Nm magic_error ,
+.Nm magic_errno ,
+.Nm magic_descriptor ,
+.Nm magic_buffer ,
+.Nm magic_getflags ,
+.Nm magic_setflags ,
+.Nm magic_check ,
+.Nm magic_compile ,
+.Nm magic_list ,
+.Nm magic_load ,
+.Nm magic_load_buffers ,
+.Nm magic_setparam ,
+.Nm magic_getparam ,
+.Nm magic_version
+.Nd Magic number recognition library
+.Sh LIBRARY
+.Lb libmagic
+.Sh SYNOPSIS
+.In magic.h
+.Ft magic_t
+.Fn magic_open "int flags"
+.Ft void
+.Fn magic_close "magic_t cookie"
+.Ft const char *
+.Fn magic_error "magic_t cookie"
+.Ft int
+.Fn magic_errno "magic_t cookie"
+.Ft const char *
+.Fn magic_descriptor "magic_t cookie" "int fd"
+.Ft const char *
+.Fn magic_file "magic_t cookie" "const char *filename"
+.Ft const char *
+.Fn magic_buffer "magic_t cookie" "const void *buffer" "size_t length"
+.Ft int
+.Fn magic_getflags "magic_t cookie"
+.Ft int
+.Fn magic_setflags "magic_t cookie" "int flags"
+.Ft int
+.Fn magic_check "magic_t cookie" "const char *filename"
+.Ft int
+.Fn magic_compile "magic_t cookie" "const char *filename"
+.Ft int
+.Fn magic_list "magic_t cookie" "const char *filename"
+.Ft int
+.Fn magic_load "magic_t cookie" "const char *filename"
+.Ft int
+.Fn magic_load_buffers "magic_t cookie" "void **buffers" "size_t *sizes" "size_t nbuffers"
+.Ft int
+.Fn magic_getparam "magic_t cookie" "int param" "void *value"
+.Ft int
+.Fn magic_setparam "magic_t cookie" "int param" "const void *value"
+.Ft int
+.Fn magic_version "void"
+.Sh DESCRIPTION
+These functions
+operate on the magic database file
+which is described
+in
+.Xr magic __FSECTION__ .
+.Pp
+The function
+.Fn magic_open
+creates a magic cookie pointer and returns it.
+It returns
+.Dv NULL
+if there was an error allocating the magic cookie.
+The
+.Ar flags
+argument specifies how the other magic functions should behave:
+.Bl -tag -width MAGIC_COMPRESS
+.It Dv MAGIC_NONE
+No special handling.
+.It Dv MAGIC_DEBUG
+Print debugging messages to stderr.
+.It Dv MAGIC_SYMLINK
+If the file queried is a symlink, follow it.
+.It Dv MAGIC_COMPRESS
+If the file is compressed, unpack it and look at the contents.
+.It Dv MAGIC_DEVICES
+If the file is a block or character special device, then open the device
+and try to look in its contents.
+.It Dv MAGIC_MIME_TYPE
+Return a MIME type string, instead of a textual description.
+.It Dv MAGIC_MIME_ENCODING
+Return a MIME encoding, instead of a textual description.
+.It Dv MAGIC_MIME
+A shorthand for MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING.
+.It Dv MAGIC_CONTINUE
+Return all matches, not just the first.
+.It Dv MAGIC_CHECK
+Check the magic database for consistency and print warnings to stderr.
+.It Dv MAGIC_PRESERVE_ATIME
+On systems that support
+.Xr utime 3
+or
+.Xr utimes 2 ,
+attempt to preserve the access time of files analysed.
+.It Dv MAGIC_RAW
+Don't translate unprintable characters to a \eooo octal representation.
+.It Dv MAGIC_ERROR
+Treat operating system errors while trying to open files and follow symlinks
+as real errors, instead of printing them in the magic buffer.
+.It Dv MAGIC_APPLE
+Return the Apple creator and type.
+.It Dv MAGIC_EXTENSION
+Return a slash-separated list of extensions for this file type.
+.It Dv MAGIC_COMPRESS_TRANSP
+Don't report on compression, only report about the uncompressed data.
+.It Dv MAGIC_NO_CHECK_APPTYPE
+Don't check for
+.Dv EMX
+application type (only on EMX).
+.It Dv MAGIC_NO_CHECK_CDF
+Don't get extra information on MS Composite Document Files.
+.It Dv MAGIC_NO_CHECK_COMPRESS
+Don't look inside compressed files.
+.It Dv MAGIC_NO_CHECK_ELF
+Don't print ELF details.
+.It Dv MAGIC_NO_CHECK_ENCODING
+Don't check text encodings.
+.It Dv MAGIC_NO_CHECK_SOFT
+Don't consult magic files.
+.It Dv MAGIC_NO_CHECK_TAR
+Don't examine tar files.
+.It Dv MAGIC_NO_CHECK_TEXT
+Don't check for various types of text files.
+.It Dv MAGIC_NO_CHECK_TOKENS
+Don't look for known tokens inside ascii files.
+.It Dv MAGIC_NO_CHECK_JSON
+Don't example JSON files.
+.El
+.Pp
+The
+.Fn magic_close
+function closes the
+.Xr magic __FSECTION__
+database and deallocates any resources used.
+.Pp
+The
+.Fn magic_error
+function returns a textual explanation of the last error, or
+.Dv NULL
+if there was no error.
+.Pp
+The
+.Fn magic_errno
+function returns the last operating system error number
+.Pq Xr errno 2
+that was encountered by a system call.
+.Pp
+The
+.Fn magic_file
+function returns a textual description of the contents of the
+.Ar filename
+argument, or
+.Dv NULL
+if an error occurred.
+If the
+.Ar filename
+is
+.Dv NULL ,
+then stdin is used.
+.Pp
+The
+.Fn magic_descriptor
+function returns a textual description of the contents of the
+.Ar fd
+argument, or
+.Dv NULL
+if an error occurred.
+.Pp
+The
+.Fn magic_buffer
+function returns a textual description of the contents of the
+.Ar buffer
+argument with
+.Ar length
+bytes size.
+.Pp
+The
+.Fn magic_getflags
+functions returns a value representing current
+.Ar flags
+set.
+.Pp
+The
+.Fn magic_setflags
+function sets the
+.Ar flags
+described above.
+Note that using both MIME flags together can also
+return extra information on the charset.
+.Pp
+The
+.Fn magic_check
+function can be used to check the validity of entries in the colon
+separated database files passed in as
+.Ar filename ,
+or
+.Dv NULL
+for the default database.
+It returns 0 on success and \-1 on failure.
+.Pp
+The
+.Fn magic_compile
+function can be used to compile the colon
+separated list of database files passed in as
+.Ar filename ,
+or
+.Dv NULL
+for the default database.
+It returns 0 on success and \-1 on failure.
+The compiled files created are named from the
+.Xr basename 1
+of each file argument with
+.Dq .mgc
+appended to it.
+.Pp
+The
+.Fn magic_list
+function dumps all magic entries in a human readable format,
+dumping first the entries that are matched against binary files and then the
+ones that match text files.
+It takes and optional
+.Fa filename
+argument which is a colon separated list of database files, or
+.Dv NULL
+for the default database.
+.Pp
+The
+.Fn magic_load
+function must be used to load the colon
+separated list of database files passed in as
+.Ar filename ,
+or
+.Dv NULL
+for the default database file before any magic queries can performed.
+.Pp
+The default database file is named by the MAGIC environment variable.
+If that variable is not set, the default database file name is __MAGIC__.
+.Fn magic_load
+adds
+.Dq .mgc
+to the database filename as appropriate.
+.Pp
+The
+.Fn magic_load_buffers
+function takes an array of size
+.Fa nbuffers
+of
+.Fa buffers
+with a respective size for each in the array of
+.Fa sizes
+loaded with the contents of the magic databases from the filesystem.
+This function can be used in environment where the magic library does
+not have direct access to the filesystem, but can access the magic
+database via shared memory or other IPC means.
+.Pp
+The
+.Fn magic_getparam
+and
+.Fn magic_setparam
+allow getting and setting various limits related to the magic
+library.
+.Bl -column "MAGIC_PARAM_ELF_PHNUM_MAX" "size_t" "Default" -offset indent
+.It Sy "Parameter" Ta Sy "Type" Ta Sy "Default"
+.It Li MAGIC_PARAM_INDIR_MAX Ta size_t Ta 15
+.It Li MAGIC_PARAM_NAME_MAX Ta size_t Ta 30
+.It Li MAGIC_PARAM_ELF_NOTES_MAX Ta size_t Ta 256
+.It Li MAGIC_PARAM_ELF_PHNUM_MAX Ta size_t Ta 128
+.It Li MAGIC_PARAM_ELF_SHNUM_MAX Ta size_t Ta 32768
+.It Li MAGIC_PARAM_REGEX_MAX Ta size_t Ta 8192
+.It Li MAGIC_PARAM_BYTES_MAX Ta size_t Ta 1048576
+.El
+.Pp
+The
+.Dv MAGIC_PARAM_INDIR_RECURSION
+parameter controls how many levels of recursion will be followed for
+indirect magic entries.
+.Pp
+The
+.Dv MAGIC_PARAM_NAME_RECURSION
+parameter controls how many levels of recursion will be followed for
+for name/use calls.
+.Pp
+The
+.Dv MAGIC_PARAM_NAME_MAX
+parameter controls the maximum number of calls for name/use.
+.Pp
+The
+.Dv MAGIC_PARAM_NOTES_MAX
+parameter controls how many ELF notes will be processed.
+.Pp
+The
+.Dv MAGIC_PARAM_PHNUM_MAX
+parameter controls how many ELF program sections will be processed.
+.Pp
+The
+.Dv MAGIC_PARAM_SHNUM_MAX
+parameter controls how many ELF sections will be processed.
+.Pp
+The
+.Fn magic_version
+command returns the version number of this library which is compiled into
+the shared library using the constant
+.Dv MAGIC_VERSION
+from
+.In magic.h .
+This can be used by client programs to verify that the version they compile
+against is the same as the version that they run against.
+.Sh RETURN VALUES
+The function
+.Fn magic_open
+returns a magic cookie on success and
+.Dv NULL
+on failure setting errno to an appropriate value.
+It will set errno to
+.Er EINVAL
+if an unsupported value for flags was given.
+The
+.Fn magic_list ,
+.Fn magic_load ,
+.Fn magic_compile ,
+and
+.Fn magic_check
+functions return 0 on success and \-1 on failure.
+The
+.Fn magic_buffer ,
+.Fn magic_getpath ,
+and
+.Fn magic_file ,
+functions return a string on success and
+.Dv NULL
+on failure.
+The
+.Fn magic_error
+function returns a textual description of the errors of the above
+functions, or
+.Dv NULL
+if there was no error.
+The
+.Fn magic_version
+always returns the version number of the library.
+Finally,
+.Fn magic_setflags
+returns \-1 on systems that don't support
+.Xr utime 3 ,
+or
+.Xr utimes 2
+when
+.Dv MAGIC_PRESERVE_ATIME
+is set.
+.Sh FILES
+.Bl -tag -width __MAGIC__.mgc -compact
+.It Pa __MAGIC__
+The non-compiled default magic database.
+.It Pa __MAGIC__.mgc
+The compiled default magic database.
+.El
+.Sh SEE ALSO
+.Xr file __CSECTION__ ,
+.Xr magic __FSECTION__
+.Sh BUGS
+The results from
+.Fn magic_buffer
+and
+.Fn magic_file
+where the buffer and the file contain the same data
+can produce different results, because in the
+.Fn magic_file
+case, the program can
+.Xr lseek 2
+and
+.Xr stat 2
+the file descriptor.
+.Sh AUTHORS
+.An M\(oans Rullg\(oard
+Initial libmagic implementation, and configuration.
+.An Christos Zoulas
+API cleanup, error code and allocation handling.
diff --git a/doc/magic.man b/doc/magic.man
new file mode 100644 (file)
index 0000000..bc69604
--- /dev/null
@@ -0,0 +1,755 @@
+.\" $File: magic.man,v 1.96 2019/01/21 14:56:53 christos Exp $
+.Dd January 21, 2019
+.Dt MAGIC __FSECTION__
+.Os
+.\" install as magic.4 on USG, magic.5 on V7, Berkeley and Linux systems.
+.Sh NAME
+.Nm magic
+.Nd file command's magic pattern file
+.Sh DESCRIPTION
+This manual page documents the format of magic files as
+used by the
+.Xr file __CSECTION__
+command, version __VERSION__.
+The
+.Xr file __CSECTION__
+command identifies the type of a file using,
+among other tests,
+a test for whether the file contains certain
+.Dq "magic patterns" .
+The database of these
+.Dq "magic patterns"
+is usually located in a binary file in
+.Pa __MAGIC__.mgc
+or a directory of source text magic pattern fragment files in
+.Pa __MAGIC__ .
+The database specifies what patterns are to be tested for, what message or
+MIME type to print if a particular pattern is found,
+and additional information to extract from the file.
+.Pp
+The format of the source fragment files that are used to build this database
+is as follows:
+Each line of a fragment file specifies a test to be performed.
+A test compares the data starting at a particular offset
+in the file with a byte value, a string or a numeric value.
+If the test succeeds, a message is printed.
+The line consists of the following fields:
+.Bl -tag -width ".Dv message"
+.It Dv offset
+A number specifying the offset (in bytes) into the file of the data
+which is to be tested.
+This offset can be a negative number if it is:
+.Bl -bullet  -compact
+.It
+The first direct offset of the magic entry (at continuation level 0),
+in which case it is interpreted an offset from end end of the file
+going backwards.
+This works only when a file descriptor to the file is a available and it
+is a regular file.
+.It
+A continuation offset relative to the end of the last up-level field
+.Dv ( \*[Am] ) .
+.El
+.It Dv type
+The type of the data to be tested.
+The possible values are:
+.Bl -tag -width ".Dv lestring16"
+.It Dv byte
+A one-byte value.
+.It Dv short
+A two-byte value in this machine's native byte order.
+.It Dv long
+A four-byte value in this machine's native byte order.
+.It Dv quad
+An eight-byte value in this machine's native byte order.
+.It Dv float
+A 32-bit single precision IEEE floating point number in this machine's native byte order.
+.It Dv double
+A 64-bit double precision IEEE floating point number in this machine's native byte order.
+.It Dv string
+A string of bytes.
+The string type specification can be optionally followed
+by /[WwcCtbT]*.
+The
+.Dq W
+flag compacts whitespace in the target, which must
+contain at least one whitespace character.
+If the magic has
+.Dv n
+consecutive blanks, the target needs at least
+.Dv n
+consecutive blanks to match.
+The
+.Dq w
+flag treats every blank in the magic as an optional blank.
+The
+.Dq c
+flag specifies case insensitive matching: lower case
+characters in the magic match both lower and upper case characters in the
+target, whereas upper case characters in the magic only match upper case
+characters in the target.
+The
+.Dq C
+flag specifies case insensitive matching: upper case
+characters in the magic match both lower and upper case characters in the
+target, whereas lower case characters in the magic only match upper case
+characters in the target.
+To do a complete case insensitive match, specify both
+.Dq c
+and
+.Dq C .
+The
+.Dq t
+flag forces the test to be done for text files, while the
+.Dq b
+flag forces the test to be done for binary files.
+The
+.Dq T
+flag causes the string to be trimmed, i.e. leading and trailing whitespace
+is deleted before the string is printed.
+.It Dv pstring
+A Pascal-style string where the first byte/short/int is interpreted as the
+unsigned length.
+The length defaults to byte and can be specified as a modifier.
+The following modifiers are supported:
+.Bl -tag -compact -width B
+.It B
+A byte length (default).
+.It H
+A 2 byte big endian length.
+.It h
+A 2 byte little endian length.
+.It L
+A 4 byte big endian length.
+.It l
+A 4 byte little endian length.
+.It J
+The length includes itself in its count.
+.El
+The string is not NUL terminated.
+.Dq J
+is used rather than the more
+valuable
+.Dq I
+because this type of length is a feature of the JPEG
+format.
+.It Dv date
+A four-byte value interpreted as a UNIX date.
+.It Dv qdate
+A eight-byte value interpreted as a UNIX date.
+.It Dv ldate
+A four-byte value interpreted as a UNIX-style date, but interpreted as
+local time rather than UTC.
+.It Dv qldate
+An eight-byte value interpreted as a UNIX-style date, but interpreted as
+local time rather than UTC.
+.It Dv qwdate
+An eight-byte value interpreted as a Windows-style date.
+.It Dv beid3
+A 32-bit ID3 length in big-endian byte order.
+.It Dv beshort
+A two-byte value in big-endian byte order.
+.It Dv belong
+A four-byte value in big-endian byte order.
+.It Dv bequad
+An eight-byte value in big-endian byte order.
+.It Dv befloat
+A 32-bit single precision IEEE floating point number in big-endian byte order.
+.It Dv bedouble
+A 64-bit double precision IEEE floating point number in big-endian byte order.
+.It Dv bedate
+A four-byte value in big-endian byte order,
+interpreted as a Unix date.
+.It Dv beqdate
+An eight-byte value in big-endian byte order,
+interpreted as a Unix date.
+.It Dv beldate
+A four-byte value in big-endian byte order,
+interpreted as a UNIX-style date, but interpreted as local time rather
+than UTC.
+.It Dv beqldate
+An eight-byte value in big-endian byte order,
+interpreted as a UNIX-style date, but interpreted as local time rather
+than UTC.
+.It Dv beqwdate
+An eight-byte value in big-endian byte order,
+interpreted as a Windows-style date.
+.It Dv bestring16
+A two-byte unicode (UCS16) string in big-endian byte order.
+.It Dv leid3
+A 32-bit ID3 length in little-endian byte order.
+.It Dv leshort
+A two-byte value in little-endian byte order.
+.It Dv lelong
+A four-byte value in little-endian byte order.
+.It Dv lequad
+An eight-byte value in little-endian byte order.
+.It Dv lefloat
+A 32-bit single precision IEEE floating point number in little-endian byte order.
+.It Dv ledouble
+A 64-bit double precision IEEE floating point number in little-endian byte order.
+.It Dv ledate
+A four-byte value in little-endian byte order,
+interpreted as a UNIX date.
+.It Dv leqdate
+An eight-byte value in little-endian byte order,
+interpreted as a UNIX date.
+.It Dv leldate
+A four-byte value in little-endian byte order,
+interpreted as a UNIX-style date, but interpreted as local time rather
+than UTC.
+.It Dv leqldate
+An eight-byte value in little-endian byte order,
+interpreted as a UNIX-style date, but interpreted as local time rather
+than UTC.
+.It Dv leqwdate
+An eight-byte value in little-endian byte order,
+interpreted as a Windows-style date.
+.It Dv lestring16
+A two-byte unicode (UCS16) string in little-endian byte order.
+.It Dv melong
+A four-byte value in middle-endian (PDP-11) byte order.
+.It Dv medate
+A four-byte value in middle-endian (PDP-11) byte order,
+interpreted as a UNIX date.
+.It Dv meldate
+A four-byte value in middle-endian (PDP-11) byte order,
+interpreted as a UNIX-style date, but interpreted as local time rather
+than UTC.
+.It Dv indirect
+Starting at the given offset, consult the magic database again.
+The offset of the
+.Dv indirect
+magic is by default absolute in the file, but one can specify
+.Dv /r
+to indicate that the offset is relative from the beginning of the entry.
+.It Dv name
+Define a
+.Dq named
+magic instance that can be called from another
+.Dv use
+magic entry, like a subroutine call.
+Named instance direct magic offsets are relative to the offset of the
+previous matched entry, but indirect offsets are relative to the beginning
+of the file as usual.
+Named magic entries always match.
+.It Dv use
+Recursively call the named magic starting from the current offset.
+If the name of the referenced begins with a
+.Dv ^
+then the endianness of the magic is switched; if the magic mentioned
+.Dv leshort
+for example,
+it is treated as
+.Dv beshort
+and vice versa.
+This is useful to avoid duplicating the rules for different endianness.
+.It Dv regex
+A regular expression match in extended POSIX regular expression syntax
+(like egrep).
+Regular expressions can take exponential time to process, and their
+performance is hard to predict, so their use is discouraged.
+When used in production environments, their performance
+should be carefully checked.
+The size of the string to search should also be limited by specifying
+.Dv /<length> ,
+to avoid performance issues scanning long files.
+The type specification can also be optionally followed by
+.Dv /[c][s][l] .
+The
+.Dq c
+flag makes the match case insensitive, while the
+.Dq s
+flag update the offset to the start offset of the match, rather than the end.
+The
+.Dq l
+modifier, changes the limit of length to mean number of lines instead of a
+byte count.
+Lines are delimited by the platforms native line delimiter.
+When a line count is specified, an implicit byte count also computed assuming
+each line is 80 characters long.
+If neither a byte or line count is specified, the search is limited automatically
+to 8KiB.
+.Dv ^
+and
+.Dv $
+match the beginning and end of individual lines, respectively,
+not beginning and end of file.
+.It Dv search
+A literal string search starting at the given offset.
+The same modifier flags can be used as for string patterns.
+The search expression must contain the range in the form
+.Dv /number,
+that is the number of positions at which the match will be
+attempted, starting from the start offset.
+This is suitable for
+searching larger binary expressions with variable offsets, using
+.Dv \e
+escapes for special characters.
+The order of modifier and number is not relevant.
+.It Dv default
+This is intended to be used with the test
+.Em x
+(which is always true) and it has no type.
+It matches when no other test at that continuation level has matched before.
+Clearing that matched tests for a continuation level, can be done using the
+.Dv clear
+test.
+.It Dv clear
+This test is always true and clears the match flag for that continuation level.
+It is intended to be used with the
+.Dv default
+test.
+.El
+.Pp
+For compatibility with the Single
+.Ux
+Standard, the type specifiers
+.Dv dC
+and
+.Dv d1
+are equivalent to
+.Dv byte ,
+the type specifiers
+.Dv uC
+and
+.Dv u1
+are equivalent to
+.Dv ubyte ,
+the type specifiers
+.Dv dS
+and
+.Dv d2
+are equivalent to
+.Dv short ,
+the type specifiers
+.Dv uS
+and
+.Dv u2
+are equivalent to
+.Dv ushort ,
+the type specifiers
+.Dv dI ,
+.Dv dL ,
+and
+.Dv d4
+are equivalent to
+.Dv long ,
+the type specifiers
+.Dv uI ,
+.Dv uL ,
+and
+.Dv u4
+are equivalent to
+.Dv ulong ,
+the type specifier
+.Dv d8
+is equivalent to
+.Dv quad ,
+the type specifier
+.Dv u8
+is equivalent to
+.Dv uquad ,
+and the type specifier
+.Dv s
+is equivalent to
+.Dv string .
+In addition, the type specifier
+.Dv dQ
+is equivalent to
+.Dv quad
+and the type specifier
+.Dv uQ
+is equivalent to
+.Dv uquad .
+.Pp
+Each top-level magic pattern (see below for an explanation of levels)
+is classified as text or binary according to the types used.
+Types
+.Dq regex
+and
+.Dq search
+are classified as text tests, unless non-printable characters are used
+in the pattern.
+All other tests are classified as binary.
+A top-level
+pattern is considered to be a test text when all its patterns are text
+patterns; otherwise, it is considered to be a binary pattern.
+When
+matching a file, binary patterns are tried first; if no match is
+found, and the file looks like text, then its encoding is determined
+and the text patterns are tried.
+.Pp
+The numeric types may optionally be followed by
+.Dv \*[Am]
+and a numeric value,
+to specify that the value is to be AND'ed with the
+numeric value before any comparisons are done.
+Prepending a
+.Dv u
+to the type indicates that ordered comparisons should be unsigned.
+.It Dv test
+The value to be compared with the value from the file.
+If the type is
+numeric, this value
+is specified in C form; if it is a string, it is specified as a C string
+with the usual escapes permitted (e.g. \en for new-line).
+.Pp
+Numeric values
+may be preceded by a character indicating the operation to be performed.
+It may be
+.Dv = ,
+to specify that the value from the file must equal the specified value,
+.Dv \*[Lt] ,
+to specify that the value from the file must be less than the specified
+value,
+.Dv \*[Gt] ,
+to specify that the value from the file must be greater than the specified
+value,
+.Dv \*[Am] ,
+to specify that the value from the file must have set all of the bits
+that are set in the specified value,
+.Dv ^ ,
+to specify that the value from the file must have clear any of the bits
+that are set in the specified value, or
+.Dv ~ ,
+the value specified after is negated before tested.
+.Dv x ,
+to specify that any value will match.
+If the character is omitted, it is assumed to be
+.Dv = .
+Operators
+.Dv \*[Am] ,
+.Dv ^ ,
+and
+.Dv ~
+don't work with floats and doubles.
+The operator
+.Dv !\&
+specifies that the line matches if the test does
+.Em not
+succeed.
+.Pp
+Numeric values are specified in C form; e.g.
+.Dv 13
+is decimal,
+.Dv 013
+is octal, and
+.Dv 0x13
+is hexadecimal.
+.Pp
+Numeric operations are not performed on date types, instead the numeric
+value is interpreted as an offset.
+.Pp
+For string values, the string from the
+file must match the specified string.
+The operators
+.Dv = ,
+.Dv \*[Lt]
+and
+.Dv \*[Gt]
+(but not
+.Dv \*[Am] )
+can be applied to strings.
+The length used for matching is that of the string argument
+in the magic file.
+This means that a line can match any non-empty string (usually used to
+then print the string), with
+.Em \*[Gt]\e0
+(because all non-empty strings are greater than the empty string).
+.Pp
+Dates are treated as numerical values in the respective internal
+representation.
+.Pp
+The special test
+.Em x
+always evaluates to true.
+.It Dv message
+The message to be printed if the comparison succeeds.
+If the string contains a
+.Xr printf 3
+format specification, the value from the file (with any specified masking
+performed) is printed using the message as the format string.
+If the string begins with
+.Dq \eb ,
+the message printed is the remainder of the string with no whitespace
+added before it: multiple matches are normally separated by a single
+space.
+.El
+.Pp
+An APPLE 4+4 character APPLE creator and type can be specified as:
+.Bd -literal -offset indent
+!:apple        CREATYPE
+.Ed
+.Pp
+A MIME type is given on a separate line, which must be the next
+non-blank or comment line after the magic line that identifies the
+file type, and has the following format:
+.Bd -literal -offset indent
+!:mime MIMETYPE
+.Ed
+.Pp
+i.e. the literal string
+.Dq !:mime
+followed by the MIME type.
+.Pp
+An optional strength can be supplied on a separate line which refers to
+the current magic description using the following format:
+.Bd -literal -offset indent
+!:strength OP VALUE
+.Ed
+.Pp
+The operand
+.Dv OP
+can be:
+.Dv + ,
+.Dv - ,
+.Dv * ,
+or
+.Dv /
+and
+.Dv VALUE
+is a constant between 0 and 255.
+This constant is applied using the specified operand
+to the currently computed default magic strength.
+.Pp
+Some file formats contain additional information which is to be printed
+along with the file type or need additional tests to determine the true
+file type.
+These additional tests are introduced by one or more
+.Em \*[Gt]
+characters preceding the offset.
+The number of
+.Em \*[Gt]
+on the line indicates the level of the test; a line with no
+.Em \*[Gt]
+at the beginning is considered to be at level 0.
+Tests are arranged in a tree-like hierarchy:
+if the test on a line at level
+.Em n
+succeeds, all following tests at level
+.Em n+1
+are performed, and the messages printed if the tests succeed, until a line
+with level
+.Em n
+(or less) appears.
+For more complex files, one can use empty messages to get just the
+"if/then" effect, in the following way:
+.Bd -literal -offset indent
+0      string   MZ
+\*[Gt]0x18  leshort  \*[Lt]0x40   MS-DOS executable
+\*[Gt]0x18  leshort  \*[Gt]0x3f   extended PC executable (e.g., MS Windows)
+.Ed
+.Pp
+Offsets do not need to be constant, but can also be read from the file
+being examined.
+If the first character following the last
+.Em \*[Gt]
+is a
+.Em \&(
+then the string after the parenthesis is interpreted as an indirect offset.
+That means that the number after the parenthesis is used as an offset in
+the file.
+The value at that offset is read, and is used again as an offset
+in the file.
+Indirect offsets are of the form:
+.Em (( x [[.,][bBcCeEfFgGhHiIlmsSqQ]][+\-][ y ]) .
+The value of
+.Em x
+is used as an offset in the file.
+A byte, id3 length, short or long is read at that offset depending on the
+.Em [bBcCeEfFgGhHiIlmsSqQ]
+type specifier.
+The value is treated as signed if
+.Dq ,
+is specified or unsigned if
+.Dq .
+is specified.
+The capitalized types interpret the number as a big endian
+value, whereas the small letter versions interpret the number as a little
+endian value;
+the
+.Em m
+type interprets the number as a middle endian (PDP-11) value.
+To that number the value of
+.Em y
+is added and the result is used as an offset in the file.
+The default type if one is not specified is long.
+The following types are recognized:
+.Bl -column -offset indent "Type" "Half/Short" "Little" "Size"
+.It Sy Type    Sy Mnemonic     Sy Endian       Sy Size
+.It bcBc       Byte/Char       N/A     1
+.It efg        Double  Little  8
+.It EFG        Double  Big     8
+.It hs Half/Short      Little  2
+.It HS Half/Short      Big     2
+.It i  ID3     Little  4
+.It I  ID3     Big     4
+.It m  Middle  Middle  4
+.It q  Quad    Little  8
+.It Q  Quad    Big     8
+.El
+.Pp
+That way variable length structures can be examined:
+.Bd -literal -offset indent
+# MS Windows executables are also valid MS-DOS executables
+0           string  MZ
+\*[Gt]0x18       leshort \*[Lt]0x40   MZ executable (MS-DOS)
+# skip the whole block below if it is not an extended executable
+\*[Gt]0x18       leshort \*[Gt]0x3f
+\*[Gt]\*[Gt](0x3c.l)  string  PE\e0\e0  PE executable (MS-Windows)
+\*[Gt]\*[Gt](0x3c.l)  string  LX\e0\e0  LX executable (OS/2)
+.Ed
+.Pp
+This strategy of examining has a drawback: you must make sure that you
+eventually print something, or users may get empty output (such as when
+there is neither PE\e0\e0 nor LE\e0\e0 in the above example).
+.Pp
+If this indirect offset cannot be used directly, simple calculations are
+possible: appending
+.Em [+-*/%\*[Am]|^]number
+inside parentheses allows one to modify
+the value read from the file before it is used as an offset:
+.Bd -literal -offset indent
+# MS Windows executables are also valid MS-DOS executables
+0           string  MZ
+# sometimes, the value at 0x18 is less that 0x40 but there's still an
+# extended executable, simply appended to the file
+\*[Gt]0x18       leshort \*[Lt]0x40
+\*[Gt]\*[Gt](4.s*512) leshort 0x014c  COFF executable (MS-DOS, DJGPP)
+\*[Gt]\*[Gt](4.s*512) leshort !0x014c MZ executable (MS-DOS)
+.Ed
+.Pp
+Sometimes you do not know the exact offset as this depends on the length or
+position (when indirection was used before) of preceding fields.
+You can specify an offset relative to the end of the last up-level
+field using
+.Sq \*[Am]
+as a prefix to the offset:
+.Bd -literal -offset indent
+0           string  MZ
+\*[Gt]0x18       leshort \*[Gt]0x3f
+\*[Gt]\*[Gt](0x3c.l)  string  PE\e0\e0    PE executable (MS-Windows)
+# immediately following the PE signature is the CPU type
+\*[Gt]\*[Gt]\*[Gt]\*[Am]0       leshort 0x14c     for Intel 80386
+\*[Gt]\*[Gt]\*[Gt]\*[Am]0       leshort 0x184     for DEC Alpha
+.Ed
+.Pp
+Indirect and relative offsets can be combined:
+.Bd -literal -offset indent
+0             string  MZ
+\*[Gt]0x18         leshort \*[Lt]0x40
+\*[Gt]\*[Gt](4.s*512)   leshort !0x014c MZ executable (MS-DOS)
+# if it's not COFF, go back 512 bytes and add the offset taken
+# from byte 2/3, which is yet another way of finding the start
+# of the extended executable
+\*[Gt]\*[Gt]\*[Gt]\*[Am](2.s-514) string  LE      LE executable (MS Windows VxD driver)
+.Ed
+.Pp
+Or the other way around:
+.Bd -literal -offset indent
+0                 string  MZ
+\*[Gt]0x18             leshort \*[Gt]0x3f
+\*[Gt]\*[Gt](0x3c.l)        string  LE\e0\e0  LE executable (MS-Windows)
+# at offset 0x80 (-4, since relative offsets start at the end
+# of the up-level match) inside the LE header, we find the absolute
+# offset to the code area, where we look for a specific signature
+\*[Gt]\*[Gt]\*[Gt](\*[Am]0x7c.l+0x26) string  UPX     \eb, UPX compressed
+.Ed
+.Pp
+Or even both!
+.Bd -literal -offset indent
+0                string  MZ
+\*[Gt]0x18            leshort \*[Gt]0x3f
+\*[Gt]\*[Gt](0x3c.l)       string  LE\e0\e0 LE executable (MS-Windows)
+# at offset 0x58 inside the LE header, we find the relative offset
+# to a data area where we look for a specific signature
+\*[Gt]\*[Gt]\*[Gt]\*[Am](\*[Am]0x54.l-3)  string  UNACE  \eb, ACE self-extracting archive
+.Ed
+.Pp
+If you have to deal with offset/length pairs in your file, even the
+second value in a parenthesized expression can be taken from the file itself,
+using another set of parentheses.
+Note that this additional indirect offset is always relative to the
+start of the main indirect offset.
+.Bd -literal -offset indent
+0                 string       MZ
+\*[Gt]0x18             leshort      \*[Gt]0x3f
+\*[Gt]\*[Gt](0x3c.l)        string       PE\e0\e0 PE executable (MS-Windows)
+# search for the PE section called ".idata"...
+\*[Gt]\*[Gt]\*[Gt]\*[Am]0xf4          search/0x140 .idata
+# ...and go to the end of it, calculated from start+length;
+# these are located 14 and 10 bytes after the section name
+\*[Gt]\*[Gt]\*[Gt]\*[Gt](\*[Am]0xe.l+(-4)) string       PK\e3\e4 \eb, ZIP self-extracting archive
+.Ed
+.Pp
+If you have a list of known values at a particular continuation level,
+and you want to provide a switch-like default case:
+.Bd -literal -offset indent
+# clear that continuation level match
+\*[Gt]18       clear
+\*[Gt]18       lelong  1       one
+\*[Gt]18       lelong  2       two
+\*[Gt]18       default x
+# print default match
+\*[Gt]\*[Gt]18 lelong  x       unmatched 0x%x
+.Ed
+.Sh SEE ALSO
+.Xr file __CSECTION__
+\- the command that reads this file.
+.Sh BUGS
+The formats
+.Dv long ,
+.Dv belong ,
+.Dv lelong ,
+.Dv melong ,
+.Dv short ,
+.Dv beshort ,
+and
+.Dv leshort
+do not depend on the length of the C data types
+.Dv short
+and
+.Dv long
+on the platform, even though the Single
+.Ux
+Specification implies that they do.  However, as OS X Mountain Lion has
+passed the Single
+.Ux
+Specification validation suite, and supplies a version of
+.Xr file __CSECTION__
+in which they do not depend on the sizes of the C data types and that is
+built for a 64-bit environment in which
+.Dv long
+is 8 bytes rather than 4 bytes, presumably the validation suite does not
+test whether, for example
+.Dv long
+refers to an item with the same size as the C data type
+.Dv long .
+There should probably be
+.Dv type
+names
+.Dv int8 ,
+.Dv uint8 ,
+.Dv int16 ,
+.Dv uint16 ,
+.Dv int32 ,
+.Dv uint32 ,
+.Dv int64 ,
+and
+.Dv uint64 ,
+and specified-byte-order variants of them,
+to make it clearer that those types have specified widths.
+.\"
+.\" From: guy@sun.uucp (Guy Harris)
+.\" Newsgroups: net.bugs.usg
+.\" Subject: /etc/magic's format isn't well documented
+.\" Message-ID: <2752@sun.uucp>
+.\" Date: 3 Sep 85 08:19:07 GMT
+.\" Organization: Sun Microsystems, Inc.
+.\" Lines: 136
+.\"
+.\" Here's a manual page for the format accepted by the "file" made by adding
+.\" the changes I posted to the S5R2 version.
+.\"
+.\" Modified for Ian Darwin's version of the file command.
diff --git a/fuzz/Dockerfile b/fuzz/Dockerfile
new file mode 100644 (file)
index 0000000..c965aab
--- /dev/null
@@ -0,0 +1,21 @@
+# Copyright 2016 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+MAINTAINER mike.aizatsky@gmail.com
+RUN apt-get install -y make autoconf automake libtool shtool
+RUN git clone --depth 1 https://github.com/file/file.git
+WORKDIR file/fuzz
diff --git a/fuzz/build.sh b/fuzz/build.sh
new file mode 100755 (executable)
index 0000000..6f23fcd
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash -eu
+# Copyright 2016 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+: ${SRC:=.}
+: ${OUT:=.}
+: ${CC:=cc}
+: ${CFLAGS:=-O -DHAVE_CONFIG_H -Wall}
+
+#(cd .. && autoreconf -i && ./configure --enable-static && make V=1 all)
+
+"$CC" $CFLAGS -I../src/ -I.. \
+     "$SRC/magic_fuzzer.c" -o "$OUT/magic_fuzzer" \
+     -lFuzzingEngine ../src/.libs/libmagic.a
+
+cp ../magic/magic.mgc "$OUT/magic.mgc"
diff --git a/fuzz/magic_fuzzer.c b/fuzz/magic_fuzzer.c
new file mode 100644 (file)
index 0000000..9a11162
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * LLVM fuzzing integration.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: magic_fuzzer.c,v 1.1 2017/04/24 19:41:34 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <libgen.h>
+#include <stdlib.h>
+#include <err.h>
+
+int LLVMFuzzerInitialize(int *, char ***);
+int LLVMFuzzerTestOneInput(const uint8_t *, size_t);
+
+static magic_t magic;
+
+int
+LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+       char dfile[MAXPATHLEN], mfile[MAXPATHLEN];
+
+       magic = magic_open(MAGIC_NONE);
+       if (magic == NULL) {
+               warn("magic_open");
+               return -1;
+       }
+
+       // Poor man's strlcpy(3), to avoid potentially destructive dirname(3)
+       snprintf(dfile, sizeof(dfile), "%s", (*argv)[0]);
+       snprintf(mfile, sizeof(mfile), "%s/magic", dirname(dfile));
+
+       if (magic_load(magic, mfile) == -1) {
+               warnx("magic_load: %s", magic_error(magic));
+               return -1;
+       }
+
+       return 0;
+}
+
+int
+LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+       if (size == 0)
+               return 0;
+
+       magic_buffer(magic, data, size);
+       return 0;
+}
diff --git a/fuzz/project.yaml b/fuzz/project.yaml
new file mode 100644 (file)
index 0000000..1a8eda7
--- /dev/null
@@ -0,0 +1,6 @@
+homepage: "http://www.darwinsys.com/file/"
+primary_contact: "zoulasc@gmail.com"
+sanitizers:
+  - address
+  - memory
+  - undefined
diff --git a/m4/.cvsignore b/m4/.cvsignore
new file mode 100644 (file)
index 0000000..56c190a
--- /dev/null
@@ -0,0 +1,2 @@
+*.m4
+.cvsignore
diff --git a/magic/.cvsignore b/magic/.cvsignore
new file mode 100644 (file)
index 0000000..cbb1b4f
--- /dev/null
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+magic
+*.mgc
+Localstuff
+.gitignore
diff --git a/magic/Header b/magic/Header
new file mode 100644 (file)
index 0000000..345a50f
--- /dev/null
@@ -0,0 +1,5 @@
+# Magic data for file(1) command.
+# Format is described in magic(files), where:
+# files is 5 on V7 and BSD, 4 on SV, and ?? on SVID.
+# Don't edit this file, edit /etc/magic or send your magic improvements
+# to the maintainers, at file@astron.com
diff --git a/magic/Localstuff b/magic/Localstuff
new file mode 100644 (file)
index 0000000..419855f
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# Localstuff:  file(1) magic for locally observed files
+#
+# $File: Localstuff,v 1.4 2003/03/23 04:17:27 christos Exp $
+# Add any locally observed files here.  Remember:
+# text if readable, executable if runnable binary, data if unreadable.
diff --git a/magic/Magdir/acorn b/magic/Magdir/acorn
new file mode 100644 (file)
index 0000000..4aa3455
--- /dev/null
@@ -0,0 +1,102 @@
+
+#------------------------------------------------------------------------------
+# $File: acorn,v 1.7 2019/04/19 00:42:27 christos Exp $
+# acorn:  file(1) magic for files found on Acorn systems
+#
+
+# RISC OS Chunk File Format
+# From RISC OS Programmer's Reference Manual, Appendix D
+# We guess the file type from the type of the first chunk.
+0      lelong          0xc3cbc6c5      RISC OS Chunk data
+>12    string          OBJ_            \b, AOF object
+>12    string          LIB_            \b, ALF library
+
+# RISC OS AIF, contains "SWI OS_Exit" at offset 16.
+16     lelong          0xef000011      RISC OS AIF executable
+
+# RISC OS Draw files
+# From RISC OS Programmer's Reference Manual, Appendix E
+0      string          Draw            RISC OS Draw file data
+
+# RISC OS new format font files
+# From RISC OS Programmer's Reference Manual, Appendix E
+0      string          FONT\0          RISC OS outline font data,
+>5     byte            x               version %d
+0      string          FONT\1          RISC OS 1bpp font data,
+>5     byte            x               version %d
+0      string          FONT\4          RISC OS 4bpp font data
+>5     byte            x               version %d
+
+# RISC OS Music files
+# From RISC OS Programmer's Reference Manual, Appendix E
+0      string          Maestro\r       RISC OS music file
+>8     byte            x               version %d
+
+>8     byte            x               type %d
+
+# Digital Symphony data files
+# From: Bernard Jungen (bern8817@euphonynet.be)
+0              string  \x02\x01\x13\x13\x13\x01\x0d\x10        Digital Symphony sound sample (RISC OS),
+>8             byte    x       version %d,
+>9             pstring x       named "%s",
+>(9.b+19)      byte    =0      8-bit logarithmic
+>(9.b+19)      byte    =1      LZW-compressed linear
+>(9.b+19)      byte    =2      8-bit linear signed
+>(9.b+19)      byte    =3      16-bit linear signed
+>(9.b+19)      byte    =4      SigmaDelta-compressed linear
+>(9.b+19)      byte    =5      SigmaDelta-compressed logarithmic
+>(9.b+19)      byte    >5      unknown format
+
+0      string  \x02\x01\x13\x13\x14\x12\x01\x0b        Digital Symphony song (RISC OS),
+>8     byte    x       version %d,
+>9     byte    =1      1 voice,
+>9     byte    !1      %d voices,
+>10    leshort =1      1 track,
+>10    leshort !1      %d tracks,
+>12    leshort =1      1 pattern
+>12    leshort !1      %d patterns
+
+0      string  \x02\x01\x13\x13\x10\x14\x12\x0e
+>9     byte    =0      Digital Symphony sequence (RISC OS),
+>>8    byte    x       version %d,
+>>10   byte    =1      1 line,
+>>10   byte    !1      %d lines,
+>>11   leshort =1      1 position
+>>11   leshort !1      %d positions
+>9     byte    =1      Digital Symphony pattern data (RISC OS),
+>>8    byte    x       version %d,
+>>10   leshort =1      1 pattern
+>>10   leshort !1      %d patterns
+
+# From: Joerg Jenderek
+# URL: https://www.kyzer.me.uk/pack/xad/#PackDir
+# reference: https://www.kyzer.me.uk/pack/xad/xad_PackDir.lha/PackDir.c
+# GRR: line below is too general as it matches also "Git pack" in ./revision
+0      string  PACK\0
+# check for valid compression method 0-4
+>5     ulelong <5
+# https://www.riscosopen.org/wiki/documentation/show/Introduction%20To%20Filing%20Systems
+# To skip "Git pack" version 0 test for root directory object like
+# ADFS::RPC.$.websitezip.FONTFIX
+>>9    string  >ADFS\  PackDir archive (RISC OS)
+# TrID labels above as "Acorn PackDir compressed Archive"
+# compression mode y (0 - 4) for GIF LZW with a maximum n bits
+# (y~n,0~12,1~13,2~14,3~15,4~16)
+>>>5   ulelong+12 x    \b, LZW %u-bits compression
+# https://www.filebase.org.uk/filetypes
+# !Packdir compressed archive has three hexadecimal digits code 68E
+!:mime application/x-acorn-68E
+!:ext  pkd/bin
+# null terminated root directory object like IDEFS::IDE-4.$.Apps.GRAPHICS.!XFMPdemo
+>>>9   string  x       \b, root "%s"
+# load address 0xFFFtttdd, ttt is the object filetype and dddddddddd is time
+>>>>&1 ulelong x       \b, load address 0x%x
+# execution address 0xdddddddd dddddddddd is 40 bit unsigned centiseconds since 1.1.1900 UTC
+>>>>&5 ulelong x       \b, exec address 0x%x
+# attributes (bits: 0~owner read,1~owner write,3~no delete,4~public read,5~public write)
+>>>>&9 ulelong x       \b, attributes 0x%x 
+# number of entries in this directory. for root dir 0
+#>>>&13        ulelong x       \b, entries 0x%x 
+# the entries start here with object name
+>>>>&17        string  x       \b, 1st object "%s"
+
diff --git a/magic/Magdir/adi b/magic/Magdir/adi
new file mode 100644 (file)
index 0000000..f35a447
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# adi: file(1) magic for ADi's objects
+# From Gregory McGarry <g.mcgarry@ieee.org>
+#
+0      leshort         0x521c          COFF DSP21k
+>18    lelong          &02             executable,
+>18    lelong          ^02
+>>18   lelong          &01             static object,
+>>18   lelong          ^01             relocatable object,
+>18    lelong          &010            stripped
+>18    lelong          ^010            not stripped
diff --git a/magic/Magdir/adventure b/magic/Magdir/adventure
new file mode 100644 (file)
index 0000000..bd7f863
--- /dev/null
@@ -0,0 +1,122 @@
+
+#------------------------------------------------------------------------------
+# $File: adventure,v 1.18 2019/04/19 00:42:27 christos Exp $
+# adventure: file(1) magic for Adventure game files
+#
+# from Allen Garvin <earendil@faeryland.tamu-commerce.edu>
+# Edited by Dave Chapeskie <dchapes@ddm.on.ca> Jun 28, 1998
+# Edited by Chris Chittleborough <cchittleborough@yahoo.com.au>, March 2002
+#
+# ALAN
+# I assume there are other, lower versions, but these are the only ones I
+# saw in the archive.
+0      beshort 0x0206  ALAN game data
+>2     byte    <10     version 2.6%d
+
+
+# Infocom (see z-machine)
+#------------------------------------------------------------------------------
+# Z-machine:  file(1) magic for Z-machine binaries.
+# Sanity checks by David Griffith <dave@661.org>
+# Updated by Adam Buchbinder <adam.buchbinder@gmail.com>
+#
+#http://www.gnelson.demon.co.uk/zspec/sect11.html
+#https://www.jczorkmid.net/~jpenney/ZSpec11-latest.txt
+#https://en.wikipedia.org/wiki/Z-machine
+# The first byte is the Z-machine revision; it is always between 1 and 8. We
+# had false matches (for instance, inbig5.ocp from the Omega TeX extension as
+# well as an occasional MP3 file), so we sanity-check the version number.
+#
+# It might be possible to sanity-check the release number as well, as it seems
+# (at least in classic Infocom games) to always be a relatively small number,
+# always under 150 or so, but as this isn't rigorous, we'll wait on that until
+# it becomes clear that it's needed.
+#
+0      ubyte                   >0
+>0     ubyte                   <9
+>>16   belong&0xfe00f0f0       0x3030
+>>>0   ubyte                   < 10
+>>>>2  ubeshort                x
+>>>>>18        regex                   [0-9][0-9][0-9][0-9][0-9][0-9]
+>>>>>>0        ubyte                   < 10    Infocom (Z-machine %d
+>>>>>>>2       ubeshort        x       \b, Release %d
+>>>>>>>>18     string          >\0     \b, Serial %.6s
+>>>>>>>>18     string          x       \b)
+!:strength + 40
+!:mime application/x-zmachine
+
+#------------------------------------------------------------------------------
+# Glulx:  file(1) magic for Glulx binaries.
+#
+# David Griffith <dave@661.org>
+# I haven't checked for false matches yet.
+#
+0      string                  Glul    Glulx game data
+>4     beshort                 x       (Version %d
+>>6    byte                    x       \b.%d
+>>8    byte                    x       \b.%d)
+>36    string                  Info    Compiled by Inform
+!:mime application/x-glulx
+
+
+# For Quetzal and blorb magic see iff
+
+
+# TADS (Text Adventure Development System) version 2
+#  All files are machine-independent (games compile to byte-code) and are tagged
+#  with a version string of the form "V2.<digit>.<digit>\0".
+#  Game files start with "TADS2 bin\n\r\032\0" then the compiler version.
+0      string  TADS2\ bin      TADS
+>9     belong  !0x0A0D1A00     game data, CORRUPTED
+>9     belong   0x0A0D1A00
+>>13   string  >\0             %s game data
+!:mime application/x-tads
+#  Resource files start with "TADS2 rsc\n\r\032\0" then the compiler version.
+0      string  TADS2\ rsc      TADS
+>9     belong  !0x0A0D1A00     resource data, CORRUPTED
+>9     belong   0x0A0D1A00
+>>13   string  >\0             %s resource data
+!:mime application/x-tads
+#  Some saved game files start with "TADS2 save/g\n\r\032\0", a little-endian
+#  2-byte length N, the N-char name of the game file *without* a NUL (darn!),
+# "TADS2 save\n\r\032\0" and the interpreter version.
+0      string  TADS2\ save/g   TADS
+>12    belong  !0x0A0D1A00     saved game data, CORRUPTED
+>12    belong   0x0A0D1A00
+>>(16.s+32) string >\0         %s saved game data
+!:mime application/x-tads
+#  Other saved game files start with "TADS2 save\n\r\032\0" and the interpreter
+#  version.
+0      string  TADS2\ save     TADS
+>10    belong  !0x0A0D1A00     saved game data, CORRUPTED
+>10    belong   0x0A0D1A00
+>>14   string  >\0             %s saved game data
+!:mime application/x-tads
+
+# TADS (Text Adventure Development System) version 3
+#  Game files start with "T3-image\015\012\032"
+0      string  T3-image\015\012\032
+>11    leshort x               TADS 3 game data (format version %d)
+#  Saved game files start with "T3-state-v####\015\012\032"
+#  where #### is a format version number
+0      string  T3-state-v
+>14    string  \015\012\032    TADS 3 saved game data (format version
+>>10   byte    x               %c
+>>11   byte    x               \b%c
+>>12   byte    x               \b%c
+>>13   byte    x               \b%c)
+!:mime application/x-t3vm-image
+
+# edited by David Griffith <dave@661.org>
+# Danny Milosavljevic <danny.milo@gmx.net>
+# These are ADRIFT (adventure game standard) game files, extension .taf
+# Checked from source at (http://www.adrift.co/) and various taf files
+# found at the Interactive Fiction Archive (https://ifarchive.org/)
+0      belong  0x3C423FC9
+>4     belong  0x6A87C2CF      Adrift game file version
+>>8    belong  0x94453661      3.80
+>>8    belong  0x94453761      3.90
+>>8    belong  0x93453E61      4.0
+>>8    belong  0x92453E61      5.0
+>>8    default x               unknown
+!:mime application/x-adrift
diff --git a/magic/Magdir/algol68 b/magic/Magdir/algol68
new file mode 100644 (file)
index 0000000..3675b84
--- /dev/null
@@ -0,0 +1,19 @@
+
+#------------------------------------------------------------------------------
+# $File: algol68,v 1.3 2018/10/19 01:04:21 christos Exp $
+# algol68:  file(1) magic for Algol 68 source
+#
+0      search/8192     (input,                 Algol 68 source text
+!:mime text/x-Algol68
+0      regex/1024      \^PROC                  Algol 68 source text
+!:mime text/x-Algol68
+0      regex/1024      \bMODE[\t\ ]            Algol 68 source text
+!:mime text/x-Algol68
+0      regex/1024      \bREF[\t\ ]             Algol 68 source text
+!:mime text/x-Algol68
+0      regex/1024      \bFLEX[\t\ ]\*\\[       Algol 68 source text
+!:mime text/x-Algol68
+#0     regex           [\t\ ]OD                Algol 68 source text
+#!:mime        text/x-Algol68
+#0     regex           [\t\ ]FI                Algol 68 source text
+#!:mime        text/x-Algol68
diff --git a/magic/Magdir/allegro b/magic/Magdir/allegro
new file mode 100644 (file)
index 0000000..e829510
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# allegro:  file(1) magic for Allegro datafiles
+# Toby Deshane <hac@shoelace.digivill.net>
+#
+0 belong 0x736C6821   Allegro datafile (packed)
+0 belong 0x736C682E   Allegro datafile (not packed/autodetect)
+0 belong 0x736C682B   Allegro datafile (appended exe data)
diff --git a/magic/Magdir/alliant b/magic/Magdir/alliant
new file mode 100644 (file)
index 0000000..dc0f7d5
--- /dev/null
@@ -0,0 +1,18 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# alliant:  file(1) magic for Alliant FX series a.out files
+#
+# If the FX series is the one that had a processor with a 68K-derived
+# instruction set, the "short" should probably become "beshort" and the
+# "long" should probably become "belong".
+# If it's the i860-based one, they should probably become either the
+# big-endian or little-endian versions, depending on the mode they ran
+# the 860 in....
+#
+0      short           0420            0420 Alliant virtual executable
+>2     short           &0x0020         common library
+>16    long            >0              not stripped
+0      short           0421            0421 Alliant compact executable
+>2     short           &0x0020         common library
+>16    long            >0              not stripped
diff --git a/magic/Magdir/alpha b/magic/Magdir/alpha
new file mode 100644 (file)
index 0000000..ea0b04b
--- /dev/null
@@ -0,0 +1,32 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# alpha architecture description
+#
+
+0      leshort         0603            COFF format alpha
+>22    leshort&030000  !020000         executable
+>24    leshort         0410            pure
+>24    leshort         0413            paged
+>22    leshort&020000  !0              dynamically linked
+>16    lelong          !0              not stripped
+>16    lelong          0               stripped
+>22    leshort&030000  020000          shared library
+>24    leshort         0407            object
+>27    byte            x               - version %d
+>26    byte            x               \b.%d
+>28    byte            x               \b-%d
+
+# Basic recognition of Digital UNIX core dumps - Mike Bremford <mike@opac.bl.uk>
+#
+# The actual magic number is just "Core", followed by a 2-byte version
+# number; however, treating any file that begins with "Core" as a Digital
+# UNIX core dump file may produce too many false hits, so we include one
+# byte of the version number as well; DU 5.0 appears only to be up to
+# version 2.
+#
+0      string          Core\001        Alpha COFF format core dump (Digital UNIX)
+>24    string          >\0             \b, from '%s'
+0      string          Core\002        Alpha COFF format core dump (Digital UNIX)
+>24    string          >\0             \b, from '%s'
+
diff --git a/magic/Magdir/amanda b/magic/Magdir/amanda
new file mode 100644 (file)
index 0000000..e7fa539
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: amanda,v 1.6 2017/03/17 21:35:28 christos Exp $
+# amanda:  file(1) magic for amanda file format
+#
+0      string  AMANDA:\                AMANDA
+>8     string  TAPESTART\ DATE         tape header file,
+>>23   string  X
+>>>25  string  >\                      Unused %s
+>>23   string  >\                      DATE %s
+>8     string  FILE\                   dump file,
+>>13   string  >\                      DATE %s
diff --git a/magic/Magdir/amigaos b/magic/Magdir/amigaos
new file mode 100644 (file)
index 0000000..e719921
--- /dev/null
@@ -0,0 +1,87 @@
+
+#------------------------------------------------------------------------------
+# $File: amigaos,v 1.17 2018/10/16 18:57:19 christos Exp $
+# amigaos:  file(1) magic for AmigaOS binary formats:
+
+#
+# From ignatios@cs.uni-bonn.de (Ignatios Souvatzis)
+#
+0      belong          0x000003fa      AmigaOS shared library
+0      belong          0x000003f3      AmigaOS loadseg()ble executable/binary
+0      belong          0x000003e7      AmigaOS object/library data
+#
+0      beshort         0xe310          Amiga Workbench
+>2     beshort         1
+>>48   byte            1               disk icon
+>>48   byte            2               drawer icon
+>>48   byte            3               tool icon
+>>48   byte            4               project icon
+>>48   byte            5               garbage icon
+>>48   byte            6               device icon
+>>48   byte            7               kickstart icon
+>>48   byte            8               workbench application icon
+>2     beshort         >1              icon, vers. %d
+#
+# various sound formats from the Amiga
+# G=F6tz Waschk <waschk@informatik.uni-rostock.de>
+#
+0      string          FC14            Future Composer 1.4 Module sound file
+0      string          SMOD            Future Composer 1.3 Module sound file
+0      string          AON4artofnoise  Art Of Noise Module sound file
+1      string          MUGICIAN/SOFTEYES Mugician Module sound file
+58     string          SIDMON\ II\ -\ THE      Sidmon 2.0 Module sound file
+0      string          Synth4.0        Synthesis Module sound file
+0      string          ARP.            The Holy Noise Module sound file
+0      string          BeEp\0          JamCracker Module sound file
+0      string          COSO\0          Hippel-COSO Module sound file
+# Too simple (short, pure ASCII, deep), MPi
+#26    string          V.3             Brian Postma's Soundmon Module sound file v3
+#26    string          BPSM            Brian Postma's Soundmon Module sound file v3
+#26    string          V.2             Brian Postma's Soundmon Module sound file v2
+
+# The following are from: "Stefan A. Haubenthal" <polluks@web.de>
+0      beshort         0x0f00          AmigaOS bitmap font
+0      beshort         0x0f03          AmigaOS outline font
+0      belong          0x80001001      AmigaOS outline tag
+0      string          ##\ version     catalog translation
+0      string          EMOD\0          Amiga E module
+8      string          ECXM\0          ECX module
+0      string/c        @database       AmigaGuide file
+
+# Amiga disk types
+#
+0      string          RDSK            Rigid Disk Block
+>160   string          x               on %.24s
+0      string          DOS\0           Amiga DOS disk
+0      string          DOS\1           Amiga FFS disk
+0      string          DOS\2           Amiga Inter DOS disk
+0      string          DOS\3           Amiga Inter FFS disk
+0      string          DOS\4           Amiga Fastdir DOS disk
+0      string          DOS\5           Amiga Fastdir FFS disk
+0      string          KICK            Kickstart disk
+
+# From: Alex Beregszaszi <alex@fsn.hu>
+0      string          LZX             LZX compressed archive (Amiga)
+
+# From: Przemek Kramarczyk <pkramarczyk@gmail.com>
+0      string          .KEY            AmigaDOS script
+0      string          .key            AmigaDOS script
+
+# AMOS Basic file formats
+# https://www.exotica.org.uk/wiki/AMOS_file_formats
+0      string          AMOS\040Basic\040       AMOS Basic source code
+>11    byte            =0x56                   \b, tested
+>11    byte            =0x76                   \b, untested
+0      string          AMOS\040Pro             AMOS Basic source code
+>11    byte            =0x56                   \b, tested
+>11    byte            =0x76                   \b, untested
+0      string          AmSp                    AMOS Basic sprite bank
+>4     beshort         x                       \b, %d sprites
+0      string          AmIc                    AMOS Basic icon bank
+>4     beshort         x                       \b, %d icons
+0      string          AmBk                    AMOS Basic memory bank
+>4     beshort         x                       \b, bank number %d
+>8     belong&0xFFFFFFF        x               \b, length %d
+>12    regex           .{8}                    \b, type %s
+0      string          AmBs                    AMOS Basic memory banks
+>4     beshort         x                       \b, %d banks
diff --git a/magic/Magdir/android b/magic/Magdir/android
new file mode 100644 (file)
index 0000000..a9cfb35
--- /dev/null
@@ -0,0 +1,180 @@
+
+#------------------------------------------------------------
+# $File: android,v 1.12 2019/04/19 00:42:27 christos Exp $
+# Various android related magic entries
+#------------------------------------------------------------
+
+# Dalvik .dex format. http://retrodev.com/android/dexformat.html
+# From <mkf@google.com> "Mike Fleming"
+# Fixed to avoid regexec 17 errors on some dex files
+# From <diff@lookout.com> "Tim Strazzere"
+0      string  dex\n
+>0     regex   dex\n[0-9]{2}\0 Dalvik dex file
+>4     string  >000                    version %s
+0      string  dey\n
+>0     regex   dey\n[0-9]{2}\0 Dalvik dex file (optimized for host)
+>4     string  >000                    version %s
+
+# Android bootimg format
+# From https://android.googlesource.com/\
+# platform/system/core/+/master/mkbootimg/bootimg.h
+0              string  ANDROID!        Android bootimg
+>1024  string  LOKI\01         \b, LOKI'd
+>8             lelong  >0                      \b, kernel
+>>12   lelong  >0                      \b (0x%x)
+>16            lelong  >0                      \b, ramdisk
+>>20   lelong  >0                      \b (0x%x)
+>24            lelong  >0                      \b, second stage
+>>28   lelong  >0                      \b (0x%x)
+>36            lelong  >0                      \b, page size: %d
+>38            string  >0                      \b, name: %s
+>64            string  >0                      \b, cmdline (%s)
+
+# Android Backup archive
+# From: Ariel Shkedi
+# Update: Joerg Jenderek 
+# URL: https://github.com/android/platform_frameworks_base/blob/\
+# 0bacfd2ba68d21a68a3df345b830bc2a1e515b5a/services/java/com/\
+# android/server/BackupManagerService.java#L2367
+# Reference: https://sourceforge.net/projects/adbextractor/
+#            android-backup-extractor/perl/backupencrypt.pl 
+# Note:        only unix line feeds "\n" found
+# After the header comes a tar file
+# If compressed, the entire tar file is compressed with JAVA deflate
+#
+# Include the version number hardcoded with the magic string to avoid
+# false positives
+0      string/b        ANDROID\ BACKUP\n       Android Backup
+# maybe look for some more characteristics like linefeed '\n' or version
+#>16   string          \n                      
+# No mime-type defined offically
+!:mime application/x-google-ab
+!:ext  ab
+# on 2nd line version (often 1, 2 on kitkat 4.4.3+, 4 on 7.1.2)
+>15    string          >\0                     \b, version %s
+# "1" on 3rd line means compressed
+>17    string          0\n                     \b, Not-Compressed
+>17    string          1\n                     \b, Compressed
+# The 4th line is encryption "none" or "AES-256"
+# any string as long as it's not the word none (which is matched below)
+>19    string          none\n                  \b, Not-Encrypted
+# look for backup content after line with encryption info
+#>>19  search/7        \n
+# data part after header for not encrypted Android Backup 
+#>>>&0 ubequad         x       \b, content 0x%16.16llx...
+# look for zlib compressed by ./compress after message with 1 space at end
+#>>>&0 indirect        x       \b; contains 
+# look for tar archive block by ./archive for package name manifest
+>>288  string          ustar   \b; contains
+>>>31  use     tar-file
+# look for zip/jar archive by ./archive ./zip after message with 1 space at end
+#>>2079        search/1025/s   PK\003\004      \b; contains 
+#>>>&0 indirect        x
+>19    string          !none                   
+>>19    regex/1l       \^([^n\n]|n[^o]|no[^n]|non[^e]|none.+).*        \b, Encrypted (%s)
+# Commented out because they don't seem useful to print
+# (but they are part of the header - the tar file comes after them):
+# The 5th line is User Password Salt (128 Hex)
+# string length too high with standard src configuration
+#>>>&1         string  >\0     \b, PASSWORD salt: "%-128.128s"
+#>>>&1         regex/1l .*     \b, Password salt: %s
+# The 6th line is Master Key Checksum Salt (128 Hex)
+#>>>>&1                regex/1l .*     \b, Master salt: %s
+# The 7th line is Number of PBDKF2 Rounds (10000)
+#>>>>>&1       regex/1l .*     \b, PBKDF2 rounds: %s
+# The 8th line is User key Initialization Vector (IV) (32 Hex)
+#>>>>>>&1      regex/1l .*     \b, IV: %s
+#>>>>>>&1      regex/1l .*     \b, IV: %s
+# The 9th line is Master IV+Key+Checksum (192 Hex)
+#>>>>>>>&1     regex/1l .*     \b, Key: %s
+# look for new line separator char after line number 9
+#>>>0x204      ubyte   0x0a    NL found
+#>>>>&1                ubequad x       \b, Content magic %16.16llx
+
+# *.pit files by Joerg Jenderek
+# https://forum.xda-developers.com/showthread.php?p=9122369
+# https://forum.xda-developers.com/showthread.php?t=816449
+# Partition Information Table for Samsung's smartphone with Android
+# used by flash software Odin
+0              ulelong                 0x12349876
+# 1st pit entry marker
+>0x01C ulequad&0xFFFFFFFCFFFFFFFC      =0x0000000000000000
+# minimal 13 and maximal 18 PIT entries found
+>>4            ulelong                 <128    Partition Information Table for Samsung smartphone
+>>>4           ulelong                 x       \b, %d entries
+# 1. pit entry
+>>>4           ulelong                 >0      \b; #1
+>>>0x01C       use                             PIT-entry
+>>>4           ulelong                 >1      \b; #2
+>>>0x0A0       use                             PIT-entry
+>>>4           ulelong                 >2      \b; #3
+>>>0x124       use                             PIT-entry
+>>>4           ulelong                 >3      \b; #4
+>>>0x1A8       use                             PIT-entry
+>>>4           ulelong                 >4      \b; #5
+>>>0x22C       use                             PIT-entry
+>>>4           ulelong                 >5      \b; #6
+>>>0x2B0       use                             PIT-entry
+>>>4           ulelong                 >6      \b; #7
+>>>0x334       use                             PIT-entry
+>>>4           ulelong                 >7      \b; #8
+>>>0x3B8       use                             PIT-entry
+>>>4           ulelong                 >8      \b; #9
+>>>0x43C       use                             PIT-entry
+>>>4           ulelong                 >9      \b; #10
+>>>0x4C0       use                             PIT-entry
+>>>4           ulelong                 >10     \b; #11
+>>>0x544       use                             PIT-entry
+>>>4           ulelong                 >11     \b; #12
+>>>0x5C8       use                             PIT-entry
+>>>4           ulelong                 >12     \b; #13
+>>>>0x64C      use                             PIT-entry
+# 14. pit entry
+>>>4           ulelong                 >13     \b; #14
+>>>>0x6D0      use                             PIT-entry
+>>>4           ulelong                 >14     \b; #15
+>>>0x754       use                             PIT-entry
+>>>4           ulelong                 >15     \b; #16
+>>>0x7D8       use                             PIT-entry
+>>>4           ulelong                 >16     \b; #17
+>>>0x85C       use                             PIT-entry
+# 18. pit entry
+>>>4           ulelong                 >17     \b; #18
+>>>0x8E0       use                             PIT-entry
+
+0      name                    PIT-entry
+# garbage value implies end of pit entries
+>0x00          ulequad&0xFFFFFFFCFFFFFFFC      =0x0000000000000000
+# skip empty partition name
+>>0x24         ubyte                           !0
+# partition name
+>>>0x24                string                          >\0                     %-.32s
+# flags
+>>>0x0C                ulelong&0x00000002              2                       \b+RW
+# partition ID:
+# 0~IPL,MOVINAND,GANG;1~PIT,GPT;2~HIDDEN;3~SBL,HIDDEN;4~SBL2,HIDDEN;5~BOOT;6~KENREl,RECOVER,misc;7~RECOVER
+# ;11~MODEM;20~efs;21~PARAM;22~FACTORY,SYSTEM;23~DBDATAFS,USERDATA;24~CACHE;80~BOOTLOADER;81~TZSW
+>>>0x08        ulelong         x                       (0x%x)
+# filename
+>>>0x44                string                          >\0                     "%-.64s"
+#>>>0x18       ulelong                         >0
+# blocksize in 512 byte units ?
+#>>>>0x18      ulelong                         x                       \b, %db
+# partition size in blocks ?
+#>>>>0x22      ulelong                         x                       \b*%d
+
+# Android sparse img format
+# From https://android.googlesource.com/\
+# platform/system/core/+/master/libsparse/sparse_format.h
+0              lelong  0xed26ff3a              Android sparse image
+>4             leshort x                       \b, version: %d
+>6             leshort x                       \b.%d
+>16            lelong  x                       \b, Total of %d
+>12            lelong  x                       \b %d-byte output blocks in
+>20            lelong  x                       \b %d input chunks.
+
+# Android binary XML magic
+# In include/androidfw/ResourceTypes.h:
+# RES_XML_TYPE = 0x0003 followed by the size of the header (ResXMLTree_header),
+# which is 8 bytes (2 bytes type + 2 bytes header size + 4 bytes size).
+0      lelong  0x00080003      Android binary XML
diff --git a/magic/Magdir/animation b/magic/Magdir/animation
new file mode 100644 (file)
index 0000000..aaf32dd
--- /dev/null
@@ -0,0 +1,1074 @@
+
+#------------------------------------------------------------------------------
+# $File: animation,v 1.71 2019/04/19 00:42:27 christos Exp $
+# animation:  file(1) magic for animation/movie formats
+#
+# animation formats
+# MPEG, FLI, DL originally from vax@ccwf.cc.utexas.edu (VaX#n8)
+# FLC, SGI, Apple originally from Daniel Quinlan (quinlan@yggdrasil.com)
+
+# SGI and Apple formats
+0      string          MOVI            Silicon Graphics movie file
+!:mime video/x-sgi-movie
+4       string          moov            Apple QuickTime
+!:mime video/quicktime
+>12     string          mvhd            \b movie (fast start)
+>12     string          mdra            \b URL
+>12     string          cmov            \b movie (fast start, compressed header)
+>12     string          rmra            \b multiple URLs
+4       string          mdat            Apple QuickTime movie (unoptimized)
+!:mime video/quicktime
+#4       string          wide            Apple QuickTime movie (unoptimized)
+#!:mime        video/quicktime
+#4       string          skip            Apple QuickTime movie (modified)
+#!:mime        video/quicktime
+#4       string          free            Apple QuickTime movie (modified)
+#!:mime        video/quicktime
+4       string          idsc            Apple QuickTime image (fast start)
+!:mime image/x-quicktime
+#4       string          idat            Apple QuickTime image (unoptimized)
+#!:mime        image/x-quicktime
+4       string          pckg            Apple QuickTime compressed archive
+!:mime application/x-quicktime-player
+4      string/W        jP              JPEG 2000 image
+!:mime image/jp2
+# https://www.ftyps.com/ with local additions
+4      string          ftyp            ISO Media
+# https://aeroquartet.com/wordpress/2016/03/05/3-xavc-s/
+>8     string          XAVC            \b, MPEG v4 system, Sony XAVC Codec
+>>96   string          x               \b, Audio "%.4s"
+>>118  beshort         x               at %dHz
+>>140  string          x               \b, Video "%.4s"
+>>168  beshort         x               %d
+>>170  beshort         x               \bx%d
+>8     string          3g2             \b, MPEG v4 system, 3GPP2
+!:mime video/3gpp2
+>>11   byte            4               \b v4 (H.263/AMR GSM 6.10)
+>>11   byte            5               \b v5 (H.263/AMR GSM 6.10)
+>>11   byte            6               \b v6 (ITU H.264/AMR GSM 6.10)
+# https://www.3gpp2.org/Public_html/Specs/C.S0050-B_v1.0_070521.pdf
+# Section 8.1.1, corresponds to a, b, c
+>>11   byte            0x61            \b C.S0050-0 V1.0
+>>11   byte            0x62            \b C.S0050-0-A V1.0.0
+>>11   byte            0x63            \b C.S0050-0-B V1.0
+>8     string          3ge             \b, MPEG v4 system, 3GPP
+!:mime video/3gpp
+>>11   byte            6               \b, Release 6 MBMS Extended Presentations
+>>11   byte            7               \b, Release 7 MBMS Extended Presentations
+>8     string          3gg             \b, MPEG v4 system, 3GPP
+!:mime video/3gpp
+>>11   byte            6               \b, Release 6 General Profile
+>8     string          3gp             \b, MPEG v4 system, 3GPP
+!:mime video/3gpp
+>>11   byte            1               \b, Release %d (non existent)
+>>11   byte            2               \b, Release %d (non existent)
+>>11   byte            3               \b, Release %d (non existent)
+>>11   byte            4               \b, Release %d
+>>11   byte            5               \b, Release %d
+>>11   byte            6               \b, Release %d
+>>11   byte            7               \b, Release %d Streaming Servers
+>8     string          3gs             \b, MPEG v4 system, 3GPP
+!:mime video/3gpp
+>>11   byte            7               \b, Release %d Streaming Servers
+>8     string          avc1            \b, MPEG v4 system, 3GPP JVT AVC [ISO 14496-12:2005]
+!:mime video/mp4
+>8     string/W        qt              \b, Apple QuickTime movie
+!:mime video/quicktime
+>8     string          CAEP            \b, Canon Digital Camera
+>8     string          caqv            \b, Casio Digital Camera
+>8     string          CDes            \b, Convergent Design
+>8     string          da0a            \b, DMB MAF w/ MPEG Layer II aud, MOT slides, DLS, JPG/PNG/MNG
+>8     string          da0b            \b, DMB MAF, ext DA0A, with 3GPP timed text, DID, TVA, REL, IPMP
+>8     string          da1a            \b, DMB MAF audio with ER-BSAC audio, JPG/PNG/MNG images
+>8     string          da1b            \b, DMB MAF, ext da1a, with 3GPP timed text, DID, TVA, REL, IPMP
+>8     string          da2a            \b, DMB MAF aud w/ HE-AAC v2 aud, MOT slides, DLS, JPG/PNG/MNG
+>8     string          da2b            \b, DMB MAF, ext da2a, with 3GPP timed text, DID, TVA, REL, IPMP
+>8     string          da3a            \b, DMB MAF aud with HE-AAC aud, JPG/PNG/MNG images
+>8     string          da3b            \b, DMB MAF, ext da3a w/ BIFS, 3GPP, DID, TVA, REL, IPMP
+>8     string          dash            \b, MPEG v4 system, Dynamic Adaptive Streaming over HTTP
+!:mime video/mp4
+>8     string          dmb1            \b, DMB MAF supporting all the components defined in the spec
+>8     string          dmpf            \b, Digital Media Project
+>8     string          drc1            \b, Dirac (wavelet compression), encap in ISO base media (MP4)
+>8     string          dv1a            \b, DMB MAF vid w/ AVC vid, ER-BSAC aud, BIFS, JPG/PNG/MNG, TS
+>8     string          dv1b            \b, DMB MAF, ext dv1a, with 3GPP timed text, DID, TVA, REL, IPMP
+>8     string          dv2a            \b, DMB MAF vid w/ AVC vid, HE-AAC v2 aud, BIFS, JPG/PNG/MNG, TS
+>8     string          dv2b            \b, DMB MAF, ext dv2a, with 3GPP timed text, DID, TVA, REL, IPMP
+>8     string          dv3a            \b, DMB MAF vid w/ AVC vid, HE-AAC aud, BIFS, JPG/PNG/MNG, TS
+>8     string          dv3b            \b, DMB MAF, ext dv3a, with 3GPP timed text, DID, TVA, REL, IPMP
+>8     string          dvr1            \b, DVB (.DVB) over RTP
+!:mime video/vnd.dvb.file
+>8     string          dvt1            \b, DVB (.DVB) over MPEG-2 Transport Stream
+!:mime video/vnd.dvb.file
+>8     string          F4V             \b, Video for Adobe Flash Player 9+ (.F4V)
+!:mime video/mp4
+>8     string          F4P             \b, Protected Video for Adobe Flash Player 9+ (.F4P)
+!:mime video/mp4
+>8     string          F4A             \b, Audio for Adobe Flash Player 9+ (.F4A)
+!:mime audio/mp4
+>8     string          F4B             \b, Audio Book for Adobe Flash Player 9+ (.F4B)
+!:mime audio/mp4
+>8     string          isc2            \b, ISMACryp 2.0 Encrypted File
+#      ?/enc-isoff-generic
+>8     string          iso2            \b, MP4 Base Media v2 [ISO 14496-12:2005]
+!:mime video/mp4
+>8     string          isom            \b, MP4 Base Media v1 [IS0 14496-12:2003]
+!:mime video/mp4
+>8     string/W        jp2             \b, JPEG 2000
+!:mime image/jp2
+>8     string          JP2             \b, JPEG 2000 Image (.JP2) [ISO 15444-1 ?]
+!:mime image/jp2
+>8     string          JP20            \b, Unknown, from GPAC samples (prob non-existent)
+>8     string          jpm             \b, JPEG 2000 Compound Image (.JPM) [ISO 15444-6]
+!:mime image/jpm
+>8     string          jpx             \b, JPEG 2000 w/ extensions (.JPX) [ISO 15444-2]
+!:mime image/jpx
+>8     string          KDDI            \b, 3GPP2 EZmovie for KDDI 3G cellphones
+!:mime video/3gpp2
+>8     string          M4A             \b, Apple iTunes ALAC/AAC-LC (.M4A) Audio
+!:mime audio/x-m4a
+>8     string          M4B             \b, Apple iTunes ALAC/AAC-LC (.M4B) Audio Book
+!:mime audio/mp4
+>8     string          M4P             \b, Apple iTunes ALAC/AAC-LC (.M4P) AES Protected Audio
+!:mime video/mp4
+>8     string          M4V             \b, Apple iTunes Video (.M4V) Video
+!:mime video/x-m4v
+>8     string          M4VH            \b, Apple TV (.M4V)
+!:mime video/x-m4v
+>8     string          M4VP            \b, Apple iPhone (.M4V)
+!:mime video/x-m4v
+>8     string          mj2s            \b, Motion JPEG 2000 [ISO 15444-3] Simple Profile
+!:mime video/mj2
+>8     string          mjp2            \b, Motion JPEG 2000 [ISO 15444-3] General Profile
+!:mime video/mj2
+>8     string          mmp4            \b, MPEG-4/3GPP Mobile Profile (.MP4 / .3GP) (for NTT)
+!:mime video/mp4
+>8     string          mobi            \b, MPEG-4, MOBI format
+!:mime video/mp4
+>8     string          mp21            \b, MPEG-21 [ISO/IEC 21000-9]
+>8     string          mp41            \b, MP4 v1 [ISO 14496-1:ch13]
+!:mime video/mp4
+>8     string          mp42            \b, MP4 v2 [ISO 14496-14]
+!:mime video/mp4
+>8     string          mp71            \b, MP4 w/ MPEG-7 Metadata [per ISO 14496-12]
+>8     string          mp7t            \b, MPEG v4 system, MPEG v7 XML
+>8     string          mp7b            \b, MPEG v4 system, MPEG v7 binary XML
+>8     string          mmp4            \b, MPEG v4 system, 3GPP Mobile
+!:mime video/mp4
+>8     string          MPPI            \b, Photo Player, MAF [ISO/IEC 23000-3]
+>8     string          mqt             \b, Sony / Mobile QuickTime (.MQV) US Pat 7,477,830
+!:mime video/quicktime
+>8     string          MSNV            \b, MPEG-4 (.MP4) for SonyPSP
+!:mime audio/mp4
+>8     string          NDAS            \b, MP4 v2 [ISO 14496-14] Nero Digital AAC Audio
+!:mime audio/mp4
+>8     string          NDSC            \b, MPEG-4 (.MP4) Nero Cinema Profile
+!:mime video/mp4
+>8     string          NDSH            \b, MPEG-4 (.MP4) Nero HDTV Profile
+!:mime video/mp4
+>8     string          NDSM            \b, MPEG-4 (.MP4) Nero Mobile Profile
+!:mime video/mp4
+>8     string          NDSP            \b, MPEG-4 (.MP4) Nero Portable Profile
+!:mime video/mp4
+>8     string          NDSS            \b, MPEG-4 (.MP4) Nero Standard Profile
+!:mime video/mp4
+>8     string          NDXC            \b, H.264/MPEG-4 AVC (.MP4) Nero Cinema Profile
+!:mime video/mp4
+>8     string          NDXH            \b, H.264/MPEG-4 AVC (.MP4) Nero HDTV Profile
+!:mime video/mp4
+>8     string          NDXM            \b, H.264/MPEG-4 AVC (.MP4) Nero Mobile Profile
+!:mime video/mp4
+>8     string          NDXP            \b, H.264/MPEG-4 AVC (.MP4) Nero Portable Profile
+!:mime video/mp4
+>8     string          NDXS            \b, H.264/MPEG-4 AVC (.MP4) Nero Standard Profile
+!:mime video/mp4
+>8     string          odcf            \b, OMA DCF DRM Format 2.0 (OMA-TS-DRM-DCF-V2_0-20060303-A)
+>8     string          opf2            \b, OMA PDCF DRM Format 2.1 (OMA-TS-DRM-DCF-V2_1-20070724-C)
+>8     string          opx2            \b, OMA PDCF DRM + XBS ext (OMA-TS-DRM_XBS-V1_0-20070529-C)
+>8     string          pana            \b, Panasonic Digital Camera
+>8     string          qt              \b, Apple QuickTime (.MOV/QT)
+!:mime video/quicktime
+# HEIF image format
+# see https://nokiatech.github.io/heif/technical.html
+>8     string          mif1            \b, HEIF Image
+!:mime image/heif
+>8     string          msf1            \b, HEIF Image Sequence
+!:mime image/heif-sequence
+>8     string          heic            \b, HEIF Image HEVC Main or Main Still Picture Profile
+!:mime image/heic
+>8     string          heix            \b, HEIF Image HEVC Main 10 Profile
+!:mime image/heic
+>8     string          hevc            \b, HEIF Image Sequenz HEVC Main or Main Still Picture Profile
+!:mime image/heic-sequence
+>8     string          hevx            \b, HEIF Image Sequence HEVC Main 10 Profile
+!:mime image/heic-sequence
+# following HEIF brands are not mentioned in the heif technical info currently (Oct 2017)
+# but used in the reference implementation:
+# https://github.com/nokiatech/heif/blob/d5e9a21c8ba8df712bdf643021dd9f6518134776/Srcs/reader/hevcimagefilereader.cpp
+>8     string          heim            \b, HEIF Image L-HEVC
+!:mime image/heif
+>8     string          heis            \b, HEIF Image L-HEVC
+!:mime image/heif
+>8     string          avic            \b, HEIF Image AVC
+!:mime image/heif
+>8     string          hevm            \b, HEIF Image Sequence L-HEVC
+!:mime image/heif-sequence
+>8     string          hevs            \b, HEIF Image Sequence L-HEVC
+!:mime image/heif-sequence
+>8     string          avcs            \b, HEIF Image Sequence AVC
+!:mime image/heif-sequence
+
+>8     string          ROSS            \b, Ross Video
+>8     string          sdv             \b, SD Memory Card Video
+>8     string          ssc1            \b, Samsung stereo, single stream (patent pending)
+>8     string          ssc2            \b, Samsung stereo, dual stream (patent pending)
+
+# MPEG sequences
+# Scans for all common MPEG header start codes
+0       belong             0x00000001
+>4      byte&0x1F          0x07           JVT NAL sequence, H.264 video
+>>5      byte               66             \b, baseline
+>>5      byte               77             \b, main
+>>5      byte               88             \b, extended
+>>7      byte               x              \b @ L %u
+0        belong&0xFFFFFF00  0x00000100
+>3       byte               0xBA           MPEG sequence
+!:mime  video/mpeg
+>>4      byte               &0x40          \b, v2, program multiplex
+>>4      byte               ^0x40          \b, v1, system multiplex
+>3       byte               0xBB           MPEG sequence, v1/2, multiplex (missing pack header)
+>3       byte&0x1F          0x07           MPEG sequence, H.264 video
+>>4      byte               66             \b, baseline
+>>4      byte               77             \b, main
+>>4      byte               88             \b, extended
+>>6      byte               x              \b @ L %u
+# GRR too general as it catches also FoxPro Memo example NG.FPT
+>3       byte               0xB0           MPEG sequence, v4
+# TODO: maybe this extra line exclude FoxPro Memo example NG.FPT starting with 000001b0 00000100 00000000
+#>>4      byte               !0             MPEG sequence, v4
+!:mime  video/mpeg4-generic
+>>5      belong             0x000001B5
+>>>9     byte               &0x80
+>>>>10   byte&0xF0          16             \b, video
+>>>>10   byte&0xF0          32             \b, still texture
+>>>>10   byte&0xF0          48             \b, mesh
+>>>>10   byte&0xF0          64             \b, face
+>>>9     byte&0xF8          8              \b, video
+>>>9     byte&0xF8          16             \b, still texture
+>>>9     byte&0xF8          24             \b, mesh
+>>>9     byte&0xF8          32             \b, face
+>>4      byte               1              \b, simple @ L1
+>>4      byte               2              \b, simple @ L2
+>>4      byte               3              \b, simple @ L3
+>>4      byte               4              \b, simple @ L0
+>>4      byte               17             \b, simple scalable @ L1
+>>4      byte               18             \b, simple scalable @ L2
+>>4      byte               33             \b, core @ L1
+>>4      byte               34             \b, core @ L2
+>>4      byte               50             \b, main @ L2
+>>4      byte               51             \b, main @ L3
+>>4      byte               53             \b, main @ L4
+>>4      byte               66             \b, n-bit @ L2
+>>4      byte               81             \b, scalable texture @ L1
+>>4      byte               97             \b, simple face animation @ L1
+>>4      byte               98             \b, simple face animation @ L2
+>>4      byte               99             \b, simple face basic animation @ L1
+>>4      byte               100            \b, simple face basic animation @ L2
+>>4      byte               113            \b, basic animation text @ L1
+>>4      byte               114            \b, basic animation text @ L2
+>>4      byte               129            \b, hybrid @ L1
+>>4      byte               130            \b, hybrid @ L2
+>>4      byte               145            \b, advanced RT simple @ L!
+>>4      byte               146            \b, advanced RT simple @ L2
+>>4      byte               147            \b, advanced RT simple @ L3
+>>4      byte               148            \b, advanced RT simple @ L4
+>>4      byte               161            \b, core scalable @ L1
+>>4      byte               162            \b, core scalable @ L2
+>>4      byte               163            \b, core scalable @ L3
+>>4      byte               177            \b, advanced coding efficiency @ L1
+>>4      byte               178            \b, advanced coding efficiency @ L2
+>>4      byte               179            \b, advanced coding efficiency @ L3
+>>4      byte               180            \b, advanced coding efficiency @ L4
+>>4      byte               193            \b, advanced core @ L1
+>>4      byte               194            \b, advanced core @ L2
+>>4      byte               209            \b, advanced scalable texture @ L1
+>>4      byte               210            \b, advanced scalable texture @ L2
+>>4      byte               211            \b, advanced scalable texture @ L3
+>>4      byte               225            \b, simple studio @ L1
+>>4      byte               226            \b, simple studio @ L2
+>>4      byte               227            \b, simple studio @ L3
+>>4      byte               228            \b, simple studio @ L4
+>>4      byte               229            \b, core studio @ L1
+>>4      byte               230            \b, core studio @ L2
+>>4      byte               231            \b, core studio @ L3
+>>4      byte               232            \b, core studio @ L4
+>>4      byte               240            \b, advanced simple @ L0
+>>4      byte               241            \b, advanced simple @ L1
+>>4      byte               242            \b, advanced simple @ L2
+>>4      byte               243            \b, advanced simple @ L3
+>>4      byte               244            \b, advanced simple @ L4
+>>4      byte               245            \b, advanced simple @ L5
+>>4      byte               247            \b, advanced simple @ L3b
+>>4      byte               248            \b, FGS @ L0
+>>4      byte               249            \b, FGS @ L1
+>>4      byte               250            \b, FGS @ L2
+>>4      byte               251            \b, FGS @ L3
+>>4      byte               252            \b, FGS @ L4
+>>4      byte               253            \b, FGS @ L5
+>3       byte               0xB5           MPEG sequence, v4
+!:mime  video/mpeg4-generic
+>>4      byte               &0x80
+>>>5     byte&0xF0          16             \b, video (missing profile header)
+>>>5     byte&0xF0          32             \b, still texture (missing profile header)
+>>>5     byte&0xF0          48             \b, mesh (missing profile header)
+>>>5     byte&0xF0          64             \b, face (missing profile header)
+>>4      byte&0xF8          8              \b, video (missing profile header)
+>>4      byte&0xF8          16             \b, still texture (missing profile header)
+>>4      byte&0xF8          24             \b, mesh (missing profile header)
+>>4      byte&0xF8          32             \b, face (missing profile header)
+>3       byte               0xB3           MPEG sequence
+!:mime  video/mpeg
+>>12     belong             0x000001B8     \b, v1, progressive Y'CbCr 4:2:0 video
+>>12     belong             0x000001B2     \b, v1, progressive Y'CbCr 4:2:0 video
+>>12     belong             0x000001B5     \b, v2,
+>>>16    byte&0x0F          1              \b HP
+>>>16    byte&0x0F          2              \b Spt
+>>>16    byte&0x0F          3              \b SNR
+>>>16    byte&0x0F          4              \b MP
+>>>16    byte&0x0F          5              \b SP
+>>>17    byte&0xF0          64             \b@HL
+>>>17    byte&0xF0          96             \b@H-14
+>>>17    byte&0xF0          128            \b@ML
+>>>17    byte&0xF0          160            \b@LL
+>>>17    byte               &0x08          \b progressive
+>>>17    byte               ^0x08          \b interlaced
+>>>17    byte&0x06          2              \b Y'CbCr 4:2:0 video
+>>>17    byte&0x06          4              \b Y'CbCr 4:2:2 video
+>>>17    byte&0x06          6              \b Y'CbCr 4:4:4 video
+>>11     byte               &0x02
+>>>75    byte               &0x01
+>>>>140  belong             0x000001B8     \b, v1, progressive Y'CbCr 4:2:0 video
+>>>>140  belong             0x000001B2     \b, v1, progressive Y'CbCr 4:2:0 video
+>>>>140  belong             0x000001B5     \b, v2,
+>>>>>144 byte&0x0F          1              \b HP
+>>>>>144 byte&0x0F          2              \b Spt
+>>>>>144 byte&0x0F          3              \b SNR
+>>>>>144 byte&0x0F          4              \b MP
+>>>>>144 byte&0x0F          5              \b SP
+>>>>>145 byte&0xF0          64             \b@HL
+>>>>>145 byte&0xF0          96             \b@H-14
+>>>>>145 byte&0xF0          128            \b@ML
+>>>>>145 byte&0xF0          160            \b@LL
+>>>>>145 byte               &0x08          \b progressive
+>>>>>145 byte               ^0x08          \b interlaced
+>>>>>145 byte&0x06          2              \b Y'CbCr 4:2:0 video
+>>>>>145 byte&0x06          4              \b Y'CbCr 4:2:2 video
+>>>>>145 byte&0x06          6              \b Y'CbCr 4:4:4 video
+>>76    belong             0x000001B8     \b, v1, progressive Y'CbCr 4:2:0 video
+>>76    belong             0x000001B2     \b, v1, progressive Y'CbCr 4:2:0 video
+>>76    belong             0x000001B5     \b, v2,
+>>>80   byte&0x0F          1              \b HP
+>>>80   byte&0x0F          2              \b Spt
+>>>80   byte&0x0F          3              \b SNR
+>>>80   byte&0x0F          4              \b MP
+>>>80   byte&0x0F          5              \b SP
+>>>81   byte&0xF0          64             \b@HL
+>>>81   byte&0xF0          96             \b@H-14
+>>>81   byte&0xF0          128            \b@ML
+>>>81   byte&0xF0          160            \b@LL
+>>>81   byte               &0x08          \b progressive
+>>>81   byte               ^0x08          \b interlaced
+>>>81   byte&0x06          2              \b Y'CbCr 4:2:0 video
+>>>81   byte&0x06          4              \b Y'CbCr 4:2:2 video
+>>>81   byte&0x06          6              \b Y'CbCr 4:4:4 video
+>>4      belong&0xFFFFFF00  0x78043800     \b, HD-TV 1920P
+>>>7     byte&0xF0          0x10           \b, 16:9
+>>4      belong&0xFFFFFF00  0x50002D00     \b, SD-TV 1280I
+>>>7     byte&0xF0          0x10           \b, 16:9
+>>4      belong&0xFFFFFF00  0x30024000     \b, PAL Capture
+>>>7     byte&0xF0          0x10           \b, 4:3
+>>4      beshort&0xFFF0     0x2C00         \b, 4CIF
+>>>5     beshort&0x0FFF     0x01E0         \b NTSC
+>>>5     beshort&0x0FFF     0x0240         \b PAL
+>>>7     byte&0xF0          0x20           \b, 4:3
+>>>7     byte&0xF0          0x30           \b, 16:9
+>>>7     byte&0xF0          0x40           \b, 11:5
+>>>7     byte&0xF0          0x80           \b, PAL 4:3
+>>>7     byte&0xF0          0xC0           \b, NTSC 4:3
+>>4      belong&0xFFFFFF00  0x2801E000     \b, LD-TV 640P
+>>>7     byte&0xF0          0x10           \b, 4:3
+>>4      belong&0xFFFFFF00  0x1400F000     \b, 320x240
+>>>7     byte&0xF0          0x10           \b, 4:3
+>>4      belong&0xFFFFFF00  0x0F00A000     \b, 240x160
+>>>7     byte&0xF0          0x10           \b, 4:3
+>>4      belong&0xFFFFFF00  0x0A007800     \b, 160x120
+>>>7     byte&0xF0          0x10           \b, 4:3
+>>4      beshort&0xFFF0     0x1600         \b, CIF
+>>>5     beshort&0x0FFF     0x00F0         \b NTSC
+>>>5     beshort&0x0FFF     0x0120         \b PAL
+>>>7     byte&0xF0          0x20           \b, 4:3
+>>>7     byte&0xF0          0x30           \b, 16:9
+>>>7     byte&0xF0          0x40           \b, 11:5
+>>>7     byte&0xF0          0x80           \b, PAL 4:3
+>>>7     byte&0xF0          0xC0           \b, NTSC 4:3
+>>>5     beshort&0x0FFF     0x0240         \b PAL 625
+>>>>7    byte&0xF0          0x20           \b, 4:3
+>>>>7    byte&0xF0          0x30           \b, 16:9
+>>>>7    byte&0xF0          0x40           \b, 11:5
+>>4      beshort&0xFFF0     0x2D00         \b, CCIR/ITU
+>>>5     beshort&0x0FFF     0x01E0         \b NTSC 525
+>>>5     beshort&0x0FFF     0x0240         \b PAL 625
+>>>7     byte&0xF0          0x20           \b, 4:3
+>>>7     byte&0xF0          0x30           \b, 16:9
+>>>7     byte&0xF0          0x40           \b, 11:5
+>>4      beshort&0xFFF0     0x1E00         \b, SVCD
+>>>5     beshort&0x0FFF     0x01E0         \b NTSC 525
+>>>5     beshort&0x0FFF     0x0240         \b PAL 625
+>>>7     byte&0xF0          0x20           \b, 4:3
+>>>7     byte&0xF0          0x30           \b, 16:9
+>>>7     byte&0xF0          0x40           \b, 11:5
+>>7      byte&0x0F          1              \b, 23.976 fps
+>>7      byte&0x0F          2              \b, 24 fps
+>>7      byte&0x0F          3              \b, 25 fps
+>>7      byte&0x0F          4              \b, 29.97 fps
+>>7      byte&0x0F          5              \b, 30 fps
+>>7      byte&0x0F          6              \b, 50 fps
+>>7      byte&0x0F          7              \b, 59.94 fps
+>>7      byte&0x0F          8              \b, 60 fps
+>>11     byte               &0x04          \b, Constrained
+
+# MPEG ADTS Audio (*.mpx/mxa/aac)
+# from dreesen@math.fu-berlin.de
+# modified to fully support MPEG ADTS
+
+# MP3, M1A
+# modified by Joerg Jenderek
+# GRR the original test are too common for many DOS files
+# so don't accept as MP3 until we've tested the rate
+0       beshort&0xFFFE  0xFFFA
+# rates
+>2      byte&0xF0       0x10           MPEG ADTS, layer III, v1,  32 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x20           MPEG ADTS, layer III, v1,  40 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x30           MPEG ADTS, layer III, v1,  48 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x40           MPEG ADTS, layer III, v1,  56 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x50           MPEG ADTS, layer III, v1,  64 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x60           MPEG ADTS, layer III, v1,  80 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x70           MPEG ADTS, layer III, v1,  96 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x80           MPEG ADTS, layer III, v1, 112 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0x90           MPEG ADTS, layer III, v1, 128 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0xA0           MPEG ADTS, layer III, v1, 160 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0xB0           MPEG ADTS, layer III, v1, 192 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0xC0           MPEG ADTS, layer III, v1, 224 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0xD0           MPEG ADTS, layer III, v1, 256 kbps
+!:mime audio/mpeg
+>2      byte&0xF0       0xE0           MPEG ADTS, layer III, v1, 320 kbps
+!:mime audio/mpeg
+# timing
+>2      byte&0x0C       0x00           \b, 44.1 kHz
+>2      byte&0x0C       0x04           \b, 48 kHz
+>2      byte&0x0C       0x08           \b, 32 kHz
+# channels/options
+>3      byte&0xC0       0x00           \b, Stereo
+>3      byte&0xC0       0x40           \b, JntStereo
+>3      byte&0xC0       0x80           \b, 2x Monaural
+>3      byte&0xC0       0xC0           \b, Monaural
+#>1     byte            ^0x01          \b, Data Verify
+#>2     byte            &0x02          \b, Packet Pad
+#>2     byte            &0x01          \b, Custom Flag
+#>3     byte            &0x08          \b, Copyrighted
+#>3     byte            &0x04          \b, Original Source
+#>3     byte&0x03       1              \b, NR: 50/15 ms
+#>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# MP2, M1A
+0       beshort&0xFFFE  0xFFFC         MPEG ADTS, layer II, v1
+!:mime audio/mpeg
+# rates
+>2      byte&0xF0       0x10           \b,  32 kbps
+>2      byte&0xF0       0x20           \b,  48 kbps
+>2      byte&0xF0       0x30           \b,  56 kbps
+>2      byte&0xF0       0x40           \b,  64 kbps
+>2      byte&0xF0       0x50           \b,  80 kbps
+>2      byte&0xF0       0x60           \b,  96 kbps
+>2      byte&0xF0       0x70           \b, 112 kbps
+>2      byte&0xF0       0x80           \b, 128 kbps
+>2      byte&0xF0       0x90           \b, 160 kbps
+>2      byte&0xF0       0xA0           \b, 192 kbps
+>2      byte&0xF0       0xB0           \b, 224 kbps
+>2      byte&0xF0       0xC0           \b, 256 kbps
+>2      byte&0xF0       0xD0           \b, 320 kbps
+>2      byte&0xF0       0xE0           \b, 384 kbps
+# timing
+>2      byte&0x0C       0x00           \b, 44.1 kHz
+>2      byte&0x0C       0x04           \b, 48 kHz
+>2      byte&0x0C       0x08           \b, 32 kHz
+# channels/options
+>3      byte&0xC0       0x00           \b, Stereo
+>3      byte&0xC0       0x40           \b, JntStereo
+>3      byte&0xC0       0x80           \b, 2x Monaural
+>3      byte&0xC0       0xC0           \b, Monaural
+#>1     byte            ^0x01          \b, Data Verify
+#>2     byte            &0x02          \b, Packet Pad
+#>2     byte            &0x01          \b, Custom Flag
+#>3     byte            &0x08          \b, Copyrighted
+#>3     byte            &0x04          \b, Original Source
+#>3     byte&0x03       1              \b, NR: 50/15 ms
+#>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# MPA, M1A
+# updated by Joerg Jenderek
+# GRR the original test are too common for many DOS files, so test 32 <= kbits <= 448
+# GRR this test is still too general as it catches a BOM of UTF-16 files (0xFFFE)
+# FIXME: Almost all little endian UTF-16 text with BOM are clobbered by these entries
+#0     beshort&0xFFFE          0xFFFE
+#>2    ubyte&0xF0      >0x0F
+#>>2   ubyte&0xF0      <0xE1           MPEG ADTS, layer I, v1
+## rate
+#>>>2      byte&0xF0       0x10           \b,  32 kbps
+#>>>2      byte&0xF0       0x20           \b,  64 kbps
+#>>>2      byte&0xF0       0x30           \b,  96 kbps
+#>>>2      byte&0xF0       0x40           \b, 128 kbps
+#>>>2      byte&0xF0       0x50           \b, 160 kbps
+#>>>2      byte&0xF0       0x60           \b, 192 kbps
+#>>>2      byte&0xF0       0x70           \b, 224 kbps
+#>>>2      byte&0xF0       0x80           \b, 256 kbps
+#>>>2      byte&0xF0       0x90           \b, 288 kbps
+#>>>2      byte&0xF0       0xA0           \b, 320 kbps
+#>>>2      byte&0xF0       0xB0           \b, 352 kbps
+#>>>2      byte&0xF0       0xC0           \b, 384 kbps
+#>>>2      byte&0xF0       0xD0           \b, 416 kbps
+#>>>2      byte&0xF0       0xE0           \b, 448 kbps
+## timing
+#>>>2      byte&0x0C       0x00           \b, 44.1 kHz
+#>>>2      byte&0x0C       0x04           \b, 48 kHz
+#>>>2      byte&0x0C       0x08           \b, 32 kHz
+## channels/options
+#>>>3      byte&0xC0       0x00           \b, Stereo
+#>>>3      byte&0xC0       0x40           \b, JntStereo
+#>>>3      byte&0xC0       0x80           \b, 2x Monaural
+#>>>3      byte&0xC0       0xC0           \b, Monaural
+##>1     byte            ^0x01          \b, Data Verify
+##>2     byte            &0x02          \b, Packet Pad
+##>2     byte            &0x01          \b, Custom Flag
+##>3     byte            &0x08          \b, Copyrighted
+##>3     byte            &0x04          \b, Original Source
+##>3     byte&0x03       1              \b, NR: 50/15 ms
+##>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# MP3, M2A
+0       beshort&0xFFFE  0xFFF2         MPEG ADTS, layer III, v2
+!:mime audio/mpeg
+# rate
+>2      byte&0xF0       0x10           \b,   8 kbps
+>2      byte&0xF0       0x20           \b,  16 kbps
+>2      byte&0xF0       0x30           \b,  24 kbps
+>2      byte&0xF0       0x40           \b,  32 kbps
+>2      byte&0xF0       0x50           \b,  40 kbps
+>2      byte&0xF0       0x60           \b,  48 kbps
+>2      byte&0xF0       0x70           \b,  56 kbps
+>2      byte&0xF0       0x80           \b,  64 kbps
+>2      byte&0xF0       0x90           \b,  80 kbps
+>2      byte&0xF0       0xA0           \b,  96 kbps
+>2      byte&0xF0       0xB0           \b, 112 kbps
+>2      byte&0xF0       0xC0           \b, 128 kbps
+>2      byte&0xF0       0xD0           \b, 144 kbps
+>2      byte&0xF0       0xE0           \b, 160 kbps
+# timing
+>2      byte&0x0C       0x00           \b, 22.05 kHz
+>2      byte&0x0C       0x04           \b, 24 kHz
+>2      byte&0x0C       0x08           \b, 16 kHz
+# channels/options
+>3      byte&0xC0       0x00           \b, Stereo
+>3      byte&0xC0       0x40           \b, JntStereo
+>3      byte&0xC0       0x80           \b, 2x Monaural
+>3      byte&0xC0       0xC0           \b, Monaural
+#>1     byte            ^0x01          \b, Data Verify
+#>2     byte            &0x02          \b, Packet Pad
+#>2     byte            &0x01          \b, Custom Flag
+#>3     byte            &0x08          \b, Copyrighted
+#>3     byte            &0x04          \b, Original Source
+#>3     byte&0x03       1              \b, NR: 50/15 ms
+#>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# MP2, M2A
+0       beshort&0xFFFE  0xFFF4         MPEG ADTS, layer II, v2
+!:mime audio/mpeg
+# rate
+>2      byte&0xF0       0x10           \b,   8 kbps
+>2      byte&0xF0       0x20           \b,  16 kbps
+>2      byte&0xF0       0x30           \b,  24 kbps
+>2      byte&0xF0       0x40           \b,  32 kbps
+>2      byte&0xF0       0x50           \b,  40 kbps
+>2      byte&0xF0       0x60           \b,  48 kbps
+>2      byte&0xF0       0x70           \b,  56 kbps
+>2      byte&0xF0       0x80           \b,  64 kbps
+>2      byte&0xF0       0x90           \b,  80 kbps
+>2      byte&0xF0       0xA0           \b,  96 kbps
+>2      byte&0xF0       0xB0           \b, 112 kbps
+>2      byte&0xF0       0xC0           \b, 128 kbps
+>2      byte&0xF0       0xD0           \b, 144 kbps
+>2      byte&0xF0       0xE0           \b, 160 kbps
+# timing
+>2      byte&0x0C       0x00           \b, 22.05 kHz
+>2      byte&0x0C       0x04           \b, 24 kHz
+>2      byte&0x0C       0x08           \b, 16 kHz
+# channels/options
+>3      byte&0xC0       0x00           \b, Stereo
+>3      byte&0xC0       0x40           \b, JntStereo
+>3      byte&0xC0       0x80           \b, 2x Monaural
+>3      byte&0xC0       0xC0           \b, Monaural
+#>1     byte            ^0x01          \b, Data Verify
+#>2     byte            &0x02          \b, Packet Pad
+#>2     byte            &0x01          \b, Custom Flag
+#>3     byte            &0x08          \b, Copyrighted
+#>3     byte            &0x04          \b, Original Source
+#>3     byte&0x03       1              \b, NR: 50/15 ms
+#>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# MPA, M2A
+0       beshort&0xFFFE  0xFFF6         MPEG ADTS, layer I, v2
+!:mime audio/mpeg
+# rate
+>2      byte&0xF0       0x10           \b,  32 kbps
+>2      byte&0xF0       0x20           \b,  48 kbps
+>2      byte&0xF0       0x30           \b,  56 kbps
+>2      byte&0xF0       0x40           \b,  64 kbps
+>2      byte&0xF0       0x50           \b,  80 kbps
+>2      byte&0xF0       0x60           \b,  96 kbps
+>2      byte&0xF0       0x70           \b, 112 kbps
+>2      byte&0xF0       0x80           \b, 128 kbps
+>2      byte&0xF0       0x90           \b, 144 kbps
+>2      byte&0xF0       0xA0           \b, 160 kbps
+>2      byte&0xF0       0xB0           \b, 176 kbps
+>2      byte&0xF0       0xC0           \b, 192 kbps
+>2      byte&0xF0       0xD0           \b, 224 kbps
+>2      byte&0xF0       0xE0           \b, 256 kbps
+# timing
+>2      byte&0x0C       0x00           \b, 22.05 kHz
+>2      byte&0x0C       0x04           \b, 24 kHz
+>2      byte&0x0C       0x08           \b, 16 kHz
+# channels/options
+>3      byte&0xC0       0x00           \b, Stereo
+>3      byte&0xC0       0x40           \b, JntStereo
+>3      byte&0xC0       0x80           \b, 2x Monaural
+>3      byte&0xC0       0xC0           \b, Monaural
+#>1     byte            ^0x01          \b, Data Verify
+#>2     byte            &0x02          \b, Packet Pad
+#>2     byte            &0x01          \b, Custom Flag
+#>3     byte            &0x08          \b, Copyrighted
+#>3     byte            &0x04          \b, Original Source
+#>3     byte&0x03       1              \b, NR: 50/15 ms
+#>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# MP3, M25A
+0       beshort&0xFFFE  0xFFE2         MPEG ADTS, layer III,  v2.5
+!:mime audio/mpeg
+# rate
+>2      byte&0xF0       0x10           \b,   8 kbps
+>2      byte&0xF0       0x20           \b,  16 kbps
+>2      byte&0xF0       0x30           \b,  24 kbps
+>2      byte&0xF0       0x40           \b,  32 kbps
+>2      byte&0xF0       0x50           \b,  40 kbps
+>2      byte&0xF0       0x60           \b,  48 kbps
+>2      byte&0xF0       0x70           \b,  56 kbps
+>2      byte&0xF0       0x80           \b,  64 kbps
+>2      byte&0xF0       0x90           \b,  80 kbps
+>2      byte&0xF0       0xA0           \b,  96 kbps
+>2      byte&0xF0       0xB0           \b, 112 kbps
+>2      byte&0xF0       0xC0           \b, 128 kbps
+>2      byte&0xF0       0xD0           \b, 144 kbps
+>2      byte&0xF0       0xE0           \b, 160 kbps
+# timing
+>2      byte&0x0C       0x00           \b, 11.025 kHz
+>2      byte&0x0C       0x04           \b, 12 kHz
+>2      byte&0x0C       0x08           \b, 8 kHz
+# channels/options
+>3      byte&0xC0       0x00           \b, Stereo
+>3      byte&0xC0       0x40           \b, JntStereo
+>3      byte&0xC0       0x80           \b, 2x Monaural
+>3      byte&0xC0       0xC0           \b, Monaural
+#>1     byte            ^0x01          \b, Data Verify
+#>2     byte            &0x02          \b, Packet Pad
+#>2     byte            &0x01          \b, Custom Flag
+#>3     byte            &0x08          \b, Copyrighted
+#>3     byte            &0x04          \b, Original Source
+#>3     byte&0x03       1              \b, NR: 50/15 ms
+#>3     byte&0x03       3              \b, NR: CCIT J.17
+
+# AAC (aka MPEG-2 NBC audio) and MPEG-4 audio
+
+# Stored AAC streams (instead of the MP4 format)
+0       string          ADIF           MPEG ADIF, AAC
+!:mime audio/x-hx-aac-adif
+>4      byte            &0x80
+>>13    byte            &0x10          \b, VBR
+>>13    byte            ^0x10          \b, CBR
+>>16    byte&0x1E       0x02           \b, single stream
+>>16    byte&0x1E       0x04           \b, 2 streams
+>>16    byte&0x1E       0x06           \b, 3 streams
+>>16    byte            &0x08          \b, 4 or more streams
+>>16    byte            &0x10          \b, 8 or more streams
+>>4    byte            &0x80          \b, Copyrighted
+>>13   byte            &0x40          \b, Original Source
+>>13   byte            &0x20          \b, Home Flag
+>4      byte            ^0x80
+>>4     byte            &0x10          \b, VBR
+>>4     byte            ^0x10          \b, CBR
+>>7     byte&0x1E       0x02           \b, single stream
+>>7     byte&0x1E       0x04           \b, 2 streams
+>>7     byte&0x1E       0x06           \b, 3 streams
+>>7     byte            &0x08          \b, 4 or more streams
+>>7     byte            &0x10          \b, 8 or more streams
+>>4    byte            &0x40          \b, Original Stream(s)
+>>4    byte            &0x20          \b, Home Source
+
+# Live or stored single AAC stream (used with MPEG-2 systems)
+0       beshort&0xFFF6  0xFFF0         MPEG ADTS, AAC
+!:mime audio/x-hx-aac-adts
+>1      byte            &0x08          \b, v2
+>1      byte            ^0x08          \b, v4
+# profile
+>>2     byte            &0xC0          \b LTP
+>2      byte&0xc0       0x00           \b Main
+>2      byte&0xc0       0x40           \b LC
+>2      byte&0xc0       0x80           \b SSR
+# timing
+>2      byte&0x3c       0x00           \b, 96 kHz
+>2      byte&0x3c       0x04           \b, 88.2 kHz
+>2      byte&0x3c       0x08           \b, 64 kHz
+>2      byte&0x3c       0x0c           \b, 48 kHz
+>2      byte&0x3c       0x10           \b, 44.1 kHz
+>2      byte&0x3c       0x14           \b, 32 kHz
+>2      byte&0x3c       0x18           \b, 24 kHz
+>2      byte&0x3c       0x1c           \b, 22.05 kHz
+>2      byte&0x3c       0x20           \b, 16 kHz
+>2      byte&0x3c       0x24           \b, 12 kHz
+>2      byte&0x3c       0x28           \b, 11.025 kHz
+>2      byte&0x3c       0x2c           \b, 8 kHz
+# channels
+>2      beshort&0x01c0  0x0040         \b, monaural
+>2      beshort&0x01c0  0x0080         \b, stereo
+>2      beshort&0x01c0  0x00c0         \b, stereo + center
+>2      beshort&0x01c0  0x0100         \b, stereo+center+LFE
+>2      beshort&0x01c0  0x0140         \b, surround
+>2      beshort&0x01c0  0x0180         \b, surround + LFE
+>2      beshort         &0x01C0        \b, surround + side
+#>1     byte            ^0x01           \b, Data Verify
+#>2     byte            &0x02           \b, Custom Flag
+#>3     byte            &0x20           \b, Original Stream
+#>3     byte            &0x10           \b, Home Source
+#>3     byte            &0x08           \b, Copyrighted
+
+# Live MPEG-4 audio streams (instead of RTP FlexMux)
+0       beshort&0xFFE0  0x56E0         MPEG-4 LOAS
+!:mime audio/x-mp4a-latm
+#>1     beshort&0x1FFF  x              \b, %hu byte packet
+>3      byte&0xE0       0x40
+>>4     byte&0x3C       0x04           \b, single stream
+>>4     byte&0x3C       0x08           \b, 2 streams
+>>4     byte&0x3C       0x0C           \b, 3 streams
+>>4     byte            &0x08          \b, 4 or more streams
+>>4     byte            &0x20          \b, 8 or more streams
+>3      byte&0xC0       0
+>>4     byte&0x78       0x08           \b, single stream
+>>4     byte&0x78       0x10           \b, 2 streams
+>>4     byte&0x78       0x18           \b, 3 streams
+>>4     byte            &0x20          \b, 4 or more streams
+>>4     byte            &0x40          \b, 8 or more streams
+# This magic isn't strong enough (matches plausible ISO-8859-1 text)
+#0       beshort         0x4DE1         MPEG-4 LO-EP audio stream
+#!:mime        audio/x-mp4a-latm
+
+# Summary: FLI animation format
+# Created by: Daniel Quinlan <quinlan@yggdrasil.com>
+# Modified by (1): Abel Cheung <abelcheung@gmail.com> (avoid over-generic detection)
+4      leshort         0xAF11
+# standard FLI always has 320x200 resolution and 8 bit color
+>8     leshort         320
+>>10   leshort         200
+>>>12  leshort         8                       FLI animation, 320x200x8
+!:mime video/x-fli
+>>>>6  leshort         x                       \b, %d frames
+# frame speed is multiple of 1/70s
+>>>>16 leshort         x                       \b, %d/70s per frame
+
+# Summary: FLC animation format
+# Created by: Daniel Quinlan <quinlan@yggdrasil.com>
+# Modified by (1): Abel Cheung <abelcheung@gmail.com> (avoid over-generic detection)
+4      leshort         0xAF12
+# standard FLC always use 8 bit color
+>12    leshort         8                       FLC animation
+!:mime video/x-flc
+>>8    leshort         x                       \b, %d
+>>10   leshort         x                       \bx%dx8
+>>6    uleshort        x                       \b, %d frames
+>>16   uleshort        x                       \b, %dms per frame
+
+# DL animation format
+# XXX - collision with most `mips' magic
+#
+# I couldn't find a real magic number for these, however, this
+# -appears- to work.  Note that it might catch other files, too, so be
+# careful!
+#
+# Note that title and author appear in the two 20-byte chunks
+# at decimal offsets 2 and 22, respectively, but they are XOR'ed with
+# 255 (hex FF)!  The DL format is really bad.
+#
+#0     byte    1       DL version 1, medium format (160x100, 4 images/screen)
+#!:mime        video/x-unknown
+#>42   byte    x       - %d screens,
+#>43   byte    x       %d commands
+#0     byte    2       DL version 2
+#!:mime        video/x-unknown
+#>1    byte    1       - large format (320x200,1 image/screen),
+#>1    byte    2       - medium format (160x100,4 images/screen),
+#>1    byte    >2      - unknown format,
+#>42   byte    x       %d screens,
+#>43   byte    x       %d commands
+# Based on empirical evidence, DL version 3 have several nulls following the
+# \003.  Most of them start with non-null values at hex offset 0x34 or so.
+#0     string  \3\0\0\0\0\0\0\0\0\0\0\0        DL version 3
+
+# iso 13818 transport stream
+#
+# from Oskar Schirmer <schirmer@scara.com> Feb 3, 2001 (ISO 13818.1)
+# syncbyte      8 bit  0x47
+# error_ind     1 bit  -
+# payload_start 1 bit  1
+# priority      1 bit  -
+# PID          13 bit  0x0000
+# scrambling    2 bit  -
+# adaptfld_ctrl 2 bit  1 or 3
+# conti_count   4 bit  -
+0      belong&0xFF5FFF10       0x47400010
+>188   byte                    0x47            MPEG transport stream data
+!:mime  video/MP2T
+
+# DIF digital video file format <mpruett@sgi.com>
+0      belong&0xffffff00       0x1f070000      DIF
+>4     byte                    &0x01           (DVCPRO) movie file
+>4     byte                    ^0x01           (DV) movie file
+>3     byte                    &0x80           (PAL)
+>3     byte                    ^0x80           (NTSC)
+
+# Microsoft Advanced Streaming Format (ASF) <mpruett@sgi.com>
+0      belong                  0x3026b275      Microsoft ASF
+!:mime  video/x-ms-asf
+
+# MNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/>
+0      string                  \x8aMNG         MNG video data,
+!:mime video/x-mng
+>4     belong                  !0x0d0a1a0a     CORRUPTED,
+>4     belong                  0x0d0a1a0a
+>>16    belong x                               %d x
+>>20    belong x                               %d
+
+# JNG Video Format, <URL:http://www.libpng.org/pub/mng/spec/>
+0      string                  \x8bJNG         JNG video data,
+!:mime video/x-jng
+>4     belong                  !0x0d0a1a0a     CORRUPTED,
+>4     belong                  0x0d0a1a0a
+>>16    belong x                               %d x
+>>20    belong x                               %d
+
+# Vivo video (Wolfram Kleff)
+3      string          \x0D\x0AVersion:Vivo    Vivo video data
+
+# VRML (Virtual Reality Modelling Language)
+0       string/w        #VRML\ V1.0\ ascii     VRML 1 file
+!:mime model/vrml
+0      string/w        #VRML\ V2.0\ utf8       ISO/IEC 14772 VRML 97 file
+!:mime model/vrml
+
+# X3D (Extensible 3D) [https://www.web3d.org/specifications/x3d-3.0.dtd]
+# From Michel Briand <michelbriand@free.fr>
+# mimetype from https://www.iana.org/assignments/media-types/model/x3d+xml
+# Example https://www.web3d.org/x3d/content/examples/Basic/course/CreateX3DFromStringRandomSpheres.x3d
+0      string/w        \<?xml\ version=
+!:strength + 5
+>20    search/1000/w   \<!DOCTYPE\ X3D         X3D (Extensible 3D) model xml text
+!:mime model/x3d+xml
+
+#---------------------------------------------------------------------------
+# HVQM4: compressed movie format designed by Hudson for Nintendo GameCube
+# From Mark Sheppard <msheppard@climax.co.uk>, 2002-10-03
+#
+0      string          HVQM4           %s
+>6     string          >\0             v%s
+>0     byte            x               GameCube movie,
+>0x34  ubeshort        x               %d x
+>0x36  ubeshort        x               %d,
+>0x26  ubeshort        x               %dus,
+>0x42  ubeshort        0               no audio
+>0x42  ubeshort        >0              %dHz audio
+
+# From: "Stefan A. Haubenthal" <polluks@web.de>
+0      string          DVDVIDEO-VTS    Video title set,
+>0x21  byte            x               v%x
+0      string          DVDVIDEO-VMG    Video manager,
+>0x21  byte            x               v%x
+
+# From: Behan Webster <behanw@websterwood.com>
+# NuppelVideo used by Mythtv (*.nuv)
+# Note: there are two identical stanzas here differing only in the
+# initial string matched. It used to be done with a regex, but we're
+# trying to get rid of those.
+0      string          NuppelVideo     MythTV NuppelVideo
+>12    string          x               v%s
+>20    lelong          x               (%d
+>24    lelong          x               \bx%d),
+>36    string          P               \bprogressive,
+>36    string          I               \binterlaced,
+>40    ledouble        x               \baspect:%.2f,
+>48    ledouble        x               \bfps:%.2f
+0      string          MythTV          MythTV NuppelVideo
+>12    string          x               v%s
+>20    lelong          x               (%d
+>24    lelong          x               \bx%d),
+>36    string          P               \bprogressive,
+>36    string          I               \binterlaced,
+>40    ledouble        x               \baspect:%.2f,
+>48    ledouble        x               \bfps:%.2f
+
+#                                              MPEG file
+# MPEG sequences
+# FIXME: This section is from the old magic.mime file and needs
+# integrating with the rest
+#0       belong             0x000001BA
+#>4      byte               &0x40
+#!:mime        video/mp2p
+#>4      byte               ^0x40
+#!:mime        video/mpeg
+#0       belong             0x000001BB
+#!:mime        video/mpeg
+#0       belong             0x000001B0
+#!:mime        video/mp4v-es
+#0       belong             0x000001B5
+#!:mime        video/mp4v-es
+#0       belong             0x000001B3
+#!:mime        video/mpv
+#0       belong&0xFF5FFF10  0x47400010
+#!:mime        video/mp2t
+#0       belong             0x00000001
+#>4      byte&0x1F        0x07
+#!:mime        video/h264
+
+# Type: Bink Video
+# Extension: .bik
+# URL:  https://wiki.multimedia.cx/index.php?title=Bink_Container
+# From: <hoehle@users.sourceforge.net>  2008-07-18
+0      string          BIK     Bink Video
+>3     regex           =[a-z]  rev.%s
+#>4    ulelong         x       size %d
+>20    ulelong         x       \b, %d
+>24    ulelong         x       \bx%d
+>8     ulelong         x       \b, %d frames
+>32    ulelong         x       at rate %d/
+>28    ulelong         >1      \b%d
+>40    ulelong         =0      \b, no audio
+>40    ulelong         !0      \b, %d audio track
+>>40   ulelong         !1      \bs
+# follow properties of the first audio track only
+>>48   uleshort        x       %dHz
+>>51   byte&0x20       0       mono
+>>51   byte&0x20       !0      stereo
+#>>51  byte&0x10       0       FFT
+#>>51  byte&0x10       !0      DCT
+
+# Type:        NUT Container
+# URL: https://wiki.multimedia.cx/index.php?title=NUT
+# From:        Adam Buchbinder <adam.buchbinder@gmail.com>
+0      string  nut/multimedia\ container\0     NUT multimedia container
+
+# Type: Nullsoft Video (NSV)
+# URL:  https://wiki.multimedia.cx/index.php?title=Nullsoft_Video
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  NSVf    Nullsoft Video
+
+# Type: REDCode Video
+# URL:  https://www.red.com/ ; https://wiki.multimedia.cx/index.php?title=REDCode
+# From: Mike Melanson <mike@multimedia.cx>
+4      string  RED1    REDCode Video
+
+# Type: MTV Multimedia File
+# URL:  https://wiki.multimedia.cx/index.php?title=MTV
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  AMVS    MTV Multimedia File
+
+# Type: ARMovie
+# URL:  https://wiki.multimedia.cx/index.php?title=ARMovie
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  ARMovie\012     ARMovie
+
+# Type: Interplay MVE Movie
+# URL:  https://wiki.multimedia.cx/index.php?title=Interplay_MVE
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  Interplay\040MVE\040File\032    Interplay MVE Movie
+
+# Type: Windows Television DVR File
+# URL:  https://wiki.multimedia.cx/index.php?title=WTV
+# From: Mike Melanson <mike@mutlimedia.cx>
+# This takes the form of a Windows-style GUID
+0      bequad  0xB7D800203749DA11
+>8     bequad  0xA64E0007E95EAD8D      Windows Television DVR Media
+
+# Type: Sega FILM/CPK Multimedia
+# URL:  https://wiki.multimedia.cx/index.php?title=Sega_FILM
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  FILM    Sega FILM/CPK Multimedia,
+>32    belong  x       %d x
+>28    belong  x       %d
+
+# Type: Nintendo THP Multimedia
+# URL:  https://wiki.multimedia.cx/index.php?title=THP
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  THP\0   Nintendo THP Multimedia
+
+# Type: BBC Dirac Video
+# URL:  https://wiki.multimedia.cx/index.php?title=Dirac
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  BBCD    BBC Dirac Video
+
+# Type: RAD Game Tools Smacker Multimedia
+# URL:  https://wiki.multimedia.cx/index.php?title=Smacker
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  SMK     RAD Game Tools Smacker Multimedia
+>3     byte    x       version %c,
+>4     lelong  x       %d x
+>8     lelong  x       %d,
+>12    lelong  x       %d frames
+
+# Material Exchange Format
+# More information:
+# https://en.wikipedia.org/wiki/Material_Exchange_Format
+# http://www.freemxf.org/
+0      string  \x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02\x01\x01\x02        Material exchange container format
+!:ext  mxf
+!:mime application/mxf
+
+# Recognize LucasArts Smush video files (cf.
+# https://wiki.multimedia.cx/index.php/Smush)
+0      string  ANIM
+>8     string  AHDR    LucasArts Smush Animation Format (SAN) video
+0      string  SANM
+>8     string  SHDR    LucasArts Smush v2 (SANM) video
+
+# Type: Scaleform video
+# Extension: .usm
+# URL:  https://wiki.multimedia.cx/index.php/USM
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+0      string  CRID
+>32    string  @UTF    Scaleform video
diff --git a/magic/Magdir/aout b/magic/Magdir/aout
new file mode 100644 (file)
index 0000000..ba9630a
--- /dev/null
@@ -0,0 +1,46 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# aout:  file(1) magic for a.out executable/object/etc entries that
+# handle executables on multiple platforms.
+#
+
+#
+# Little-endian 32-bit-int a.out, merged from bsdi (for BSD/OS, from
+# BSDI), netbsd, and vax (for UNIX/32V and BSD)
+#
+# XXX - is there anything we can look at to distinguish BSD/OS 386 from
+# NetBSD 386 from various VAX binaries?  The BSD/OS shared library flag
+# works only for binaries using shared libraries.  Grabbing the entry
+# point from the a.out header, using it to find the first code executed
+# in the program, and looking at that might help.
+#
+0      lelong          0407            a.out little-endian 32-bit executable
+>16    lelong          >0              not stripped
+>32    byte            0x6a            (uses BSD/OS shared libs)
+
+0      lelong          0410            a.out little-endian 32-bit pure executable
+>16    lelong          >0              not stripped
+>32    byte            0x6a            (uses BSD/OS shared libs)
+
+0      lelong          0413            a.out little-endian 32-bit demand paged pure executable
+>16    lelong          >0              not stripped
+>32    byte            0x6a            (uses BSD/OS shared libs)
+
+#
+# Big-endian 32-bit-int a.out, merged from sun (for old 68010 SunOS a.out),
+# mips (for old 68020(!) SGI a.out), and netbsd (for old big-endian a.out).
+#
+# XXX - is there anything we can look at to distinguish old SunOS 68010
+# from old 68020 IRIX from old NetBSD?  Again, I guess we could look at
+# the first instruction or instructions in the program.
+#
+0      belong          0407            a.out big-endian 32-bit executable
+>16    belong          >0              not stripped
+
+0      belong          0410            a.out big-endian 32-bit pure executable
+>16    belong          >0              not stripped
+
+0      belong          0413            a.out big-endian 32-bit demand paged executable
+>16    belong          >0              not stripped
+
diff --git a/magic/Magdir/apache b/magic/Magdir/apache
new file mode 100755 (executable)
index 0000000..d896b50
--- /dev/null
@@ -0,0 +1,28 @@
+
+#------------------------------------------------------------------------------
+# $File: apache,v 1.1 2017/04/11 14:52:15 christos Exp $
+# apache: file(1) magic for Apache Big Data formats
+
+# Avro files
+0      string          Obj             Apache Avro
+>3     byte            x               version %d
+
+# ORC files
+# Important information is in file footer, which we can't index to :(
+0      string          ORC             Apache ORC
+
+# Parquet files
+0      string          PAR1            Apache Parquet
+
+# Hive RC files
+0      string          RCF             Apache Hive RC file
+>3     byte            x               version %d
+
+# Sequence files (and the careless first version of RC file)
+
+0      string          SEQ
+>3     byte            <6              Apache Hadoop Sequence file version %d
+>3     byte            >6              Apache Hadoop Sequence file version %d
+>3     byte            =6
+>>5    string          org.apache.hadoop.hive.ql.io.RCFile$KeyBuffer  Apache Hive RC file version 0
+>>3    default         x               Apache Hadoop Sequence file version 6
diff --git a/magic/Magdir/apl b/magic/Magdir/apl
new file mode 100644 (file)
index 0000000..cb2b3ff
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# apl:  file(1) magic for APL (see also "pdp" and "vax" for other APL
+#       workspaces)
+#
+0      long            0100554         APL workspace (Ken's original?)
diff --git a/magic/Magdir/apple b/magic/Magdir/apple
new file mode 100644 (file)
index 0000000..4ac10fc
--- /dev/null
@@ -0,0 +1,524 @@
+
+#------------------------------------------------------------------------------
+# $File: apple,v 1.43 2019/04/19 00:42:27 christos Exp $
+# apple:  file(1) magic for Apple file formats
+#
+0      search/1/t      FiLeStArTfIlEsTaRt      binscii (apple ][) text
+0      string          \x0aGL                  Binary II (apple ][) data
+0      string          \x76\xff                Squeezed (apple ][) data
+0      string          NuFile                  NuFile archive (apple ][) data
+0      string          N\xf5F\xe9l\xe5         NuFile archive (apple ][) data
+0      belong          0x00051600              AppleSingle encoded Macintosh file
+0      belong          0x00051607              AppleDouble encoded Macintosh file
+
+# Type: Apple Emulator WOZ format
+# From: Greg Wildman <greg@apple2.org.za>
+# Ref: https://applesaucefdc.com/woz/reference/
+# Ref: https://applesaucefdc.com/woz/reference2/
+#
+# Note: The following test are mostly identical. I would rather not
+# use a regex to identify the WOZ format number.
+0      string          WOZ1
+>4     string          \xFF\x0A\x0D\x0A        Apple ][ WOZ 1.0 Disk Image
+>12    string          INFO
+>>21   byte            01                      \b, 5.25 inch
+>>21   byte            02                      \b, 3.5 inch
+>>22   byte            01                      \b, write protected
+>>23   byte            01                      \b, cross track synchronized
+>>25   string/T        x                       \b, %.32s
+0      string          WOZ2
+>4     string          \xFF\x0A\x0D\x0A        Apple ][ WOZ 2.0 Disk Image
+>12    string          INFO
+>>21   byte            01                      \b, 5.25 inch
+>>21   byte            02                      \b, 3.5 inch
+>>22   byte            01                      \b, write protected
+>>23   byte            01                      \b, cross track synchronized
+>>25   string/T        x                       \b, %.32s
+
+# Type: Apple Emulator disk images
+# From: Greg Wildman <greg@apple2.org.za>
+# ProDOS boot loader?
+0              string  \x01\x38\xB0\x03\x4C    Apple ProDOS Image
+# Detect Volume Directory block ($02)
+>0x400         string  \x00\x00\x03\x00
+>>0x404                byte    &0xF0
+>>>0x405       string  x                       \b, Volume /%s
+>>>0x429       leshort x                       \b, %u Blocks
+# ProDOS ordered ?
+>0xb00         string  \x00\x00\x03\x00
+>>0xb04                byte    &0xF0
+>>>0xb05       string  x                       \b, Volume /%s
+>>>0xb29       leshort x                       \b, %u Blocks
+#
+# DOS3.3 boot loader?
+0              string  \x01\xA5\x27\xC9\x09\xD0\x18\xA5\x2B
+>0x11001       string  \x11\x0F\x03    Apple DOS 3.3 Image
+>>0x11006      byte    x               \b, Volume %u
+>>0x11034      byte    x               \b, %u Tracks
+>>0x11035      byte    x               \b, %u Sectors
+>>0x11036      leshort x               \b, %u bytes per sector
+# DOS3.2 ?
+>0x11001       string  \x11\x0C\x02    Apple DOS 3.2 Image
+>>0x11006      byte    x               \b, Volume %u
+>>0x11034      byte    x               \b, %u Tracks
+>>0x11035      byte    x               \b, %u Sectors
+>>0x11036      leshort x               \b, %u bytes per sector
+# DOS3.1 ?
+>0x11001       string  \x11\x0C\x01
+>>0x11c00      string  \x00\x11\x0B    Apple DOS 3.1 Image
+#
+# Pascal boot loader?
+0              string  \x01\xE0\x60\xF0\x03\x4C\xE3\x08\xAD
+>0xd6          pstring SYSTEM.APPLE
+>>0xb00                leshort 0x0000
+>>>0xb04       leshort 0x0000          Apple Pascal Image
+>>>>0xb06      pstring x               \b, Volume %s:
+>>>>0xb0e      leshort x               \b, %u Blocks
+>>>>0xb10      leshort x               \b, %u Files
+
+# Type: Apple Emulator 2IMG format
+# From: Radek Vokal <rvokal@redhat.com>
+# Update: Greg Wildman <greg@apple2.org.za>
+0      string          2IMG            Apple ][ 2IMG Disk Image
+>4     clear           x
+>4     string          XGS!            \b, XGS
+>4     string          CTKG            \b, Catakig
+>4     string          ShIm            \b, Sheppy's ImageMaker
+>4     string          SHEP            \b, Sheppy's ImageMaker
+>4     string          WOOF            \b, Sweet 16
+>4     string          B2TR            \b, Bernie ][ the Rescue
+>4     string          \!nfc           \b, ASIMOV2
+>4     string          \>BD\<          \b, Brutal Deluxe's Cadius
+>4     string          CdrP            \b, CiderPress
+>4     string          Vi][            \b, Virtual ][
+>4     string          PRFS            \b, ProFUSE
+>4     string          FISH            \b, FishWings
+>4     string          RVLW            \b, Revival for Windows
+>4     default         x
+>>4    string          x               \b, Creator tag "%-4.4s"
+>0xc   byte            00              \b, DOS 3.3 sector order
+>>0x10 byte            00              \b, Volume 254
+>>0x10 byte&0x7f       x               \b, Volume %u
+>0xc   byte            01              \b, ProDOS sector order
+>>0x14 short           x               \b, %u Blocks
+>0xc   byte            02              \b, NIB data
+
+# magic for Newton PDA package formats
+# from Ruda Moura <ruda@helllabs.org>
+0      string  package0        Newton package, NOS 1.x,
+>12    belong  &0x80000000     AutoRemove,
+>12    belong  &0x40000000     CopyProtect,
+>12    belong  &0x10000000     NoCompression,
+>12    belong  &0x04000000     Relocation,
+>12    belong  &0x02000000     UseFasterCompression,
+>16    belong  x               version %d
+
+0      string  package1        Newton package, NOS 2.x,
+>12    belong  &0x80000000     AutoRemove,
+>12    belong  &0x40000000     CopyProtect,
+>12    belong  &0x10000000     NoCompression,
+>12    belong  &0x04000000     Relocation,
+>12    belong  &0x02000000     UseFasterCompression,
+>16    belong  x               version %d
+
+0      string  package4        Newton package,
+>8     byte    8               NOS 1.x,
+>8     byte    9               NOS 2.x,
+>12    belong  &0x80000000     AutoRemove,
+>12    belong  &0x40000000     CopyProtect,
+>12    belong  &0x10000000     NoCompression,
+
+# The following entries for the Apple II are for files that have
+# been transferred as raw binary data from an Apple, without having
+# been encapsulated by any of the above archivers.
+#
+# In general, Apple II formats are hard to identify because Apple DOS
+# and especially Apple ProDOS have strong typing in the file system and
+# therefore programmers never felt much need to include type information
+# in the files themselves.
+#
+# Eric Fischer <enf@pobox.com>
+
+# AppleWorks word processor:
+# URL: https://en.wikipedia.org/wiki/AppleWorks
+# Reference: http://www.gno.org/pub/apple2/doc/apple/filetypes/ftn.1a.xxxx
+# Update: Joerg Jenderek
+# NOTE:
+# The "O" is really the magic number, but that's so common that it's
+# necessary to check the tab stops that follow it to avoid false positives.
+# and/or look for unused bits of booleans bytes like zoom, paginated, mail merge
+# the newer AppleWorks is from claris with extension CWK
+4      string          O
+# test for unused bits of zoom- , paginated-boolean bytes
+>84    ubequad         ^0x00Fe00000000Fe00
+# look for tabstop definitions "=" no tab, "|" no tab
+# "<" left tab,"^" center tab,">" right tab, "." decimal tab,
+# unofficial "!" other , "\x8a" other
+# official only if SFMinVers is nonzero
+>>5    regex/s [=.<>|!^\x8a]{79}       AppleWorks Word Processor
+# AppleWorks Word Processor File (Apple II)
+# ./apple (version 5.25) labeled the entry as "AppleWorks word processor data"
+# application/x-appleworks is mime type for claris version with cwk extension
+!:mime application/x-appleworks3
+# http://home.earthlink.net/~hughhood/appleiiworksenvoy/
+# ('p' + 1-byte ProDOS File Type + 2-byte ProDOS Aux Type')
+# $70 $1A $F8 $FF is this the apple type ?
+#:apple pdosp^Z\xf8\xff
+!:ext awp
+# minimum version needed to read this files. SFMinVers (0 , 30~3.0 )
+>>>183 ubyte           30      3.0
+>>>183 ubyte           !30
+>>>>183        ubyte           !0      0x%x
+# usual tabstop start sequence "=====<"
+>>>5   string          x       \b, tabstop ruler "%6.6s"
+# tabstop ruler
+#>>>5  string          >\0     \b, tabstops "%-79s"
+# zoom switch
+>>>85    byte&0x01     >0      \b, zoomed
+# whether paginated
+>>>90    byte&0x01     >0      \b, paginated
+# contains any mail-merge commands
+>>>92    byte&0x01     >0      \b, with mail merge
+# left margin in 1/10 inches ( normally 0 or 10 )
+>>>91  ubyte           >0
+>>>>91 ubyte           x       \b, %d/10 inch left margin
+
+# AppleWorks database:
+#
+# This isn't really a magic number, but it's the closest thing to one
+# that I could find.  The 1 and 2 really mean "order in which you defined
+# categories" and "left to right, top to bottom," respectively; the D and R
+# mean that the cursor should move either down or right when you press Return.
+
+#30    string          \x01D   AppleWorks database data
+#30    string          \x02D   AppleWorks database data
+#30    string          \x01R   AppleWorks database data
+#30    string          \x02R   AppleWorks database data
+
+# AppleWorks spreadsheet:
+#
+# Likewise, this isn't really meant as a magic number.  The R or C means
+# row- or column-order recalculation; the A or M means automatic or manual
+# recalculation.
+
+#131   string          RA      AppleWorks spreadsheet data
+#131   string          RM      AppleWorks spreadsheet data
+#131   string          CA      AppleWorks spreadsheet data
+#131   string          CM      AppleWorks spreadsheet data
+
+# Applesoft BASIC:
+#
+# This is incredibly sloppy, but will be true if the program was
+# written at its usual memory location of 2048 and its first line
+# number is less than 256.  Yuck.
+# update by Joerg Jenderek at Feb 2013
+
+# GRR: this test is still too general as it catches also Gujin BOOT144.SYS (0xfa080000)
+#0       belong&0xff00ff 0x80000 Applesoft BASIC program data
+0      belong&0x00ff00ff       0x00080000
+# assuming that line number must be positive
+>2     leshort                 >0              Applesoft BASIC program data, first line number %d
+#>2     leshort         x       \b, first line number %d
+
+# ORCA/EZ assembler:
+#
+# This will not identify ORCA/M source files, since those have
+# some sort of date code instead of the two zero bytes at 6 and 7
+# XXX Conflicts with ELF
+#4       belong&0xff00ffff       0x01000000      ORCA/EZ assembler source data
+#>5      byte                    x               \b, build number %d
+
+# Broderbund Fantavision
+#
+# I don't know what these values really mean, but they seem to recur.
+# Will they cause too many conflicts?
+
+# Probably :-)
+#2     belong&0xFF00FF         0x040008        Fantavision movie data
+
+# Some attempts at images.
+#
+# These are actually just bit-for-bit dumps of the frame buffer, so
+# there's really no reasonably way to distinguish them except for their
+# address (if preserved) -- 8192 or 16384 -- and their length -- 8192
+# or, occasionally, 8184.
+#
+# Nevertheless this will manage to catch a lot of images that happen
+# to have a solid-colored line at the bottom of the screen.
+
+# GRR: Magic too weak
+#8144  string  \x7F\x7F\x7F\x7F\x7F\x7F\x7F\x7F        Apple II image with white background
+#8144  string  \x55\x2A\x55\x2A\x55\x2A\x55\x2A        Apple II image with purple background
+#8144  string  \x2A\x55\x2A\x55\x2A\x55\x2A\x55        Apple II image with green background
+#8144  string  \xD5\xAA\xD5\xAA\xD5\xAA\xD5\xAA        Apple II image with blue background
+#8144  string  \xAA\xD5\xAA\xD5\xAA\xD5\xAA\xD5        Apple II image with orange background
+
+# Beagle Bros. Apple Mechanic fonts
+
+0      belong&0xFF00FFFF       0x6400D000      Apple Mechanic font
+
+# Apple Universal Disk Image Format (UDIF) - dmg files.
+# From Johan Gade.
+# These entries are disabled for now until we fix the following issues.
+#
+# Note there might be some problems with the "VAX COFF executable"
+# entry. Note this entry should be placed before the mac filesystem section,
+# particularly the "Apple Partition data" entry.
+#
+# The intended meaning of these tests is, that the file is only of the
+# specified type if both of the lines are correct - i.e. if the first
+# line matches and the second doesn't then it is not of that type.
+#
+#0     long    0x7801730d
+#>4    long    0x62626060      UDIF read-only zlib-compressed image (UDZO)
+#
+# Note that this entry is recognized correctly by the "Apple Partition
+# data" entry - however since this entry is more specific - this
+# information seems to be more useful.
+#0     long    0x45520200
+#>0x410        string  disk\ image     UDIF read/write image (UDRW)
+
+# From: Toby Peterson <toby@apple.com>
+0      string  bplist00        Apple binary property list
+
+# Apple binary property list (bplist)
+#  Assumes version bytes are hex.
+#  Provides content hints for version 0 files. Assumes that the root
+#  object is the first object (true for CoreFoundation implementation).
+# From: David Remahl <dremahl@apple.com>
+0              string  bplist
+>6             byte    x       \bCoreFoundation binary property list data, version 0x%c
+>>7            byte    x       \b%c
+>6             string          00              \b
+>>8            byte&0xF0       0x00    \b
+>>>8   byte&0x0F       0x00    \b, root type: null
+>>>8   byte&0x0F       0x08    \b, root type: false boolean
+>>>8   byte&0x0F       0x09    \b, root type: true boolean
+>>8            byte&0xF0       0x10    \b, root type: integer
+>>8            byte&0xF0       0x20    \b, root type: real
+>>8            byte&0xF0       0x30    \b, root type: date
+>>8            byte&0xF0       0x40    \b, root type: data
+>>8            byte&0xF0       0x50    \b, root type: ascii string
+>>8            byte&0xF0       0x60    \b, root type: unicode string
+>>8            byte&0xF0       0x80    \b, root type: uid (CORRUPT)
+>>8            byte&0xF0       0xa0    \b, root type: array
+>>8            byte&0xF0       0xd0    \b, root type: dictionary
+
+# Apple/NeXT typedstream data
+#  Serialization format used by NeXT and Apple for various
+#  purposes in YellowStep/Cocoa, including some nib files.
+# From: David Remahl <dremahl@apple.com>
+2              string          typedstream     NeXT/Apple typedstream data, big endian
+>0             byte            x               \b, version %d
+>0             byte            <5              \b
+>>13   byte            0x81    \b
+>>>14  ubeshort        x               \b, system %d
+2              string          streamtyped NeXT/Apple typedstream data, little endian
+>0             byte            x               \b, version %d
+>0             byte            <5              \b
+>>13   byte            0x81    \b
+>>>14  uleshort        x               \b, system %d
+
+#------------------------------------------------------------------------------
+# CAF: Apple CoreAudio File Format
+#
+# Container format for high-end audio purposes.
+# From: David Remahl <dremahl@apple.com>
+#
+0      string          caff            CoreAudio Format audio file
+>4     beshort         <10             version %d
+>6     beshort         x
+
+
+#------------------------------------------------------------------------------
+# Keychain database files
+0      string          kych            Mac OS X Keychain File
+
+#------------------------------------------------------------------------------
+# Code Signing related file types
+0      belong          0xfade0c00      Mac OS X Code Requirement
+>8     belong          1                       (opExpr)
+>4     belong          x                       - %d bytes
+
+0      belong          0xfade0c01      Mac OS X Code Requirement Set
+>8     belong          >1                      containing %d items
+>4     belong          x                       - %d bytes
+
+0      belong          0xfade0c02      Mac OS X Code Directory
+>8     belong          x                       version %x
+>12    belong          >0                      flags 0x%x
+>4     belong          x                       - %d bytes
+
+0      belong          0xfade0cc0      Mac OS X Detached Code Signature (non-executable)
+>4     belong          x                       - %d bytes
+
+0      belong          0xfade0cc1      Mac OS X Detached Code Signature
+>8     belong          >1                      (%d elements)
+>4     belong          x                       - %d bytes
+
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+# .vdi
+4      string innotek\ VirtualBox\ Disk\ Image %s
+
+# Apple disk partition stuff
+# URL: https://en.wikipedia.org/wiki/Apple_Partition_Map
+# Reference: https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/sys/bootblock.h
+# Update: Joerg Jenderek
+# "ER" is APPLE_DRVR_MAP_MAGIC signature
+0      beshort 0x4552
+# display Apple Driver Map (strength=50) after Syslinux bootloader (71)
+#!:strength +0
+# strengthen the magic by looking for used blocksizes 512 2048
+>2     ubeshort&0xf1FF         0       Apple Driver Map
+# last 6 bytes for padding found are 0 or end with 55AAh marker for MBR hybrid
+#>>504 ubequad&0x0000FFffFFff0000      0
+!:mime application/x-apple-diskimage
+!:apple        ????devr
+# https://en.wikipedia.org/wiki/Apple_Disk_Image
+!:ext  dmg/iso
+# sbBlkSize for driver descriptor map 512 2048
+>>2    beshort x                       \b, blocksize %d
+# sbBlkCount sometimes garbish like
+# 0xb0200000 for unzlibed install_flash_player_19.0.0.245_osx.dmg
+# 0xf2720100 for bunziped Firefox 48.0-2.dmg
+# 0xeb02ffff for super_grub2_disk_hybrid_2.02s3.iso
+# 0x00009090 by syslinux-6.03/utils/isohybrid.c
+>>4    ubelong x                       \b, blockcount %u
+# following device/driver information not very useful
+# device type 0 1 (37008 garbage for super_grub2_disk_hybrid_2.02s3.iso)
+>>8    ubeshort        x               \b, devtype %u
+# device id 0 1 (37008 garbage for super_grub2_disk_hybrid_2.02s3.iso)
+>>10   ubeshort        x               \b, devid %u
+# driver data 0 (2425393296 garbage for super_grub2_disk_hybrid_2.02s3.iso)
+>>12   ubelong         >0
+>>>12  ubelong         x               \b, driver data %u
+# number of driver descriptors sbDrvrCount <= 61
+# (37008 garbage for super_grub2_disk_hybrid_2.02s3.iso)
+>>16   ubeshort        x               \b, driver count %u
+# 61 * apple_drvr_descriptor[8]. information not very useful or same as in partition map
+# >>18 use             apple-driver-map
+# >>26 use             apple-driver-map
+# # ...
+# >>500        use             apple-driver-map
+# number of partitions is always same in every partition (map block count)
+#>>0x0204      ubelong         x       \b, %u partitions
+>>0x0204       ubelong         >0      \b, contains[@0x200]:
+>>>0x0200      use             apple-apm
+>>0x0204       ubelong         >1      \b, contains[@0x400]:
+>>>0x0400      use             apple-apm
+>>0x0204       ubelong         >2      \b, contains[@0x600]:
+>>>0x0600      use             apple-apm
+>>0x0204       ubelong         >3      \b, contains[@0x800]:
+>>>0x0800      use             apple-apm
+>>0x0204       ubelong         >4      \b, contains[@0xA00]:
+>>>0x0A00      use             apple-apm
+>>0x0204       ubelong         >5      \b, contains[@0xC00]:
+>>>0x0C00      use             apple-apm
+>>0x0204       ubelong         >6      \b, contains[@0xE00]:
+>>>0x0E00      use             apple-apm
+>>0x0204       ubelong         >7      \b, contains[@0x1000]:
+>>>0x1000      use             apple-apm
+#      display apple driver descriptor map (start-block, # blocks in sbBlkSize sizes, type)
+0      name                            apple-driver-map
+>0     ubequad         !0
+# descBlock first block of driver
+>>0    ubelong x                       \b, driver start block %u
+# descSize driver size in blocks
+>>4    ubeshort        x               \b, size %u
+# descType driver system type 1 701h F8FFh FFFFh
+>>6    ubeshort        x               \b, type 0x%x
+
+# URL: https://en.wikipedia.org/wiki/Apple_Partition_Map
+# Reference: https://opensource.apple.com/source/IOStorageFamily/IOStorageFamily-116/IOApplePartitionScheme.h
+# Update: Joerg Jenderek
+# Yes, the 3rd and 4th bytes pmSigPad are reserved, but we use them to make the
+# magic stronger.
+# for apple partition map stored as a single file
+0      belong  0x504d0000
+# to display Apple Partition Map (strength=70) after Syslinux bootloader (71)
+#!:strength +0
+>0     use             apple-apm
+# magic/Magdir/apple14.test, 365: Warning: Current entry does not yet have a description for adding a EXTENSION type
+# file: could not find any valid magic files!
+#!:ext bin
+#      display apple partition map. Normally called after Apple driver map
+0      name                            apple-apm
+>0     belong  0x504d0000              Apple Partition Map
+# number of partitions
+>>4    ubelong x                       \b, map block count %u
+# logical block (512 bytes) start of partition
+>>8    ubelong x                       \b, start block %u
+>>12   ubelong x                       \b, block count %u
+>>16   string >0                       \b, name %s
+>>48   string >0                       \b, type %s
+# processor type dpme_process_id[16] e.g. "68000" "68020"
+>>120  string >0                       \b, processor %s
+# A/UX boot arguments BootArgs[128]
+>>136  string >0                       \b, boot arguments %s
+# status of partition dpme_flags
+>>88   belong  & 1                     \b, valid
+>>88   belong  & 2                     \b, allocated
+>>88   belong  & 4                     \b, in use
+>>88   belong  & 8                     \b, has boot info
+>>88   belong  & 16                    \b, readable
+>>88   belong  & 32                    \b, writable
+>>88   belong  & 64                    \b, pic boot code
+>>88   belong  & 128                   \b, chain compatible driver
+>>88   belong  & 256                   \b, real driver
+>>88   belong  & 512                   \b, chain driver
+# mount automatically at startup APPLE_PS_AUTO_MOUNT
+>>88   ubelong &0x40000000             \b, mount at startup
+# is the startup partition APPLE_PS_STARTUP
+>>88   ubelong &0x80000000             \b, is the startup partition
+
+#https://wiki.mozilla.org/DS_Store_File_Format
+#https://en.wikipedia.org/wiki/.DS_Store
+0      string  \0\0\0\1Bud1\0          Apple Desktop Services Store
+
+# HFS/HFS+ Resource fork files (andrew.roazen@nau.edu Apr 13 2015)
+# Usually not in separate files, but have either filename rsrc with
+# no extension, or a filename corresponding to another file, with
+# extensions rsr/rsrc
+0      string  \000\000\001\000
+>4     leshort 0
+>>16   lelong  0                       Apple HFS/HFS+ resource fork
+
+#https://en.wikipedia.org/wiki/AppleScript
+0      string  FasdUAS                 AppleScript compiled
+
+# AppleWorks/ClarisWorks
+# https://github.com/joshenders/appleworks_format
+# http://fileformats.archiveteam.org/wiki/AppleWorks
+0      name                    appleworks
+>0     belong&0x00ffffff       0x07e100        AppleWorks CWK Document
+>0     belong&0x00ffffff       0x008803        ClarisWorks CWK Document
+>0     default                 x
+>>0    belong                  x               AppleWorks/ClarisWorks CWK Document
+>0     byte                    x               \b, version %d
+>30    beshort                 x               \b, %d
+>32    beshort                 x               \bx%d
+!:ext cwk
+
+4      string  BOBO
+>0     byte    >4
+>>12   belong  0
+>>>26  belong  0
+>>>>0  use     appleworks
+>0     belong  0x0481ad00
+>>0    use     appleworks
+
+# magic for Apple File System (APFS)
+# from Alex Myczko <alex@aiei.ch>
+32             string  NXSB            Apple File System (APFS)
+>36            ulelong x               \b, blocksize %u
+
+# iTunes cover art (versions 1 and 2)
+4              string  itch
+>24            string  artw
+>>0x1e8                string  data            iTunes cover art
+>>>0x1ed       string  PNG             (PNG)
+>>>0x1ec       beshort 0xffd8          (JPEG)
+
+# MacPaint image
+65             string  PNTGMPNT        MacPaint image data
+#0             belong  2               MacPaint image data
diff --git a/magic/Magdir/application b/magic/Magdir/application
new file mode 100644 (file)
index 0000000..ea30347
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File: apple,v 1.35 2016/08/17 09:45:13 christos Exp $
+# application:  file(1) magic for applications on small devices
+#
+# Pebble Application
+0      string  PBLAPP\000\000  Pebble application
diff --git a/magic/Magdir/applix b/magic/Magdir/applix
new file mode 100644 (file)
index 0000000..ea69830
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# applix:  file(1) magic for Applixware
+# From: Peter Soos <sp@osb.hu>
+#
+0      string          *BEGIN          Applixware
+>7     string          WORDS                   Words Document
+>7     string          GRAPHICS                Graphic
+>7     string          RASTER                  Bitmap
+>7     string          SPREADSHEETS            Spreadsheet
+>7     string          MACRO                   Macro
+>7     string          BUILDER                 Builder Object
diff --git a/magic/Magdir/apt b/magic/Magdir/apt
new file mode 100644 (file)
index 0000000..26fb3bd
--- /dev/null
@@ -0,0 +1,52 @@
+
+#------------------------------------------------------------------------------
+# $File: apple,v 1.35 2016/08/17 09:45:13 christos Exp $
+# apt: file(1) magic for APT Cache files
+# <http://www.fifi.org/doc/libapt-pkg-doc/cache.html/ch2.html>
+# <https://anonscm.debian.org/cgit/apt/apt.git/tree/apt-pkg/pkgcache.h#n292>
+
+# before version 10 ("old format"), data was in arch-specific long/short
+
+# old format 64 bit
+0      name            apt-cache-64bit-be
+>12    beshort         1               \b, dirty
+>40    bequad          x               \b, %llu packages
+>48    bequad          x               \b, %llu versions
+
+# old format 32 bit
+0      name            apt-cache-32bit-be
+>8     beshort         1               \b, dirty
+>40    belong          x               \b, %u packages
+>44    belong          x               \b, %u versions
+
+# new format
+0      name            apt-cache-be
+>6     byte            1               \b, dirty
+>24    belong          x               \b, %u packages
+>28    belong          x               \b, %u versions
+
+0      bequad          0x98FE76DC
+>8     ubeshort        <10             APT cache data, version %u
+>>10   beshort         x               \b.%u, 64 bit big-endian
+>>0    use             apt-cache-64bit-be
+
+0      lequad          0x98FE76DC
+>8     uleshort        <10             APT cache data, version %u
+>>10   leshort         x               \b.%u, 64 bit little-endian
+>>0    use             \^apt-cache-64bit-be
+
+0      belong          0x98FE76DC
+>4     ubeshort        <10             APT cache data, version %u
+>>6    ubeshort        x               \b.%u, 32 bit big-endian
+>>0    use             apt-cache-32bit-be
+>4     ubyte           >9              APT cache data, version %u
+>>5    ubyte           x               \b.%u, big-endian
+>>0    use             apt-cache-be
+
+0      lelong          0x98FE76DC
+>4     uleshort        <10             APT cache data, version %u
+>>6    uleshort        x               \b.%u, 32 bit little-endian
+>>0    use             \^apt-cache-32bit-be
+>4     ubyte           >9              APT cache data, version %u
+>>5    ubyte           x               \b.%u, little-endian
+>>0    use             \^apt-cache-be
diff --git a/magic/Magdir/archive b/magic/Magdir/archive
new file mode 100644 (file)
index 0000000..cd0213f
--- /dev/null
@@ -0,0 +1,1592 @@
+#------------------------------------------------------------------------------
+# $File: archive,v 1.129 2019/05/09 18:58:02 christos Exp $
+# archive:  file(1) magic for archive formats (see also "msdos" for self-
+#           extracting compressed archives)
+#
+# cpio, ar, arc, arj, hpack, lha/lharc, rar, squish, uc2, zip, zoo, etc.
+# pre-POSIX "tar" archives are also handled in the C code ../../src/is_tar.c.
+
+# POSIX tar archives
+# URL: https://en.wikipedia.org/wiki/Tar_(computing)
+# Reference: https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5&manpath=FreeBSD+8-current
+# header mainly padded with nul bytes
+500    quad            0               
+!:strength /2
+# filename or extended attribute printable strings in range space null til umlaut ue
+>0     ubeshort        >0x1F00         
+>>0    ubeshort        <0xFCFD
+# last 4 header bytes often null but tar\0 in gtarfail2.tar gtarfail.tar-bad
+# at https://sourceforge.net/projects/s-tar/files/testscripts/
+>>>508 ubelong&0x8B9E8DFF      0       
+# nul, space or ascii digit 0-7 at start of mode
+>>>>100        ubyte&0xC8      =0              
+>>>>>101 ubyte&0xC8    =0              
+# nul, space at end of check sum
+>>>>>>155 ubyte&0xDF   =0      
+# space or ascii digit 0 at start of check sum
+>>>>>>>148     ubyte&0xEF      =0x20   
+>>>>>>>>0      use     tar-file
+#      minimal check and then display tar archive information which can also be
+#      embedded inside others like Android Backup, Clam AntiVirus database
+0      name            tar-file
+>257   string          !ustar          
+# header padded with nuls
+>>257  ulong           =0              
+# GNU tar version 1.29 with non pax format option without refusing
+# creates misleading V7 header for Long path, Multi-volume, Volume type
+>>>156 ubyte           0x4c            GNU tar archive
+!:mime application/x-gtar
+!:ext  tar/gtar
+>>>156 ubyte           0x4d            GNU tar archive
+!:mime application/x-gtar
+!:ext  tar/gtar
+>>>156 ubyte           0x56            GNU tar archive
+!:mime application/x-gtar
+!:ext  tar/gtar
+>>>156 default         x               tar archive (V7)
+!:mime application/x-tar
+!:ext  tar
+# other stuff in padding
+# some implementations add new fields to the blank area at the end of the header record
+# created for example by DOS TAR 3.20g 1994 Tim V.Shapore with -j option
+>>257  ulong           !0              tar archive (old)
+!:mime application/x-tar
+!:ext  tar
+# magic in newer, GNU, posix variants
+>257   string          =ustar          
+# 2 last char of magic and UStar version because string expression does not work
+# 2 space characters followed by a null for GNU variant
+>>261  ubelong         =0x72202000     POSIX tar archive (GNU)
+!:mime application/x-gtar
+!:ext  tar/gtar
+# UStar version with ASCII "00"
+>>261  ubelong         0x72003030      POSIX
+# gLOBAL and ExTENSION type only found in POSIX.1-2001 format
+>>>156 ubyte           0x67            \b.1-2001
+>>>156 ubyte           0x78            \b.1-2001
+>>>156 ubyte           x               tar archive
+!:mime application/x-ustar
+!:ext  tar/ustar
+# version with 2 binary nuls embedded in Android Backup like com.android.settings.ab
+>>261  ubelong         0x72000000      tar archive (ustar)
+!:mime application/x-ustar
+!:ext  tar/ustar
+# not seen ustar variant with garbish version
+>>261  default         x               tar archive (unknown ustar)
+!:mime application/x-ustar
+!:ext  tar/ustar
+# type flag of 1st tar archive member
+#>156  ubyte           x               \b, %c-type
+>156   ubyte           x               
+>>156  ubyte           0               \b, file
+>>156  ubyte           0x30            \b, file
+>>156  ubyte           0x31            \b, hard link
+>>156  ubyte           0x32            \b, symlink
+>>156  ubyte           0x33            \b, char device
+>>156  ubyte           0x34            \b, block device
+>>156  ubyte           0x35            \b, directory
+>>156  ubyte           0x36            \b, fifo
+>>156  ubyte           0x37            \b, reserved
+>>156  ubyte           0x4c            \b, long path
+>>156  ubyte           0x4d            \b, multi volume
+>>156  ubyte           0x56            \b, volume
+>>156  ubyte           0x67            \b, global
+>>156  ubyte           0x78            \b, extension
+>>156  default         x               \b, type
+>>>156 ubyte           x               '%c'
+# name[100]
+>0     string          >\0             %-.60s
+# mode mainly stored as an octal number in ASCII null or space terminated
+>100   string          >\0             \b, mode %-.7s
+# user id mainly as octal numbers in ASCII null or space terminated
+>108   string          >\0             \b, uid %-.7s
+# group id mainly as octal numbers in ASCII null or space terminated
+>116   string          >\0             \b, gid %-.7s
+# size mainly as octal number in ASCII
+>124   ubyte           <0x38           
+>>124  string          >\0             \b, size %-.12s
+# coding indicated by setting the high-order bit of the leftmost byte
+>124   ubyte           >0xEF           \b, size 0x
+>>124  ubyte           !0xff           \b%2.2x
+>>125  ubyte           !0xff           \b%2.2x
+>>126  ubyte           !0xff           \b%2.2x
+>>127  ubyte           !0xff           \b%2.2x
+>>128  ubyte           !0xff           \b%2.2x
+>>129  ubyte           !0xff           \b%2.2x
+>>130  ubyte           !0xff           \b%2.2x
+>>131  ubyte           !0xff           \b%2.2x
+>>132  ubyte           !0xff           \b%2.2x
+>>133  ubyte           !0xff           \b%2.2x
+>>134  ubyte           !0xff           \b%2.2x
+>>135  ubyte           !0xff           \b%2.2x
+# seconds since 0:0:0 1 jan 1970 UTC as octal number mainly in ASCII null or space terminated
+>136   string          >\0             \b, seconds %-.11s
+# header checksum stored as an octal number in ASCII null or space terminated
+#>148  string          x               \b, cksum %.7s
+# linkname[100]
+>157   string          >\0             \b, linkname %-.40s
+# additional fields for ustar
+>257   string          =ustar          
+# owner user name null terminated
+>>265  string          >\0             \b, user %-.32s
+# group name null terminated
+>>297  string          >\0             \b, group %-.32s
+# device major minor if not zero
+>>329  ubequad&0xCFCFCFCFcFcFcFdf      !0
+>>>329 string          x               \b, devmaj %-.7s
+>>337  ubequad&0xCFCFCFCFcFcFcFdf      !0
+>>>337 string          x               \b, devmin %-.7s
+# prefix[155]
+>>345  string          >\0             \b, prefix %-.155s
+# old non ustar/POSIX tar
+>257   string          !ustar          
+>>508  string          =tar\0          
+# padding[255] in old star
+>>>257 string          >\0             \b, padding: %-.40s
+>>508  default         x               
+# padding[255] in old tar sometimes comment field
+>>>257 string          >\0             \b, comment: %-.40s
+
+# Incremental snapshot gnu-tar format from:
+# https://www.gnu.org/software/tar/manual/html_node/Snapshot-Files.html
+0      string          GNU\ tar-       GNU tar incremental snapshot data
+>&0    regex           [0-9]\.[0-9]+-[0-9]+    version %s
+
+# cpio archives
+#
+# Yes, the top two "cpio archive" formats *are* supposed to just be "short".
+# The idea is to indicate archives produced on machines with the same
+# byte order as the machine running "file" with "cpio archive", and
+# to indicate archives produced on machines with the opposite byte order
+# from the machine running "file" with "byte-swapped cpio archive".
+#
+# The SVR4 "cpio(4)" hints that there are additional formats, but they
+# are defined as "short"s; I think all the new formats are
+# character-header formats and thus are strings, not numbers.
+0      short           070707          cpio archive
+!:mime application/x-cpio
+0      short           0143561         byte-swapped cpio archive
+!:mime application/x-cpio # encoding: swapped
+0      string          070707          ASCII cpio archive (pre-SVR4 or odc)
+0      string          070701          ASCII cpio archive (SVR4 with no CRC)
+0      string          070702          ASCII cpio archive (SVR4 with CRC)
+
+#
+# Various archive formats used by various versions of the "ar"
+# command.
+#
+
+#
+# Original UNIX archive formats.
+# They were written with binary values in host byte order, and
+# the magic number was a host "int", which might have been 16 bits
+# or 32 bits.  We don't say "PDP-11" or "VAX", as there might have
+# been ports to little-endian 16-bit-int or 32-bit-int platforms
+# (x86?) using some of those formats; if none existed, feel free
+# to use "PDP-11" for little-endian 16-bit and "VAX" for little-endian
+# 32-bit.  There might have been big-endian ports of that sort as
+# well.
+#
+0      leshort         0177555         very old 16-bit-int little-endian archive
+0      beshort         0177555         very old 16-bit-int big-endian archive
+0      lelong          0177555         very old 32-bit-int little-endian archive
+0      belong          0177555         very old 32-bit-int big-endian archive
+
+0      leshort         0177545         old 16-bit-int little-endian archive
+>2     string          __.SYMDEF       random library
+0      beshort         0177545         old 16-bit-int big-endian archive
+>2     string          __.SYMDEF       random library
+0      lelong          0177545         old 32-bit-int little-endian archive
+>4     string          __.SYMDEF       random library
+0      belong          0177545         old 32-bit-int big-endian archive
+>4     string          __.SYMDEF       random library
+
+#
+# From "pdp" (but why a 4-byte quantity?)
+#
+0      lelong          0x39bed         PDP-11 old archive
+0      lelong          0x39bee         PDP-11 4.0 archive
+
+#
+# XXX - what flavor of APL used this, and was it a variant of
+# some ar archive format?  It's similar to, but not the same
+# as, the APL workspace magic numbers in pdp.
+#
+0      long            0100554         apl workspace
+
+#
+# System V Release 1 portable(?) archive format.
+#
+0      string          =<ar>           System V Release 1 ar archive
+!:mime application/x-archive
+
+#
+# Debian package; it's in the portable archive format, and needs to go
+# before the entry for regular portable archives, as it's recognized as
+# a portable archive whose first member has a name beginning with
+# "debian".
+#
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Deb_(file_format)
+0      string          =!<arch>\ndebian
+# https://manpages.debian.org/testing/dpkg/dpkg-split.1.en.html
+>14    string          -split  part of multipart Debian package
+!:mime application/vnd.debian.binary-package
+# udeb is used for stripped down deb file
+!:ext  deb/udeb
+>14    string          -binary Debian binary package
+!:mime application/vnd.debian.binary-package
+!:ext  deb/udeb
+# This should not happen
+>14    default         x       Unknown Debian package
+# NL terminated version; for most Debian cases this is 2.0 or 2.1 for splitted
+>68    string          >\0             (format %s)
+#>68   string          !2.0\n
+#>>68  string          x               (format %.3s)
+>68    string          =2.0\n
+# 2nd archive name=control archive name like control.tar.gz or control.tar.xz
+>>72   string          >\0             \b, with %.14s
+# look for 3rd archive name=data archive name like data.tar.{gz,xz,bz2,lzma}
+>>0    search/0x93e4f  data.tar.       \b, data compression
+# the above line only works if FILE_BYTES_MAX in ../../src/file.h is raised
+# for example like libreoffice-dev-doc_1%3a5.2.7-1+rpi1+deb9u3_all.deb
+>>>&0  string          x               %.4s
+# splitted debian package case
+>68    string          =2.1\n
+# dpkg-1.18.25/dpkg-split/info.c
+# NL terminated ASCII package name like ckermit
+>>&0   string          x               \b, %s
+# NL terminated package version like 302-5.3
+>>>&1  string          x               %s
+# NL terminated MD5 checksum
+>>>>&1 string          x               \b, MD5 %s
+# NL terminated original package length
+>>>>>&1        string          x               \b, unsplitted size %s
+# NL terminated part length
+>>>>>>&1       string  x               \b, part lenght %s
+# NL terminated package part like n/m
+>>>>>>>&1      string  x               \b, part %s
+# NL terminated package architecture like armhf since dpkg 1.16.1 or later
+>>>>>>>>&1     string  x               \b, %s
+
+#
+# MIPS archive; they're in the portable archive format, and need to go
+# before the entry for regular portable archives, as it's recognized as
+# a portable archive whose first member has a name beginning with
+# "__________E".
+#
+0      string  =!<arch>\n__________E   MIPS archive
+!:mime application/x-archive
+>20    string  U                       with MIPS Ucode members
+>21    string  L                       with MIPSEL members
+>21    string  B                       with MIPSEB members
+>19    string  L                       and an EL hash table
+>19    string  B                       and an EB hash table
+>22    string  X                       -- out of date
+
+#
+# BSD/SVR2-and-later portable archive formats.
+#
+# Update: Joerg Jenderek
+# URL:         http://fileformats.archiveteam.org/wiki/AR
+# Reference:   https://www.unix.com/man-page/opensolaris/3HEAD/ar.h/
+# Note:                Mach-O universal binary in ./cafebabe is dependent
+# TODO:                unify current ar archive, MIPS archive, Debian package
+#              distinguish BSD, SVR; 32, 64 bit; HP from other 32-bit SVR;
+#              *.ar packages from *.a libraries. handle empty archive
+0      string          =!<arch>\n              current ar archive
+# print first and possibly second ar_name[16] for debugging purpose
+#>8                    string  x       \b, 1st "%.16s"
+#>68                   string  x       \b, 2nd "%.16s"
+!:mime application/x-archive
+# a in most case for libraries; lib for Microsoft libraries; ar else cases
+!:ext  a/lib/ar
+>8     string          __.SYMDEF       random library
+# first member with long marked name __.SYMDEF SORTED implies BSD library
+>68    string          __.SYMDEF\ SORTED       random library
+# Reference: https://parisc.wiki.kernel.org/images-parisc/b/b2/Rad_11_0_32.pdf
+# "archive file" entry moved from ./hp
+# LST header system_id 0210h~PA-RISC 1.1,... identifies the target architecture
+# LST header a_magic 0619h~relocatable library
+>68    belong          0x020b0619      - PA-RISC1.0 relocatable library
+>68    belong          0x02100619      - PA-RISC1.1 relocatable library
+>68    belong          0x02110619      - PA-RISC1.2 relocatable library
+>68    belong          0x02140619      - PA-RISC2.0 relocatable library
+#EOF for common ar archives
+
+#
+# "Thin" archive, as can be produced by GNU ar.
+#
+0      string          =!<thin>\n      thin archive with
+>68    belong          0               no symbol entries
+>68    belong          1               %d symbol entry
+>68    belong          >1              %d symbol entries
+
+0      search/1        -h-             Software Tools format archive text
+
+# ARC archiver, from Daniel Quinlan (quinlan@yggdrasil.com)
+#
+# The first byte is the magic (0x1a), byte 2 is the compression type for
+# the first file (0x01 through 0x09), and bytes 3 to 15 are the MS-DOS
+# filename of the first file (null terminated).  Since some types collide
+# we only test some types on basis of frequency: 0x08 (83%), 0x09 (5%),
+# 0x02 (5%), 0x03 (3%), 0x04 (2%), 0x06 (2%).  0x01 collides with terminfo.
+0      lelong&0x8080ffff       0x0000081a      ARC archive data, dynamic LZW
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000091a      ARC archive data, squashed
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000021a      ARC archive data, uncompressed
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000031a      ARC archive data, packed
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000041a      ARC archive data, squeezed
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000061a      ARC archive data, crunched
+!:mime application/x-arc
+# [JW] stuff taken from idarc, obviously ARC successors:
+0      lelong&0x8080ffff       0x00000a1a      PAK archive data
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000141a      ARC+ archive data
+!:mime application/x-arc
+0      lelong&0x8080ffff       0x0000481a      HYP archive data
+!:mime application/x-arc
+
+# Acorn archive formats (Disaster prone simpleton, m91dps@ecs.ox.ac.uk)
+# I can't create either SPARK or ArcFS archives so I have not tested this stuff
+# [GRR:  the original entries collide with ARC, above; replaced with combined
+#  version (not tested)]
+#0     byte            0x1a            RISC OS archive (spark format)
+0      string          \032archive     RISC OS archive (ArcFS format)
+0       string          Archive\000     RISC OS archive (ArcFS format)
+
+# All these were taken from idarc, many could not be verified. Unfortunately,
+# there were many low-quality sigs, i.e. easy to trigger false positives.
+# Please notify me of any real-world fishy/ambiguous signatures and I'll try
+# to get my hands on the actual archiver and see if I find something better. [JW]
+# probably many can be enhanced by finding some 0-byte or control char near the start
+
+# idarc calls this Crush/Uncompressed... *shrug*
+0      string  CRUSH Crush archive data
+# Squeeze It (.sqz)
+0      string  HLSQZ Squeeze It archive data
+# SQWEZ
+0      string  SQWEZ SQWEZ archive data
+# HPack (.hpk)
+0      string  HPAK HPack archive data
+# HAP
+0      string  \x91\x33HF HAP archive data
+# MD/MDCD
+0      string  MDmd MDCD archive data
+# LIM
+0      string  LIM\x1a LIM archive data
+# SAR
+3      string  LH5 SAR archive data
+# BSArc/BS2
+0      string  \212\3SB\020\0  BSArc/BS2 archive data
+# Bethesda Softworks Archive (Oblivion)
+0      string  BSA\0           BSArc archive data
+>4     lelong  x               version %d
+# MAR
+2      string  =-ah MAR archive data
+# ACB
+#0     belong&0x00f800ff       0x00800000 ACB archive data
+# CPZ
+# TODO, this is what idarc says: 0     string  \0\0\0 CPZ archive data
+# JRC
+0      string  JRchive JRC archive data
+# Quantum
+0      string  DS\0 Quantum archive data
+# ReSOF
+0      string  PK\3\6 ReSOF archive data
+# QuArk
+0      string  7\4 QuArk archive data
+# YAC
+14     string  YC YAC archive data
+# X1
+0      string  X1 X1 archive data
+0      string  XhDr X1 archive data
+# CDC Codec (.dqt)
+0      belong&0xffffe000       0x76ff2000 CDC Codec archive data
+# AMGC
+0      string  \xad6" AMGC archive data
+# NuLIB
+0      string  N\xc3\xb5F\xc3\xa9lx\xc3\xa5 NuLIB archive data
+# PakLeo
+0      string  LEOLZW PAKLeo archive data
+# ChArc
+0      string  SChF ChArc archive data
+# PSA
+0      string  PSA PSA archive data
+# CrossePAC
+0      string  DSIGDCC CrossePAC archive data
+# Freeze
+0      string  \x1f\x9f\x4a\x10\x0a Freeze archive data
+# KBoom
+0      string  \xc2\xa8MP\xc2\xa8 KBoom archive data
+# NSQ, must go after CDC Codec
+0      string  \x76\xff NSQ archive data
+# DPA
+0      string  Dirk\ Paehl DPA archive data
+# BA
+# TODO: idarc says "bytes 0-2 == bytes 3-5"
+# TTComp
+# URL: http://fileformats.archiveteam.org/wiki/TTComp_archive
+# Update: Joerg Jenderek
+# GRR: line below is too general as it matches also Panorama database "TCDB 2003-10 demo.pan", others
+0      string  \0\6
+# look for first keyword of Panorama database *.pan
+>12    search/261      DESIGN
+# skip keyword with low entropy
+>12    default         x       TTComp archive, binary, 4K dictionary
+# (version 5.25) labeled the above entry as "TTComp archive data"
+# ESP, could this conflict with Easy Software Products' (e.g.ESP ghostscript) documentation?
+0      string  ESP ESP archive data
+# ZPack
+0      string  \1ZPK\1 ZPack archive data
+# Sky
+0      string  \xbc\x40 Sky archive data
+# UFA
+0      string  UFA UFA archive data
+# Dry
+0      string  =-H2O DRY archive data
+# FoxSQZ
+0      string  FOXSQZ FoxSQZ archive data
+# AR7
+0      string  ,AR7 AR7 archive data
+# PPMZ
+0      string  PPMZ PPMZ archive data
+# MS Compress
+# Update: Joerg Jenderek
+# URL: http://fileformats.archiveteam.org/wiki/MS-DOS_installation_compression
+# Reference: https://hwiegman.home.xs4all.nl/fileformats/compress/szdd_kwaj_format.html
+# Note: use correct version of extracting tool like EXPAND, UNPACK, DECOMP or 7Z  
+4      string  \x88\xf0\x27
+#              KWAJ variant
+>0     string  KWAJ            MS Compress archive data, KWAJ variant
+!:mime application/x-ms-compress-kwaj
+# extension not working in version 5.32
+# magic/Magdir/archive, 284: Warning: EXTENSION type ` ??_' has bad char '?'
+# file: line 284: Bad magic entry '   ??_'
+!:ext  ??_
+# compression method (0-4)
+>>8    uleshort        x       \b, %u method
+# offset of compressed data
+>>10   uleshort        x       \b, 0x%x offset
+#>>(10.s)      uleshort        x
+#>>>&-6                string  x       \b, TEST extension %-.3s
+# header flags to mark header extensions
+>>12   uleshort        >0      \b, 0x%x flags
+# 4 bytes: decompressed length of file
+>>12   uleshort        &0x01
+>>>14  ulelong         x       \b, original size: %u bytes
+# 2 bytes: unknown purpose
+# 2 bytes: length of unknown data + mentioned bytes
+# 1-9 bytes: null-terminated file name
+# 1-4 bytes: null-terminated file extension
+>>12   uleshort        &0x08
+>>>12  uleshort                                ^0x01
+>>>>12         uleshort                        ^0x02
+>>>>>12                        uleshort                ^0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>14                              string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>14                              string  x       \b, %-.8s
+>>>>>>>>&1                             string  x       \b.%-.3s
+>>>>>12                        uleshort                &0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>(14.s)                  uleshort        x
+>>>>>>>>&14                            string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>(14.s)                  uleshort        x
+>>>>>>>>&14                            string  x       \b, %-.8s
+>>>>>>>>>&1                            string  x       \b.%-.3s
+>>>>12         uleshort                        &0x02
+>>>>>12                        uleshort                ^0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>16                              string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>16                              string  x       \b, %-.8s
+>>>>>>>>&1                             string  x       \b.%-.3s
+>>>>>12                        uleshort                &0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>(16.s)                  uleshort        x
+>>>>>>>>&16                            string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>(16.s)                  uleshort        x
+>>>>>>>&16                             string  x       %-.8s
+>>>>>>>>&1                             string  x       \b.%-.3s
+>>>12  uleshort                                &0x01
+>>>>12         uleshort                        ^0x02
+>>>>>12                        uleshort                ^0x04
+>>>>>>12                       uleshort        ^0x10
+>>>>>>>18                              string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>18                              string  x       \b, %-.8s
+>>>>>>>>&1                             string  x       \b.%-.3s
+>>>>>12                        uleshort                &0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>(18.s)                  uleshort        x
+>>>>>>>>&18                            string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>(18.s)                  uleshort        x
+>>>>>>>>&18                            string  x       \b, %-.8s
+>>>>>>>>>&1                            string  x       \b.%-.3s
+>>>>12         uleshort                        &0x02
+>>>>>12                        uleshort                ^0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>20                              string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>20                              string  x       \b, %-.8s
+>>>>>>>>&1                             string  x       \b.%-.3s
+>>>>>12                        uleshort                &0x04
+>>>>>>12                       uleshort        ^0x10   
+>>>>>>>(20.s)                  uleshort        x
+>>>>>>>>&20                            string  x       \b, %-.8s
+>>>>>>12                       uleshort        &0x10   
+>>>>>>>(20.s)                  uleshort        x
+>>>>>>>>&20                            string  x       \b, %-.8s
+>>>>>>>>>&1                            string  x       \b.%-.3s
+# 2 bytes: length of data + mentioned bytes
+#
+#              SZDD variant Haruhiko Okumura's LZSS or 7z type MsLZ
+>0     string  SZDD            MS Compress archive data, SZDD variant
+!:mime application/x-ms-compress-szdd
+!:ext  ??_
+# The character missing from the end of the filename (0=unknown)
+>>9    string  >\0             \b, %-.1s is last character of original name
+# https://www.betaarchive.com/forum/viewtopic.php?t=26161
+# Compression mode: "A" (0x41) found but sometimes "B" in Windows 3.1 builds 026 and 034e
+>>8    string  !A              \b, %-.1s method
+>>10   ulelong >0              \b, original size: %u bytes
+#              QBasic SZDD variant
+3      string  \x88\xf0\x27
+>0     string  SZ\x20          MS Compress archive data, QBasic variant
+!:mime application/x-ms-compress-sz
+!:ext  ??$
+>>8    ulelong >0              \b, original size: %u bytes
+
+# MP3 (archiver, not lossy audio compression)
+0      string  MP3\x1a MP3-Archiver archive data
+# ZET
+0      string  OZ\xc3\x9d ZET archive data
+# TSComp
+0      string  \x65\x5d\x13\x8c\x08\x01\x03\x00 TSComp archive data
+# ARQ
+0      string  gW\4\1 ARQ archive data
+# Squash
+3      string  OctSqu Squash archive data
+# Terse
+0      string  \5\1\1\0 Terse archive data
+# PUCrunch
+0      string  \x01\x08\x0b\x08\xef\x00\x9e\x32\x30\x36\x31 PUCrunch archive data
+# UHarc
+0      string  UHA UHarc archive data
+# ABComp
+0      string  \2AB ABComp archive data
+0      string  \3AB2 ABComp archive data
+# CMP
+0      string  CO\0 CMP archive data
+# Splint
+0      string  \x93\xb9\x06 Splint archive data
+# InstallShield
+0      string  \x13\x5d\x65\x8c InstallShield Z archive Data
+# Gather
+1      string  GTH Gather archive data
+# BOA
+0      string  BOA BOA archive data
+# RAX
+0      string  ULEB\xa RAX archive data
+# Xtreme
+0      string  ULEB\0 Xtreme archive data
+# Pack Magic
+0      string  @\xc3\xa2\1\0 Pack Magic archive data
+# BTS
+0      belong&0xfeffffff       0x1a034465 BTS archive data
+# ELI 5750
+0      string  Ora\  ELI 5750 archive data
+# QFC
+0      string  \x1aFC\x1a QFC archive data
+0      string  \x1aQF\x1a QFC archive data
+# PRO-PACK
+0      string  RNC PRO-PACK archive data
+# 777
+0      string  777 777 archive data
+# LZS221
+0      string  sTaC LZS221 archive data
+# HPA
+0      string  HPA HPA archive data
+# Arhangel
+0      string  LG Arhangel archive data
+# EXP1, uses bzip2
+0      string  0123456789012345BZh EXP1 archive data
+# IMP
+0      string  IMP\xa IMP archive data
+# NRV
+0      string  \x00\x9E\x6E\x72\x76\xFF NRV archive data
+# Squish
+0      string  \x73\xb2\x90\xf4 Squish archive data
+# Par
+0      string  PHILIPP Par archive data
+0      string  PAR Par archive data
+# HIT
+0      string  UB HIT archive data
+# SBX
+0      belong&0xfffff000       0x53423000 SBX archive data
+# NaShrink
+0      string  NSK NaShrink archive data
+# SAPCAR
+0      string  #\ CAR\ archive\ header SAPCAR archive data
+0      string  CAR\ 2.00RG SAPCAR archive data
+# Disintegrator
+0      string  DST Disintegrator archive data
+# ASD
+0      string  ASD ASD archive data
+# InstallShield CAB
+0      string  ISc( InstallShield CAB
+# TOP4
+0      string  T4\x1a TOP4 archive data
+# BatComp left out: sig looks like COM executable
+# so TODO: get real 4dos batcomp file and find sig
+# BlakHole
+0      string  BH\5\7 BlakHole archive data
+# BIX
+0      string  BIX0 BIX archive data
+# ChiefLZA
+0      string  ChfLZ ChiefLZA archive data
+# Blink
+0      string  Blink Blink archive data
+# Logitech Compress
+0      string  \xda\xfa Logitech Compress archive data
+# ARS-Sfx (FIXME: really a SFX? then goto COM/EXE)
+1      string  (C)\ STEPANYUK ARS-Sfx archive data
+# AKT/AKT32
+0      string  AKT32 AKT32 archive data
+0      string  AKT AKT archive data
+# NPack
+0      string  MSTSM NPack archive data
+# PFT
+0      string  \0\x50\0\x14 PFT archive data
+# SemOne
+0      string  SEM SemOne archive data
+# PPMD
+0      string  \x8f\xaf\xac\x84 PPMD archive data
+# FIZ
+0      string  FIZ FIZ archive data
+# MSXiE
+0      belong&0xfffff0f0       0x4d530000 MSXiE archive data
+# DeepFreezer
+0      belong&0xfffffff0       0x797a3030 DeepFreezer archive data
+# DC
+0      string  =<DC- DC archive data
+# TPac
+0      string  \4TPAC\3 TPac archive data
+# Ai
+0      string  Ai\1\1\0 Ai archive data
+0      string  Ai\1\0\0 Ai archive data
+# Ai32
+0      string  Ai\2\0 Ai32 archive data
+0      string  Ai\2\1 Ai32 archive data
+# SBC
+0      string  SBC SBC archive data
+# Ybs
+0      string  YBS Ybs archive data
+# DitPack
+0      string  \x9e\0\0 DitPack archive data
+# DMS
+0      string  DMS! DMS archive data
+# EPC
+0      string  \x8f\xaf\xac\x8c EPC archive data
+# VSARC
+0      string  VS\x1a VSARC archive data
+# PDZ
+0      string  PDZ PDZ archive data
+# ReDuq
+0      string  rdqx ReDuq archive data
+# GCA
+0      string  GCAX GCA archive data
+# PPMN
+0      string  pN PPMN archive data
+# WinImage
+3      string  WINIMAGE WinImage archive data
+# Compressia
+0      string  CMP0CMP Compressia archive data
+# UHBC
+0      string  UHB UHBC archive data
+# WinHKI
+0      string  \x61\x5C\x04\x05 WinHKI archive data
+# WWPack data file
+0      string  WWP WWPack archive data
+# BSN (BSA, PTS-DOS)
+0      string  \xffBSG BSN archive data
+1      string  \xffBSG BSN archive data
+3      string  \xffBSG BSN archive data
+1      string  \0\xae\2 BSN archive data
+1      string  \0\xae\3 BSN archive data
+1      string  \0\xae\7 BSN archive data
+# AIN
+0      string  \x33\x18 AIN archive data
+0      string  \x33\x17 AIN archive data
+# XPA32 test moved and merged with XPA by Joerg Jenderek at Sep 2015
+# SZip (TODO: doesn't catch all versions)
+0      string  SZ\x0a\4 SZip archive data
+# XPack DiskImage
+# *.XDI updated by Joerg Jenderek Sep 2015
+# ftp://ftp.sac.sk/pub/sac/pack/0index.txt
+# GRR: this test is still too general as it catches also text files starting with jm
+0      string  jm
+# only found examples with this additional characteristic 2 bytes
+>2     string  \x2\x4  Xpack DiskImage archive data
+#!:ext xdi
+# XPack Data
+# *.xpa updated by Joerg Jenderek Sep 2015
+# ftp://ftp.elf.stuba.sk/pub/pc/pack/
+0      string  xpa     XPA
+!:ext  xpa
+# XPA32
+# ftp://ftp.elf.stuba.sk/pub/pc/pack/xpa32.zip
+# created by XPA32.EXE version 1.0.2 for Windows
+>0     string  xpa\0\1 \b32 archive data
+# created by XPACK.COM version 1.67m or 1.67r with short 0x1800
+>3     ubeshort        !0x0001 \bck archive data
+# XPack Single Data
+# changed by Joerg Jenderek Sep 2015 back to like in version 5.12
+# letter 'I'+ acute accent is equivalent to \xcd
+0      string  \xcd\ jm        Xpack single archive data
+#!:mime        application/x-xpa-compressed
+!:ext xpa
+
+# TODO: missing due to unknown magic/magic at end of file:
+#DWC
+#ARG
+#ZAR
+#PC/3270
+#InstallIt
+#RKive
+#RK
+#XPack Diskimage
+
+# These were inspired by idarc, but actually verified
+# Dzip archiver (.dz)
+# Update: Joerg Jenderek
+# URL: http://speeddemosarchive.com/dzip/
+# reference: http://speeddemosarchive.com/dzip/dz29src.zip/main.c 
+# GRR: line below is too general as it matches also ASCII texts like Doszip commander help dz.txt
+0      string  DZ 
+# latest version is 2.9 dated 7 may 2003
+>2     byte    <4 Dzip archive data
+!:mime application/x-dzip
+!:ext  dz
+>>2    byte    x \b, version %i
+>>3    byte    x \b.%i
+>>4    ulelong x \b, offset 0x%x
+>>8    ulelong x \b, %u files
+# ZZip archiver (.zz)
+0      string  ZZ\ \0\0 ZZip archive data
+0      string  ZZ0 ZZip archive data
+# PAQ archiver (.paq)
+0      string  \xaa\x40\x5f\x77\x1f\xe5\x82\x0d PAQ archive data
+0      string  PAQ PAQ archive data
+>3     byte&0xf0       0x30
+>>3    byte    x (v%c)
+# JAR archiver (.j), this is the successor to ARJ, not Java's JAR (which is essentially ZIP)
+0xe    string  \x1aJar\x1b JAR (ARJ Software, Inc.) archive data
+0      string  JARCS JAR (ARJ Software, Inc.) archive data
+
+# ARJ archiver (jason@jarthur.Claremont.EDU)
+0      leshort         0xea60          ARJ archive data
+!:mime application/x-arj
+>5     byte            x               \b, v%d,
+>8     byte            &0x04           multi-volume,
+>8     byte            &0x10           slash-switched,
+>8     byte            &0x20           backup,
+>34    string          x               original name: %s,
+>7     byte            0               os: MS-DOS
+>7     byte            1               os: PRIMOS
+>7     byte            2               os: Unix
+>7     byte            3               os: Amiga
+>7     byte            4               os: Macintosh
+>7     byte            5               os: OS/2
+>7     byte            6               os: Apple ][ GS
+>7     byte            7               os: Atari ST
+>7     byte            8               os: NeXT
+>7     byte            9               os: VAX/VMS
+>3     byte            >0              %d]
+# [JW] idarc says this is also possible
+2      leshort         0xea60          ARJ archive data
+
+# HA archiver (Greg Roelofs, newt@uchicago.edu)
+# This is a really bad format. A file containing HAWAII will match this...
+#0     string          HA              HA archive data,
+#>2    leshort         =1              1 file,
+#>2    leshort         >1              %hu files,
+#>4    byte&0x0f       =0              first is type CPY
+#>4    byte&0x0f       =1              first is type ASC
+#>4    byte&0x0f       =2              first is type HSC
+#>4    byte&0x0f       =0x0e           first is type DIR
+#>4    byte&0x0f       =0x0f           first is type SPECIAL
+# suggestion: at least identify small archives (<1024 files)
+0  belong&0xffff00fc 0x48410000 HA archive data
+>2     leshort         =1              1 file,
+>2     leshort         >1              %u files,
+>4     byte&0x0f       =0              first is type CPY
+>4     byte&0x0f       =1              first is type ASC
+>4     byte&0x0f       =2              first is type HSC
+>4     byte&0x0f       =0x0e           first is type DIR
+>4     byte&0x0f       =0x0f           first is type SPECIAL
+
+# HPACK archiver (Peter Gutmann, pgut1@cs.aukuni.ac.nz)
+0      string          HPAK            HPACK archive data
+
+# JAM Archive volume format, by Dmitry.Kohmanyuk@UA.net
+0      string          \351,\001JAM\           JAM archive,
+>7     string          >\0                     version %.4s
+>0x26  byte            =0x27                   -
+>>0x2b string          >\0                     label %.11s,
+>>0x27 lelong          x                       serial %08x,
+>>0x36 string          >\0                     fstype %.8s
+
+# LHARC/LHA archiver (Greg Roelofs, newt@uchicago.edu)
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/LHA_(file_format)
+# Reference: https://web.archive.org/web/20021005080911/http://www.osirusoft.com/joejared/lzhformat.html
+#
+#      check and display information of lharc (LHa,PMarc) file
+0      name                            lharc-file
+# check 1st character of method id like -lz4- -lh5- or -pm2-
+>2     string          -
+# check 5th character of method id
+>>6    string          -
+# check header level 0 1 2 3
+>>>20  ubyte           <4
+# check 2nd, 3th and 4th character of method id
+>>>>3  regex           \^(lh[0-9a-ex]|lz[s2-8]|pm[012]|pc1)            \b 
+!:mime application/x-lzh-compressed
+# creator type "LHA "
+!:apple        ????LHA
+# display archive type name like "LHa/LZS archive data" or "LArc archive"
+>>>>>2 string          -lz             \b 
+!:ext  lzs
+# already known  -lzs- -lz4- -lz5- with old names
+>>>>>>2        string  -lzs            LHa/LZS archive data
+>>>>>>3        regex   \^lz[45]        LHarc 1.x archive data
+# missing -lz?- with wikipedia names
+>>>>>>3        regex   \^lz[2378]      LArc archive
+# display archive type name like "LHa (2.x) archive data"
+>>>>>2 string          -lh             \b
+# already known -lh0- -lh1- -lh2- -lh3-  -lh4- -lh5- -lh6- -lh7- -lhd- variants with old names
+>>>>>>3        regex           \^lh[01]        LHarc 1.x/ARX archive data
+# LHice archiver use ".ICE" as name extension instead usual one ".lzh"
+# FOOBAR archiver use ".foo" as name extension instead usual one
+# "Florain Orjanov's and Olga Bachetska's ARchiver" not found at the moment
+>>>>>>>2       string  -lh1            \b 
+!:ext lha/lzh/ice
+>>>>>>3        regex           \^lh[23d]       LHa 2.x? archive data
+>>>>>>3        regex           \^lh[7]         LHa (2.x)/LHark archive data
+>>>>>>3        regex           \^lh[456]       LHa (2.x) archive data
+>>>>>>>2       string  -lh5            \b 
+# https://en.wikipedia.org/wiki/BIOS
+# Some mainboard BIOS like Award use LHa compression. So archives with unusal extension are found like
+# bios.rom , kd7_v14.bin, 1010.004, ...
+!:ext lha/lzh/rom/bin
+# missing -lh?- variants (Joe Jared)
+>>>>>>3        regex           \^lh[89a-ce]    LHa (Joe Jared) archive
+# UNLHA32 2.67a
+>>>>>>2        string          -lhx            LHa (UNLHA32) archive
+# lha archives with standard file name extensions ".lha" ".lzh"
+>>>>>>3        regex           !\^(lh1|lh5)    \b 
+!:ext lha/lzh
+# this should not happen if all -lh variants are described
+>>>>>>2        default         x               LHa (unknown) archive
+#!:ext lha
+# PMarc
+>>>>>3 regex           \^pm[012]       PMarc archive data
+!:ext pma
+# append method id without leading and trailing minus character
+>>>>>3 string          x               [%3.3s]
+>>>>>>0        use     lharc-header
+#
+#      check and display information of lharc header
+0      name                            lharc-header
+# header size 0x4 , 0x1b-0x61
+>0     ubyte           x
+# compressed data size != compressed file size
+#>7    ulelong         x               \b, data size %d
+# attribute: 0x2~?? 0x10~symlink|target 0x20~normal
+#>19   ubyte           x               \b, 19_0x%x
+# level identifier 0 1 2 3
+#>20   ubyte           x               \b, level %d
+# time stamp
+#>15           ubelong x               DATE 0x%8.8x
+# OS ID for level 1
+>20    ubyte           1
+# 0x20 types find for *.rom files
+>>(21.b+24)    ubyte   <0x21           \b, 0x%x OS
+# ascii type like M for MSDOS
+>>(21.b+24)    ubyte   >0x20           \b, '%c' OS
+# OS ID for level 2
+>20    ubyte           2
+#>>23  ubyte           x               \b, OS ID 0x%x
+>>23   ubyte           <0x21           \b, 0x%x OS
+>>23   ubyte           >0x20           \b, '%c' OS
+# filename only for level 0 and 1
+>20    ubyte           <2
+# length of filename
+>>21           ubyte   >0              \b, with
+# filename
+>>>21          pstring x               "%s"
+#
+#2     string          -lh0-           LHarc 1.x/ARX archive data [lh0]
+#!:mime        application/x-lharc
+2      string          -lh0-
+>0     use     lharc-file
+#2     string          -lh1-           LHarc 1.x/ARX archive data [lh1]
+#!:mime        application/x-lharc
+2      string          -lh1-
+>0     use     lharc-file
+# NEW -lz2- ... -lz8-
+2      string          -lz2-
+>0     use     lharc-file
+2      string          -lz3-
+>0     use     lharc-file
+2      string          -lz4-
+>0     use     lharc-file
+2      string          -lz5-
+>0     use     lharc-file
+2      string          -lz7-
+>0     use     lharc-file
+2      string          -lz8-
+>0     use     lharc-file
+#      [never seen any but the last; -lh4- reported in comp.compression:]
+#2     string          -lzs-           LHa/LZS archive data [lzs]
+2      string          -lzs-
+>0     use     lharc-file
+# According to wikipedia and others such a version does not exist
+#2     string          -lh\40-         LHa 2.x? archive data [lh ]
+#2     string          -lhd-           LHa 2.x? archive data [lhd]
+2      string          -lhd-
+>0     use     lharc-file
+#2     string          -lh2-           LHa 2.x? archive data [lh2]
+2      string          -lh2-
+>0     use     lharc-file
+#2     string          -lh3-           LHa 2.x? archive data [lh3]
+2      string          -lh3-
+>0     use     lharc-file
+#2     string          -lh4-           LHa (2.x) archive data [lh4]
+2      string          -lh4-
+>0     use     lharc-file
+#2     string          -lh5-           LHa (2.x) archive data [lh5]
+2      string          -lh5-
+>0     use     lharc-file
+#2     string          -lh6-           LHa (2.x) archive data [lh6]
+2      string          -lh6-
+>0     use     lharc-file
+#2     string          -lh7-           LHa (2.x)/LHark archive data [lh7]
+2      string          -lh7-
+# !:mime       application/x-lha
+# >20  byte            x               - header level %d
+>0     use     lharc-file
+# NEW -lh8- ... -lhe- , -lhx-
+2      string          -lh8-
+>0     use     lharc-file
+2      string          -lh9-
+>0     use     lharc-file
+2      string          -lha-
+>0     use     lharc-file
+2      string          -lhb-
+>0     use     lharc-file
+2      string          -lhc-
+>0     use     lharc-file
+2      string          -lhe-
+>0     use     lharc-file
+2      string          -lhx-
+>0     use     lharc-file
+# taken from idarc [JW]
+2   string      -lZ         PUT archive data
+# already done by LHarc magics
+# this should never happen if all sub types of LZS archive are identified
+#2   string      -lz         LZS archive data
+2   string      -sw1-       Swag archive data
+
+0      name            rar-file-header
+>24    byte            15              \b, v1.5
+>24    byte            20              \b, v2.0
+>24    byte            29              \b, v4
+>15    byte            0               \b, os: MS-DOS
+>15    byte            1               \b, os: OS/2
+>15    byte            2               \b, os: Win32
+>15    byte            3               \b, os: Unix
+>15    byte            4               \b, os: Mac OS
+>15    byte            5               \b, os: BeOS
+
+0      name            rar-archive-header
+>3     leshort&0x1ff   >0              \b, flags:
+>>3    leshort         &0x01           ArchiveVolume
+>>3    leshort         &0x02           Commented
+>>3    leshort         &0x04           Locked
+>>3    leshort         &0x10           NewVolumeNaming
+>>3    leshort         &0x08           Solid
+>>3    leshort         &0x20           Authenticated
+>>3    leshort         &0x40           RecoveryRecordPresent
+>>3    leshort         &0x80           EncryptedBlockHeader
+>>3    leshort         &0x100          FirstVolume
+
+# RAR (Roshal Archive) archive
+0      string          Rar!\x1a\7\0            RAR archive data
+!:mime application/x-rar
+!:ext  rar/cbr
+# file header
+>(0xc.l+9)     byte    0x74
+>>(0xc.l+7)    use     rar-file-header
+# subblock seems to share information with file header
+>(0xc.l+9)     byte    0x7a
+>>(0xc.l+7)    use     rar-file-header
+>9             byte    0x73
+>>7            use     rar-archive-header
+
+0      string          Rar!\x1a\7\1\0          RAR archive data, v5
+!:mime application/x-rar
+!:ext  rar
+
+# Very old RAR archive
+# https://jasonblanks.com/wp-includes/images/papers/KnowyourarchiveRAR.pdf
+0      string          RE\x7e\x5e  RAR archive data (<v1.5)
+!:mime application/x-rar
+!:ext  rar/cbr
+
+# SQUISH archiver (Greg Roelofs, newt@uchicago.edu)
+0      string          SQSH            squished archive data (Acorn RISCOS)
+
+# UC2 archiver (Greg Roelofs, newt@uchicago.edu)
+# [JW] see exe section for self-extracting version
+0      string          UC2\x1a         UC2 archive data
+
+# PKZIP multi-volume archive
+0      string          PK\x07\x08PK\x03\x04    Zip multi-volume archive data, at least PKZIP v2.50 to extract
+!:mime application/zip
+!:ext zip/cbz
+
+# Zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
+0      string          PK\005\006      Zip archive data (empty)
+!:mime application/zip
+!:ext zip/cbz
+!:strength +1
+0      string          PK\003\004
+!:strength +1
+
+# Specialised zip formats which start with a member named 'mimetype'
+# (stored uncompressed, with no 'extra field') containing the file's MIME type.
+# Check for have 8-byte name, 0-byte extra field, name "mimetype", and
+#  contents starting with "application/":
+>26    string          \x8\0\0\0mimetypeapplication/
+
+#  KOffice / OpenOffice & StarOffice / OpenDocument formats
+#    From: Abel Cheung <abel@oaka.org>
+
+#   KOffice (1.2 or above) formats
+#    (mimetype contains "application/vnd.kde.<SUBTYPE>")
+>>50   string  vnd.kde.                KOffice (>=1.2)
+>>>58  string  karbon                  Karbon document
+>>>58  string  kchart                  KChart document
+>>>58  string  kformula                KFormula document
+>>>58  string  kivio                   Kivio document
+>>>58  string  kontour                 Kontour document
+>>>58  string  kpresenter              KPresenter document
+>>>58  string  kspread                 KSpread document
+>>>58  string  kword                   KWord document
+
+#   OpenOffice formats (for OpenOffice 1.x / StarOffice 6/7)
+#    (mimetype contains "application/vnd.sun.xml.<SUBTYPE>")
+>>50   string  vnd.sun.xml.            OpenOffice.org 1.x
+>>>62  string  writer                  Writer
+>>>>68 byte    !0x2e                   document
+>>>>68 string  .template               template
+>>>>68 string  .global                 global document
+>>>62  string  calc                    Calc
+>>>>66 byte    !0x2e                   spreadsheet
+>>>>66 string  .template               template
+>>>62  string  draw                    Draw
+>>>>66 byte    !0x2e                   document
+>>>>66 string  .template               template
+>>>62  string  impress                 Impress
+>>>>69 byte    !0x2e                   presentation
+>>>>69 string  .template               template
+>>>62  string  math                    Math document
+>>>62  string  base                    Database file
+
+#   OpenDocument formats (for OpenOffice 2.x / StarOffice >= 8)
+#    https://lists.oasis-open.org/archives/office/200505/msg00006.html
+#    (mimetype contains "application/vnd.oasis.opendocument.<SUBTYPE>")
+>>50   string  vnd.oasis.opendocument. OpenDocument
+>>>73  string  text
+>>>>77 byte    !0x2d                   Text
+!:mime application/vnd.oasis.opendocument.text
+>>>>77 string  -template               Text Template
+!:mime application/vnd.oasis.opendocument.text-template
+>>>>77 string  -web                    HTML Document Template
+!:mime application/vnd.oasis.opendocument.text-web
+>>>>77 string  -master                 Master Document
+!:mime application/vnd.oasis.opendocument.text-master
+>>>73  string  graphics
+>>>>81 byte    !0x2d                   Drawing
+!:mime application/vnd.oasis.opendocument.graphics
+>>>>81 string  -template               Template
+!:mime application/vnd.oasis.opendocument.graphics-template
+>>>73  string  presentation
+>>>>85 byte    !0x2d                   Presentation
+!:mime application/vnd.oasis.opendocument.presentation
+>>>>85 string  -template               Template
+!:mime application/vnd.oasis.opendocument.presentation-template
+>>>73  string  spreadsheet
+>>>>84 byte    !0x2d                   Spreadsheet
+!:mime application/vnd.oasis.opendocument.spreadsheet
+>>>>84 string  -template               Template
+!:mime application/vnd.oasis.opendocument.spreadsheet-template
+>>>73  string  chart
+>>>>78 byte    !0x2d                   Chart
+!:mime application/vnd.oasis.opendocument.chart
+>>>>78 string  -template               Template
+!:mime application/vnd.oasis.opendocument.chart-template
+>>>73  string  formula
+>>>>80 byte    !0x2d                   Formula
+!:mime application/vnd.oasis.opendocument.formula
+>>>>80 string  -template               Template
+!:mime application/vnd.oasis.opendocument.formula-template
+>>>73  string  database                Database
+!:mime application/vnd.oasis.opendocument.database
+# Valid for LibreOffice Base 6.0.1.1 at least
+>>>73  string  base                    Database
+!:mime application/vnd.oasis.opendocument.base
+>>>73  string  image
+>>>>78 byte    !0x2d                   Image
+!:mime application/vnd.oasis.opendocument.image
+>>>>78 string  -template               Template
+!:mime application/vnd.oasis.opendocument.image-template
+
+#  EPUB (OEBPS) books using OCF (OEBPS Container Format)
+#    https://www.idpf.org/ocf/ocf1.0/download/ocf10.htm, section 4.
+#    From: Ralf Brown <ralf.brown@gmail.com>
+>>50   string  epub+zip        EPUB document
+!:mime application/epub+zip
+
+#  Catch other ZIP-with-mimetype formats
+#      In a ZIP file, the bytes immediately after a member's contents are
+#      always "PK". The 2 regex rules here print the "mimetype" member's
+#      contents up to the first 'P'. Luckily, most MIME types don't contain
+#      any capital 'P's. This is a kludge.
+#    (mimetype contains "application/<OTHER>")
+>>50           string  !epub+zip
+>>>50          string  !vnd.oasis.opendocument.
+>>>>50         string  !vnd.sun.xml.
+>>>>>50                string  !vnd.kde.
+>>>>>>38       regex   [!-OQ-~]+               Zip data (MIME type "%s"?)
+!:mime application/zip
+#    (mimetype contents other than "application/*")
+>26            string  \x8\0\0\0mimetype
+>>38           string  !application/
+>>>38          regex   [!-OQ-~]+               Zip data (MIME type "%s"?)
+!:mime application/zip
+
+# Java Jar files
+>(26.s+30)     leshort 0xcafe          Java archive data (JAR)
+!:mime application/java-archive
+
+# iOS App
+>(26.s+30)     leshort !0xcafe
+>>26           string  !\x8\0\0\0mimetype
+>>>30          string  Payload/
+>>>>38         search/64       .app/   iOS App
+!:mime application/x-ios-app
+
+
+# Generic zip archives (Greg Roelofs, c/o zip-bugs@wkuvx1.wku.edu)
+#   Next line excludes specialized formats:
+>(26.s+30)     leshort !0xcafe
+>>26    string          !\x8\0\0\0mimetype     Zip archive data
+!:mime application/zip
+>>>4   beshort         x                       \b, at least
+>>>4   use             zipversion
+>>>4   beshort         x                       to extract
+>>>0x161       string          WINZIP          \b, WinZIP self-extracting
+
+# StarView Metafile
+# From Pierre Ducroquet <pinaraf@pinaraf.info>
+0      string  VCLMTF  StarView MetaFile
+>6     beshort x       \b, version %d
+>8     belong  x       \b, size %d
+
+# Zoo archiver
+20     lelong          0xfdc4a7dc      Zoo archive data
+!:mime application/x-zoo
+>4     byte            >48             \b, v%c.
+>>6    byte            >47             \b%c
+>>>7   byte            >47             \b%c
+>32    byte            >0              \b, modify: v%d
+>>33   byte            x               \b.%d+
+>42    lelong          0xfdc4a7dc      \b,
+>>70   byte            >0              extract: v%d
+>>>71  byte            x               \b.%d+
+
+# Shell archives
+10     string          #\ This\ is\ a\ shell\ archive  shell archive text
+!:mime application/octet-stream
+
+#
+# LBR. NB: May conflict with the questionable
+#          "binary Computer Graphics Metafile" format.
+#
+0       string  \0\ \ \ \ \ \ \ \ \ \ \ \0\0    LBR archive data
+#
+# PMA (CP/M derivative of LHA)
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/LHA_(file_format)
+#
+#2       string          -pm0-           PMarc archive data [pm0]
+2      string          -pm0-
+>0     use     lharc-file
+#2       string          -pm1-           PMarc archive data [pm1]
+2      string          -pm1-
+>0     use     lharc-file
+#2       string          -pm2-           PMarc archive data [pm2]
+2      string          -pm2-
+>0     use     lharc-file
+2       string          -pms-           PMarc SFX archive (CP/M, DOS)
+#!:mime        application/x-foobar-exec
+!:ext com
+5       string          -pc1-           PopCom compressed executable (CP/M)
+#!:mime        application/x-
+#!:ext com
+
+# From Rafael Laboissiere <rafael@laboissiere.net>
+# The Project Revision Control System (see
+# http://prcs.sourceforge.net) generates a packaged project
+# file which is recognized by the following entry:
+0      leshort         0xeb81  PRCS packaged project
+
+# Microsoft cabinets
+# by David Necas (Yeti) <yeti@physics.muni.cz>
+#0     string  MSCF\0\0\0\0    Microsoft cabinet file data,
+#>25   byte    x               v%d
+#>24   byte    x               \b.%d
+# MPi: All CABs have version 1.3, so this is pointless.
+# Better magic in debian-additions.
+
+# GTKtalog catalogs
+# by David Necas (Yeti) <yeti@physics.muni.cz>
+4      string  gtktalog\       GTKtalog catalog data,
+>13    string  3               version 3
+>>14   beshort 0x677a          (gzipped)
+>>14   beshort !0x677a         (not gzipped)
+>13    string  >3              version %s
+
+############################################################################
+# Parity archive reconstruction file, the 'par' file format now used on Usenet.
+0       string          PAR\0  PARity archive data
+>48    leshort         =0      - Index file
+>48    leshort         >0      - file number %d
+
+# Felix von Leitner <felix-file@fefe.de>
+0      string  d8:announce     BitTorrent file
+!:mime application/x-bittorrent
+# Durval Menezes, <jmgthbfile at durval dot com>
+0      string  d13:announce-list       BitTorrent file
+!:mime application/x-bittorrent
+
+# Atari MSA archive - Teemu Hukkanen <tjhukkan@iki.fi>
+0      beshort 0x0e0f          Atari MSA archive data
+>2     beshort x               \b, %d sectors per track
+>4     beshort 0               \b, 1 sided
+>4     beshort 1               \b, 2 sided
+>6     beshort x               \b, starting track: %d
+>8     beshort x               \b, ending track: %d
+
+# Alternate ZIP string (amc@arwen.cs.berkeley.edu)
+0      string  PK00PK\003\004  Zip archive data
+!:mime application/zip
+!:ext zip/cbz
+
+# ACE archive (from http://www.wotsit.org/download.asp?f=ace)
+# by Stefan `Sec` Zehl <sec@42.org>
+7      string          **ACE**         ACE archive data
+>15    byte    >0              version %d
+>16    byte    =0x00           \b, from MS-DOS
+>16    byte    =0x01           \b, from OS/2
+>16    byte    =0x02           \b, from Win/32
+>16    byte    =0x03           \b, from Unix
+>16    byte    =0x04           \b, from MacOS
+>16    byte    =0x05           \b, from WinNT
+>16    byte    =0x06           \b, from Primos
+>16    byte    =0x07           \b, from AppleGS
+>16    byte    =0x08           \b, from Atari
+>16    byte    =0x09           \b, from Vax/VMS
+>16    byte    =0x0A           \b, from Amiga
+>16    byte    =0x0B           \b, from Next
+>14    byte    x               \b, version %d to extract
+>5     leshort &0x0080         \b, multiple volumes,
+>>17   byte    x               \b (part %d),
+>5     leshort &0x0002         \b, contains comment
+>5     leshort &0x0200         \b, sfx
+>5     leshort &0x0400         \b, small dictionary
+>5     leshort &0x0800         \b, multi-volume
+>5     leshort &0x1000         \b, contains AV-String
+>>30   string  \x16*UNREGISTERED\x20VERSION*   (unregistered)
+>5     leshort &0x2000         \b, with recovery record
+>5     leshort &0x4000         \b, locked
+>5     leshort &0x8000         \b, solid
+# Date in MS-DOS format (whatever that is)
+#>18   lelong  x               Created on
+
+# sfArk : compression program for Soundfonts (sf2) by Dirk Jagdmann
+# <doj@cubic.org>
+0x1A   string  sfArk           sfArk compressed Soundfont
+>0x15  string  2
+>>0x1  string  >\0             Version %s
+>>0x2A string  >\0             : %s
+
+# DR-DOS 7.03 Packed File *.??_
+0      string  Packed\ File\   Personal NetWare Packed File
+>12    string  x               \b, was "%.12s"
+
+# EET archive
+# From: Tilman Sauerbeck <tilman@code-monkey.de>
+0      belong  0x1ee7ff00      EET archive
+!:mime application/x-eet
+
+# rzip archives
+0      string  RZIP            rzip compressed data
+>4     byte    x               - version %d
+>5     byte    x               \b.%d
+>6     belong  x               (%d bytes)
+
+# From:                Joerg Jenderek
+# URL:         https://help.foxitsoftware.com/kb/install-fzip-file.php
+# reference:   http://mark0.net/download/triddefs_xml.7z/
+#              defs/f/fzip.trid.xml
+# Note: unknown compression; No "PK" zip magic; normally in directory like
+#      "%APPDATA%\Foxit Software\Addon\Foxit Reader\Install"
+0      ubequad 0x2506781901010000      Foxit add-on/update
+!:mime application/x-fzip
+!:ext  fzip
+
+# From: "Robert Dale" <robdale@gmail.com>
+0      belong  123             dar archive,
+>4     belong  x               label "%.8x
+>>8    belong  x               %.8x
+>>>12  beshort x               %.4x"
+>14    byte    0x54            end slice
+>14    beshort 0x4e4e          multi-part
+>14    beshort 0x4e53          multi-part, with -S
+
+# Symbian installation files
+#  https://www.thouky.co.uk/software/psifs/sis.html
+#  http://developer.symbian.com/main/downloads/papers/SymbianOSv91/softwareinstallsis.pdf
+8      lelong  0x10000419      Symbian installation file
+!:mime application/vnd.symbian.install
+>4     lelong  0x1000006D      (EPOC release 3/4/5)
+>4     lelong  0x10003A12      (EPOC release 6)
+0      lelong  0x10201A7A      Symbian installation file (Symbian OS 9.x)
+!:mime x-epoc/x-sisx-app
+
+# From "Nelson A. de Oliveira" <naoliv@gmail.com>
+0      string  MPQ\032         MoPaQ (MPQ) archive
+
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+# .kgb
+0      string KGB_arch         KGB Archiver file
+>10    string x                with compression level %.1s
+
+# xar (eXtensible ARchiver) archive
+# URL: https://en.wikipedia.org/wiki/Xar_(archiver)
+# xar archive format: https://code.google.com/p/xar/
+# From: "David Remahl" <dremahl@apple.com>
+# Update: Joerg Jenderek
+# TODO: lzma compression; X509Data for pkg and xip
+# Note: verified by `xar --dump-header -f FullBundleUpdate.xar` or
+# 7z t -txar Xcode_10.2_beta_4.xip`
+0      string  xar!            xar archive
+!:mime application/x-xar
+# pkg for Mac OSX installer package like FullBundleUpdate.pkg
+# xip for signed Apple software like Xcode_10.2_beta_4.xip
+!:ext  xar/pkg/xip
+# always 28 in older archives
+>4     ubeshort >28            \b, header size %u
+# currently there exit only version 1 since about 2014
+>6     ubeshort >1             version %u,
+>8     ubequad x               compressed TOC: %llu,
+#>16   ubequad x               uncompressed TOC: %llu,
+# cksum_alg 0-2 in older and also 3-4 in newer
+>24    belong  0               no checksum
+>24    belong  1               SHA-1 checksum
+>24    belong  2               MD5 checksum
+>24    belong  3               SHA-256 checksum
+>24    belong  4               SHA-512 checksum
+>24    belong  >4              unknown 0x%x checksum
+#>24   belong  >4              checksum
+#                      For no compression jump 0 bytes
+>24    belong  0
+>>0            ubyte   x
+# jump more bytes forward by header size
+>>>&(4.S)      ubyte   x
+# jump more bytes forward by compressed table of contents size
+#>>>>&(8.Q)    ubequad x       \b, heap data 0x%llx
+>>>>&(8.Q)     ubyte   x
+# look for data by ./compress after message with 1 space at end
+>>>>>&-3       indirect x      \b, contains 
+#                      For SHA-1 jump 20 minus 2 bytes
+>24    belong  1
+>>18           ubyte   x
+# jump more bytes forward by header size
+>>>&(4.S)      ubyte   x
+# jump more bytes forward by compressed table of contents size
+>>>>&(8.Q)     ubyte   x
+# data compressed by gzip, bzip, lzma or none
+>>>>>&-1       indirect x      \b, contains 
+#                      For SHA-256 jump 32 minus 2 bytes
+>24    belong  3
+>>30           ubyte   x
+# jump more bytes forward by header size
+>>>&(4.S)      ubyte   x
+# jump more bytes forward by compressed table of contents size
+>>>>&(8.Q)     ubyte   x
+>>>>>&-1       indirect x      \b, contains 
+#                      For SHA-512 jump 64 minus 2 bytes
+>24    belong  4
+>>62           ubyte   x
+# jump more bytes forward by header size
+>>>&(4.S)      ubyte   x
+# jump more bytes forward by compressed table of contents size
+>>>>&(8.Q)     ubyte   x
+>>>>>&-1       indirect x      \b, contains 
+
+# Type: Parity Archive
+# From: Daniel van Eeden <daniel_e@dds.nl>
+0      string  PAR2            Parity Archive Volume Set
+
+# Bacula volume format. (Volumes always start with a block header.)
+# URL: https://bacula.org/3.0.x-manuals/en/developers/developers/Block_Header.html
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+12     string  BB02            Bacula volume
+>20    bedate  x               \b, started %s
+
+# ePub is XHTML + XML inside a ZIP archive.  The first member of the
+#   archive must be an uncompressed file called 'mimetype' with contents
+#   'application/epub+zip'
+
+
+# From: "Michael Gorny" <mgorny@gentoo.org>
+# ZPAQ: http://mattmahoney.net/dc/zpaq.html
+0      string  zPQ     ZPAQ stream
+>3     byte    x       \b, level %d
+# From: Barry Carter <carter.barry@gmail.com>
+# https://encode.ru/threads/456-zpaq-updates/page32
+0      string  7kSt    ZPAQ file
+
+# BBeB ebook, unencrypted (LRF format)
+# URL: https://www.sven.de/librie/Librie/LrfFormat
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+0      string  L\0R\0F\0\0\0   BBeB ebook data, unencrypted
+>8     beshort x               \b, version %d
+>36    byte    1               \b, front-to-back
+>36    byte    16              \b, back-to-front
+>42    beshort x               \b, (%dx,
+>44    beshort x               %d)
+
+# Symantec GHOST image by Joerg Jenderek at May 2014
+# https://us.norton.com/ghost/
+# https://www.garykessler.net/library/file_sigs.html
+0              ubelong&0xFFFFf7f0      0xFEEF0100      Norton GHost image
+# *.GHO
+>2             ubyte&0x08              0x00            \b, first file
+# *.GHS or *.[0-9] with cns program option
+>2             ubyte&0x08              0x08            \b, split file
+# part of split index interesting for *.ghs
+>>4            ubyte                   x               id=0x%x
+# compression tag minus one equals numeric compression command line switch z[1-9]
+>3             ubyte                   0               \b, no compression
+>3             ubyte                   2               \b, fast compression (Z1)
+>3             ubyte                   3               \b, medium compression (Z2)
+>3             ubyte                   >3
+>>3            ubyte                   <11             \b, compression (Z%d-1)
+>2             ubyte&0x08              0x00
+# ~ 30 byte password field only for *.gho
+>>12           ubequad                 !0              \b, password protected
+>>44           ubyte                   !1
+# 1~Image All, sector-by-sector only for *.gho
+>>>10          ubyte                   1               \b, sector copy
+# 1~Image Boot track only for *.gho
+>>>43          ubyte                   1               \b, boot track
+# 1~Image Disc only for *.gho implies Image Boot track and sector copy
+>>44           ubyte                   1               \b, disc sector copy
+# optional image description only *.gho
+>>0xff         string                  >\0             "%-.254s"
+# look for DOS sector end sequence
+>0xE08 search/7776             \x55\xAA
+>>&-512        indirect                x               \b; contains
+
+# Google Chrome extensions
+# https://developer.chrome.com/extensions/crx
+# https://developer.chrome.com/extensions/hosting
+0      string  Cr24    Google Chrome extension
+!:mime application/x-chrome-extension
+>4     ulong   x       \b, version %u
+
+# SeqBox - Sequenced container
+# ext: sbx, seqbox
+# Marco Pontello marcopon@gmail.com
+# reference: https://github.com/MarcoPon/SeqBox
+0      string  SBx     SeqBox,
+>3     byte    x       version %d
+
+# LyNX archive
+56     string  USE\040LYNX\040TO\040DISSOLVE\040THIS\040FILE    LyNX archive
+
+# From: Joerg Jenderek
+# URL: https://www.acronis.com/
+# Reference: https://en.wikipedia.org/wiki/TIB_(file_format)
+# Note: only tested with True Image 2013 Build 5962 and 2019 Build 14110
+0      ubequad         0xce24b9a220000000      Acronis True Image backup
+!:mime application/x-acronis-tib
+!:ext  tib
+# 01000000
+#>20   ubelong         x                       \b, at 20 0x%x
+# 20000000
+#>28   ubelong         x                       \b, at 28 0x%x
+# strings like "Generic- SD/MMC 1.00" "Unknown Disk" "Msft Virtual Disk 1.0"
+# ???
+# strings like "\Device\0000011e" "\Device\0000015a"
+#>0    search/0x6852300/cs     \\Device\\
+#>>&-1 pstring         x                       \b, %s
+# "\Device\HarddiskVolume30" "\Device\HarddiskVolume39"
+#>>>&1 search/180/cs   \\Device\\
+#>>>>&-1       pstring         x                       \b, %s
+#>>>>>&0       search/29/cs    \0\0\xc8\0
+# disk label
+#>>>>>>&10     lestring16      x               \b, disk label %11.11s
+#>>>>>>&9      plestring16     x               \b, disk label "%11.11s"
+#>>>>>>&10     ubequad x                       %16.16llx
+
+
+# Gentoo XPAK binary package
+# by Michal Gorny <mgorny@gentoo.org>
+# https://gitweb.gentoo.org/proj/portage.git/tree/man/xpak.5
+-4     string  STOP
+>-16   string  XPAKSTOP        Gentoo binary package (XPAK)
+
+# From:                Joerg Jenderek
+# URL:         https://kodi.wiki/view/TexturePacker
+# Reference:   https://mirrors.kodi.tv/releases/source/17.3-Krypton.tar.gz
+# /xbmc-Krypton/xbmc/guilib/XBTF.h
+# /xbmc-Krypton/xbmc/guilib/XBTF.cpp 
+0      string  XBTF
+# skip ASCII text by looking for terminating \0 of path
+>264   ubyte   0               XBMC texture package
+!:mime application/x-xbmc-xbt
+!:ext  xbt
+# XBTF_VERSION 2
+>>4    string  !2              \b, version %-.1s
+# nofFiles /xbmc-Krypton/xbmc/guilib/XBTFReader.cpp
+>>5    ulelong x               \b, %u file
+# plural s
+>>5    ulelong >1              \bs
+# path[CXBTFFile[MaximumPathLength=256]
+>>9    string  x               \b, 1st %s
+
diff --git a/magic/Magdir/assembler b/magic/Magdir/assembler
new file mode 100644 (file)
index 0000000..efa8e19
--- /dev/null
@@ -0,0 +1,18 @@
+#------------------------------------------------------------------------------
+# $File: assembler,v 1.5 2013/09/17 17:33:36 christos Exp $
+# make:  file(1) magic for assembler source
+#
+0      regex   \^[\040\t]{0,50}\\.asciiz               assembler source text
+!:mime text/x-asm
+0      regex   \^[\040\t]{0,50}\\.byte         assembler source text
+!:mime text/x-asm
+0      regex   \^[\040\t]{0,50}\\.even         assembler source text
+!:mime text/x-asm
+0      regex   \^[\040\t]{0,50}\\.globl                assembler source text
+!:mime text/x-asm
+0      regex   \^[\040\t]{0,50}\\.text         assembler source text
+!:mime text/x-asm
+0      regex   \^[\040\t]{0,50}\\.file         assembler source text
+!:mime text/x-asm
+0      regex   \^[\040\t]{0,50}\\.type         assembler source text
+!:mime text/x-asm
diff --git a/magic/Magdir/asterix b/magic/Magdir/asterix
new file mode 100644 (file)
index 0000000..45e0e09
--- /dev/null
@@ -0,0 +1,18 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# asterix:  file(1) magic for Aster*x; SunOS 5.5.1 gave the 4-character
+# strings as "long" - we assume they're just strings:
+# From: guy@netapp.com (Guy Harris)
+#
+0      string          *STA            Aster*x
+>7     string          WORD                    Words Document
+>7     string          GRAP                    Graphic
+>7     string          SPRE                    Spreadsheet
+>7     string          MACR                    Macro
+0      string          2278            Aster*x Version 2
+>29    byte            0x36                    Words Document
+>29    byte            0x35                    Graphic
+>29    byte            0x32                    Spreadsheet
+>29    byte            0x38                    Macro
+
diff --git a/magic/Magdir/att3b b/magic/Magdir/att3b
new file mode 100644 (file)
index 0000000..b83ae2e
--- /dev/null
@@ -0,0 +1,41 @@
+
+#------------------------------------------------------------------------------
+# $File: att3b,v 1.10 2017/03/17 21:35:28 christos Exp $
+# att3b:  file(1) magic for AT&T 3B machines
+#
+# The `versions' should be un-commented if they work for you.
+# (Was the problem just one of endianness?)
+#
+# 3B20
+#
+# The 3B20 conflicts with SCCS.
+#0     beshort         0550            3b20 COFF executable
+#>12   belong          >0              not stripped
+#>22   beshort         >0              - version %d
+#0     beshort         0551            3b20 COFF executable (TV)
+#>12   belong          >0              not stripped
+#>22   beshort         >0              - version %d
+#
+# WE32K
+#
+0      beshort         0560            WE32000 COFF
+>18    beshort         ^00000020       object
+>18    beshort         &00000020       executable
+>12    belong          >0              not stripped
+>18    beshort         ^00010000       N/A on 3b2/300 w/paging
+>18    beshort         &00020000       32100 required
+>18    beshort         &00040000       and MAU hardware required
+>20    beshort         0407            (impure)
+>20    beshort         0410            (pure)
+>20    beshort         0413            (demand paged)
+>20    beshort         0443            (target shared library)
+>22    beshort         >0              - version %d
+0      beshort         0561            WE32000 COFF executable (TV)
+>12    belong          >0              not stripped
+#>18   beshort         &00020000       - 32100 required
+#>18   beshort         &00040000       and MAU hardware required
+#>22   beshort         >0              - version %d
+#
+# core file for 3b2
+0      string          \000\004\036\212\200    3b2 core file
+>364   string          >\0             of '%s'
diff --git a/magic/Magdir/audio b/magic/Magdir/audio
new file mode 100644 (file)
index 0000000..5492635
--- /dev/null
@@ -0,0 +1,1113 @@
+
+#------------------------------------------------------------------------------
+# $File: audio,v 1.111 2019/05/08 18:02:45 christos Exp $
+# audio:  file(1) magic for sound formats (see also "iff")
+#
+# Jan Nicolai Langfeldt (janl@ifi.uio.no), Dan Quinlan (quinlan@yggdrasil.com),
+# and others
+#
+
+# Sun/NeXT audio data
+0      string          .snd            Sun/NeXT audio data:
+>12    belong          1               8-bit ISDN mu-law,
+!:mime audio/basic
+>12    belong          2               8-bit linear PCM [REF-PCM],
+!:mime audio/basic
+>12    belong          3               16-bit linear PCM,
+!:mime audio/basic
+>12    belong          4               24-bit linear PCM,
+!:mime audio/basic
+>12    belong          5               32-bit linear PCM,
+!:mime audio/basic
+>12    belong          6               32-bit IEEE floating point,
+!:mime audio/basic
+>12    belong          7               64-bit IEEE floating point,
+!:mime audio/basic
+>12    belong          8               Fragmented sample data,
+>12    belong          10              DSP program,
+>12    belong          11              8-bit fixed point,
+>12    belong          12              16-bit fixed point,
+>12    belong          13              24-bit fixed point,
+>12    belong          14              32-bit fixed point,
+>12    belong          18              16-bit linear with emphasis,
+>12    belong          19              16-bit linear compressed,
+>12    belong          20              16-bit linear with emphasis and compression,
+>12    belong          21              Music kit DSP commands,
+>12    belong          23              8-bit ISDN mu-law compressed (CCITT G.721 ADPCM voice enc.),
+!:mime  audio/x-adpcm
+>12    belong          24              compressed (8-bit CCITT G.722 ADPCM)
+>12    belong          25              compressed (3-bit CCITT G.723.3 ADPCM),
+>12    belong          26              compressed (5-bit CCITT G.723.5 ADPCM),
+>12    belong          27              8-bit A-law (CCITT G.711),
+>20    belong          1               mono,
+>20    belong          2               stereo,
+>20    belong          4               quad,
+>16    belong          >0              %d Hz
+
+# DEC systems (e.g. DECstation 5000) use a variant of the Sun/NeXT format
+# that uses little-endian encoding and has a different magic number
+0      lelong          0x0064732E      DEC audio data:
+>12    lelong          1               8-bit ISDN mu-law,
+!:mime audio/x-dec-basic
+>12    lelong          2               8-bit linear PCM [REF-PCM],
+!:mime audio/x-dec-basic
+>12    lelong          3               16-bit linear PCM,
+!:mime audio/x-dec-basic
+>12    lelong          4               24-bit linear PCM,
+!:mime audio/x-dec-basic
+>12    lelong          5               32-bit linear PCM,
+!:mime audio/x-dec-basic
+>12    lelong          6               32-bit IEEE floating point,
+!:mime audio/x-dec-basic
+>12    lelong          7               64-bit IEEE floating point,
+!:mime audio/x-dec-basic
+>12    belong          8               Fragmented sample data,
+>12    belong          10              DSP program,
+>12    belong          11              8-bit fixed point,
+>12    belong          12              16-bit fixed point,
+>12    belong          13              24-bit fixed point,
+>12    belong          14              32-bit fixed point,
+>12    belong          18              16-bit linear with emphasis,
+>12    belong          19              16-bit linear compressed,
+>12    belong          20              16-bit linear with emphasis and compression,
+>12    belong          21              Music kit DSP commands,
+>12    lelong          23              8-bit ISDN mu-law compressed (CCITT G.721 ADPCM voice enc.),
+!:mime audio/x-dec-basic
+>12    belong          24              compressed (8-bit CCITT G.722 ADPCM)
+>12    belong          25              compressed (3-bit CCITT G.723.3 ADPCM),
+>12    belong          26              compressed (5-bit CCITT G.723.5 ADPCM),
+>12    belong          27              8-bit A-law (CCITT G.711),
+>20    lelong          1               mono,
+>20    lelong          2               stereo,
+>20    lelong          4               quad,
+>16    lelong          >0              %d Hz
+
+# Creative Labs AUDIO stuff
+0      string  MThd                    Standard MIDI data
+!:mime audio/midi
+>8     beshort x                       (format %d)
+>10    beshort x                       using %d track
+>10    beshort         >1              \bs
+>12    beshort&0x7fff  x               at 1/%d
+>12    beshort&0x8000  >0              SMPTE
+
+0      string  CTMF                    Creative Music (CMF) data
+!:mime audio/x-unknown
+0      string  SBI                     SoundBlaster instrument data
+!:mime audio/x-unknown
+0      string  Creative\ Voice\ File   Creative Labs voice data
+!:mime audio/x-unknown
+# is this next line right?  it came this way...
+>19    byte    0x1A
+>23    byte    >0                      - version %d
+>22    byte    >0                      \b.%d
+
+# first entry is also the string "NTRK"
+0      belong          0x4e54524b      MultiTrack sound data
+>4     belong          x               - version %d
+
+# Extended MOD format (*.emd) (Greg Roelofs, newt@uchicago.edu); NOT TESTED
+# [based on posting 940824 by "Dirk/Elastik", husberg@lehtori.cc.tut.fi]
+0      string          EMOD            Extended MOD sound data,
+>4     byte&0xf0       x               version %d
+>4     byte&0x0f       x               \b.%d,
+>45    byte            x               %d instruments
+>83    byte            0               (module)
+>83    byte            1               (song)
+
+# Real Audio (Magic .ra\0375)
+0      belong          0x2e7261fd      RealAudio sound file
+!:mime audio/x-pn-realaudio
+0      string          .RMF\0\0\0      RealMedia file
+!:mime application/vnd.rn-realmedia
+#video/x-pn-realvideo
+#video/vnd.rn-realvideo
+#application/vnd.rn-realmedia
+#      sigh, there are many mimes for that but the above are the most common.
+
+# MTM/669/FAR/S3M/ULT/XM format checking [Aaron Eppert, aeppert@dialin.ind.net]
+# Oct 31, 1995
+# fixed by <doj@cubic.org> 2003-06-24
+# Too short...
+#0     string          MTM             MultiTracker Module sound file
+#0     string          if              Composer 669 Module sound data
+#0     string          JN              Composer 669 Module sound data (extended format)
+0      string          MAS_U           ULT(imate) Module sound data
+
+#0     string          FAR             Module sound data
+#>4    string          >\15            Title: "%s"
+
+0x2c   string          SCRM            ScreamTracker III Module sound data
+>0     string          >\0             Title: "%s"
+
+# Gravis UltraSound patches
+# From <ache@nagual.ru>
+
+0      string          GF1PATCH110\0ID#000002\0        GUS patch
+0      string          GF1PATCH100\0ID#000002\0        Old GUS patch
+
+# mime types according to http://www.geocities.com/nevilo/mod.htm:
+#      audio/it        .it
+#      audio/x-zipped-it       .itz
+#      audio/xm        fasttracker modules
+#      audio/x-s3m     screamtracker modules
+#      audio/s3m       screamtracker modules
+#      audio/x-zipped-mod      mdz
+#      audio/mod       mod
+#      audio/x-mod     All modules (mod, s3m, 669, mtm, med, xm, it, mdz, stm, itz, xmz, s3z)
+
+#
+# Taken from loader code from mikmod version 2.14
+# by Steve McIntyre (stevem@chiark.greenend.org.uk)
+# <doj@cubic.org> added title printing on 2003-06-24
+0      string  MAS_UTrack_V00
+>14    string  >/0             ultratracker V1.%.1s module sound data
+!:mime audio/x-mod
+#audio/x-tracker-module
+
+0      string  UN05            MikMod UNI format module sound data
+
+0      string  Extended\ Module: Fasttracker II module sound data
+!:mime audio/x-mod
+#audio/x-tracker-module
+>17    string  >\0             Title: "%s"
+
+21     string/c        =!SCREAM!       Screamtracker 2 module sound data
+!:mime audio/x-mod
+#audio/x-screamtracker-module
+21     string  BMOD2STM        Screamtracker 2 module sound data
+!:mime audio/x-mod
+#audio/x-screamtracker-module
+1080   string  M.K.            4-channel Protracker module sound data
+!:mime audio/x-mod
+#audio/x-protracker-module
+>0     string  >\0             Title: "%s"
+1080   string  M!K!            4-channel Protracker module sound data
+!:mime audio/x-mod
+#audio/x-protracker-module
+>0     string  >\0             Title: "%s"
+1080   string  FLT4            4-channel Startracker module sound data
+!:mime audio/x-mod
+#audio/x-startracker-module
+>0     string  >\0             Title: "%s"
+1080   string  FLT8            8-channel Startracker module sound data
+!:mime audio/x-mod
+#audio/x-startracker-module
+>0     string  >\0             Title: "%s"
+1080   string  4CHN            4-channel Fasttracker module sound data
+!:mime audio/x-mod
+#audio/x-fasttracker-module
+>0     string  >\0             Title: "%s"
+1080   string  6CHN            6-channel Fasttracker module sound data
+!:mime audio/x-mod
+#audio/x-fasttracker-module
+>0     string  >\0             Title: "%s"
+1080   string  8CHN            8-channel Fasttracker module sound data
+!:mime audio/x-mod
+#audio/x-fasttracker-module
+>0     string  >\0             Title: "%s"
+1080   string  CD81            8-channel Octalyser module sound data
+!:mime audio/x-mod
+#audio/x-octalysertracker-module
+>0     string  >\0             Title: "%s"
+1080   string  OKTA            8-channel Octalyzer module sound data
+!:mime audio/x-mod
+#audio/x-octalysertracker-module
+>0     string  >\0             Title: "%s"
+# Not good enough.
+#1082  string  CH
+#>1080 string  >/0             %.2s-channel Fasttracker "oktalyzer" module sound data
+1080   string  16CN            16-channel Taketracker module sound data
+!:mime audio/x-mod
+#audio/x-taketracker-module
+>0     string  >\0             Title: "%s"
+1080   string  32CN            32-channel Taketracker module sound data
+!:mime audio/x-mod
+#audio/x-taketracker-module
+>0     string  >\0             Title: "%s"
+
+# TOC sound files -Trevor Johnson <trevor@jpj.net>
+#
+0       string          TOC             TOC sound file
+
+# sidfiles <pooka@iki.fi>
+# added name,author,(c) and new RSID type by <doj@cubic.org> 2003-06-24
+0      string          SIDPLAY\ INFOFILE       Sidplay info file
+
+0      string          PSID                    PlaySID v2.2+ (AMIGA) sidtune
+>4     beshort         >0                      w/ header v%d,
+>14    beshort         =1                      single song,
+>14    beshort         >1                      %d songs,
+>16    beshort         >0                      default song: %d
+>0x16  string          >\0                     name: "%s"
+>0x36  string          >\0                     author: "%s"
+>0x56  string          >\0                     copyright: "%s"
+
+0      string          RSID                    RSID sidtune PlaySID compatible
+>4     beshort         >0                      w/ header v%d,
+>14    beshort         =1                      single song,
+>14    beshort         >1                      %d songs,
+>16    beshort         >0                      default song: %d
+>0x16  string          >\0                     name: "%s"
+>0x36  string          >\0                     author: "%s"
+>0x56  string          >\0                     copyright: "%s"
+
+# IRCAM sound files - Michael Pruett <michael@68k.org>
+# http://www-mmsp.ece.mcgill.ca/documents/AudioFormats/IRCAM/IRCAM.html
+0      belong          0x64a30100              IRCAM file (VAX little-endian)
+0      belong          0x0001a364              IRCAM file (VAX big-endian)
+0      belong          0x64a30200              IRCAM file (Sun big-endian)
+0      belong          0x0002a364              IRCAM file (Sun little-endian)
+0      belong          0x64a30300              IRCAM file (MIPS little-endian)
+0      belong          0x0003a364              IRCAM file (MIPS big-endian)
+0      belong          0x64a30400              IRCAM file (NeXT big-endian)
+0      belong          0x64a30400              IRCAM file (NeXT big-endian)
+0      belong          0x0004a364              IRCAM file (NeXT little-endian)
+
+# NIST SPHERE <mpruett@sgi.com>
+0      string          NIST_1A\n\ \ \ 1024\n   NIST SPHERE file
+
+# Sample Vision <mpruett@sgi.com>
+0      string          SOUND\ SAMPLE\ DATA\    Sample Vision file
+
+# Audio Visual Research <tonigonenstein@users.sourceforge.net>
+0      string          2BIT                    Audio Visual Research file,
+>12    beshort         =0                      mono,
+>12    beshort         =-1                     stereo,
+>14    beshort         x                       %d bits
+>16    beshort         =0                      unsigned,
+>16    beshort         =-1                     signed,
+>22    belong&0x00ffffff       x               %d Hz,
+>18    beshort         =0                      no loop,
+>18    beshort         =-1                     loop,
+>21    ubyte           <128                    note %d,
+>22    byte            =0                      replay 5.485 KHz
+>22    byte            =1                      replay 8.084 KHz
+>22    byte            =2                      replay 10.971 KHz
+>22    byte            =3                      replay 16.168 KHz
+>22    byte            =4                      replay 21.942 KHz
+>22    byte            =5                      replay 32.336 KHz
+>22    byte            =6                      replay 43.885 KHz
+>22    byte            =7                      replay 47.261 KHz
+
+# SGI SoundTrack <mpruett@sgi.com>
+0      string          _SGI_SoundTrack         SGI SoundTrack project file
+# ID3 version 2 tags <waschk@informatik.uni-rostock.de>
+0      string          ID3     Audio file with ID3 version 2
+>3     byte            x       \b.%d
+>4     byte            x       \b.%d
+>>5    byte            &0x80   \b, unsynchronized frames
+>>5    byte            &0x40   \b, extended header
+>>5    byte            &0x20   \b, experimental
+>>5    byte            &0x10   \b, footer present
+>(6.I+10)      indirect        x       \b, contains:
+
+# NSF (NES sound file) magic
+0      string          NESM\x1a        NES Sound File
+>14    string          >\0             ("%s" by
+>46    string          >\0             %s, copyright
+>78    string          >\0             %s),
+>5     byte            x               version %d,
+>6     byte            x               %d tracks,
+>122   byte&0x2        =1              dual PAL/NTSC
+>122   byte&0x1        =1              PAL
+>122   byte&0x1        =0              NTSC
+
+# NSFE (Extended NES sound file) magic
+# http://slickproductions.org/docs/NSF/nsfespec.txt
+# From: David Pflug <david@pflug.email>
+0      string          NSFE            Extended NES Sound File
+>48    search/0x1000   auth
+>>&0   string          >\0             ("%s"
+>>>&1  string          >\0             by %s
+>>>>&1 string          >\0             \b, copyright %s
+>>>>>&1        string          >\0             \b, ripped by %s
+>20    byte            x               \b), %d tracks,
+>18    byte&0x2        =1              dual PAL/NTSC
+>18     byte&0x2       =0
+>>18   byte&0x1        =1              PAL
+>>18   byte&0x1        =0              NTSC
+
+# Type: SNES SPC700 sound files
+# From: Josh Triplett <josh@freedesktop.org>
+0      string  SNES-SPC700\ Sound\ File\ Data\ v       SNES SPC700 sound file
+>&0    string  0.30                                    \b, version %s
+>>0x23 byte    0x1B                                    \b, without ID666 tag
+>>0x23 byte    0x1A                                    \b, with ID666 tag
+>>>0x2E        string  >\0                                     \b, song "%.32s"
+>>>0x4E        string  >\0                                     \b, game "%.32s"
+
+# Impulse tracker module (audio/x-it)
+0      string          IMPM            Impulse Tracker module sound data -
+!:mime audio/x-mod
+>4     string          >\0             "%s"
+>40    leshort         !0              compatible w/ITv%x
+>42    leshort         !0              created w/ITv%x
+
+# Imago Orpheus module (audio/x-imf)
+60     string          IM10            Imago Orpheus module sound data -
+>0     string          >\0             "%s"
+
+# From <collver1@attbi.com>
+# These are the /etc/magic entries to decode modules, instruments, and
+# samples in Impulse Tracker's native format.
+
+0      string          IMPS            Impulse Tracker Sample
+>18    byte            &2              16 bit
+>18    byte            ^2              8 bit
+>18    byte            &4              stereo
+>18    byte            ^4              mono
+0      string          IMPI            Impulse Tracker Instrument
+>28    leshort         !0              ITv%x
+>30    byte            !0              %d samples
+
+# Yamaha TX Wave:  file(1) magic for Yamaha TX Wave audio files
+# From <collver1@attbi.com>
+0      string          LM8953          Yamaha TX Wave
+>22    byte            0x49            looped
+>22    byte            0xC9            non-looped
+>23    byte            1               33kHz
+>23    byte            2               50kHz
+>23    byte            3               16kHz
+
+# scream tracker:  file(1) magic for Scream Tracker sample files
+#
+# From <collver1@attbi.com>
+76     string          SCRS            Scream Tracker Sample
+>0     byte            1               sample
+>0     byte            2               adlib melody
+>0     byte            >2              adlib drum
+>31    byte            &2              stereo
+>31    byte            ^2              mono
+>31    byte            &4              16bit little endian
+>31    byte            ^4              8bit
+>30    byte            0               unpacked
+>30    byte            1               packed
+
+# audio
+# From: Cory Dikkers <cdikkers@swbell.net>
+0      string          MMD0            MED music file, version 0
+0      string          MMD1            OctaMED Pro music file, version 1
+0      string          MMD3            OctaMED Soundstudio music file, version 3
+0      string          OctaMEDCmpr     OctaMED Soundstudio compressed file
+0      string          MED             MED_Song
+0      string          SymM            Symphonie SymMOD music file
+#
+# Track Length (TRL), Tracks (TRK), Samples (SMP), Subsongs (SS)
+# http://lclevy.free.fr/exotica/ahx/ahxformat.txt
+0      string          THX             AHX version
+>3     byte            =0              1 module data
+>3     byte            =1              2 module data
+>10    byte            x               TRL: %u
+>11    byte            x               TRK: %u
+>12    byte            x               SMP: %u
+>13    byte            x               SS: %u
+#
+0      string          OKTASONG        Oktalyzer module data
+#
+0      string          DIGI\ Booster\ module\0 %s
+>20    byte            >0              %c
+>>21   byte            >0              \b%c
+>>>22  byte            >0              \b%c
+>>>>23 byte            >0              \b%c
+>610   string          >\0             \b, "%s"
+#
+0      string          DBM0            DIGI Booster Pro Module
+>4     byte            >0              V%X.
+>>5    byte            x               \b%02X
+>16    string          >\0             \b, "%s"
+#
+0      string          FTMN            FaceTheMusic module
+>16    string          >\0d            \b, "%s"
+
+# From: <doj@cubic.org> 2003-06-24
+0      string          AMShdr\32       Velvet Studio AMS Module v2.2
+0      string          Extreme         Extreme Tracker AMS Module v1.3
+0      string          DDMF            Xtracker DMF Module
+>4     byte            x               v%i
+>0xD   string          >\0             Title: "%s"
+>0x2B  string          >\0             Composer: "%s"
+0      string          DSM\32          Dynamic Studio Module DSM
+0      string          SONG            DigiTrekker DTM Module
+0      string          DMDL            DigiTrakker MDL Module
+0      string          PSM\32          Protracker Studio PSM Module
+44     string          PTMF            Poly Tracker PTM Module
+>0     string          >\32            Title: "%s"
+0      string          MT20            MadTracker 2.0 Module MT2
+0      string          RAD\40by\40REALiTY!! RAD Adlib Tracker Module RAD
+0      string          RTMM            RTM Module
+0x426  string          MaDoKaN96       XMS Adlib Module
+>0     string          >\0             Composer: "%s"
+0      string          AMF             AMF Module
+>4     string          >\0             Title: "%s"
+0      string          MODINFO1        Open Cubic Player Module Inforation MDZ
+0      string          Extended\40Instrument: Fast Tracker II Instrument
+
+# From: Takeshi Hamasaki <hma@syd.odn.ne.jp>
+# NOA Nancy Codec file
+0      string          \210NOA\015\012\032     NOA Nancy Codec Movie file
+# Yamaha SMAF format
+0      string          MMMD            Yamaha SMAF file
+# Sharp Jisaku Melody format for PDC
+0      string          \001Sharp\040JisakuMelody       SHARP Cell-Phone ringing Melody
+>20    string          Ver01.00        Ver. 1.00
+>>32   byte            x               , %d tracks
+
+# Free lossless audio codec <http://flac.sourceforge.net>
+# From: Przemyslaw Augustyniak <silvathraec@rpg.pl>
+0      string                  fLaC            FLAC audio bitstream data
+!:mime audio/flac
+>4     byte&0x7f               >0              \b, unknown version
+>4     byte&0x7f               0               \b
+# some common bits/sample values
+>>20   beshort&0x1f0           0x030           \b, 4 bit
+>>20   beshort&0x1f0           0x050           \b, 6 bit
+>>20   beshort&0x1f0           0x070           \b, 8 bit
+>>20   beshort&0x1f0           0x0b0           \b, 12 bit
+>>20   beshort&0x1f0           0x0f0           \b, 16 bit
+>>20   beshort&0x1f0           0x170           \b, 24 bit
+>>20   byte&0xe                0x0             \b, mono
+>>20   byte&0xe                0x2             \b, stereo
+>>20   byte&0xe                0x4             \b, 3 channels
+>>20   byte&0xe                0x6             \b, 4 channels
+>>20   byte&0xe                0x8             \b, 5 channels
+>>20   byte&0xe                0xa             \b, 6 channels
+>>20   byte&0xe                0xc             \b, 7 channels
+>>20   byte&0xe                0xe             \b, 8 channels
+# sample rates derived from known oscillator frequencies;
+# 24.576 MHz (video/fs=48kHz), 22.5792 (audio/fs=44.1kHz) and
+# 16.384 (other/fs=32kHz).
+>>17   belong&0xfffff0         0x02b110        \b, 11.025 kHz
+>>17   belong&0xfffff0         0x03e800        \b, 16 kHz
+>>17   belong&0xfffff0         0x056220        \b, 22.05 kHz
+>>17   belong&0xfffff0         0x05dc00        \b, 24 kHz
+>>17   belong&0xfffff0         0x07d000        \b, 32 kHz
+>>17   belong&0xfffff0         0x0ac440        \b, 44.1 kHz
+>>17   belong&0xfffff0         0x0bb800        \b, 48 kHz
+>>17   belong&0xfffff0         0x0fa000        \b, 64 kHz
+>>17   belong&0xfffff0         0x158880        \b, 88.2 kHz
+>>17   belong&0xfffff0         0x177000        \b, 96 kHz
+>>17   belong&0xfffff0         0x1f4000        \b, 128 kHz
+>>17   belong&0xfffff0         0x2b1100        \b, 176.4 kHz
+>>17   belong&0xfffff0         0x2ee000        \b, 192 kHz
+>>17   belong&0xfffff0         0x3e8000        \b, 256 kHz
+>>17   belong&0xfffff0         0x562200        \b, 352.8 kHz
+>>17   belong&0xfffff0         0x5dc000        \b, 384 kHz
+>>21   byte&0xf                >0              \b, >4G samples
+>>21   byte&0xf                0               \b
+>>>22  belong                  >0              \b, %u samples
+>>>22  belong                  0               \b, length unknown
+
+# (ISDN) VBOX voice message file (Wolfram Kleff)
+0       string          VBOX            VBOX voice message data
+
+# ReBorn Song Files (.rbs)
+# David J. Singer <doc@deadvirgins.org.uk>
+8       string          RB40             RBS Song file
+>29     string          ReBorn           created by ReBorn
+>37     string          Propellerhead    created by ReBirth
+
+# Synthesizer Generator and Kimwitu share their file format
+0      string          A#S#C#S#S#L#V#3     Synthesizer Generator or Kimwitu data
+# Kimwitu++ uses a slightly different magic
+0      string          A#S#C#S#S#L#HUB     Kimwitu++ data
+
+# From "Simon Hosie
+0       string  TFMX-SONG       TFMX module sound data
+
+# Monkey's Audio compressed audio format (.ape)
+# From danny.milo@gmx.net (Danny Milosavljevic)
+# New version from Abel Cheung <abel (@) oaka.org>
+0              string          MAC\040         Monkey's Audio compressed format
+!:mime audio/x-ape
+>4             uleshort        >0x0F8B         version %d
+>>(0x08.l)     uleshort        =1000           with fast compression
+>>(0x08.l)     uleshort        =2000           with normal compression
+>>(0x08.l)     uleshort        =3000           with high compression
+>>(0x08.l)     uleshort        =4000           with extra high compression
+>>(0x08.l)     uleshort        =5000           with insane compression
+>>(0x08.l+18)  uleshort        =1              \b, mono
+>>(0x08.l+18)  uleshort        =2              \b, stereo
+>>(0x08.l+20)  ulelong         x               \b, sample rate %d
+>4             uleshort        <0x0F8C         version %d
+>>6            uleshort        =1000           with fast compression
+>>6            uleshort        =2000           with normal compression
+>>6            uleshort        =3000           with high compression
+>>6            uleshort        =4000           with extra high compression
+>>6            uleshort        =5000           with insane compression
+>>10           uleshort        =1              \b, mono
+>>10           uleshort        =2              \b, stereo
+>>12           ulelong         x               \b, sample rate %d
+
+# adlib sound files
+# From: Alex Myczko <alex@aiei.ch>
+
+# https://github.com/rerrahkr/BambooTracker
+0      string          BambooTrackerMod        BambooTracker module
+>22    byte    x       \b, version %u
+>21    byte    x       \b.%u
+>20    byte    x       \b.%u
+
+0      string          BambooTrackerIst        BambooTracker instrument
+>22    byte    x       \b, version %u
+>21    byte    x       \b.%u
+>20    byte    x       \b.%u
+
+0      string          RAWADATA        RdosPlay RAW
+
+1068   string          RoR             AMUSIC Adlib Tracker
+
+0      string          JCH             EdLib
+
+0      string          mpu401tr        MPU-401 Trakker
+
+0      string          SAdT            Surprise! Adlib Tracker
+>4     byte            x               Version %d
+
+0      string          XAD!            eXotic ADlib
+
+0      string          ofTAZ!          eXtra Simple Music
+
+0      string          FMK!            FM Kingtracker Song
+
+0      string          DFM             DFM Song
+
+0      string          \<CUD-FM-File\> CFF Song
+
+0      string          _A2module       A2M Song
+
+# Spectrum 128 tunes (.ay files).
+# From: Emanuel Haupt <ehaupt@critical.ch>
+0      string          ZXAYEMUL        Spectrum 128 tune
+
+0      string          \0BONK          BONK,
+#>5    byte            x               version %d
+>14    byte            x               %d channel(s),
+>15    byte            =1              lossless,
+>15    byte            =0              lossy,
+>16    byte            x               mid-side
+
+384    string          LockStream      LockStream Embedded file (mostly MP3 on old Nokia phones)
+
+# format VQF (proprietary codec for sound)
+# some infos on the header file available at :
+# http://www.twinvq.org/english/technology_format.html
+0      string          TWIN97012000    VQF data
+>27    short           0               \b, Mono
+>27    short           1               \b, Stereo
+>31    short           >0              \b, %d kbit/s
+>35    short           >0              \b, %d kHz
+
+# Nelson A. de Oliveira (naoliv@gmail.com)
+# .eqf
+0      string  Winamp\ EQ\ library\ file       %s
+# it will match only versions like v<digit>.<digit>
+# Since I saw only eqf files with version v1.1 I think that it's OK
+>23    string  x       \b%.4s
+# .preset
+0      string  [Equalizer\ preset]     XMMS equalizer preset
+# .m3u
+0      search/1        #EXTM3U         M3U playlist text
+# .pls
+0      search/1        [playlist]      PLS playlist text
+# licq.conf
+1      string  [licq]                  LICQ configuration file
+
+# Atari ST audio files by Dirk Jagdmann <doj@cubic.org>
+0      string          ICE!            SNDH Atari ST music
+0      string          SC68\ Music-file\ /\ (c)\ (BeN)jami     sc68 Atari ST music
+
+# musepak support From: "Jiri Pejchal" <jiri.pejchal@gmail.com>
+0       string          MP+     Musepack audio (MP+)
+!:mime audio/x-musepack
+>3      byte            255     \b, SV pre8
+>3      byte&0xF        0x6     \b, SV 6
+>3      byte&0xF        0x8     \b, SV 8
+>3      byte&0xF        0x7     \b, SV 7
+>>3     byte&0xF0       0x0     \b.0
+>>3     byte&0xF0       0x10    \b.1
+>>3     byte&0xF0       240     \b.15
+>>10    byte&0xF0       0x0     \b, no profile
+>>10    byte&0xF0       0x10    \b, profile 'Unstable/Experimental'
+>>10    byte&0xF0       0x50    \b, quality 0
+>>10    byte&0xF0       0x60    \b, quality 1
+>>10    byte&0xF0       0x70    \b, quality 2 (Telephone)
+>>10    byte&0xF0       0x80    \b, quality 3 (Thumb)
+>>10    byte&0xF0       0x90    \b, quality 4 (Radio)
+>>10    byte&0xF0       0xA0    \b, quality 5 (Standard)
+>>10    byte&0xF0       0xB0    \b, quality 6 (Xtreme)
+>>10    byte&0xF0       0xC0    \b, quality 7 (Insane)
+>>10    byte&0xF0       0xD0    \b, quality 8 (BrainDead)
+>>10    byte&0xF0       0xE0    \b, quality 9
+>>10    byte&0xF0       0xF0    \b, quality 10
+>>27    byte            0x0     \b, Buschmann 1.7.0-9, Klemm 0.90-1.05
+>>27    byte            102     \b, Beta 1.02
+>>27    byte            104     \b, Beta 1.04
+>>27    byte            105     \b, Alpha 1.05
+>>27    byte            106     \b, Beta 1.06
+>>27    byte            110     \b, Release 1.1
+>>27    byte            111     \b, Alpha 1.11
+>>27    byte            112     \b, Beta 1.12
+>>27    byte            113     \b, Alpha 1.13
+>>27    byte            114     \b, Beta 1.14
+>>27    byte            115     \b, Alpha 1.15
+
+0       string          MPCK    Musepack audio (MPCK)
+!:mime audio/x-musepack
+
+# IMY
+# from http://filext.com/detaillist.php?extdetail=IMY
+# https://cellphones.about.com/od/cellularfaqs/f/rf_imelody.htm
+# http://download.ncl.ie/doc/api/ie/ncl/media/music/IMelody.html
+# http://www.wx800.com/msg/download/irda/iMelody.pdf
+0      string  BEGIN:IMELODY   iMelody Ringtone Format
+
+# From: "Mateus Caruccio" <mateus@caruccio.com>
+# guitar pro v3,4,5 from http://filext.com/file-extension/gp3
+0      string  \030FICHIER\ GUITAR\ PRO\ v3.   Guitar Pro Ver. 3 Tablature
+
+# From: "Leslie P. Polzer" <leslie.polzer@gmx.net>
+60     string  SONG            SoundFX Module sound file
+
+# Type: Adaptive Multi-Rate Codec
+# URL:  http://filext.com/detaillist.php?extdetail=AMR
+# From: Russell Coker <russell@coker.com.au>
+0      string  #!AMR           Adaptive Multi-Rate Codec (GSM telephony)
+!:mime audio/amr
+!:ext  amr
+
+# Type: SuperCollider 3 Synth Definition File Format
+# From: Mario Lang <mlang@debian.org>
+0      string  SCgf    SuperCollider3 Synth Definition file,
+>4     belong  x       version %d
+
+# Type: True Audio Lossless Audio
+# URL:  https://wiki.multimedia.cx/index.php?title=True_Audio
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  TTA1    True Audio Lossless Audio
+
+# Type: WavPack Lossless Audio
+# URL:  https://wiki.multimedia.cx/index.php?title=WavPack
+# From: Mike Melanson <mike@multimedia.cx>
+0      string  wvpk    WavPack Lossless Audio
+
+# From Fabio R. Schmidlin <frs@pop.com.br>
+# VGM music file
+0      string          Vgm\040
+>9     ubyte           >0      VGM Video Game Music dump v
+!:mime audio/x-vgm
+!:ext  vgm
+>>9    ubyte/16        >0      \b%d
+>>9    ubyte&0x0F      x       \b%d
+>>8    ubyte/16        x       \b.%d
+>>8    ubyte&0x0F      >0      \b%d
+#Get soundchips
+>>8    ubyte           x       \b, soundchip(s)=
+>>0x0C ulelong         >0      SN76489,
+>>0x10 ulelong         >0      YM2413,
+>>0x2C ulelong         >0      YM2612,
+>>0x30 ulelong         >0      YM2151,
+>>0x38 ulelong         >0      Sega PCM,
+>>0x34 ulelong         >0xC
+>>>0x40        ulelong         >0      RF5C68,
+>>0x34 ulelong         >0x10
+>>>0x44        ulelong         >0      YM2203,
+>>0x34 ulelong         >0x14
+>>>0x48        ulelong         >0      YM2608,
+>>0x34 ulelong         >0x18
+>>>0x4C        lelong          >0      YM2610,
+>>>0x4C        lelong          <0      YM2610B,
+>>0x34 ulelong         >0x1C
+>>>0x50        ulelong         >0      YM3812,
+>>0x34 ulelong         >0x20
+>>>0x54        ulelong         >0      YM3526,
+>>0x34 ulelong         >0x24
+>>>0x58        ulelong         >0      Y8950,
+>>0x34 ulelong         >0x28
+>>>0x5C        ulelong         >0      YMF262,
+>>0x34 ulelong         >0x2C
+>>>0x60        ulelong         >0      YMF278B,
+>>0x34 ulelong         >0x30
+>>>0x64        ulelong         >0      YMF271,
+>>0x34 ulelong         >0x34
+>>>0x68        ulelong         >0      YMZ280B,
+>>0x34 ulelong         >0x38
+>>>0x6C        ulelong         >0      RF5C164,
+>>0x34 ulelong         >0x3C
+>>>0x70        ulelong         >0      PWM,
+>>0x34 ulelong         >0x40
+>>>0x74        ulelong         >0
+>>>>0x78 ubyte         0x00    AY-3-8910,
+>>>>0x78 ubyte         0x01    AY-3-8912,
+>>>>0x78 ubyte         0x02    AY-3-8913,
+>>>>0x78 ubyte         0x03    AY-3-8930,
+>>>>0x78 ubyte         0x10    YM2149,
+>>>>0x78 ubyte         0x11    YM3439,
+# VGM 1.61
+>>0x34 ulelong         >0x4C
+>>>0x80        ulelong         >0      DMG,
+>>0x34 ulelong         >0x50
+>>>0x84        lelong          >0      NES APU,
+>>>0x84        lelong          <0      NES APU with FDS,
+>>0x34 ulelong         >0x54
+>>>0x88        ulelong         >0      MultiPCM,
+>>0x34 ulelong         >0x58
+>>>0x8C        ulelong         >0      uPD7759,
+>>0x34 ulelong         >0x5C
+>>>0x90        ulelong         >0      OKIM6258,
+>>0x34 ulelong         >0x64
+>>>0x98        ulelong         >0      OKIM6295,
+>>0x34 ulelong         >0x68
+>>>0x9C        ulelong         >0      K051649,
+>>0x34 ulelong         >0x6C
+>>>0xA0        ulelong         >0      K054539,
+>>0x34 ulelong         >0x70
+>>>0xA4        ulelong         >0      HuC6280,
+>>0x34 ulelong         >0x74
+>>>0xA8        ulelong         >0      C140,
+>>0x34 ulelong         >0x78
+>>>0xAC        ulelong         >0      K053260,
+>>0x34 ulelong         >0x7C
+>>>0xB0        ulelong         >0      Pokey,
+>>0x34 ulelong         >0x80
+>>>0xB4        ulelong         >0      QSound,
+# VGM 1.71
+>>0x34 ulelong         >0x84
+>>>0xB8        ulelong         >0      SCSP,
+>>0x34 ulelong         >0x8C
+>>>0xC0        ulelong         >0      WonderSwan,
+>>0x34 ulelong         >0x90
+>>>0xC4        ulelong         >0      VSU,
+>>0x34 ulelong         >0x94
+>>>0xC8        ulelong         >0      SAA1099,
+>>0x34 ulelong         >0x98
+>>>0xCC        ulelong         >0      ES5503,
+>>0x34 ulelong         >0x9C
+>>>0xD0        lelong          >0      ES5505,
+>>>0xD0        lelong          <0      ES5506,
+>>0x34 ulelong         >0xA4
+>>>0xD8        ulelong         >0      X1-010,
+>>0x34 ulelong         >0xA8
+>>>0xDC        ulelong         >0      C352,
+>>0x34 ulelong         >0xAC
+>>>0xE0        ulelong         >0      GA20,
+
+# GVOX Encore file format
+# Since this is a proprietary file format and there is no publicly available
+# format specification, this is just based on induction
+#
+0      string  SCOW
+>4     byte    0xc4    GVOX Encore music, version 5.0 or above
+>4     byte    0xc2    GVOX Encore music, version < 5.0
+
+0      string  ZBOT
+>4     byte    0xc5    GVOX Encore music, version < 5.0
+
+# Summary:     Garmin Voice Processing Module (WAVE audios)
+# From:                Joerg Jenderek
+# URL:         https://www.garmin.com/
+# Reference:   http://www.poi-factory.com/node/19580
+# NOTE:                there exist 2 other Garmin VPM formats
+0              string  AUDIMG
+# skip text files starting with string "AUDIMG"
+>13            ubyte           <13     Garmin Voice Processing Module
+!:mime audio/x-vpm-wav-garmin
+!:ext  vpm
+# 3 bytes indicating the voice version (200,220)
+>>6            string          x       \b, version %3.3s
+# day of release (01-31)
+>>12           ubyte           x       \b, %.2d
+# month of release (01-12)
+>>13           ubyte           x       \b.%.2d
+# year of release (like 2006, 2007, 2008)
+>>14           uleshort        x       \b.%.4d
+# hour of release (0-23)
+>>11           ubyte           x       %.2d
+# minute of release (0-59)
+>>10           ubyte           x       \b:%.2d
+# second of release (0-59)
+>>9            ubyte           x       \b:%.2d
+# if you select a language like german on your garmin device
+# you can only select voice modules with corresponding language byte ID like 1
+>>18           ubyte           x       \b, language ID %d
+# structure for phrases/sentences?
+# number of voice sample in the 1st phrase?
+#>>19          uleshort                x       \b, 0x%x samples
+#>>>21         uleshort                >0      \b, at 0x%4.4x
+#>>>(21.s)     ubequad                 x       0x%llx
+# 2nd phrase?
+#>>23          uleshort                x       \b, 0x%x samples
+#>>>25         uleshort                >0      \b, at 0x%4.4x
+#>>>(25.s)     ubequad                 x       0x%llx
+# pointer to 1st audio WAV sample
+>>16           uleshort        >0
+>>>(16.s)      ulelong         >0      \b, at 0x%x
+# WAV length
+# 1 space char after "bytes" to get phrase "bytes RIFF"
+>>>>(16.s+4)   ulelong         >0      %u bytes 
+# look for magic
+>>>>>(&-8.l)   string          RIFF
+# determine type by ./riff
+>>>>>>&-4      indirect        x
+# 2 - ~ 131 WAV samples following same way
+#
+# Summary:     encrypted Garmin Voice Processing Module
+# From:                Joerg Jenderek
+# URL:         https://www.garmin.com/us/products/ontheroad/voicestudio
+# NOTE:                Encrypted variant used in voices like DrNightmare, Elfred, Yeti.
+#              There exist 2 other Garmin VPM formats
+0      ubequad         0xa141190fecc8ced6      Garmin Voice Processing Module (encrypted)
+!:mime audio/x-vpm-garmin
+!:ext  vpm
+
+# From Martin Mueller Skarbiniks Pedersen
+0              string          GDM
+>0x3           byte            0xFE    General Digital Music.
+>0x4           string          >\0     title: "%s"
+>0x24          string          >\0     musician: "%s"
+>>0x44         beshort         0x0D0A
+>>>0x46                byte            0x1A
+>>>>0x47       string          GMFS    Version
+>>>>0x4B       byte            x       %d.
+>>>>0x4C       byte            x       \b%02d
+>>>>0x4D       beshort         0x000   (2GDM v
+>>>>0x4F       byte            x       \b%d.
+>>>>>0x50      byte            x       \b%d)
+
+0              string          MTM     Multitracker
+>0x3           byte/16         x       Version %d.
+>0x3           byte&0x0F       x       \b%02d
+>>0x4          string          >\0     title: "%s"
+
+0              string          HVL
+>3             byte            <2      Hively Tracker Song
+>3             byte            0       1 module data
+>3             byte            1       2 module data
+
+0              string          MO3
+>3             ubyte           <6      MOdule with MP3
+>>3            byte            0       Version 0       (With MP3 and lossless)
+>>3            byte            1       Version 1       (With ogg and lossless)
+>>3            byte            3       Version 2.2
+>>3            byte            4       (With no LAME header)
+>>3            byte            5       Version 2.4
+
+0              string          ADRVPACK        AProSys module
+
+# ftp://ftp.modland.com/pub/documents/format_documentation/\
+# Art%20Of%20Noise%20(.aon).txt
+0              string          AON
+>4             string          "ArtOfNoise by Bastian Spiegel(twice/lego)"
+>0x2e          string          NAME    Art of Noise Tracker Song
+>3             string          <9
+>3             string          4       (4 voices)
+>3             string          8       (8 voices)
+>>0x36         string          >\0     Title: "%s"
+
+0              string          FAR
+>0x2c          byte            0x0d
+>0x2d          byte            0x0a
+>0x2e          byte            0x1a
+>>0x3          byte            0xFE    Farandole Tracker Song
+>>>0x31                byte/16         x       Version %d.
+>>>0x31                byte&0x0F       x       \b%02d
+>>>>0x4                string          >\0     \b, title: "%s"
+
+# magic for Klystrack, https://kometbomb.github.io/klystrack/
+# from Alex Myczko <alex@aiei.ch>
+0      string  cyd!song        Klystrack song
+>8     byte    >0              \b, version %u
+>8     byte    >26
+#>>9   byte    x               \b, channels %u
+#>>10  leshort x               \b, time signature %u
+#>>12  leshort x               \b, sequence step %u
+#>>14  byte    x               \b, instruments %u
+#>>15  leshort x               \b, patterns %u
+#>>17  leshort x               \b, sequences %u
+#>>19  leshort x               \b, length %u
+#>>21  leshort x               \b, loop point %u
+#>>23  byte    x               \b, master volume %u
+#>>24  byte    x               \b, song speed %u
+#>>25  byte    x               \b, song speed2 %u
+#>>26  byte    x               \b, song rate %u
+#>>27  belong  x               \b, flags %#x
+#>>31  byte    x               \b, multiplex period %u
+#>>32  byte    x               \b, pitch inaccuracy %u
+>>149  pstring x               \b, title %s
+
+0      string  cyd!inst        Klystrack instrument
+
+# magic for WOPL instrument files, https://github.com/Wohlstand/OPL3BankEditor
+# see Specifications/WOPL-and-OPLI-Specification.txt
+
+0      string  WOPL3-INST\0    WOPL instrument
+>11    leshort x       \b, version %u
+0      string  WOPL3-BANK\0    WOPL instrument bank
+>11    leshort x       \b, version %u
+
+# AdLib/OPL instrument files. Format specifications on
+#  http://www.shikadi.net/moddingwiki
+0      string  Junglevision\ Patch\ File       Junglevision instrument data
+0      string  #OPL_II#        DMX OP2 instrument data
+0      string  IBK\x1a         IBK instrument data
+0      string  2OP\x1a         IBK instrument data, 2 operators
+0      string  4OP\x1a         IBK instrument data, 4 operators
+2      string  ADLIB-          AdLib instrument data
+>0     byte    x               \b, version %u
+>1     byte    x               \b.%u
+
+# CRI ADX ADPCM audio
+# Used by various Sega games.
+# https://en.wikipedia.org/wiki/ADX_(file_format)
+# https://wiki.multimedia.cx/index.php/CRI_ADX_file
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0x00           beshort         0x8000
+>(2.S-2)       string          (c)CRI          CRI ADX ADPCM audio
+!:ext adx
+!:mime audio/x-adx
+!:strength +50
+>>0x12         byte            x               v%u
+>>0x04         byte            0x02            \b, pre-set prediction coefficients
+>>0x04         byte            0x03            \b, standard ADX
+>>0x04         byte            0x04            \b, exponential scale
+>>0x04         byte            0x10            \b, AHX (Dreamcast)
+>>0x04         byte            0x11            \b, AHX
+>>0x08         belong          x               \b, %u Hz
+>>0x12         byte            0x03
+>>>0x02                beshort         >0x2B
+>>>>0x18       belong          !0              \b, looping
+>>0x12         byte            0x04
+>>>0x02                beshort         >0x37
+>>>>0x24       belong          !0              \b, looping
+>>0x13         byte&0x08       0x08            \b, encrypted
+
+# Lossless audio (.la) (http://www.lossless-audio.com/)
+0      string  LA
+>2     string  03      Lossless audio version 0.3
+>2     string  04      Lossless audio version 0.4
+
+# Sony PlayStation Audio (.xa)
+0      leshort 0x4158  Sony PlayStation Audio
+
+# Portable Sound Format
+# Used for audio rips for various consoles.
+# http://fileformats.archiveteam.org/wiki/Portable_Sound_Format
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0      string  PSF     Portable Sound Format
+!:mime audio/x-psf
+>3     byte    0x01    (Sony PlayStation)
+>3     byte    0x02    (Sony PlayStation 2)
+>3     byte    0x11    (Sega Saturn)
+>3     byte    0x12    (Sega Dreamcast)
+>3     byte    0x13    (Sega Mega Drive)
+>3     byte    0x21    (Nintendo 64)
+>3     byte    0x22    (Game Boy Advance)
+>3     byte    0x23    (Super NES)
+>3     byte    0x41    (Capcom QSound)
+
+# Atari 8-bit SAP audio format
+# http://asap.sourceforge.net/sap-format.html
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0      string          SAP\r\n Atari 8-bit SAP audio file
+!:mime audio/x-sap
+!:ext  sap
+>5     search/1024     NAME
+>>&1   string          x       \b: %s
+>>5    search/1024     AUTHOR
+>>>&1  string          x       by %s
+
+# Nintendo Wii BRSTM audio format (fields)
+# NOTE: Assuming HEAD starts at 0x40.
+# FIXME: Replace 0x48 with HEAD offset plus 8.
+0      name    nintendo-wii-brstm-fields
+>(0x10.L)      string  HEAD    \b:
+>>(0x10.L+0x0C)        belong  x
+>>>(&-4.L+0x48)        belong  x
+>>>>&-4                byte    0       PCM, signed 8-bit,
+>>>>&-4                byte    1       PCM, signed 16-bit,
+>>>>&-4                byte    2       THP ADPCM,
+>>>>&-3                byte    !0      looping,
+>>>>&-2                byte    1       mono
+>>>>&-2                byte    2       stereo
+>>>>&-2                byte    3       3 channels
+>>>>&-2                byte    4       quad
+>>>>&-2                byte    >4      %u channels
+>>>>&0         beshort !0      %u Hz
+
+# Nintendo Wii BRSTM audio format
+# https://wiibrew.org/wiki/BRSTM_file
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0      string          RSTM    Nintendo Wii BRSTM audio file
+!:mime audio/x-brstm
+!:ext  brstm
+# Wii is big-endian, so default to BE.
+>4     beshort         0xFEFF
+>>0    use             nintendo-wii-brstm-fields
+>4     leshort         0xFEFF
+>>0    use             \^nintendo-wii-brstm-fields
+
+# Nintendo 3DS BCSTM audio format (fields)
+0      name    nintendo-3ds-bcstm-fields
+>(0x18.l)      string  INFO    \b:
+# INFO block: Stream information starts at 0x20 (minus 4 for the 'INFO' magic)
+>>&0x1C                byte    0       PCM, signed 8-bit,
+>>&0x1C                byte    1       PCM, signed 16-bit,
+>>&0x1C                byte    2       DSP ADPCM,
+>>&0x1C                byte    3       IMA ADPCM,
+>>&0x1D                byte    !0      looping,
+>>&0x1E                byte    1       mono
+>>&0x1E                byte    2       stereo
+>>&0x1E                byte    3       3 channels
+>>&0x1E                byte    4       quad
+>>&0x1E                byte    >4      %u channels
+>>&0x20                lelong  !0      %u Hz
+
+# Nintendo 3DS BCSTM audio format
+# https://www.3dbrew.org/wiki/BCSTM
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0      string          CSTM    Nintendo 3DS BCSTM audio file
+!:mime audio/x-bcstm
+!:ext  bcstm
+# 3DS is little-endian, so default to LE.
+>4     leshort         0xFEFF
+>>0    use             nintendo-3ds-bcstm-fields
+>4     beshort         0xFEFF
+>>0    use             \^nintendo-3ds-bcstm-fields
+
+# Nintendo Wii U BFSTM audio format
+# http://mk8.tockdom.com/wiki/BFSTM_(File_Format)
+# NOTE: This format is very similar to BCSTM.
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0      string          FSTM    Nintendo Wii U BFSTM audio file
+!:mime audio/x-bfstm
+!:ext  bfstm
+# BFSTM is used on both Wii U (BE) and Switch (LE),
+# so default to LE.
+>4     leshort         0xFEFF
+>>0    use             nintendo-3ds-bcstm-fields
+>4     beshort         0xFEFF
+>>0    use             \^nintendo-3ds-bcstm-fields
+
+# Nintendo 3DS BCSTM audio format (fields)
+0      name    nintendo-3ds-bcwav-fields
+>(0x18.l)      string  INFO    \b:
+# INFO block (minus 4 for INFO magic)
+>>&0x4         byte    0       PCM, signed 8-bit,
+>>&0x4         byte    1       PCM, signed 16-bit,
+>>&0x4         byte    2       DSP ADPCM,
+>>&0x4         byte    3       IMA ADPCM,
+>>&0x5         byte    !0      looping,
+>>&0x8         lelong  x       stereo
+>>&0x8         lelong  !0      %u Hz
+
+# Nintendo 3DS BCWAV audio format
+# https://www.3dbrew.org/wiki/BCWAV
+# Added by David Korth <gerbilsoft@gerbilsoft.com>
+0      string          CWAV    Nintendo 3DS BCWAV audio file
+!:mime audio/x-bcwav
+!:ext  bcwav
+# 3DS is little-endian, so default to LE.
+>4     leshort         0xFEFF
+>>0    use             nintendo-3ds-bcwav-fields
+>4     beshort         0xFEFF
+>>0    use             \^nintendo-3ds-bcwav-fields
diff --git a/magic/Magdir/basis b/magic/Magdir/basis
new file mode 100644 (file)
index 0000000..19dd463
--- /dev/null
@@ -0,0 +1,18 @@
+
+#----------------------------------------------------------------
+# $File: basis,v 1.5 2019/04/19 00:42:27 christos Exp $
+# basis: file(1) magic for BBx/Pro5-files
+#      Oliver Dammer <dammer@olida.de>  2005/11/07
+# https://www.basis.com business-basic-files.
+#
+0      string          \074\074bbx\076\076     BBx
+>7     string          \000                    indexed file
+>7     string          \001                    serial file
+>7     string          \002                    keyed file
+>>13   short           0                       (sort)
+>7     string          \004                    program
+>>18   byte            x                       (LEVEL %d)
+>>>23  string          >\000                   psaved
+>7     string          \006                    mkeyed file
+>>13   short           0                       (sort)
+>>8    string          \000                    (mkey)
diff --git a/magic/Magdir/beetle b/magic/Magdir/beetle
new file mode 100644 (file)
index 0000000..94a835c
--- /dev/null
@@ -0,0 +1,7 @@
+#------------------------------------------------------------------------------
+# $File: beetle,v 1.2 2018/02/05 23:42:17 rrt Exp $
+# beetle:  file(1) magic for Beetle VM object files
+# https://github.com/rrthomas/beetle/
+
+# Beetle object module
+0      string          BEETLE\000      Beetle VM object file
diff --git a/magic/Magdir/ber b/magic/Magdir/ber
new file mode 100644 (file)
index 0000000..15288c6
--- /dev/null
@@ -0,0 +1,65 @@
+
+#------------------------------------------------------------------------------
+# $File: ber,v 1.2 2019/04/19 00:42:27 christos Exp $
+# ber:  file(1) magic for several BER formats used in the mobile
+# telecommunications industry (Georg Sauthoff)
+
+# The file formats are standardized by the GSMA (GSM association).
+# They are specified via ASN.1 schemas and some prose. Basic encoding
+# rules (BER) is the used encoding. The formats are used for exchanging
+# call data records (CDRs) between mobile operators and associated
+# parties for roaming clearing purposes and fraud detection.
+
+# The magic file covers:
+
+# - TAP files (TD.57) - CDR batches and notifications
+# - RAP files (TD.32) - return batches and acknowledgements
+# - NRT files (TD.35) - CDR batches for 'near real time' processing
+
+#
+# TAP 3 Files
+# TAP -> Transferred Account Procedure
+# cf. https://www.gsma.com/newsroom/wp-content/uploads/TD.57-v32.31.pdf
+# TransferBatch short tag
+0      byte    0x61
+# BatchControlInfo short tag
+>&1    search/b5       \x64
+# Sender long tag #TAP 3.x (BER encoded)
+>>&1   search/b8       \x5f\x81\x44
+# <SpecificationVersionNumber>3</><ReleaseVersionNumber> block
+>>>&64 search/b64      \x5f\x81\x49\x01\x03\x5f\x81\x3d\x01
+>>>>&0 byte    x       TAP 3.%d Batch (TD.57, Transferred Account)
+
+# Notification short tag
+0      byte    0x62
+# Sender long tag
+>2     search/b8       \x5f\x81\x44
+# <SpecificationVersionNumber>3</><ReleaseVersionNumber> block
+>>&64  search/b64      \x5f\x81\x49\x01\x03\x5f\x81\x3d\x01
+>>>&0  byte    x       TAP 3.%d Notification (TD.57, Transferred Account)
+
+
+# NRT Files
+# NRT a.k.a. NRTRDE
+0      byte    0x61
+# <SpecificationVersionNumber>2</><ReleaseVersionNumber> block
+>&1    search/b8 \x5f\x29\x01\x02\x5f\x25\x01
+>>&0   byte    x       NRT 2.%d (TD.35, Near Real Time Roaming Data Exchange)
+
+# RAP Files
+# cf. https://www.gsma.com/newsroom/wp-content/uploads/TD.32-v6.11.pdf
+# Long ReturnBatch tag
+0      string  \x7f\x84\x16
+# Long RapBatchControlInfo tag
+>&1    search/b8       \x7f\x84\x19
+# <SpecificationVersionNumber>3</><ReleaseVersionNumber> block
+>>&64  search/b64      \x5f\x81\x49\x01\x03\x5f\x81\x3d\x01
+# <RapSpecificationVersionNumber>1</><RapReleaseVersionNumber> block
+>>>&1  string/b        \x5f\x84\x20\x01\x01\x5f\x84\x1f\x01
+>>>>&0 byte    x       RAP 1.%d Batch (TD.32, Returned Account Procedure),
+>>>&0  byte    x       TAP 3.%d
+
+# Long Acknowledgement tag
+0      string \x7f\x84\x17
+# Long Sender tag
+>&1    search/b5       \x5f\x81\x44    RAP Acknowledgement (TD.32, Returned Account Procedure)
diff --git a/magic/Magdir/bflt b/magic/Magdir/bflt
new file mode 100644 (file)
index 0000000..07cc0a7
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File: bflt,v 1.4 2009/09/19 16:28:08 christos Exp $
+# bFLT: file(1) magic for BFLT uclinux binary files
+#
+# From Philippe De Muyter <phdm@macqel.be>
+#
+0      string          bFLT            BFLT executable
+>4     belong          x               - version %d
+>4     belong          4
+>>36   belong&0x1      0x1             ram
+>>36   belong&0x2      0x2             gotpic
+>>36   belong&0x4      0x4             gzip
+>>36   belong&0x8      0x8             gzdata
diff --git a/magic/Magdir/bhl b/magic/Magdir/bhl
new file mode 100644 (file)
index 0000000..6f57f03
--- /dev/null
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# $File: bhl,v 1.1 2017/06/11 22:20:02 christos Exp $
+# BlockHashLoc
+# ext: bhl
+# Marco Pontello marcopon@gmail.com
+# reference: https://github.com/MarcoPon/BlockHashLoc
+0      string  BlockHashLoc\x1a        BlockHashLoc recovery info,
+>13    byte    x                       version %d
+!:ext   bhl
diff --git a/magic/Magdir/bioinformatics b/magic/Magdir/bioinformatics
new file mode 100644 (file)
index 0000000..2966fa6
--- /dev/null
@@ -0,0 +1,178 @@
+
+#------------------------------------------------------------------------------
+# $File: bioinformatics,v 1.5 2019/04/19 00:42:27 christos Exp $
+# bioinfomatics:  file(1) magic for Bioinfomatics file formats
+
+###############################################################################
+# BGZF (Blocked GNU Zip Format) - gzip compatible, but also indexable
+# used by SAMtools bgzip/tabix (http://samtools.sourceforge.net/tabix.shtml)
+###############################################################################
+0      string          \037\213
+>3     byte            &0x04
+>>12   string          BC
+>>>14  leshort         &0x02   Blocked GNU Zip Format (BGZF; gzip compatible)
+>>>>16 leshort         x       \b, block length %d
+!:mime application/x-gzip
+
+
+###############################################################################
+# Tabix index file
+# used by SAMtools bgzip/tabix (http://samtools.sourceforge.net/tabix.shtml)
+###############################################################################
+0      string  TBI\1           SAMtools TBI (Tabix index format)
+>0x04  lelong  =1              \b, with %d reference sequence
+>0x04  lelong  >1              \b, with %d reference sequences
+>0x08  lelong  &0x10000        \b, using half-closed-half-open coordinates (BED style)
+>0x08  lelong  ^0x10000
+>>0x08 lelong  =0              \b, using closed and one based coordinates (GFF style)
+>>0x08 lelong  =1              \b, using SAM format
+>>0x08 lelong  =2              \b, using VCF format
+>0x0c  lelong  x               \b, sequence name column: %d
+>0x10  lelong  x               \b, region start column: %d
+>0x08  lelong  =0
+>>0x14 lelong  x               \b, region end column: %d
+>0x18  byte    x               \b, comment character: %c
+>0x1c  lelong  x               \b, skip line count: %d
+
+
+###############################################################################
+# BAM (Binary Sequence Alignment/Map format)
+# used by SAMtools (http://samtools.sourceforge.net/SAM1.pdf)
+# data is normally present only within compressed BGZF blocks (CDATA), so use file -z to examine it
+###############################################################################
+0      string  BAM\1   SAMtools BAM (Binary Sequence Alignment/Map)
+>0x04  lelong  >0
+>>&0x00 regex  =^[@]HD\t.*VN:          \b, with SAM header
+>>>&0  regex   =[0-9.]+                \b version %s
+>>&(0x04)      lelong  >0      \b, with %d reference sequences
+
+
+###############################################################################
+# BAI (BAM indexing format)
+# used by SAMtools (http://samtools.sourceforge.net/SAM1.pdf)
+###############################################################################
+0              string  BAI\1   SAMtools BAI (BAM indexing format)
+>0x04          lelong  >0      \b, with %d reference sequences
+
+
+###############################################################################
+# CRAM (Binary Sequence Alignment/Map format)
+###############################################################################
+0      string  CRAM    CRAM
+>0x04  byte    >-1     version %d.
+>0x05  byte    >-1     \b%d
+>0x06  string  >\0     (identified as %s)
+
+
+###############################################################################
+# BCF (Binary Call Format), version 1
+# used by SAMtools & VCFtools (http://vcftools.sourceforge.net/bcf.pdf)
+# data is normally present only within compressed BGZF blocks (CDATA), so use file -z to examine it
+###############################################################################
+0              string     BCF\4
+# length of seqnm data in bytes is positive
+>&0x00         lelong    >0
+# length of smpl data in bytes is positive
+>>&(&-0x04)    lelong    >0                    SAMtools BCF (Binary Call Format)
+# length of meta in bytes
+>>>&(&-0x04)   lelong    >0
+# have meta text string
+>>>>&0x00      search    ##samtoolsVersion=
+>>>>>&0x00     string    x                     \b, generated by SAMtools version %s
+
+
+###############################################################################
+# BCF (Binary Call Format), version 2.1
+# used by SAMtools (https://samtools.github.io/hts-specs/BCFv2_qref.pdf)
+# data is normally present only within compressed BGZF blocks (CDATA), so use file -z to examine it
+###############################################################################
+0              string     BCF\2\1    Binary Call Format (BCF) version 2.1
+# length of header text
+>&0x00         lelong    >0
+# have header string
+>>&0x00 search   ##samtoolsVersion=
+>>>&0x00       string    x                     \b, generated by SAMtools version %s
+
+
+###############################################################################
+# BCF (Binary Call Format), version 2.2
+# used by SAMtools (https://samtools.github.io/hts-specs/BCFv2_qref.pdf)
+# data is normally present only within compressed BGZF blocks (CDATA), so use file -z to examine it
+###############################################################################
+0              string     BCF\2\2    Binary Call Format (BCF) version 2.2
+# length of header text
+>&0x00         lelong    >0
+# have header string
+>>&0x00 search   ##samtoolsVersion=
+>>>&0x00       string    x                     \b, generated by SAMtools version %s
+
+###############################################################################
+# VCF (Variant Call Format)
+# used by VCFtools (http://vcftools.sourceforge.net/)
+###############################################################################
+0      search     ##fileformat=VCFv    Variant Call Format (VCF)
+>&0    string     x                    \b version %s
+
+###############################################################################
+# FASTQ
+# used by MAQ (http://maq.sourceforge.net/fastq.shtml)
+###############################################################################
+# XXX Broken?
+# @<seqname>
+#0     regex   =^@[A-Za-z0-9_.:-]+\?\n
+# <seq>
+#>&1   regex   =^[A-Za-z\n.~]++
+# +[<seqname>]
+#>>&1  regex   =^[A-Za-z0-9_.:-]*\?\n
+# <qual>
+#>>>&1 regex   =^[!-~\n]+\n            FASTQ
+
+###############################################################################
+# FASTA
+# used by FASTA (https://fasta.bioch.virginia.edu/fasta_www2/fasta_guide.pdf)
+###############################################################################
+#0     byte    0x3e
+# q>0  regex   =^[>][!-~\t\ ]+$
+# Amino Acid codes: [A-IK-Z*-]+
+#>>1   regex   !=[!-'Jj;:=?@^`|~\\]            FASTA
+# IUPAC codes/gaps: [ACGTURYKMSWBDHVNX-]+
+# not in IUPAC codes/gaps: [EFIJLOPQZ]
+#>>>1  regex   !=[EFIJLOPQZefijlopqz]          \b, with IUPAC nucleotide codes
+#>>>1  regex   =^[EFIJLOPQZefijlopqz]+$        \b, with Amino Acid codes
+
+###############################################################################
+# SAM (Sequence Alignment/Map format)
+# used by SAMtools (http://samtools.sourceforge.net/SAM1.pdf)
+###############################################################################
+# Short-cut version to recognise SAM files with (optional) header at beginning
+###############################################################################
+0      string     @HD\t
+>4     search     VN:          Sequence Alignment/Map (SAM), with header
+>>&0   regex      [0-9.]+      \b version %s
+###############################################################################
+# Longer version to recognise SAM alignment lines using (many) regexes
+###############################################################################
+# SAM Alignment QNAME
+0              regex   =^[!-?A-~]{1,255}(\t[^\t]+){11}
+# SAM Alignment FLAG
+>0             regex   =^([^\t]+\t){1}[0-9]{1,5}\t
+# SAM Alignment RNAME
+>>0            regex   =^([^\t]+\t){2}\\*|[^*=]*\t
+# SAM Alignment POS
+>>>0           regex   =^([^\t]+\t){3}[0-9]{1,9}\t
+# SAM Alignment MAPQ
+>>>>0          regex   =^([^\t]+\t){4}[0-9]{1,3}\t
+# SAM Alignment CIGAR
+>>>>>0         regex   =\t(\\*|([0-9]+[MIDNSHPX=])+)\t
+# SAM Alignment RNEXT
+>>>>>>0                regex   =\t(\\*|=|[!-()+->?-~][!-~]*)\t
+# SAM Alignment PNEXT
+>>>>>>>0       regex   =^([^\t]+\t){7}[0-9]{1,9}\t
+# SAM Alignment TLEN
+>>>>>>>>0      regex   =\t[+-]{0,1}[0-9]{1,9}\t.*\t
+# SAM Alignment SEQ
+>>>>>>>>>0     regex   =^([^\t]+\t){9}(\\*|[A-Za-z=.]+)\t
+# SAM Alignment QUAL
+>>>>>>>>>>0    regex   =^([^\t]+\t){10}[!-~]+  Sequence Alignment/Map (SAM)
+>>>>>>>>>>>0   regex   =^[@]HD\t.*VN:          \b, with header
+>>>>>>>>>>>>&0 regex   =[0-9.]+                \b version %s
diff --git a/magic/Magdir/biosig b/magic/Magdir/biosig
new file mode 100644 (file)
index 0000000..e490f6c
--- /dev/null
@@ -0,0 +1,154 @@
+
+##############################################################################
+#
+#    Magic ids for biomedical signal file formats 
+#    Copyright (C) 2018 Alois Schloegl <alois.schloegl@gmail.com>
+#
+#    The list has been derived from biosig projects
+#      http://biosig.sourceforge.net
+#      https://pub.ist.ac.at/~schloegl/matlab/eeg/
+#      https://pub.ist.ac.at/~schloegl/biosig/TESTED
+#
+##############################################################################
+#
+0      string  ABF\x20                                 Biosig/Axon Binary format
+!:mime biosig/abf2
+0      string  ABF2\0\0                                Biosig/Axon Binary format
+!:mime biosig/abf2
+#
+0      string  ATES\x20MEDICA\x20SOFT.\x20EEG\x20for\x20Windows        Biosig/ATES MEDICA SOFT. EEG for Windows
+!:mime biosig/ates
+#
+0      string  ATF\x09                                 Biosig/Axon Text fomrat
+!:mime biosig/atf
+#
+0      string  ADU1                                    Biosig/Axona file format
+!:mime biosig/axona
+0      string  ADU2                                    Biosig/Axona file format
+!:mime biosig/axona
+#
+0      string  ALPHA-TRACE-MEDICAL                     Biosig/alpha trace 
+!:mime biosig/alpha
+#
+0       string  AxGr                                   Biosig/AXG
+0       string  axgx                                   Biosig/AXG
+!:mime biosig/axg
+#
+0      string  HeaderLen=                              Biosig/BCI2000
+0      string  BCI2000V                                Biosig/BCI2000
+!:mime biosig/bci2000
+#
+### Specification: https://www.biosemi.com/faq/file_format.htm
+0      string  \xffBIOSEMI                             Biosig/Biosemi data format
+!:mime biosig/bdf
+#
+0      string  Brain\x20Vision\x20Data\x20Exchange\x20Header\x20File                   Biosig/Brainvision data file
+0      string  Brain\x20Vision\x20V-Amp\x20Data\x20Header\x20File\x20Version           Biosig/Brainvision V-Amp file
+0      string  Brain\x20Vision\x20Data\x20Exchange\x20Marker\x20File,\x20Version       Biosig/Brainvision Marker file
+!:mime biosig/brainvision
+#
+0      string  CEDFILE                                 Biosig/CFS: Cambridge Electronic devices File format 
+!:mime biosig/ced
+#
+### Specification: https://www.edfplus.info/specs/index.html
+0      string  0\x20\x20\x20\x20\x20\x20\x20           Biosig/EDF: European Data format
+!:mime biosig/edf
+#
+### Specifications: https://arxiv.org/abs/cs/0608052
+0      string  GDF                                     Biosig/GDF: General data format for biosignals
+!:mime biosig/gdf
+#
+0      string  DATA\0\0\0\0                            Biosig/Heka Patchmaster
+0      string  DAT1\0\0\0\0                            Biosig/Heka Patchmaster
+0      string  DAT2\0\0\0\0                            Biosig/Heka Patchmaster
+!:mime biosig/heka
+#
+0      string  (C)\x20CED\x2087                        Biosig/CED SMR 
+!:mime biosig/ced-smr
+#
+0      string  CFWB\1\0\0\0                            Biosig/CFWB
+!:mime biosig/cfwb
+#
+0      string  DEMG                                    Biosig/DEMG
+!:mime biosig/demg
+#
+0      string  EBS\x94\x0a\x13\x1a\x0d                 Biosig/EBS
+!:mime biosig/ebs
+#
+0      string  Embla\x20data\x20file                   Biosig/Embla
+!:mime biosig/embla
+#
+0      string  Header\r\nFile Version                  Biosig/ETG4000
+!:mime biosig/etg4000
+#
+0      string  GALILEO\x20EEG\x20TRACE\x20FILE         Biosig/Galileo 
+!:mime biosig/galileo
+#
+0      string  IGOR                                    Biosig/IgorPro ITX file
+!:mime biosig/igorpro
+#
+#      Specification: http://www.ampsmedical.com/uploads/2017-12-7/The_ISHNE_Format.pdf
+0      string  ISHNE1.0                                Biosig/ISHNE
+!:mime biosig/ishne
+#
+#      CEN/ISO 11073/22077 series, http://www.mfer.org/en/document.htm
+0      string  @\x20\x20MFER\x20                       Biosig/MFER
+0      string  @\x20MFR\x20                            Biosig/MFER
+!:mime biosig/mfer
+#
+0      string  NEURALEV                                Biosig/NEV
+0      string  N.EV.\0                                 Biosig/NEV
+!:mime biosig/nev
+#
+0      string  NEX1                                    Biosig/NEX
+!:mime biosig/nex1
+#
+0      string  PLEX                                    Biosig/Plexon v1.0
+10     string  PLEXON                                  Biosig/Plexon v2.0
+!:mime biosig/plexon
+#
+0      string  \x02\x27\x91\xC6                        Biosig/RHD2000: Intan RHD2000 format
+#
+#      Specification: CEN 1064:2005/ISO 11073:91064
+16     string  SCPECG\0\0                              Biosig/SCP-ECG format CEN 1064:2005/ISO 11073:91064
+!:mime biosig/scpecg
+#
+0      string  IAvSFo                                                                  Biosig/SIGIF
+!:mime biosig/sigif
+#
+0      string  POLY\x20SAMPLE\x20FILEversion\x20                                       Biosig/TMS32
+!:mime biosig/tms32
+#
+0      string  FileId=TMSi\x20PortiLab\x20sample\x20log\x20file\x0a\x0dVersion=        Biosig/TMSiLOG
+!:mime biosig/tmsilog
+#
+4      string  Synergy\0\48\49\50\46\48\48\51\46\48\48\48\46\48\48\48\0\28\0\0\0\2\0\0\0
+>63    string  CRawDataElement
+>>85   string  CRawDataBuffer                                                          Biosig/SYNERGY
+!:mime biosig/synergy
+#
+4      string  \40\0\4\1\44\1\102\2\146\3\44\0\190\3                                   Biosig/UNIPRO
+!:mime biosig/unipro
+#
+0      string  VER=9\r\nCTIME=                                                         Biosig/WCP
+!:mime biosig/wcp
+#
+0      string  \xAF\xFE\xDA\xDA                                                        Biosig/Walter Graphtek
+0      string  \xDA\xDA\xFE\xAF                                                        Biosig/Walter Graphtek
+0      string  \x55\x55\xFE\xAF                                                        Biosig/Walter Graphtek
+!:mime biosig/walter-graphtek
+#
+0      string  V3.0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
+>32    string  [PatInfo]                                                               Biosig/Sigma
+!:mime biosig/sigma
+#
+0      string  \067\069\078\013\010\0x1a\04\0x84                                       Biosig/File exchange format (FEF)
+!:mime biosig/fef
+0      string  \67\69\78\0x13\0x10\0x1a\4\0x84                                         Biosig/File exchange format (FEF)
+!:mime biosig/fef
+#
+0      string  \0\0\0\x64\0\0\0\x1f\0\0\0\x14\0\0\0\0\0\1
+>36    string  \0\0\0\x65\0\0\0\3\0\0\0\4\0\0
+>>56   string  \0\0\0\x6a\0\0\0\3\0\0\0\4\0\0\0\0\xff\xff\xff\xff\0\0                  Biosig/FIFF
+!:mime biosig/fiff
+#
diff --git a/magic/Magdir/blackberry b/magic/Magdir/blackberry
new file mode 100644 (file)
index 0000000..2e38a54
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File: blackberry,v 1.2 2017/03/17 21:35:28 christos Exp $
+# blackberry:  file(1) magic for BlackBerry file formats
+#
+5      belong  0
+>8     belong  010010010       BlackBerry RIM ETP file
+>>22   string  x               \b for %s
diff --git a/magic/Magdir/blcr b/magic/Magdir/blcr
new file mode 100644 (file)
index 0000000..d2f901a
--- /dev/null
@@ -0,0 +1,25 @@
+# Berkeley Lab Checkpoint Restart (BLCR) checkpoint context files
+# https://ftg.lbl.gov/checkpoint
+0      string  C\0\0\0R\0\0\0  BLCR
+>16    lelong  1       x86
+>16    lelong  3       alpha
+>16    lelong  5       x86-64
+>16    lelong  7       ARM
+>8     lelong  x       context data (little endian, version %d)
+# Uncomment the following only of your "file" program supports "search"
+#>0    search/1024     VMA\06  for kernel
+#>>&1  byte    x       %d.
+#>>&2  byte    x       \b%d.
+#>>&3  byte    x       \b%d
+0      string  \0\0\0C\0\0\0R  BLCR
+>16    belong  2       SPARC
+>16    belong  4       ppc
+>16    belong  6       ppc64
+>16    belong  7       ARMEB
+>16    belong  8       SPARC64
+>8     belong  x       context data (big endian, version %d)
+# Uncomment the following only of your "file" program supports "search"
+#>0    search/1024     VMA\06  for kernel
+#>>&1  byte    x       %d.
+#>>&2  byte    x       \b%d.
+#>>&3  byte    x       \b%d
diff --git a/magic/Magdir/blender b/magic/Magdir/blender
new file mode 100644 (file)
index 0000000..276242e
--- /dev/null
@@ -0,0 +1,39 @@
+
+#------------------------------------------------------------------------------
+# $File: blender,v 1.8 2019/04/19 00:42:27 christos Exp $
+# blender: file(1) magic for Blender 3D related files
+#
+# Native format rule v1.2. For questions use the developers list
+# https://lists.blender.org/mailman/listinfo/bf-committers
+# GLOB chunk was moved near start and provides subversion info since 2.42
+
+0              string  =BLENDER        Blender3D,
+>7             string  =_              saved as 32-bits
+>>8            string  =v              little endian
+>>>9           byte    x               with version %c.
+>>>10          byte    x               \b%c
+>>>11          byte    x               \b%c
+>>>0x40                string  =GLOB           \b.
+>>>>0x58       leshort x               \b%.4d
+>>8            string  =V              big endian
+>>>9           byte    x               with version %c.
+>>>10          byte    x               \b%c
+>>>11          byte    x               \b%c
+>>>0x40                string  =GLOB           \b.
+>>>>0x58       beshort x               \b%.4d
+>7             string  =-              saved as 64-bits
+>>8            string  =v              little endian
+>>9            byte    x               with version %c.
+>>10           byte    x               \b%c
+>>11           byte    x               \b%c
+>>0x44         string  =GLOB           \b.
+>>>0x60                leshort x               \b%.4d
+>>8            string  =V              big endian
+>>>9           byte    x               with version %c.
+>>>10          byte    x               \b%c
+>>>11          byte    x               \b%c
+>>>0x44                string  =GLOB           \b.
+>>>>0x60       beshort x               \b%.4d
+
+# Scripts that run in the embedded Python interpreter
+0              string  #!BPY           Blender3D BPython script
diff --git a/magic/Magdir/blit b/magic/Magdir/blit
new file mode 100644 (file)
index 0000000..c78c7ef
--- /dev/null
@@ -0,0 +1,20 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# blit:  file(1) magic for 68K Blit stuff as seen from 680x0 machine
+#
+# Note that this 0407 conflicts with several other a.out formats...
+#
+# XXX - should this be redone with "be" and "le", so that it works on
+# little-endian machines as well?  If so, what's the deal with
+# "VAX-order" and "VAX-order2"?
+#
+#0     long            0407            68K Blit (standalone) executable
+#0     short           0407            VAX-order2 68K Blit (standalone) executable
+0      short           03401           VAX-order 68K Blit (standalone) executable
+0      long            0406            68k Blit mpx/mux executable
+0      short           0406            VAX-order2 68k Blit mpx/mux executable
+0      short           03001           VAX-order 68k Blit mpx/mux executable
+# Need more values for WE32 DMD executables.
+# Note that 0520 is the same as COFF
+#0     short           0520            tty630 layers executable
diff --git a/magic/Magdir/bout b/magic/Magdir/bout
new file mode 100644 (file)
index 0000000..a8b2190
--- /dev/null
@@ -0,0 +1,11 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# i80960 b.out objects and archives
+#
+0      long            0x10d           i960 b.out relocatable object
+>16    long            >0              not stripped
+#
+# b.out archive (hp-rt on i960)
+0      string          =!<bout>        b.out archive
+>8     string          __.SYMDEF       random library
diff --git a/magic/Magdir/bsdi b/magic/Magdir/bsdi
new file mode 100644 (file)
index 0000000..5109445
--- /dev/null
@@ -0,0 +1,33 @@
+
+#------------------------------------------------------------------------------
+# $File: bsdi,v 1.6 2013/01/09 22:37:24 christos Exp $
+# bsdi:  file(1) magic for BSD/OS (from BSDI) objects
+# Some object/executable formats use the same magic numbers as are used
+# in other OSes; those are handled by entries in aout.
+#
+
+0      lelong          0314            386 compact demand paged pure executable
+>16    lelong          >0              not stripped
+>32    byte            0x6a            (uses shared libs)
+
+# same as in SunOS 4.x, except for static shared libraries
+0      belong&077777777        0600413         SPARC demand paged
+>0     byte            &0x80
+>>20   belong          <4096           shared library
+>>20   belong          =4096           dynamically linked executable
+>>20   belong          >4096           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+>36    belong          0xb4100001      (uses shared libs)
+
+0      belong&077777777        0600410         SPARC pure
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+>36    belong          0xb4100001      (uses shared libs)
+
+0      belong&077777777        0600407         SPARC
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+>36    belong          0xb4100001      (uses shared libs)
diff --git a/magic/Magdir/bsi b/magic/Magdir/bsi
new file mode 100644 (file)
index 0000000..51a6289
--- /dev/null
@@ -0,0 +1,9 @@
+# Chiasmus is a encryption standard developed by the German Federal
+# Office for Information Security (Bundesamt fuer Sicherheit in der
+# Informationstechnik).
+
+# Extension: .xia
+0      string  XIA1    Chiasmus encrypted data
+
+# Extension: .xis
+0      string  XIS     Chiasmus key
diff --git a/magic/Magdir/btsnoop b/magic/Magdir/btsnoop
new file mode 100644 (file)
index 0000000..a77f7d1
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# BTSnoop:  file(1) magic for BTSnoop files
+#
+# From <marcel@holtmann.org>
+0      string          btsnoop\0               BTSnoop
+>8     belong          x                       version %d,
+>12    belong          1001                    Unencapsulated HCI
+>12    belong          1002                    HCI UART (H4)
+>12    belong          1003                    HCI BCSP
+>12    belong          1004                    HCI Serial (H5)
+>>12   belong          x                       type %d
diff --git a/magic/Magdir/c-lang b/magic/Magdir/c-lang
new file mode 100644 (file)
index 0000000..becf6b0
--- /dev/null
@@ -0,0 +1,107 @@
+#------------------------------------------------------------------------------
+# $File: c-lang,v 1.27 2019/02/27 16:46:23 christos Exp $
+# c-lang:  file(1) magic for C and related languages programs
+#
+# The strength is to beat standard HTML
+
+# BCPL
+0      search/8192     "libhdr"        BCPL source text
+!:mime text/x-bcpl
+0      search/8192     "LIBHDR"        BCPL source text
+!:mime text/x-bcpl
+
+# C
+# Check for class if include is found, otherwise class is beaten by include becouse of lowered strength
+0      search/8192     #include
+>0     regex   \^#include                      C
+>>0    regex   \^class[[:space:]]+
+>>>&0  regex   \\{[\.\*]\\}(;)?$                       \b++
+>>&0   clear   x                               source text
+!:strength + 13
+!:mime text/x-c
+0      search/8192     pragma
+>0     regex   \^#[[:space:]]*pragma   C source text
+!:mime text/x-c
+0      search/8192     endif
+>0     regex   \^#[[:space:]]*(if\|ifn)def
+>>&0   regex   \^#[[:space:]]*endif$   C source text
+!:mime text/x-c
+0      search/8192     define
+>0     regex   \^#[[:space:]]*(if\|ifn)def
+>>&0   regex   \^#[[:space:]]*define   C source text
+!:mime text/x-c
+0      search/8192     char
+>0     regex   \^[[:space:]]*char(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$                   C source text
+!:mime text/x-c
+0      search/8192     double
+>0     regex   \^[[:space:]]*double(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$                 C source text
+!:mime text/x-c
+0      search/8192     extern
+>0     regex   \^[[:space:]]*extern[[:space:]]+                C source text
+!:mime text/x-c
+0      search/8192     float
+>0     regex   \^[[:space:]]*float(\ \\*|\\*)(.+)(=.*)?;[[:space:]]*$                  C source text
+!:mime text/x-c
+0      search/8192     struct
+>0     regex   \^struct[[:space:]]+            C source text
+!:mime text/x-c
+0      search/8192     union
+>0     regex   \^union[[:space:]]+             C source text
+!:mime text/x-c
+0      search/8192     main(
+>&0 regex      \\)[[:space:]]*\\{              C source text
+!:mime text/x-c
+
+# C++
+# The strength of these rules is increased so they beat the C rules above
+0      search/8192     namespace
+>0     regex   \^namespace[[:space:]]+[_[:alpha:]]{1,30}[[:space:]]*\\{        C++ source text
+!:strength + 30
+!:mime text/x-c++
+# using namespace [namespace] or using std::[lib]
+0      search/8192     using
+>0     regex   \^using[[:space:]]+(namespace\ )?std(::)?[[:alpha:]]*[[:space:]]*;              C++ source text
+!:strength + 30
+!:mime text/x-c++
+0      search/8192     template
+>0     regex   \^[[:space:]]*template[[:space:]]*<.*>[[:space:]]*$     C++ source text
+!:strength + 30
+!:mime text/x-c++
+0      search/8192     virtual
+>0     regex   \^[[:space:]]*virtual[[:space:]]+.*[};][[:space:]]*$            C++ source text
+!:strength + 30
+!:mime text/x-c++
+# But class alone is reduced to avoid beating php (Jens Schleusener)
+0      search/8192     class
+>0     regex   \^[[:space:]]*class[[:space:]]+[[:digit:][:alpha:]:_]+[[:space:]]*\\{(.*[\n]*)*\\}(;)?$         C++ source text
+!:strength + 13
+!:mime text/x-c++
+0      search/8192     public
+>0     regex   \^[[:space:]]*public:           C++ source text
+!:strength + 30
+!:mime text/x-c++
+0      search/8192     private
+>0     regex   \^[[:space:]]*private:          C++ source text
+!:strength + 30
+!:mime text/x-c++
+0      search/8192     protected
+>0     regex   \^[[:space:]]*protected:                C++ source text
+!:strength + 30
+!:mime text/x-c++
+
+# Objective-C
+0      search/8192     #import
+>0     regex   \^#import                       Objective-C source text
+!:strength + 25
+!:mime text/x-objective-c
+
+# From: Mikhail Teterin <mi@aldan.algebra.com>
+0      string          cscope          cscope reference data
+>7     string          x               version %.2s
+# We skip the path here, because it is often long (so file will
+# truncate it) and mostly redundant.
+# The inverted index functionality was added some time between
+# versions 11 and 15, so look for -q if version is above 14:
+>7     string          >14
+>>10   search/100      \ -q\           with inverted index
+>10    search/100      \ -c\           text (non-compressed)
diff --git a/magic/Magdir/c64 b/magic/Magdir/c64
new file mode 100644 (file)
index 0000000..ff4e933
--- /dev/null
@@ -0,0 +1,58 @@
+
+#------------------------------------------------------------------------------
+# $File: c64,v 1.7 2017/11/15 12:19:06 christos Exp $
+# c64:  file(1) magic for various commodore 64 related files
+#
+# From: Dirk Jagdmann <doj@cubic.org>
+
+0x16500        belong          0x12014100      D64 Image
+0x16500        belong          0x12014180      D71 Image
+0x61800 belong         0x28034400      D81 Image
+0      string          C64\40CARTRIDGE CCS C64 Emultar Cartridge Image
+0      belong          0x43154164      X64 Image
+
+0      string          GCR-1541        GCR Image
+>8     byte            x               version: %i
+>9     byte            x               tracks: %i
+
+9      string          PSUR            ARC archive (c64)
+2      string          -LH1-           LHA archive (c64)
+
+0      string          C64File         PC64 Emulator file
+>8     string          >\0             "%s"
+0      string          C64Image        PC64 Freezer Image
+
+0      beshort         0x38CD          C64 PCLink Image
+0      string          CBM\144\0\0     Power 64 C64 Emulator Snapshot
+
+0      belong          0xFF424CFF      WRAptor packer (c64)
+
+0      string          C64S\x20tape\x20file    T64 tape Image
+>32    leshort         x               Version:0x%x
+>36    leshort         !0              Entries:%i
+>40    string          x               Name:%.24s
+
+0      string          C64\x20tape\x20image\x20file\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0        T64 tape Image
+>32    leshort         x               Version:0x%x
+>36    leshort         !0              Entries:%i
+>40    string          x               Name:%.24s
+
+0      string          C64S\x20tape\x20image\x20file\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0  T64 tape Image
+>32    leshort         x               Version:0x%x
+>36    leshort         !0              Entries:%i
+>40    string          x               Name:%.24s
+
+# Raw tape file format (.tap files)
+# Esa Hyyti <esa@netlab.tkk.fi>
+0      string          C64-TAPE-RAW    C64 Raw Tape File (.tap),
+>0x0c  byte            x               Version:%u,
+>0x10  lelong          x               Length:%u cycles
+
+# magic for Goattracker2, http://covertbitops.c64.org/
+# from Alex Myczko <alex@aiei.ch>
+0      string          GTS5            GoatTracker 2 song
+>4     string          >\0             \b, "%s"
+>36    string          >\0             \b by %s
+>68    string          >\0             \b (C) %s
+>100   byte            >0              \b, %u subsong(s)
+
diff --git a/magic/Magdir/cad b/magic/Magdir/cad
new file mode 100644 (file)
index 0000000..48a76d1
--- /dev/null
@@ -0,0 +1,190 @@
+
+#------------------------------------------------------------------------------
+# $File: cad,v 1.19 2019/04/19 00:42:27 christos Exp $
+# autocad:  file(1) magic for cad files
+#
+
+# Microstation DGN/CIT Files (www.bentley.com)
+# Last updated July 29, 2005 by Lester Hightower
+# DGN is the default file extension of Microstation/Intergraph CAD files.
+# CIT is the proprietary raster format (similar to TIFF) used to attach
+# raster underlays to Microstation DGN (vector) drawings.
+#
+# http://www.wotsit.org/search.asp
+# https://filext.com/detaillist.php?extdetail=DGN
+# https://filext.com/detaillist.php?extdetail=CIT
+#
+# https://www.bentley.com/products/default.cfm?objectid=97F351F5-9C35-4E5E-89C2
+# 3F86C928&method=display&p_objectid=97F351F5-9C35-4E5E-89C280A93F86C928
+# https://www.bentley.com/products/default.cfm?objectid=A5C2FD43-3AC9-4C71-B682
+# 721C479F&method=display&p_objectid=A5C2FD43-3AC9-4C71-B682C7BE721C479F
+0      string  \010\011\376                    Microstation
+>3     string  \002
+>>30   string  \026\105                        DGNFile
+>>30   string  \034\105                        DGNFile
+>>30   string  \073\107                        DGNFile
+>>30   string  \073\110                        DGNFile
+>>30   string  \106\107                        DGNFile
+>>30   string  \110\103                        DGNFile
+>>30   string  \120\104                        DGNFile
+>>30   string  \172\104                        DGNFile
+>>30   string  \172\105                        DGNFile
+>>30   string  \172\106                        DGNFile
+>>30   string  \234\106                        DGNFile
+>>30   string  \273\105                        DGNFile
+>>30   string  \306\106                        DGNFile
+>>30   string  \310\104                        DGNFile
+>>30   string  \341\104                        DGNFile
+>>30   string  \372\103                        DGNFile
+>>30   string  \372\104                        DGNFile
+>>30   string  \372\106                        DGNFile
+>>30   string  \376\103                        DGNFile
+>4     string  \030\000\000                    CITFile
+>4     string  \030\000\003                    CITFile
+
+# AutoCAD
+# Merge of the different contributions and updates from https://en.wikipedia.org/wiki/Dwg
+# and https://www.iana.org/assignments/media-types/image/vnd.dwg
+0      string  MC0.0   DWG AutoDesk AutoCAD Release 1.0
+!:mime image/vnd.dwg
+0      string  AC1.2   DWG AutoDesk AutoCAD Release 1.2
+!:mime image/vnd.dwg
+0      string  AC1.3   DWG AutoDesk AutoCAD Release 1.3
+!:mime image/vnd.dwg
+0      string  AC1.40  DWG AutoDesk AutoCAD Release 1.40
+!:mime image/vnd.dwg
+0      string  AC1.50  DWG AutoDesk AutoCAD Release 2.05
+!:mime image/vnd.dwg
+0      string  AC2.10  DWG AutoDesk AutoCAD Release 2.10
+!:mime image/vnd.dwg
+0      string  AC2.21  DWG AutoDesk AutoCAD Release 2.21
+!:mime image/vnd.dwg
+0      string  AC2.22  DWG AutoDesk AutoCAD Release 2.22
+!:mime image/vnd.dwg
+0      string  AC1001  DWG AutoDesk AutoCAD Release 2.22
+!:mime image/vnd.dwg
+0      string  AC1002  DWG AutoDesk AutoCAD Release 2.50
+!:mime image/vnd.dwg
+0      string  AC1003  DWG AutoDesk AutoCAD Release 2.60
+!:mime image/vnd.dwg
+0      string  AC1004  DWG AutoDesk AutoCAD Release 9
+!:mime image/vnd.dwg
+0      string  AC1006  DWG AutoDesk AutoCAD Release 10
+!:mime image/vnd.dwg
+0      string  AC1009  DWG AutoDesk AutoCAD Release 11/12
+!:mime image/vnd.dwg
+# AutoCAD DWG versions R13/R14 (www.autodesk.com)
+# Written December 01, 2003 by Lester Hightower
+# Based on the DWG File Format Specifications at http://www.opendwg.org/
+# AutoCad, from Nahuel Greco
+# AutoCAD DWG versions R12/R13/R14 (www.autodesk.com)
+0      string  AC1012  DWG AutoDesk AutoCAD Release 13
+!:mime image/vnd.dwg
+0      string  AC1014  DWG AutoDesk AutoCAD Release 14
+!:mime image/vnd.dwg
+0      string  AC1015  DWG AutoDesk AutoCAD 2000/2002
+!:mime image/vnd.dwg
+
+# A new version of AutoCAD DWG
+# Sergey Zaykov (mail_of_sergey@mail.ru, sergey_zaikov@rambler.ru,
+# ICQ 358572321)
+# From various sources like:
+# https://autodesk.blogs.com/between_the_lines/autocad-release-history.html
+0      string  AC1018  DWG AutoDesk AutoCAD 2004/2005/2006
+!:mime image/vnd.dwg
+0      string  AC1021  DWG AutoDesk AutoCAD 2007/2008/2009
+!:mime image/vnd.dwg
+0      string  AC1024  DWG AutoDesk AutoCAD 2010/2011/2012
+!:mime image/vnd.dwg
+0      string  AC1027  DWG AutoDesk AutoCAD 2013/2014
+!:mime image/vnd.dwg
+
+# KOMPAS 2D drawing from ASCON
+# This is KOMPAS 2D drawing or fragment of drawing but is not detailed nor
+# gathered nor specification
+# ASCON https://ascon.net/main/ in English,
+#      https://ascon.ru/ main site in Russian
+# Extension is CDW for drawing and FRW for fragment of drawing
+# Sergey Zaykov (mail_of_sergey@mail.ru, sergey_zaikov@rambler.ru,
+# ICQ 358572321, https://vkontakte.ru/id16076543)
+# From:
+# https://sd.ascon.ru/otrs/customer.pl?Action=CustomerFAQ&CategoryID=4&ItemID=292
+# (in russian) and my experiments
+0      string  KF
+>2     belong  0x4E00000C      Kompas drawing 12.0 SP1
+>2     belong  0x4D00000C      Kompas drawing 12.0
+>2     belong  0x3200000B      Kompas drawing 11.0 SP1
+>2     belong  0x3100000B      Kompas drawing 11.0
+>2     belong  0x2310000A      Kompas drawing 10.0 SP1
+>2     belong  0x2110000A      Kompas drawing 10.0
+>2     belong  0x08000009      Kompas drawing 9.0 SP1
+>2     belong  0x05000009      Kompas drawing 9.0
+>2     belong  0x33010008      Kompas drawing 8+
+>2     belong  0x1A000008      Kompas drawing 8.0
+>2     belong  0x2C010107      Kompas drawing 7+
+>2     belong  0x05000007      Kompas drawing 7.0
+>2     belong  0x32000006      Kompas drawing 6+
+>2     belong  0x09000006      Kompas drawing 6.0
+>2     belong  0x5C009005      Kompas drawing 5.11R03
+>2     belong  0x54009005      Kompas drawing 5.11R02
+>2     belong  0x51009005      Kompas drawing 5.11R01
+>2     belong  0x22009005      Kompas drawing 5.10R03
+>2     belong  0x22009005      Kompas drawing 5.10R02 mar
+>2     belong  0x21009005      Kompas drawing 5.10R02 febr
+>2     belong  0x19009005      Kompas drawing 5.10R01
+>2     belong  0xF4008005      Kompas drawing 5.9R01.003
+>2     belong  0x1C008005      Kompas drawing 5.9R01.002
+>2     belong  0x11008005      Kompas drawing 5.8R01.003
+
+# CAD: file(1) magic for computer aided design files
+# Phillip Griffith <phillip dot griffith at gmail dot com>
+# AutoCAD magic taken from the Open Design Alliance's OpenDWG specifications.
+#
+0      belong  0x08051700      Bentley/Intergraph MicroStation DGN cell library
+0      belong  0x0809fe02      Bentley/Intergraph MicroStation DGN vector CAD
+0      belong  0xc809fe02      Bentley/Intergraph MicroStation DGN vector CAD
+0      beshort 0x0809          Bentley/Intergraph MicroStation
+>0x02  byte    0xfe
+>>0x04 beshort 0x1800          CIT raster CAD
+
+# 3DS (3d Studio files)
+0      leshort         0x4d4d
+>6     leshort         0x2
+>>8    lelong          0xa
+>>>16  leshort         0x3d3d  3D Studio model
+!:mime image/x-3ds
+!:ext 3ds
+
+# MegaCAD 2D/3D drawing (.prt)
+# https://megacad.de/
+# From: Markus Heidelberg <markus.heidelberg@web.de>
+0      string  MegaCad23\0     MegaCAD 2D/3D drawing
+
+# Hoops CAD files
+# https://docs.techsoft3d.com/visualize/3df/latest/build/general/hsf/\
+# HSF_architecture.html
+# Stephane Charette <stephane.charette@gmail.com>
+0      string  ;;\020HSF\020V          OpenHSF (Hoops Stream Format)
+>7     regex/9 V[.0-9]{4,5}\020        %s
+!:ext hsf
+
+# AutoCAD Drawing Exchange Format
+0      regex           \^[\ \t]*0\r?\000$
+>1     regex           \^[\ \t]*SECTION\r?$
+>>2    regex           \^[\ \t]*2\r?$
+>>>3   regex           \^[\ \t]*HEADER\r?$     AutoCAD Drawing Exchange Format
+!:mime application/x-dxf
+!:ext  dxf
+>>>>&1 search/8192     AC1006                  \b, R10
+>>>>&1 search/8192     AC1009                  \b, R11/R12
+>>>>&1 search/8192     AC1012                  \b, R13
+>>>>&1 search/8192     AC1014                  \b, R14
+>>>>&1 search/8192     AC1015                  \b, version 2000
+>>>>&1 search/8192     AC1018                  \b, version 2004
+>>>>&1 search/8192     AC1021                  \b, version 2007
+>>>>&1 search/8192     AC1024                  \b, version 2010
+
+# The Sketchup 3D model format https://www.sketchup.com/
+0      string  \xff\xfe\xff\x0e\x53\x00\x6b\x00\x65\x00\x74\x00\x63\x00\x68\x00\x55\x00\x70\x00\x20\x00\x4d\x00\x6f\x00\x64\x00\x65\x00\x6c\x00        SketchUp Model
+!:mime application/vnd.sketchup.skp
+!:ext skp
diff --git a/magic/Magdir/cafebabe b/magic/Magdir/cafebabe
new file mode 100644 (file)
index 0000000..18dd1a2
--- /dev/null
@@ -0,0 +1,72 @@
+
+#------------------------------------------------------------------------------
+# $File: cafebabe,v 1.24 2018/10/01 23:33:15 christos Exp $
+# Cafe Babes unite!
+#
+# Since Java bytecode and Mach-O universal binaries have the same magic number,
+# the test must be performed in the same "magic" sequence to get both right.
+# The long at offset 4 in a Mach-O universal binary tells the number of
+# architectures; the short at offset 4 in a Java bytecode file is the JVM minor
+# version and the short at offset 6 is the JVM major version.  Since there are only
+# only 18 labeled Mach-O architectures at current, and the first released
+# Java class format was version 43.0, we can safely choose any number
+# between 18 and 39 to test the number of architectures against
+# (and use as a hack). Let's not use 18, because the Mach-O people
+# might add another one or two as time goes by...
+#
+### JAVA START ###
+0      belong          0xcafebabe
+>4     belong          >30             compiled Java class data,
+!:mime application/x-java-applet
+>>6    beshort         x               version %d.
+>>4    beshort         x               \b%d
+# Which is which?
+#>>4   belong          0x032d          (Java 1.0)
+#>>4   belong          0x032d          (Java 1.1)
+>>4    belong          0x002e          (Java 1.2)
+>>4    belong          0x002f          (Java 1.3)
+>>4    belong          0x0030          (Java 1.4)
+>>4    belong          0x0031          (Java 1.5)
+>>4    belong          0x0032          (Java 1.6)
+>>4    belong          0x0033          (Java 1.7)
+>>4    belong          0x0034          (Java 1.8)
+
+0      belong          0xcafed00d      JAR compressed with pack200,
+>5     byte            x               version %d.
+>4     byte            x               \b%d
+!:mime application/x-java-pack200
+
+
+0      belong          0xcafed00d      JAR compressed with pack200,
+>5     byte            x               version %d.
+>4     byte            x               \b%d
+!:mime application/x-java-pack200
+
+### JAVA END ###
+### MACH-O START ###
+
+0      name            mach-o          \b [
+>0     use             mach-o-cpu      \b
+>(8.L) indirect        x               \b:
+>0     belong          x               \b]
+
+0      belong          0xcafebabe
+>4     belong          1               Mach-O universal binary with 1 architecture:
+!:mime application/x-mach-binary
+>>8    use             mach-o          \b
+>4     belong          >1
+>>4    belong          <20             Mach-O universal binary with %d architectures:
+!:mime application/x-mach-binary
+>>>8   use             mach-o          \b
+>>4    belong          >1
+>>>28  use             mach-o          \b
+>>4    belong          >2
+>>>48  use             mach-o          \b
+>>4    belong          >3
+>>>68  use             mach-o          \b
+>>4    belong          >4
+>>>88  use             mach-o          \b
+>>4    belong          >5
+>>>108 use             mach-o          \b
+
+### MACH-O END ###
diff --git a/magic/Magdir/cbor b/magic/Magdir/cbor
new file mode 100644 (file)
index 0000000..6bfd160
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File: elf,v 1.68 2014/09/19 19:05:57 christos Exp $
+# cbor:  file(1) magic for CBOR files as defined in RFC 7049
+
+0      string  \xd9\xd9\xf7 Concise Binary Object Representation (CBOR) container
+!:mime application/cbor
+>3     ubyte   <0x20   (positive integer)
+>3     ubyte   <0x40
+>>3    ubyte   >0x1f   (negative integer)
+>3     ubyte   <0x60
+>>3    ubyte   >0x3f   (byte string)
+>3     ubyte   <0x80
+>>3    ubyte   >0x5f   (text string)
+>3     ubyte   <0xa0
+>3     ubyte   >0x7f   (array)
+>3     ubyte   <0xc0
+>>3    ubyte   >0x9f   (map)
+>3     ubyte   <0xe0
+>>3    ubyte   >0xbf   (tagged)
+>3     ubyte   >0xdf   (other)
diff --git a/magic/Magdir/cddb b/magic/Magdir/cddb
new file mode 100644 (file)
index 0000000..e793569
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# CDDB: file(1) magic for CDDB(tm) format CD text data files
+#
+# From <steve@gracenote.com>
+#
+# This is the /etc/magic entry to decode datafiles as used by
+# CDDB-enabled CD player applications.
+#
+
+0      search/1/w      #\040xmcd       CDDB(tm) format CD text data
diff --git a/magic/Magdir/chord b/magic/Magdir/chord
new file mode 100644 (file)
index 0000000..6968829
--- /dev/null
@@ -0,0 +1,15 @@
+
+#------------------------------------------------------------------------------
+# $File: chord,v 1.4 2009/09/19 16:28:08 christos Exp $
+# chord: file(1) magic for Chord music sheet typesetting utility input files
+#
+# From Philippe De Muyter <phdm@macqel.be>
+# File format is actually free, but many distributed files begin with `{title'
+#
+0      string          {title          Chord text file
+
+# Type:        PowerTab file format
+# URL: http://www.power-tab.net/
+# From:        Jelmer Vernooij <jelmer@samba.org>
+0      string          ptab\003\000    Power-Tab v3 Tablature File
+0      string          ptab\004\000    Power-Tab v4 Tablature File
diff --git a/magic/Magdir/cisco b/magic/Magdir/cisco
new file mode 100644 (file)
index 0000000..c9fdd4a
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# cisco:  file(1) magic for cisco Systems routers
+#
+# Most cisco file-formats are covered by the generic elf code
+#
+# Microcode files are non-ELF, 0x8501 conflicts with NetBSD/alpha.
+0      belong&0xffffff00       0x85011400  cisco IOS microcode
+>7     string          >\0                 for '%s'
+0      belong&0xffffff00       0x8501cb00  cisco IOS experimental microcode
+>7     string          >\0                 for '%s'
diff --git a/magic/Magdir/citrus b/magic/Magdir/citrus
new file mode 100644 (file)
index 0000000..41ad884
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# citrus locale declaration
+#
+
+0      string          RuneCT          Citrus locale declaration for LC_CTYPE
+
diff --git a/magic/Magdir/clarion b/magic/Magdir/clarion
new file mode 100644 (file)
index 0000000..220caec
--- /dev/null
@@ -0,0 +1,27 @@
+
+#------------------------------------------------------------------------------
+# $File: clarion,v 1.4 2009/09/19 16:28:08 christos Exp $
+# clarion:  file(1) magic for # Clarion Personal/Professional Developer
+# (v2 and above)
+# From: Julien Blache <jb@jblache.org>
+
+# Database files
+# signature
+0      leshort 0x3343  Clarion Developer (v2 and above) data file
+# attributes
+>2     leshort &0x0001 \b, locked
+>2     leshort &0x0004 \b, encrypted
+>2     leshort &0x0008 \b, memo file exists
+>2     leshort &0x0010 \b, compressed
+>2     leshort &0x0040 \b, read only
+# number of records
+>5     lelong  x       \b, %d records
+
+# Memo files
+0      leshort 0x334d  Clarion Developer (v2 and above) memo data
+
+# Key/Index files
+# No magic? :(
+
+# Help files
+0      leshort 0x49e0  Clarion Developer (v2 and above) help data
diff --git a/magic/Magdir/claris b/magic/Magdir/claris
new file mode 100644 (file)
index 0000000..771190f
--- /dev/null
@@ -0,0 +1,48 @@
+
+#------------------------------------------------------------------------------
+# $File: claris,v 1.7 2014/06/03 19:17:27 christos Exp $
+# claris:  file(1) magic for claris
+# "H. Nanosecond" <aldomel@ix.netcom.com>
+# Claris Works a word processor, etc.
+# Version 3.0
+
+# .pct claris works clip art files
+#0000000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
+#*
+#0001000 #010 250 377 377 377 377 000 213 000 230 000 021 002 377 014 000
+#null to byte 1000 octal
+514    string  \377\377\377\377\000
+>0     string  \0\0\0\0\0\0\0\0\0\0\0\0\0      Claris clip art
+514    string  \377\377\377\377\001
+>0     string  \0\0\0\0\0\0\0\0\0\0\0\0\0      Claris clip art
+
+# Claris works files
+# .cwk
+# Moved to Apple AppleWorks document
+#0     string  \002\000\210\003\102\117\102\117\000\001\206 Claris works document
+# .plt
+0      string  \020\341\000\000\010\010        Claris Works palette files .plt
+
+# .msp a dictionary file I am not sure about this I have only one .msp file
+0      string  \002\271\262\000\040\002\000\164        Claris works dictionary
+
+# .usp are user dictionary bits
+# I am not sure about a magic header:
+#0000000 001 123 160 146 070 125 104 040 136 123 015 012 160 157 144 151
+#        soh   S   p   f   8   U   D  sp   ^   S  cr  nl   p   o   d   i
+#0000020 141 164 162 151 163 164 040 136 123 015 012 144 151 166 040 043
+#          a   t   r   i   s   t  sp   ^   S  cr  nl   d   i   v  sp   #
+
+# .mth Thesaurus
+# starts with \0 but no magic header
+
+# .chy Hyphenation file
+# I am not sure: 000 210 034 000 000
+
+# other claris files
+#./windows/claris/useng.ndx: data
+#./windows/claris/xtndtran.l32: data
+#./windows/claris/xtndtran.lst: data
+#./windows/claris/clworks.lbl: data
+#./windows/claris/clworks.prf: data
+#./windows/claris/userd.spl: data
diff --git a/magic/Magdir/clipper b/magic/Magdir/clipper
new file mode 100644 (file)
index 0000000..2768b3a
--- /dev/null
@@ -0,0 +1,65 @@
+
+#------------------------------------------------------------------------------
+# $File: clipper,v 1.8 2017/03/17 21:35:28 christos Exp $
+# clipper:  file(1) magic for Intergraph (formerly Fairchild) Clipper.
+#
+# XXX - what byte order does the Clipper use?
+#
+# XXX - what's the "!" stuff:
+#
+# >18  short           !074000,000000  C1 R1
+# >18  short           !074000,004000  C2 R1
+# >18  short           !074000,010000  C3 R1
+# >18  short           !074000,074000  TEST
+#
+# I shall assume it's ANDing the field with the first value and
+# comparing it with the second, and rewrite it as:
+#
+# >18  short&074000    000000          C1 R1
+# >18  short&074000    004000          C2 R1
+# >18  short&074000    010000          C3 R1
+# >18  short&074000    074000          TEST
+#
+# as SVR3.1's "file" doesn't support anything of the "!074000,000000"
+# sort, nor does SunOS 4.x, so either it's something Intergraph added
+# in CLIX, or something AT&T added in SVR3.2 or later, or something
+# somebody else thought was a good idea; it's not documented in the
+# man page for this version of "magic", nor does it appear to be
+# implemented (at least not after I blew off the bogus code to turn
+# old-style "&"s into new-style "&"s, which just didn't work at all).
+#
+0      short           0575            CLIPPER COFF executable (VAX #)
+>20    short           0407            (impure)
+>20    short           0410            (5.2 compatible)
+>20    short           0411            (pure)
+>20    short           0413            (demand paged)
+>20    short           0443            (target shared library)
+>12    long            >0              not stripped
+>22    short           >0              - version %d
+0      short           0577            CLIPPER COFF executable
+>18    short&074000    000000          C1 R1
+>18    short&074000    004000          C2 R1
+>18    short&074000    010000          C3 R1
+>18    short&074000    074000          TEST
+>20    short           0407            (impure)
+>20    short           0410            (pure)
+>20    short           0411            (separate I&D)
+>20    short           0413            (paged)
+>20    short           0443            (target shared library)
+>12    long            >0              not stripped
+>22    short           >0              - version %d
+>48    long&01         01              alignment trap enabled
+>52    byte            1               -Ctnc
+>52    byte            2               -Ctsw
+>52    byte            3               -Ctpw
+>52    byte            4               -Ctcb
+>53    byte            1               -Cdnc
+>53    byte            2               -Cdsw
+>53    byte            3               -Cdpw
+>53    byte            4               -Cdcb
+>54    byte            1               -Csnc
+>54    byte            2               -Cssw
+>54    byte            3               -Cspw
+>54    byte            4               -Cscb
+4      string          pipe            CLIPPER instruction trace
+4      string          prof            CLIPPER instruction profile
diff --git a/magic/Magdir/clojure b/magic/Magdir/clojure
new file mode 100644 (file)
index 0000000..1f1cddf
--- /dev/null
@@ -0,0 +1,30 @@
+#------------------------------------------------------------------------------
+# file:  file(1) magic for Clojure
+# URL:  https://clojure.org/
+# From: Jason Felice <jason.m.felice@gmail.com>
+
+0      string/w        #!\ /usr/bin/clj        Clojure script text executable
+!:mime text/x-clojure
+0      string/w        #!\ /usr/local/bin/clj  Clojure script text executable
+!:mime text/x-clojure
+0      string/w        #!\ /usr/bin/clojure    Clojure script text executable
+!:mime text/x-clojure
+0      string/w        #!\ /usr/local/bin/clojure      Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!/usr/bin/env\ clj     Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!/usr/bin/env\ clojure Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!\ /usr/bin/env\ clj   Clojure script text executable
+!:mime text/x-clojure
+0      string/W        #!\ /usr/bin/env\ clojure       Clojure script text executable
+!:mime text/x-clojure
+
+0      regex   \^\\\(ns[[:space:]]+[a-z]       Clojure module source text
+!:mime text/x-clojure
+
+0      regex   \^\\\(ns[[:space:]]+\\\^\\{:    Clojure module source text
+!:mime text/x-clojure
+
+0      regex   \^\\\(defn-?[[:space:]] Clojure module source text
+!:mime text/x-clojure
diff --git a/magic/Magdir/coff b/magic/Magdir/coff
new file mode 100644 (file)
index 0000000..31b47e7
--- /dev/null
@@ -0,0 +1,81 @@
+
+#------------------------------------------------------------------------------
+# $File: coff,v 1.3 2018/08/01 10:34:03 christos Exp $
+# coff: file(1) magic for Common Object Files not specific to known cpu types or manufactures
+#
+# COFF
+#
+# by Joerg Jenderek at Oct 2015
+# https://en.wikipedia.org/wiki/COFF
+# https://de.wikipedia.org/wiki/Common_Object_File_Format
+# http://www.delorie.com/djgpp/doc/coff/filhdr.html
+
+# display name+variables+flags of Common Object Files Format (32bit)
+# Maybe used also in adi,att3b,clipper,hitachi-sh,hp,ibm6000,intel,
+# mips,motorola,msdos,osf1,sharc,varied.out,vax
+0      name                            display-coff
+# test for unused flag bits (0x8000,0x0800,0x0400,0x0200,x0080) in f_flags
+>18    uleshort&0x8E80 0
+>>0    clear           x
+# f_magic - magic number
+# DJGPP, 80386 COFF executable, MS Windows COFF Intel 80386 object file (./intel)
+>>0    uleshort        0x014C          Intel 80386
+# Hitachi SH big-endian COFF (./hitachi-sh)
+>>0    uleshort        0x0500          Hitachi SH big-endian
+# Hitachi SH little-endian COFF (./hitachi-sh)
+>>0    uleshort        0x0550          Hitachi SH little-endian
+# executable (RISC System/6000 V3.1) or obj module (./ibm6000)
+#>>0   uleshort        0x01DF
+# MS Windows COFF Intel Itanium, AMD64
+# https://msdn.microsoft.com/en-us/library/windows/desktop/ms680313(v=vs.85).aspx
+>>0    uleshort        0x0200          Intel ia64
+>>0    uleshort        0x8664          Intel amd64
+# TODO for other COFFs
+#>>0   uleshort        0xABCD          COFF_TEMPLATE
+>>0    default         x
+>>>0   uleshort        x               type 0x%04x
+>>0    uleshort        x               COFF
+# F_EXEC flag bit
+>>18   leshort         ^0x0002         object file
+#!:mime        application/x-coff
+#!:ext cof/o/obj/lib
+>>18   leshort         &0x0002         executable
+#!:mime        application/x-coffexec
+# F_RELFLG flag bit,static object
+>>18   leshort         &0x0001         \b, no relocation info
+# F_LNNO flag bit
+>>18   leshort         &0x0004         \b, no line number info
+# F_LSYMS flag bit
+>>18   leshort         &0x0008         \b, stripped
+>>18   leshort         ^0x0008         \b, not stripped
+# flags in other COFF versions
+#0x0010    F_FDPR_PROF
+#0x0020    F_FDPR_OPTI
+#0x0040    F_DSA
+# F_AR32WR flag bit
+#>>>18 leshort         &0x0100         \b, 32 bit little endian
+#0x1000    F_DYNLOAD
+#0x2000    F_SHROBJ
+#0x4000    F_LOADONLY
+# f_nscns - number of sections
+>>2    uleshort        <2              \b, %d section
+>>2    uleshort        >1              \b, %d sections
+# f_timdat - file time & date stamp only for little endian
+#>>4   date            x               \b, %s
+# f_symptr - symbol table pointer, only for not stripped
+>>8    ulelong         >0              \b, symbol offset=0x%x
+# f_nsyms - number of symbols, only for not stripped
+>>12   ulelong         >0              \b, %d symbols
+# f_opthdr - optional header size
+>>16   uleshort        >0              \b, optional header size %d
+# at offset 20 can be optional header, extra bytes FILHSZ-20 because
+# do not rely on sizeof(FILHDR) to give the correct size for header.
+# or first section header
+# additional variables for other COFF files
+# >20  beshort         0407            (impure)
+# >20  beshort         0410            (pure)
+# >20  beshort         0413            (demand paged)
+# >20  beshort         0421            (standalone)
+# >22  leshort         >0              - version %d
+# >168 string          .lowmem         Apple toolbox
+
diff --git a/magic/Magdir/commands b/magic/Magdir/commands
new file mode 100644 (file)
index 0000000..1120c7d
--- /dev/null
@@ -0,0 +1,118 @@
+
+#------------------------------------------------------------------------------
+# $File: commands,v 1.60 2019/04/19 00:42:27 christos Exp $
+# commands:  file(1) magic for various shells and interpreters
+#
+#0     string/w        :                       shell archive or script for antique kernel text
+0      string/wt       #!\ /bin/sh             POSIX shell script text executable
+!:mime text/x-shellscript
+0      string/wb       #!\ /bin/sh             POSIX shell script executable (binary data)
+!:mime text/x-shellscript
+
+0      string/wt       #!\ /bin/csh            C shell script text executable
+!:mime text/x-shellscript
+
+# korn shell magic, sent by George Wu, gwu@clyde.att.com
+0      string/wt       #!\ /bin/ksh            Korn shell script text executable
+!:mime text/x-shellscript
+0      string/wb       #!\ /bin/ksh            Korn shell script executable (binary data)
+!:mime text/x-shellscript
+
+0      string/wt       #!\ /bin/tcsh           Tenex C shell script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/bin/tcsh       Tenex C shell script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/tcsh     Tenex C shell script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/bin/tcsh Tenex C shell script text executable
+!:mime text/x-shellscript
+
+#
+# zsh/ash/ae/nawk/gawk magic from cameron@cs.unsw.oz.au (Cameron Simpson)
+0      string/wt       #!\ /bin/zsh            Paul Falstad's zsh script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/bin/zsh        Paul Falstad's zsh script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/bin/zsh  Paul Falstad's zsh script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/bin/ash  Neil Brown's ash script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/bin/ae   Neil Brown's ae script text executable
+!:mime text/x-shellscript
+0      string/wt       #!\ /bin/nawk           new awk script text executable
+!:mime text/x-nawk
+0      string/wt       #!\ /usr/bin/nawk       new awk script text executable
+!:mime text/x-nawk
+0      string/wt       #!\ /usr/local/bin/nawk new awk script text executable
+!:mime text/x-nawk
+0      string/wt       #!\ /bin/gawk           GNU awk script text executable
+!:mime text/x-gawk
+0      string/wt       #!\ /usr/bin/gawk       GNU awk script text executable
+!:mime text/x-gawk
+0      string/wt       #!\ /usr/local/bin/gawk GNU awk script text executable
+!:mime text/x-gawk
+#
+0      string/wt       #!\ /bin/awk            awk script text executable
+!:mime text/x-awk
+0      string/wt       #!\ /usr/bin/awk        awk script text executable
+!:mime text/x-awk
+0      regex/4096      =^[\040\t\f\r\n]{0,100}BEGIN[\040\t\f\r\n]{0,100}[{]    awk or perl script text
+
+# AT&T Bell Labs' Plan 9 shell
+0      string/wt       #!\ /bin/rc     Plan 9 rc shell script text executable
+
+# bash shell magic, from Peter Tobias (tobias@server.et-inf.fho-emden.de)
+0      string/wt       #!\ /bin/bash   Bourne-Again shell script text executable
+!:mime text/x-shellscript
+0      string/wb       #!\ /bin/bash   Bourne-Again shell script executable (binary data)
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/bin/bash       Bourne-Again shell script text executable
+!:mime text/x-shellscript
+0      string/wb       #!\ /usr/bin/bash       Bourne-Again shell script executable (binary data)
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/bash     Bourne-Again shell script text executable
+!:mime text/x-shellscript
+0      string/wb       #!\ /usr/local/bash     Bourne-Again shell script executable (binary data)
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/local/bin/bash Bourne-Again shell script text executable
+!:mime text/x-shellscript
+0      string/wb       #!\ /usr/local/bin/bash Bourne-Again shell script executable (binary data)
+!:mime text/x-shellscript
+0      string/wt       #!\ /usr/bin/env\ bash  Bourne-Again shell script text executable
+!:mime text/x-shellscript
+
+# PHP scripts
+# Ulf Harnhammar <ulfh@update.uu.se>
+0      search/1/c      =<?php                  PHP script text
+!:strength + 30
+!:mime text/x-php
+0      search/1        =<?\n                   PHP script text
+!:mime text/x-php
+0      search/1        =<?\r                   PHP script text
+!:mime text/x-php
+0      search/1/w      #!\ /usr/local/bin/php  PHP script text executable
+!:strength + 10
+!:mime text/x-php
+0      search/1/w      #!\ /usr/bin/php        PHP script text executable
+!:strength + 10
+!:mime text/x-php
+# Smarty compiled template, https://www.smarty.net/
+# Elan Ruusamae <glen@delfi.ee>
+0      string  =<?php
+>5     regex   [\ \n]
+>>6    string  /*\ Smarty\ version             Smarty compiled template
+>>>24  regex   [0-9.]+                         \b, version %s
+!:mime text/x-php
+
+0      string          Zend\x00                PHP script Zend Optimizer data
+
+0      string/t        $!                      DCL command file
+
+# Type: Pdmenu
+# URL:  https://packages.debian.org/pdmenu
+# From: Edward Betts <edward@debian.org>
+0      string          #!/usr/bin/pdmenu       Pdmenu configuration file text
+
+# From Danny Weldon
+0      string  \x0b\x13\x08\x00
+>0x04   uleshort       <4      ksh byte-code version %d
diff --git a/magic/Magdir/communications b/magic/Magdir/communications
new file mode 100644 (file)
index 0000000..938e174
--- /dev/null
@@ -0,0 +1,22 @@
+
+#----------------------------------------------------------------------------
+# $File$
+# communication
+
+# TTCN is the Tree and Tabular Combined Notation described in ISO 9646-3.
+# It is used for conformance testing of communication protocols.
+# Added by W. Borgert <debacle@debian.org>.
+0      string          $Suite                  TTCN Abstract Test Suite
+>&1    string          $SuiteId
+>>&1   string          >\n                     %s
+>&2    string          $SuiteId
+>>&1   string          >\n                     %s
+>&3    string          $SuiteId
+>>&1   string          >\n                     %s
+
+# MSC (message sequence charts) are a formal description technique,
+# described in ITU-T Z.120, mainly used for communication protocols.
+# Added by W. Borgert <debacle@debian.org>.
+0      string          mscdocument     Message Sequence Chart (document)
+0      string          msc             Message Sequence Chart (chart)
+0      string          submsc          Message Sequence Chart (subchart)
diff --git a/magic/Magdir/compress b/magic/Magdir/compress
new file mode 100644 (file)
index 0000000..7520eb4
--- /dev/null
@@ -0,0 +1,394 @@
+#------------------------------------------------------------------------------
+# $File: compress,v 1.75 2019/04/19 00:42:27 christos Exp $
+# compress:  file(1) magic for pure-compression formats (no archives)
+#
+# compress, gzip, pack, compact, huf, squeeze, crunch, freeze, yabba, etc.
+#
+# Formats for various forms of compressed data
+# Formats for "compress" proper have been moved into "compress.c",
+# because it tries to uncompress it to figure out what's inside.
+
+# standard unix compress
+0      string          \037\235        compress'd data
+!:mime application/x-compress
+!:apple        LZIVZIVU
+>2     byte&0x80       >0              block compressed
+>2     byte&0x1f       x               %d bits
+
+# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver)
+# URL: https://en.wikipedia.org/wiki/Gzip
+# Reference: https://tools.ietf.org/html/rfc1952
+# Update: Joerg Jenderek, Apr 2019
+#   Edited by Chris Chittleborough <cchittleborough@yahoo.com.au>, March 2002
+#      * Original filename is only at offset 10 if "extra field" absent
+#      * Produce shorter output - notably, only report compression methods
+#         other than 8 ("deflate", the only method defined in RFC 1952).
+# Note: find defs -iname '*.trid.xml' -exec grep -q '<Bytes>1F8B08' {} \; -ls
+# TODO:
+# FBR  Blueberry FlashBack screen Record       https://www.flashbackrecorder.com/
+# KPR  KOffice/Calligra KPresenter             application/x-kpresenter
+# KPT  KOffice/Calligra KPresenter template?   application/x-kpresenter
+# SAV  Diggles Saved Game File                 http://www.innonics.com
+# SAV  FarCry (demo) saved game                http://www.farcry-thegame.com
+# DAT  ZOAGZIP game data format                http://en.wikipedia.org/wiki/SD_Gundam_Capsule_Fighter
+0       string          \037\213
+# to display gzip compressed (strength=100=2*50) before other (strength=50)?
+#!:strength * 2
+# no FNAME and FCOMMENT bit implies no file name/comment. That means only binary
+>3     byte&0x18       =0
+# For binary gzipped no ASCII text should occur
+#      mcd-monu-cad.trid.xml
+>>10   string          MCD                     Monu-Cad Drawing, Component or Font
+#>>36  string          Created\ with\ MONU-CAD 
+#!:mime        application/octet-stream
+# http://fileformats.archiveteam.org/wiki/Monu-CAD
+#      http://www.monucad.com/downloads/FullDemo-2005.EXE
+#      /HANDS96.MCC    Component
+#      /DEMO_DD01.MCD  Drawing
+#      /MCALF020.FNT   Font
+!:ext  mcc/mcd/fnt
+# http://www.generalcadd.com
+>>10   string          GXD                     General CADD, Drawing or Component
+#!:mime        application/octet-stream
+#      /gxc/BUILDINGEDGE.gxc                   Component
+#      /gxd/HOCKETT-STPAUL-WRHSE.gxd           Drawing
+#      /gxd/POWERLAND-MILL-ADD-11.gxd          Drawing         v9.1.06
+!:ext  gxc/gxd
+#>>>13 ubyte           0                       \b, version 0
+>>>13  string          09                      \b, version 9
+# other gzipped binary like gzipped tar, VirtualBox extension package,...
+>>10   default         x               gzip compressed data
+>>>0   use     gzip-info
+# size of the original (uncompressed) input data modulo 2^32
+>>>-4  ulelong         x               \b, original size modulo 2^32 %u
+# gzipped TAR or VirtualBox extension package
+!:mime application/gzip
+#!:mime        application/x-compressed-tar
+#!:mime        application/x-virtualbox-vbox-extpack
+# https://www.w3.org/TR/SVG/mimereg.html
+#!:mime        image/image/svg+xml-compressed
+#      zlib.3.gz
+#      microcode-20180312.tgz
+#      tpz same as tgz
+#      lua-md5_1.2-1_i386_i486.ipk     https://en.wikipedia.org/wiki/Opkg
+#      Oracle_VM_VirtualBox_Extension_Pack-5.0.12-104815.vbox-extpack
+!:ext  gz/tgz/tpz/ipk/vbox-extpack/svgz
+# FNAME/FCOMMENT bit implies file name/comment as iso-8859-1 text
+>3     byte&0x18       >0              gzip compressed data
+!:mime application/gzip
+# gzipped tar, gzipped Abiword document
+#!:mime        application/x-compressed-tar
+#!:mime        application/x-abiword-compressed
+#!:mime        image/image/svg+xml-compressed
+#      kleopatra_splashscreen.svgz     gzipped .svg
+!:ext  gz/tgz/tpz/zabw/svgz
+>>0    use     gzip-info
+# size of the original (uncompressed) input data modulo 2^32
+>>-4   ulelong         x               \b, original size modulo 2^32 %u
+#      display information of gzip compressed files
+0      name                            gzip-info
+#>2    byte            x               THIS iS GZIP
+>2     byte            <8              \b, reserved method
+>2     byte            >8              \b, unknown method
+>3     byte            &0x01           \b, ASCII
+>3     byte            &0x02           \b, has CRC
+>3     byte            &0x04           \b, extra field
+>3     byte&0xC        =0x08
+>>10   string          x               \b, was "%s"
+>3     byte            &0x10           \b, has comment
+>3     byte            &0x20           \b, encrypted
+>4     ledate          >0              \b, last modified: %s
+>8     byte            2               \b, max compression
+>8     byte            4               \b, max speed
+>9     byte            =0x00           \b, from FAT filesystem (MS-DOS, OS/2, NT)
+>9     byte            =0x01           \b, from Amiga
+>9     byte            =0x02           \b, from VMS
+>9     byte            =0x03           \b, from Unix
+>9     byte            =0x04           \b, from VM/CMS
+>9     byte            =0x05           \b, from Atari
+>9     byte            =0x06           \b, from HPFS filesystem (OS/2, NT)
+>9     byte            =0x07           \b, from MacOS
+>9     byte            =0x08           \b, from Z-System
+>9     byte            =0x09           \b, from CP/M
+>9     byte            =0x0A           \b, from TOPS/20
+>9     byte            =0x0B           \b, from NTFS filesystem (NT)
+>9     byte            =0x0C           \b, from QDOS
+>9     byte            =0x0D           \b, from Acorn RISCOS
+# size of the original (uncompressed) input data modulo 2^32
+#>-4   ulelong         x               \b, original size modulo 2^32 %u
+#ERROR: line 114: non zero offset 1048572 at level 1
+
+# packed data, Huffman (minimum redundancy) codes on a byte-by-byte basis
+0      string          \037\036        packed data
+!:mime application/octet-stream
+>2     belong          >1              \b, %d characters originally
+>2     belong          =1              \b, %d character originally
+#
+# This magic number is byte-order-independent.
+0      short           0x1f1f          old packed data
+!:mime application/octet-stream
+
+# XXX - why *two* entries for "compacted data", one of which is
+# byte-order independent, and one of which is byte-order dependent?
+#
+0      short           0x1fff          compacted data
+!:mime application/octet-stream
+# This string is valid for SunOS (BE) and a matching "short" is listed
+# in the Ultrix (LE) magic file.
+0      string          \377\037        compacted data
+!:mime application/octet-stream
+0      short           0145405         huf output
+!:mime application/octet-stream
+
+# bzip2
+0      string          BZh             bzip2 compressed data
+!:mime application/x-bzip2
+>3     byte            >47             \b, block size = %c00k
+
+# bzip a block-sorting file compressor
+#      by Julian Seward <sewardj@cs.man.ac.uk> and others
+0      string          BZ0             bzip compressed data
+!:mime application/x-bzip
+>3     byte            >47             \b, block size = %c00k
+
+# lzip
+0      string          LZIP            lzip compressed data
+!:mime application/x-lzip
+>4     byte            x               \b, version: %d
+
+# squeeze and crunch
+# Michael Haardt <michael@cantor.informatik.rwth-aachen.de>
+0      beshort         0x76FF          squeezed data,
+>4     string          x               original name %s
+0      beshort         0x76FE          crunched data,
+>2     string          x               original name %s
+0      beshort         0x76FD          LZH compressed data,
+>2     string          x               original name %s
+
+# Freeze
+0      string          \037\237        frozen file 2.1
+0      string          \037\236        frozen file 1.0 (or gzip 0.5)
+
+# SCO compress -H (LZH)
+0      string          \037\240        SCO compress -H (LZH) data
+
+# European GSM 06.10 is a provisional standard for full-rate speech
+# transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
+# excitation/long term prediction) coding at 13 kbit/s.
+#
+# There's only a magic nibble (4 bits); that nibble repeats every 33
+# bytes.  This isn't suited for use, but maybe we can use it someday.
+#
+# This will cause very short GSM files to be declared as data and
+# mismatches to be declared as data too!
+#0     byte&0xF0       0xd0            data
+#>33   byte&0xF0       0xd0
+#>66   byte&0xF0       0xd0
+#>99   byte&0xF0       0xd0
+#>132  byte&0xF0       0xd0            GSM 06.10 compressed audio
+
+# lzop from <markus.oberhumer@jk.uni-linz.ac.at>
+0      string          \x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a    lzop compressed data
+>9     beshort         <0x0940
+>>9    byte&0xf0       =0x00           - version 0.
+>>9    beshort&0x0fff  x               \b%03x,
+>>13   byte            1               LZO1X-1,
+>>13   byte            2               LZO1X-1(15),
+>>13   byte            3               LZO1X-999,
+## >>22        bedate          >0              last modified: %s,
+>>14   byte            =0x00           os: MS-DOS
+>>14   byte            =0x01           os: Amiga
+>>14   byte            =0x02           os: VMS
+>>14   byte            =0x03           os: Unix
+>>14   byte            =0x05           os: Atari
+>>14   byte            =0x06           os: OS/2
+>>14   byte            =0x07           os: MacOS
+>>14   byte            =0x0A           os: Tops/20
+>>14   byte            =0x0B           os: WinNT
+>>14   byte            =0x0E           os: Win32
+>9     beshort         >0x0939
+>>9    byte&0xf0       =0x00           - version 0.
+>>9    byte&0xf0       =0x10           - version 1.
+>>9    byte&0xf0       =0x20           - version 2.
+>>9    beshort&0x0fff  x               \b%03x,
+>>15   byte            1               LZO1X-1,
+>>15   byte            2               LZO1X-1(15),
+>>15   byte            3               LZO1X-999,
+## >>25        bedate          >0              last modified: %s,
+>>17   byte            =0x00           os: MS-DOS
+>>17   byte            =0x01           os: Amiga
+>>17   byte            =0x02           os: VMS
+>>17   byte            =0x03           os: Unix
+>>17   byte            =0x05           os: Atari
+>>17   byte            =0x06           os: OS/2
+>>17   byte            =0x07           os: MacOS
+>>17   byte            =0x0A           os: Tops/20
+>>17   byte            =0x0B           os: WinNT
+>>17   byte            =0x0E           os: Win32
+
+# 4.3BSD-Quasijarus Strong Compression
+# https://minnie.tuhs.org/Quasijarus/compress.html
+0      string          \037\241        Quasijarus strong compressed data
+
+# From: Cory Dikkers <cdikkers@swbell.net>
+0      string          XPKF            Amiga xpkf.library compressed data
+0      string          PP11            Power Packer 1.1 compressed data
+0      string          PP20            Power Packer 2.0 compressed data,
+>4     belong          0x09090909      fast compression
+>4     belong          0x090A0A0A      mediocre compression
+>4     belong          0x090A0B0B      good compression
+>4     belong          0x090A0C0C      very good compression
+>4     belong          0x090A0C0D      best compression
+
+# 7-zip archiver, from Thomas Klausner (wiz@danbala.tuwien.ac.at)
+# https://www.7-zip.org or DOC/7zFormat.txt
+#
+0      string          7z\274\257\047\034      7-zip archive data,
+>6     byte            x                       version %d
+>7     byte            x                       \b.%d
+!:mime application/x-7z-compressed
+!:ext 7z/cb7
+
+# Type: LZMA
+0      lelong&0xffffff =0x5d
+>12    leshort         0xff                    LZMA compressed data,
+!:mime application/x-lzma
+>>5    lequad          =0xffffffffffffffff     streamed
+>>5    lequad          !0xffffffffffffffff     non-streamed, size %lld
+>12    leshort         0                       LZMA compressed data,
+>>5    lequad          =0xffffffffffffffff     streamed
+>>5    lequad          !0xffffffffffffffff     non-streamed, size %lld
+
+# http://tukaani.org/xz/xz-file-format.txt
+0      ustring         \xFD7zXZ\x00            XZ compressed data
+!:strength * 2
+!:mime application/x-xz
+
+# https://github.com/ckolivas/lrzip/blob/master/doc/magic.header.txt
+0      string          LRZI                    LRZIP compressed data
+>4     byte            x                       - version %d
+>5     byte            x                       \b.%d
+!:mime application/x-lrzip
+
+# https://fastcompression.blogspot.fi/2013/04/lz4-streaming-format-final.html
+0      lelong          0x184d2204      LZ4 compressed data (v1.4+)
+!:mime application/x-lz4
+# Added by osm0sis@xda-developers.com
+0      lelong          0x184c2103      LZ4 compressed data (v1.0-v1.3)
+!:mime application/x-lz4
+0      lelong          0x184c2102      LZ4 compressed data (v0.1-v0.9)
+!:mime application/x-lz4
+
+# Zstandard/LZ4 skippable frames
+# https://github.com/facebook/zstd/blob/dev/zstd_compression_format.md
+0         lelong&0xFFFFFFF0  0x184D2A50
+>(4.l+8)  indirect     x
+
+# Zstandard Dictionary ID subroutine
+0     name        zstd-dictionary-id
+# Single Segment = True
+>0    byte        &0x20   \b, Dictionary ID:
+>>0   byte&0x03   0       None
+>>0   byte&0x03   1
+>>>1  byte        x       %u
+>>0   byte&0x03   2
+>>>1  leshort     x       %u
+>>0   byte&0x03   3
+>>>1  lelong      x       %u
+# Single Segment = False
+>0    byte        ^0x20   \b, Dictionary ID:
+>>0   byte&0x03   0       None
+>>0   byte&0x03   1
+>>>2  byte        x       %u
+>>0   byte&0x03   2
+>>>2  leshort     x       %u
+>>0   byte&0x03   3
+>>>2  lelong      x       %u
+
+# Zstandard compressed data
+# https://github.com/facebook/zstd/blob/dev/zstd_compression_format.md
+0     lelong       0xFD2FB522  Zstandard compressed data (v0.2)
+!:mime  application/x-zstd
+0     lelong       0xFD2FB523  Zstandard compressed data (v0.3)
+!:mime  application/x-zstd
+0     lelong       0xFD2FB524  Zstandard compressed data (v0.4)
+!:mime  application/x-zstd
+0     lelong       0xFD2FB525  Zstandard compressed data (v0.5)
+!:mime  application/x-zstd
+0     lelong       0xFD2FB526  Zstandard compressed data (v0.6)
+!:mime  application/x-zstd
+0     lelong       0xFD2FB527  Zstandard compressed data (v0.7)
+!:mime  application/x-zstd
+>4    use          zstd-dictionary-id
+0     lelong       0xFD2FB528  Zstandard compressed data (v0.8+)
+!:mime  application/x-zstd
+>4    use          zstd-dictionary-id
+
+# https://github.com/facebook/zstd/blob/dev/zstd_compression_format.md
+0  lelong    0xEC30A437  Zstandard dictionary
+!:mime  application/x-zstd-dictionary
+>4 lelong    x           (ID %u)
+
+# AFX compressed files (Wolfram Kleff)
+2      string          -afx-           AFX compressed file data
+
+# Supplementary magic data for the file(1) command to support
+# rzip(1).  The format is described in magic(5).
+#
+# Copyright (C) 2003 by Andrew Tridgell.  You may do whatever you want with
+# this file.
+#
+0      string          RZIP            rzip compressed data
+>4     byte            x               - version %d
+>5     byte            x               \b.%d
+>6     belong          x               (%d bytes)
+
+0      string          ArC\x01         FreeArc archive <http://freearc.org>
+
+# Type:        DACT compressed files
+0      long    0x444354C3      DACT compressed data
+>4     byte    >-1             (version %i.
+>5     byte    >-1             %i.
+>6     byte    >-1             %i)
+>7     long    >0              , original size: %i bytes
+>15    long    >30             , block size: %i bytes
+
+# Valve Pack (VPK) files
+0      lelong  0x55aa1234      Valve Pak file
+>0x4   lelong  x               \b, version %u
+>0x8   lelong  x               \b, %u entries
+
+# Snappy framing format
+# https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
+0      string  \377\006\0\0sNaPpY      snappy framed data
+!:mime application/x-snappy-framed
+
+# qpress, https://www.quicklz.com/
+0      string  qpress10        qpress compressed data
+!:mime application/x-qpress
+
+# Zlib https://www.ietf.org/rfc/rfc6713.txt
+0      string/b        x
+>0     beshort%31      =0
+>>0    byte&0xf        =8
+>>>0   byte&0x80       =0      zlib compressed data
+!:mime application/zlib
+
+# BWC compression
+0      string          BWC
+>3     byte            0       BWC compressed data
+
+# UCL compression
+0      bequad          0x00e955434cff011a      UCL compressed data
+
+# Softlib archive
+0      string          SLIB    Softlib archive
+>4     leshort         x       \b, version %d
+>6     leshort         x       (contains %d files)
+
+# URL:  https://github.com/lzfse/lzfse/blob/master/src/lzfse_internal.h#L276
+# From: Eric Hall <eric.hall@darkart.com>
+0      string  bvx-    lzfse encoded, no compression
+0      string  bvx1    lzfse compressed, uncompressed tables
+0      string  bvx2    lzfse compressed, compressed tables
+0      string  bvxn    lzfse encoded, lzvn compressed
diff --git a/magic/Magdir/console b/magic/Magdir/console
new file mode 100644 (file)
index 0000000..5e5e581
--- /dev/null
@@ -0,0 +1,950 @@
+
+#------------------------------------------------------------------------------
+# $File: console,v 1.45 2019/04/19 00:42:27 christos Exp $
+# Console game magic
+# Toby Deshane <hac@shoelace.digivill.net>
+
+# ines: file(1) magic for Marat's iNES Nintendo Entertainment System ROM dump format
+# Updated by David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://wiki.nesdev.com/w/index.php/INES
+# - https://wiki.nesdev.com/w/index.php/NES_2.0
+
+# Common header for iNES, NES 2.0, and Wii U iNES.
+0      name            nes-rom-image-ines
+>7     byte&0x0C       =0x8            (NES 2.0)
+>4     byte            x               \b: %ux16k PRG
+>5     byte            x               \b, %ux8k CHR
+>6     byte&0x08       =0x8            [4-Scr]
+>6     byte&0x09       =0x0            [H-mirror]
+>6     byte&0x09       =0x1            [V-mirror]
+>6     byte&0x02       =0x2            [SRAM]
+>6     byte&0x04       =0x4            [Trainer]
+>7     byte&0x03       =0x2            [PC10]
+>7     byte&0x03       =0x1            [VS]
+>>7    byte&0x0C       =0x8
+# NES 2.0: VS PPU
+>>>13  byte&0x0F       =0x0            \b, RP2C03B
+>>>13  byte&0x0F       =0x1            \b, RP2C03G
+>>>13  byte&0x0F       =0x2            \b, RP2C04-0001
+>>>13  byte&0x0F       =0x3            \b, RP2C04-0002
+>>>13  byte&0x0F       =0x4            \b, RP2C04-0003
+>>>13  byte&0x0F       =0x5            \b, RP2C04-0004
+>>>13  byte&0x0F       =0x6            \b, RP2C03B
+>>>13  byte&0x0F       =0x7            \b, RP2C03C
+>>>13  byte&0x0F       =0x8            \b, RP2C05-01
+>>>13  byte&0x0F       =0x9            \b, RP2C05-02
+>>>13  byte&0x0F       =0xA            \b, RP2C05-03
+>>>13  byte&0x0F       =0xB            \b, RP2C05-04
+>>>13  byte&0x0F       =0xC            \b, RP2C05-05
+# TODO: VS protection hardware?
+>>7    byte            x               \b]
+# NES 2.0-specific flags.
+>7     byte&0x0C       =0x8
+>>12   byte&0x03       =0x0            [NTSC]
+>>12   byte&0x03       =0x1            [PAL]
+>>12   byte&0x02       =0x2            [NTSC+PAL]
+
+# Standard iNES ROM header.
+0      string          NES\x1A         NES ROM image (iNES)
+!:mime application/x-nes-rom
+>0     use             nes-rom-image-ines
+
+# Wii U Virtual Console iNES ROM header.
+0      belong          0x4E455300      NES ROM image (Wii U Virtual Console)
+!:mime application/x-nes-rom
+>0     use             nes-rom-image-ines
+
+#------------------------------------------------------------------------------
+# unif: file(1) magic for UNIF-format Nintendo Entertainment System ROM images
+# Reference: https://wiki.nesdev.com/w/index.php/UNIF
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+#
+# NOTE: The UNIF format uses chunks instead of a fixed header,
+# so most of the data isn't easily parseable.
+#
+0      string  UNIF
+>4     lelong  <16     NES ROM image (UNIF v%d format)
+!:mime application/x-nes-rom
+
+#------------------------------------------------------------------------------
+# fds: file(1) magic for Famciom Disk System disk images
+# Reference: https://wiki.nesdev.com/w/index.php/Family_Computer_Disk_System#.FDS_format
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# TODO: Check "Disk info block" and get info from that in addition to the optional header.
+
+# Disk info block. (block 1)
+0      name    nintendo-fds-disk-info-block
+>23    byte    !1              FMC-
+>23    byte    1               FSC-
+>16    string  x               \b%.3s
+>15    byte    x               \b, mfr %02X
+>20    byte    x               (Rev.%02u)
+
+# Headered version.
+0      string  FDS\x1A
+>0x11  string  *NINTENDO-HVC*  Famicom Disk System disk image:
+!:mime application/x-fds-disk
+>>0x10 use     nintendo-fds-disk-info-block
+>4     byte    1       (%u side)
+>4     byte    !1      (%u sides)
+
+# Unheadered version.
+1      string  *NINTENDO-HVC*  Famicom Disk System disk image:
+!:mime application/x-fds-disk
+>0     use     nintendo-fds-disk-info-block
+
+#------------------------------------------------------------------------------
+# tnes: file(1) magic for TNES-format Nintendo Entertainment System ROM images
+# Used by Nintendo 3DS NES Virtual Console games.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+#
+0              string  TNES    NES ROM image (Nintendo 3DS Virtual Console)
+!:mime         application/x-nes-rom
+>4             byte    100     \b: FDS,
+>>0x2010       use     nintendo-fds-disk-info-block
+>4             byte    !100    \b: TNES mapper %u
+>>5    byte            x               \b, %ux8k PRG
+>>6    byte            x               \b, %ux8k CHR
+>>7    byte&0x08       =1              [WRAM]
+>>8    byte&0x09       =1              [H-mirror]
+>>8    byte&0x09       =2              [V-mirror]
+>>8    byte&0x02       =3              [VRAM]
+
+#------------------------------------------------------------------------------
+# gameboy: file(1) magic for the Nintendo (Color) Gameboy raw ROM format
+# Reference: http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header
+#
+0x104          bequad          0xCEED6666CC0D000B      Game Boy ROM image
+# TODO: application/x-gameboy-color-rom for GBC.
+!:mime         application/x-gameboy-rom
+>0x143         byte&0x80       0x80
+>>0x134                string          >\0                     \b: "%.15s"
+>0x143         byte&0x80       !0x80
+>>0x134                string          >\0                     \b: "%.16s"
+>0x14c         byte            x                       (Rev.%02u)
+
+# Machine type. (SGB, CGB, SGB+CGB)
+>0x14b         byte            0x33
+>>0x146                byte            0x03
+>>>0x143       byte&0x80       0x80    [SGB+CGB]
+>>>0x143       byte&0x80       !0x80   [SGB]
+>>0x146                byte            !0x03
+>>>0x143       byte&0xC0       0x80    [CGB]
+>>>0x143       byte&0xC0       0xC0    [CGB ONLY]
+>0x14b         byte            !0x33
+
+# Mapper.
+>0x147 byte 0x00  [ROM ONLY]
+>0x147 byte 0x01  [MBC1]
+>0x147 byte 0x02  [MBC1+RAM]
+>0x147 byte 0x03  [MBC1+RAM+BATT]
+>0x147 byte 0x05  [MBC2]
+>0x147 byte 0x06  [MBC2+BATTERY]
+>0x147 byte 0x08  [ROM+RAM]
+>0x147 byte 0x09  [ROM+RAM+BATTERY]
+>0x147 byte 0x0B  [MMM01]
+>0x147 byte 0x0C  [MMM01+SRAM]
+>0x147 byte 0x0D  [MMM01+SRAM+BATT]
+>0x147 byte 0x0F  [MBC3+TIMER+BATT]
+>0x147 byte 0x10  [MBC3+TIMER+RAM+BATT]
+>0x147 byte 0x11  [MBC3]
+>0x147 byte 0x12  [MBC3+RAM]
+>0x147 byte 0x13  [MBC3+RAM+BATT]
+>0x147 byte 0x19  [MBC5]
+>0x147 byte 0x1A  [MBC5+RAM]
+>0x147 byte 0x1B  [MBC5+RAM+BATT]
+>0x147 byte 0x1C  [MBC5+RUMBLE]
+>0x147 byte 0x1D  [MBC5+RUMBLE+SRAM]
+>0x147 byte 0x1E  [MBC5+RUMBLE+SRAM+BATT]
+>0x147 byte 0xFC  [Pocket Camera]
+>0x147 byte 0xFD  [Bandai TAMA5]
+>0x147 byte 0xFE  [Hudson HuC-3]
+>0x147 byte 0xFF  [Hudson HuC-1]
+
+# ROM size.
+>0x148 byte 0     \b, ROM: 256Kbit
+>0x148 byte 1     \b, ROM: 512Kbit
+>0x148 byte 2     \b, ROM: 1Mbit
+>0x148 byte 3     \b, ROM: 2Mbit
+>0x148 byte 4     \b, ROM: 4Mbit
+>0x148 byte 5     \b, ROM: 8Mbit
+>0x148 byte 6     \b, ROM: 16Mbit
+>0x148 byte 7     \b, ROM: 32Mbit
+>0x148 byte 0x52  \b, ROM: 9Mbit
+>0x148 byte 0x53  \b, ROM: 10Mbit
+>0x148 byte 0x54  \b, ROM: 12Mbit
+
+# RAM size.
+>0x149 byte 1     \b, RAM: 16Kbit
+>0x149 byte 2     \b, RAM: 64Kbit
+>0x149 byte 3     \b, RAM: 128Kbit
+>0x149 byte 4     \b, RAM: 1Mbit
+>0x149 byte 5     \b, RAM: 512Kbit
+
+#------------------------------------------------------------------------------
+# genesis: file(1) magic for various Sega Mega Drive / Genesis ROM image and disc formats
+# Updated by David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://www.retrodev.com/segacd.html
+# - http://devster.monkeeh.com/sega/32xguide1.txt
+#
+
+# Common Sega Mega Drive header format.
+# FIXME: Name fields are 48 bytes, but have spaces for padding instead of 00s.
+0              name    sega-mega-drive-header
+# ROM title. (Use domestic if present; if not, use international.)
+>0x120         byte    >0x20
+>>0x120                string  >\0     \b: "%.16s"
+>0x120         byte    <0x21
+>>0x150                string  >\0     \b: "%.16s"
+# Other information.
+>0x180         string  >\0     (%.14s
+>>0x110                string  >\0     \b, %.16s
+>0x180         byte    0
+>>0x110                string  >\0     (%.16s
+>0             byte    x       \b)
+
+# TODO: Check for 32X CD?
+# Sega Mega CD disc images: 2048-byte sectors.
+0      string  SEGADISCSYSTEM\ \       Sega Mega CD disc image
+!:mime application/x-sega-cd-rom
+>0     use     sega-mega-drive-header
+>0     byte    x                       \b, 2048-byte sectors
+0      string  SEGABOOTDISC\ \ \ \     Sega Mega CD disc image
+!:mime application/x-sega-cd-rom
+>0     use     sega-mega-drive-header
+>0     byte    x                       \b, 2048-byte sectors
+# Sega Mega CD disc images: 2352-byte sectors.
+0x10   string  SEGADISCSYSTEM\ \       Sega Mega CD disc image
+!:mime application/x-sega-cd-rom
+>0x10  use     sega-mega-drive-header
+>0     byte    x                       \b, 2352-byte sectors
+0x10   string  SEGABOOTDISC\ \ \ \     Sega Mega CD disc image
+!:mime application/x-sega-cd-rom
+>0x10  use     sega-mega-drive-header
+>0     byte    x                       \b, 2352-byte sectors
+
+# Sega Mega Drive, 32X, Pico, and Mega CD Boot ROM images.
+0x100          string  SEGA
+>0x3C0         bequad  0x4D41525320434845      Sega 32X ROM image
+!:mime         application/x-genesis-32x-rom
+>>0            use     sega-mega-drive-header
+>0x3C0         bequad  !0x4D41525320434845
+>>0x105                belong  0x5049434F      Sega Pico ROM image
+!:mime         application/x-sega-pico-rom
+>>>0           use     sega-mega-drive-header
+>>0x105                belong  !0x5049434F
+>>>0x180       beshort 0x4252          Sega Mega CD Boot ROM image
+!:mime         application/x-genesis-rom
+>>>0x180       beshort !0x4252         Sega Mega Drive / Genesis ROM image
+!:mime         application/x-genesis-rom
+>>>0           use     sega-mega-drive-header
+
+#------------------------------------------------------------------------------
+# genesis: file(1) magic for the Super MegaDrive ROM dump format
+#
+
+# NOTE: Due to interleaving, we can't display anything
+# other than the copier header information.
+0      name    sega-genesis-smd-header
+>0     byte    x       %dx16k blocks
+>2     byte    0       \b, last in series or standalone
+>2     byte    >0      \b, split ROM
+
+# "Sega Genesis" header.
+0x280  string EAGN
+>8     beshort 0xAABB  Sega Mega Drive / Genesis ROM image (SMD format):
+!:mime application/x-genesis-rom
+>>0    use     sega-genesis-smd-header
+
+# "Sega Mega Drive" header.
+0x280  string EAMG
+>8     beshort 0xAABB  Sega Mega Drive / Genesis ROM image (SMD format):
+!:mime application/x-genesis-rom
+>>0    use     sega-genesis-smd-header
+
+#------------------------------------------------------------------------------
+# smsgg:  file(1) magic for Sega Master System and Game Gear ROM images
+# Detects all Game Gear and export Sega Master System ROM images,
+# and some Japanese Sega Master System ROM images.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://www.smspower.org/Development/ROMHeader
+#
+
+# General SMS header rule.
+# The SMS boot ROM checks the header at three locations.
+0      name    sega-master-system-rom-header
+# Machine type.
+>0x0F  byte&0xF0       0x30    Sega Master System
+!:mime application/x-sms-rom
+>0x0F  byte&0xF0       0x40    Sega Master System
+!:mime application/x-sms-rom
+>0x0F  byte&0xF0       0x50    Sega Game Gear
+!:mime application/x-gamegear-rom
+>0x0F  byte&0xF0       0x60    Sega Game Gear
+!:mime application/x-gamegear-rom
+>0x0F  byte&0xF0       0x70    Sega Game Gear
+!:mime application/x-gamegear-rom
+>0x0F  default         x       Sega Master System / Game Gear
+!:mime application/x-sms-rom
+>0     byte            x       ROM image:
+# Product code.
+>0x0E  byte&0xF0       0x10    1
+>0x0E  byte&0xF0       0x20    2
+>0x0E  byte&0xF0       0x30    3
+>0x0E  byte&0xF0       0x40    4
+>0x0E  byte&0xF0       0x50    5
+>0x0E  byte&0xF0       0x60    6
+>0x0E  byte&0xF0       0x70    7
+>0x0E  byte&0xF0       0x80    8
+>0x0E  byte&0xF0       0x90    9
+>0x0E  byte&0xF0       0xA0    10
+>0x0E  byte&0xF0       0xB0    11
+>0x0E  byte&0xF0       0xC0    12
+>0x0E  byte&0xF0       0xD0    13
+>0x0E  byte&0xF0       0xE0    14
+>0x0E  byte&0xF0       0xF0    15
+# If the product code is 5 digits, we'll need to backspace here.
+>0x0E  byte&0xF0       !0
+>>0x0C leshort         x       \b%04x
+>0x0E  byte&0xF0       0
+>>0x0C leshort         x       %04x
+# Revision.
+>0x0E  byte&0x0F       x       (Rev.%02d)
+# ROM size. (Used for the boot ROM checksum routine.)
+>0x0F  byte&0x0F       0x0A    (8 KB)
+>0x0F  byte&0x0F       0x0B    (16 KB)
+>0x0F  byte&0x0F       0x0C    (32 KB)
+>0x0F  byte&0x0F       0x0D    (48 KB)
+>0x0F  byte&0x0F       0x0E    (64 KB)
+>0x0F  byte&0x0F       0x0F    (128 KB)
+>0x0F  byte&0x0F       0x00    (256 KB)
+>0x0F  byte&0x0F       0x01    (512 KB)
+>0x0F  byte&0x0F       0x02    (1 MB)
+
+# SMS/GG header locations.
+0x7FF0 string  TMR\ SEGA
+>0x7FF0        use     sega-master-system-rom-header
+0x3FF0 string  TMR\ SEGA
+>0x3FF0        use     sega-master-system-rom-header
+0x1FF0 string  TMR\ SEGA
+>0x1FF0        use     sega-master-system-rom-header
+
+#------------------------------------------------------------------------------
+# saturn: file(1) magic for the Sega Saturn disc image format.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+#
+
+# Common Sega Saturn disc header format.
+# NOTE: Title is 112 bytes, but we're only showing 32 due to space padding.
+# TODO: Release date, device information, region code, others?
+0      name    sega-saturn-disc-header
+>0x60  string  >\0     \b: "%.32s"
+>0x20  string  >\0     (%.10s
+>>0x2A string  >\0     \b, %.6s)
+>>0x2A byte    0       \b)
+
+# 2048-byte sector version.
+0      string  SEGA\ SEGASATURN\       Sega Saturn disc image
+!:mime application/x-saturn-rom
+>0     use     sega-saturn-disc-header
+>0     byte    x                       (2048-byte sectors)
+# 2352-byte sector version.
+0x10   string  SEGA\ SEGASATURN\       Sega Saturn disc image
+!:mime application/x-saturn-rom
+>0x10  use     sega-saturn-disc-header
+>0     byte    x                       (2352-byte sectors)
+
+#------------------------------------------------------------------------------
+# dreamcast: file(1) magic for the Sega Dreamcast disc image format.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://mc.pp.se/dc/ip0000.bin.html
+#
+
+# Common Sega Dreamcast disc header format.
+# NOTE: Title is 128 bytes, but we're only showing 32 due to space padding.
+# TODO: Release date, device information, region code, others?
+0      name    sega-dreamcast-disc-header
+>0x80  string  >\0     \b: "%.32s"
+>0x40  string  >\0     (%.10s
+>>0x4A string  >\0     \b, %.6s)
+>>0x4A byte    0       \b)
+
+# 2048-byte sector version.
+0      string  SEGA\ SEGAKATANA\       Sega Dreamcast disc image
+!:mime application/x-dc-rom
+>0     use     sega-dreamcast-disc-header
+>0     byte    x                       (2048-byte sectors)
+# 2352-byte sector version.
+0x10   string  SEGA\ SEGAKATANA\       Sega Dreamcast disc image
+!:mime application/x-dc-rom
+>0x10  use     sega-dreamcast-disc-header
+>0     byte    x                       (2352-byte sectors)
+
+#------------------------------------------------------------------------------
+# dreamcast:  file(1) uncertain magic for the Sega Dreamcast VMU image format
+#
+0 belong 0x21068028   Sega Dreamcast VMU game image
+0 string LCDi         Dream Animator file
+
+#------------------------------------------------------------------------------
+# z64: file(1) magic for the Z64 format N64 ROM dumps
+# Reference: http://forum.pj64-emu.com/showthread.php?t=2239
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+#
+0      bequad  0x803712400000000F      Nintendo 64 ROM image
+!:mime application/x-n64-rom
+>0x20  string  >\0     \b: "%.20s"
+>0x3B  string  x       (%.4s
+>0x3F  byte    x       \b, Rev.%02u)
+
+#------------------------------------------------------------------------------
+# v64: file(1) magic for the V64 format N64 ROM dumps
+# Same as z64 format, but with 16-bit byteswapping.
+#
+0      bequad  0x3780401200000F00      Nintendo 64 ROM image (V64)
+!:mime application/x-n64-rom
+
+#------------------------------------------------------------------------------
+# n64-swap2: file(1) magic for the swap2 format N64 ROM dumps
+# Same as z64 format, but with swapped 16-bit words.
+#
+0      bequad  0x12408037000F0000      Nintendo 64 ROM image (wordswapped)
+!:mime application/x-n64-rom
+
+#------------------------------------------------------------------------------
+# n64-le32: file(1) magic for the 32-bit byteswapped format N64 ROM dumps
+# Same as z64 format, but with 32-bit byteswapping.
+#
+0      bequad  0x401237800F000000      Nintendo 64 ROM image (32-bit byteswapped)
+!:mime application/x-n64-rom
+
+#------------------------------------------------------------------------------
+# gba: file(1) magic for the Nintendo Game Boy Advance raw ROM format
+# Reference: https://problemkaputt.de/gbatek.htm#gbacartridgeheader
+#
+# Original version from: "Nelson A. de Oliveira" <naoliv@gmail.com>
+# Updated version from: David Korth <gerbilsoft@gerbilsoft.com>
+#
+4      bequad  0x24FFAE51699AA221      Game Boy Advance ROM image
+!:mime application/x-gba-rom
+>0xA0  string  >\0     \b: "%.12s"
+>0xAC  string  x       (%.6s
+>0xBC  byte    x       \b, Rev.%02u)
+
+#------------------------------------------------------------------------------
+# nds: file(1) magic for the Nintendo DS(i) raw ROM format
+# Reference: https://problemkaputt.de/gbatek.htm#dscartridgeheader
+#
+# Original version from: "Nelson A. de Oliveira" <naoliv@gmail.com>
+# Updated version from: David Korth <gerbilsoft@gerbilsoft.com>
+#
+0xC0   bequad  0x24FFAE51699AA221      Nintendo DS ROM image
+!:mime application/x-nintendo-ds-rom
+>0x00  string  >\0             \b: "%.12s"
+>0x0C  string  x               (%.6s
+>0x1E  byte    x               \b, Rev.%02u)
+>0x12  byte    2               (DSi enhanced)
+>0x12  byte    3               (DSi only)
+# Secure Area check.
+>0x20          lelong  <0x4000         (homebrew)
+>0x20          lelong  >0x3FFF
+>>0x4000       lequad  0x0000000000000000      (multiboot)
+>>0x4000       lequad  !0x0000000000000000
+>>>0x4000      lequad  0xE7FFDEFFE7FFDEFF      (decrypted)
+>>>0x4000      lequad  !0xE7FFDEFFE7FFDEFF
+>>>>0x1000     lequad  0x0000000000000000      (encrypted)
+>>>>0x1000     lequad  !0x0000000000000000     (mask ROM)
+
+#------------------------------------------------------------------------------
+# nds_passme: file(1) magic for Nintendo DS ROM images for GBA cartridge boot.
+# This is also used for loading .nds files using the MSET exploit on 3DS.
+# Reference: https://github.com/devkitPro/ndstool/blob/master/source/ndscreate.cpp
+0xC0   bequad  0xC8604FE201708FE2      Nintendo DS Slot-2 ROM image (PassMe)
+!:mime application/x-nintendo-ds-rom
+
+#------------------------------------------------------------------------------
+# ngp: file(1) magic for the Neo Geo Pocket (Color) raw ROM format.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://neogpc.googlecode.com/svn-history/r10/trunk/src/core/neogpc.cpp
+# - https://www.devrs.com/ngp/files/ngpctech.txt
+#
+0x0A   string  BY\ SNK\ CORPORATION    Neo Geo Pocket
+!:mime application/x-neo-geo-pocket-rom
+>0x23  byte    0x10                    Color
+>0     byte    x                       ROM image
+>0x24  string  >\0                     \b: "%.12s"
+>0x1F  byte    0xFF                    (debug mode enabled)
+
+#------------------------------------------------------------------------------
+# msx: file(1) magic for MSX game cartridge dumps
+# Too simple - MPi
+#0 beshort 0x4142 MSX game cartridge dump
+
+#------------------------------------------------------------------------------
+# Sony Playstation executables (Adam Sjoegren <asjo@diku.dk>) :
+0      string  PS-X\ EXE       Sony Playstation executable
+>16    lelong  x               PC=0x%08x,
+>20    lelong  !0              GP=0x%08x,
+>24    lelong  !0              .text=[0x%08x,
+>>28   lelong  x               \b0x%x],
+>32    lelong  !0              .data=[0x%08x,
+>>36   lelong  x               \b0x%x],
+>40    lelong  !0              .bss=[0x%08x,
+>>44   lelong  x               \b0x%x],
+>48    lelong  !0              Stack=0x%08x,
+>48    lelong  =0              No Stack!,
+>52    lelong  !0              StackSize=0x%x,
+#>76   string  >\0             (%s)
+#  Area:
+>113   string  x               (%s)
+
+# CPE executables
+0      string  CPE             CPE executable
+>3     byte    x               (version %d)
+
+#------------------------------------------------------------------------------
+# Microsoft Xbox executables .xbe (Esa Hyytia <ehyytia@cc.hut.fi>)
+0      string  XBEH    Microsoft Xbox executable
+# expect base address of 0x10000
+>0x0104                 ulelong =0x10000
+>>(0x0118.l-0x0FFF4)    lestring16 x       \b: "%.40s"
+>>(0x0118.l-0x0FFF5)    byte     x         (%c
+>>(0x0118.l-0x0FFF6)    byte     x         \b%c-
+>>(0x0118.l-0x0FFF8)    uleshort x         \b%03u)
+>>(0x0118.l-0x0FF60)    ulelong&0x80000007  0x80000007 \b, all regions
+>>(0x0118.l-0x0FF60)    ulelong&0x80000007  !0x80000007
+>>>(0x0118.l-0x0FF60)   ulelong >0           (regions:
+>>>>(0x0118.l-0x0FF60)  ulelong &0x00000001  NA
+>>>>(0x0118.l-0x0FF60)  ulelong &0x00000002  Japan
+>>>>(0x0118.l-0x0FF60)  ulelong &0x00000004  Rest_of_World
+>>>>(0x0118.l-0x0FF60)  ulelong &0x80000000  Manufacturer
+>>>(0x0118.l-0x0FF60)   ulelong >0           \b)
+# probabilistic checks whether signed or not
+>0x0004 ulelong =0x0
+>>&2    ulelong =0x0
+>>>&2   ulelong =0x0  \b, not signed
+>0x0004 ulelong >0
+>>&2    ulelong >0
+>>>&2   ulelong >0    \b, signed
+
+# --------------------------------
+# Microsoft Xbox data file formats
+0       string          XIP0            XIP, Microsoft Xbox data
+0       string          XTF0            XTF, Microsoft Xbox data
+
+#------------------------------------------------------------------------------
+# Microsoft Xbox 360 executables (.xex)
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://free60project.github.io/wiki/XEX.html
+# - https://github.com/xenia-project/xenia/blob/HEAD/src/xenia/kernel/util/xex2_info.h
+
+# Title ID (part of Execution ID section)
+0              name    xbox-360-xex-execution-id
+>(0.L+0xC)     byte    x       (%c
+>(0.L+0xD)     byte    x       \b%c
+>(0.L+0xE)     beshort x       \b-%04u)
+
+0      string  XEX2    Microsoft Xbox 360 executable
+>0x18  search/0x100    \x00\x04\x00\x06
+>>&0   use     xbox-360-xex-execution-id
+>(0x010.L+0x178)       ubelong 0xFFFFFFFF      \b, all regions
+>(0x010.L+0x178)       ubelong !0xFFFFFFFF
+>>(0x010.L+0x178)      ubelong >0              (regions:
+>>(0x010.L+0x178)      ubelong&0x000000FF      0x000000FF      USA
+>>(0x010.L+0x178)      ubelong&0x00000100      0x00000100      Japan
+>>(0x010.L+0x178)      ubelong&0x00000200      0x00000200      China
+>>(0x010.L+0x178)      ubelong&0x0000FC00      0x0000FC00      Asia
+>>(0x010.L+0x178)      ubelong&0x00FF0000      0x00FF0000      PAL
+>>(0x010.L+0x178)      ubelong&0x00FF0000      0x00FE0000      PAL [except AU/NZ]
+>>(0x010.L+0x178)      ubelong&0x00FF0000      0x00010000      AU/NZ
+>>(0x010.L+0x178)      ubelong&0xFF000000      0xFF000000      Other
+>>(0x010.L+0x178)      ubelong >0              \b)
+
+
+
+# Atari Lynx cartridge dump (EXE/BLL header)
+# From: "Stefan A. Haubenthal" <polluks@web.de>
+
+# Double-check that the image type matches too, 0x8008 conflicts with
+# 8 character OMF-86 object file headers.
+0      beshort         0x8008
+>6     string          BS93            Lynx homebrew cartridge
+!:mime application/x-atari-lynx-rom
+>>2    beshort         x               \b, RAM start $%04x
+>6     string          LYNX            Lynx cartridge
+!:mime application/x-atari-lynx-rom
+>>2    beshort         x               \b, RAM start $%04x
+
+# Opera file system that is used on the 3DO console
+# From: Serge van den Boom <svdb@stack.nl>
+0      string          \x01ZZZZZ\x01   3DO "Opera" file system
+
+# From: Alex Myczko <alex@aiei.ch>
+# From: David Pflug <david@pflug.email>
+# is the offset 12 or the offset 16 correct?
+# GBS (Game Boy Sound) magic
+# ftp://ftp.modland.com/pub/documents/format_documentation/\
+# Gameboy%20Sound%20System%20(.gbs).txt
+0      string          GBS             Nintendo Gameboy Music/Audio Data
+#12    string          GameBoy\ Music\ Module  Nintendo Gameboy Music Module
+>16    string          >\0     ("%.32s" by
+>48    string          >\0     %.32s, copyright
+>80    string          >\0     %.32s),
+>3     byte            x       version %u,
+>4     byte            x       %u tracks
+
+# IPS Patch Files from: From: Thomas Klausner <tk@giga.or.at>
+# see https://zerosoft.zophar.net/ips.php
+0      string  PATCH                   IPS patch file
+
+# Playstations Patch Files from: From: Thomas Klausner <tk@giga.or.at>
+0      string  PPF30                   Playstation Patch File version 3.0
+>5     byte    0                       \b, PPF 1.0 patch
+>5     byte    1                       \b, PPF 2.0 patch
+>5     byte    2                       \b, PPF 3.0 patch
+>>56   byte    0                       \b, Imagetype BIN (any)
+>>56   byte    1                       \b, Imagetype GI (PrimoDVD)
+>>57   byte    0                       \b, Blockcheck disabled
+>>57   byte    1                       \b, Blockcheck enabled
+>>58   byte    0                       \b, Undo data not available
+>>58   byte    1                       \b, Undo data available
+>6     string  x                       \b, description: %s
+
+0      string  PPF20                   Playstation Patch File version 2.0
+>5     byte    0                       \b, PPF 1.0 patch
+>5     byte    1                       \b, PPF 2.0 patch
+>>56   lelong  >0                      \b, size of file to patch %d
+>6     string  x                       \b, description: %s
+
+0      string  PPF10                   Playstation Patch File version 1.0
+>5     byte    0                       \b, Simple Encoding
+>6     string  x                       \b, description: %s
+
+# From: Daniel Dawson <ddawson@icehouse.net>
+# SNES9x .smv "movie" file format.
+0              string          SMV\x1A SNES9x input recording
+>0x4           lelong          x       \b, version %d
+# version 4 is latest so far
+>0x4           lelong          <5
+>>0x8          ledate          x       \b, recorded at %s
+>>0xc          lelong          >0      \b, rerecorded %d times
+>>0x10         lelong          x       \b, %d frames long
+>>0x14         byte            >0      \b, data for controller(s):
+>>>0x14                byte            &0x1    #1
+>>>0x14                byte            &0x2    #2
+>>>0x14                byte            &0x4    #3
+>>>0x14                byte            &0x8    #4
+>>>0x14                byte            &0x10   #5
+>>0x15         byte            ^0x1    \b, begins from snapshot
+>>0x15         byte            &0x1    \b, begins from reset
+>>0x15         byte            ^0x2    \b, NTSC standard
+>>0x15         byte            &0x2    \b, PAL standard
+>>0x17         byte            &0x1    \b, settings:
+# WIP1Timing not used as of version 4
+>>>0x4         lelong          <4
+>>>>0x17       byte            &0x2    WIP1Timing
+>>>0x17                byte            &0x4    Left+Right
+>>>0x17                byte            &0x8    VolumeEnvX
+>>>0x17                byte            &0x10   FakeMute
+>>>0x17                byte            &0x20   SyncSound
+# New flag as of version 4
+>>>0x4         lelong          >3
+>>>>0x17       byte            &0x80   NoCPUShutdown
+>>0x4          lelong          <4
+>>>0x18                lelong          >0x23
+>>>>0x20       leshort         !0
+>>>>>0x20      lestring16      x       \b, metadata: "%s"
+>>0x4          lelong          >3
+>>>0x24                byte            >0      \b, port 1:
+>>>>0x24       byte            1       joypad
+>>>>0x24       byte            2       mouse
+>>>>0x24       byte            3       SuperScope
+>>>>0x24       byte            4       Justifier
+>>>>0x24       byte            5       multitap
+>>>0x24                byte            >0      \b, port 2:
+>>>>0x25       byte            1       joypad
+>>>>0x25       byte            2       mouse
+>>>>0x25       byte            3       SuperScope
+>>>>0x25       byte            4       Justifier
+>>>>0x25       byte            5       multitap
+>>>0x18                lelong          >0x43
+>>>>0x40       leshort         !0
+>>>>>0x40      lestring16      x       \b, metadata: "%s"
+>>0x17         byte            &0x40   \b, ROM:
+>>>(0x18.l-26) lelong          x       CRC32 0x%08x
+>>>(0x18.l-23) string          x       "%s"
+
+# Type: scummVM savegame files
+# From: Sven Hartge <debian@ds9.argh.org>
+0      string  SCVM    ScummVM savegame
+>12    string  >\0     "%s"
+
+#------------------------------------------------------------------------------
+# Nintendo GameCube / Wii file formats.
+#
+
+# Type: Nintendo GameCube/Wii common disc header data.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://wiibrew.org/wiki/Wii_Disc
+0      name    nintendo-gcn-disc-common
+>0x20  string  x       "%.64s"
+>0x00  string  x       (%.6s
+>0x06  byte    >0
+>>0x06 byte    1       \b, Disc 2
+>>0x06 byte    2       \b, Disc 3
+>>0x06 byte    3       \b, Disc 4
+>0x07  byte    x       \b, Rev.%02u)
+>0x18  belong  0x5D1C9EA3
+>>0x60 beshort 0x0101  \b (Unencrypted)
+
+# Type: Nintendo GameCube disc image
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://wiibrew.org/wiki/Wii_Disc
+0x1C   belong  0xC2339F3D      Nintendo GameCube disc image:
+!:mime application/x-gamecube-rom
+>0     use     nintendo-gcn-disc-common
+
+# Type: Nintendo GameCube embedded disc image
+# Commonly found on demo discs.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: http://hitmen.c02.at/files/yagcd/yagcd/index.html#idx14.8
+0              belong  0xAE0F38A2
+>0x0C          belong  0x00100000
+>>(8.L+0x1C)   belong  0xC2339F3D      Nintendo GameCube embedded disc image:
+!:mime application/x-gamecube-rom
+>>>(8.L)       use     nintendo-gcn-disc-common
+
+# Type: Nintendo Wii disc image
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://wiibrew.org/wiki/Wii_Disc
+0x18   belong  0x5D1C9EA3      Nintendo Wii disc image:
+>0     use     nintendo-gcn-disc-common
+
+# Type: Nintendo Wii disc image (WBFS format)
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://wiibrew.org/wiki/Wii_Disc
+0      string  WBFS
+>0x218 belong  0x5D1C9EA3      Nintendo Wii disc image (WBFS format):
+!:mime application/x-wii-rom
+>>0x200        use     nintendo-gcn-disc-common
+
+# Type: Nintendo GameCube/Wii disc image (CISO format)
+# NOTE: This is NOT the same as Compact ISO or PSP CISO,
+# though it has the same magic number.
+0              string  CISO
+# Other fields are used to determine what type of CISO this is:
+# - 0x04 == 0x00200000: GameCube/Wii CISO (block_size)
+# - 0x10 == 0x00000800: PSP CISO (ISO-9660 sector size)
+# - None of the above: Compact ISO.
+>4             lelong  0x200000
+>>8            byte    1
+>>>0x801C      belong  0xC2339F3D      Nintendo GameCube disc image (CISO format):
+!:mime application/x-wii-rom
+>>>>0x8000     use     nintendo-gcn-disc-common
+>>>0x8018      belong  0x5D1C9EA3      Nintendo Wii disc image (CISO format):
+!:mime application/x-wii-rom
+>>>>0x8000     use     nintendo-gcn-disc-common
+
+# Type: Nintendo GameCube/Wii disc image (GCZ format)
+# Due to zlib compression, we can't get the actual disc information.
+0      lelong  0xB10BC001
+>4     lelong  0               Nintendo GameCube disc image (GCZ format)
+!:mime application/x-gamecube-rom
+>4     lelong  1               Nintendo Wii disc image (GCZ format)
+!:mime application/x-wii-rom
+>4     default x               Nintendo GameCube/Wii disc image (GCZ format)
+
+# Type: Nintendo GameCube/Wii disc image (WDF format)
+0              string  WII\001DISC
+>8             belong  1
+# WDFv1
+>>0x54         belong  0xC2339F3D      Nintendo GameCube disc image (WDFv1 format):
+!:mime application/x-gamecube-rom
+>>>0x38                use     nintendo-gcn-disc-common
+>>0x58         belong  0x5D1C9EA3      Nintendo Wii disc image (WDFv1 format):
+!:mime application/x-wii-rom
+>>>0x38                use     nintendo-gcn-disc-common
+>8             belong  2
+# WDFv2
+>>(12.L+0x1C)  belong  0xC2339F3D      Nintendo GameCube disc image (WDFv2 format):
+!:mime application/x-gamecube-rom
+>>>(12.L)      use     nintendo-gcn-disc-common
+>>(12.L+0x18)  belong  0x5D1C9EA3      Nintendo Wii disc image (WDFv2 format):
+!:mime application/x-wii-rom
+>>>(12.L)      use     nintendo-gcn-disc-common
+
+# Type: Nintendo GameCube/Wii disc image (WIA format)
+0      string  WIA\001 Nintendo
+>0x48  belong  1       GameCube
+!:mime application/x-gamecube-rom
+>0x48  belong  2       Wii
+!:mime application/x-wii-rom
+>0x48  default x       GameCube/Wii
+>0x48  belong  x       disc image (WIA format):
+>>0x58 use     nintendo-gcn-disc-common
+
+# Type: Nintendo GameCube/Wii disc image (with SDK header)
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://wiibrew.org/wiki/Wii_Disc
+0              belong  0xFFFF0000
+>0x18          belong  0x00000000
+>>0x1C         belong  0x00000000
+>>>0x8018      belong  0x5D1C9EA3      Nintendo Wii SDK disc image:
+!:mime application/x-wii-rom
+>>>>0x8000     use     nintendo-gcn-disc-common
+>>>0x801C      belong  0xC2339F3D      Nintendo GameCube SDK disc image:
+!:mime application/x-gamecube-rom
+>>>>0x8000     use     nintendo-gcn-disc-common
+
+#------------------------------------------------------------------------------
+# Nintendo 3DS file formats.
+#
+
+# Type: Nintendo 3DS "NCSD" image. (game cards and eMMC)
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://www.3dbrew.org/wiki/NCSD
+0x100          string          NCSD
+>0x118         lequad          0               Nintendo 3DS Game Card image
+# NCCH header for partition 0. (game data)
+>>0x1150       string          >\0     \b: "%.16s"
+>>0x312                byte            x       (Rev.%02u)
+>>0x118C       byte            2       (New3DS only)
+>>0x18D                byte            0               (inner device)
+>>0x18D                byte            1               (Card1)
+>>0x18D                byte            2               (Card2)
+>>0x18D                byte            3               (extended device)
+>0x118         bequad          0x0102020202000000      Nintendo 3DS eMMC dump (Old3DS)
+>0x118         bequad          0x0102020203000000      Nintendo 3DS eMMC dump (New3DS)
+
+# Nintendo 3DS version code.
+# Reference: https://www.3dbrew.org/wiki/Titles
+# Format: leshort containing three fields:
+# - 6-bit: Major
+# - 6-bit: Minor
+# - 4-bit: Revision
+# NOTE: Only supporting major/minor versions from 0-15 right now.
+# NOTE: Should be prefixed with "v".
+0      name    nintendo-3ds-version-code
+# Raw version.
+>0     leshort x       \b%u,
+# Major version.
+>0     leshort&0xFC00  0x0000  0
+>0     leshort&0xFC00  0x0400  1
+>0     leshort&0xFC00  0x0800  2
+>0     leshort&0xFC00  0x0C00  3
+>0     leshort&0xFC00  0x1000  4
+>0     leshort&0xFC00  0x1400  5
+>0     leshort&0xFC00  0x1800  6
+>0     leshort&0xFC00  0x1C00  7
+>0     leshort&0xFC00  0x2000  8
+>0     leshort&0xFC00  0x2400  9
+>0     leshort&0xFC00  0x2800  10
+>0     leshort&0xFC00  0x2C00  11
+>0     leshort&0xFC00  0x3000  12
+>0     leshort&0xFC00  0x3400  13
+>0     leshort&0xFC00  0x3800  14
+>0     leshort&0xFC00  0x3C00  15
+# Minor version.
+>0     leshort&0x03F0  0x0000  \b.0
+>0     leshort&0x03F0  0x0010  \b.1
+>0     leshort&0x03F0  0x0020  \b.2
+>0     leshort&0x03F0  0x0030  \b.3
+>0     leshort&0x03F0  0x0040  \b.4
+>0     leshort&0x03F0  0x0050  \b.5
+>0     leshort&0x03F0  0x0060  \b.6
+>0     leshort&0x03F0  0x0070  \b.7
+>0     leshort&0x03F0  0x0080  \b.8
+>0     leshort&0x03F0  0x0090  \b.9
+>0     leshort&0x03F0  0x00A0  \b.10
+>0     leshort&0x03F0  0x00B0  \b.11
+>0     leshort&0x03F0  0x00C0  \b.12
+>0     leshort&0x03F0  0x00D0  \b.13
+>0     leshort&0x03F0  0x00E0  \b.14
+>0     leshort&0x03F0  0x00F0  \b.15
+# Revision.
+>0     leshort&0x000F  x       \b.%u
+
+# Type: Nintendo 3DS "NCCH" container.
+# https://www.3dbrew.org/wiki/NCCH
+0x100          string  NCCH    Nintendo 3DS
+>0x18D         byte&2  0       File Archive (CFA)
+>0x18D         byte&2  2       Executable Image (CXI)
+>0x150         string  >\0     \b: "%.16s"
+>0x18D         byte    0x05
+>>0x10E                leshort x       (Old3DS System Update v
+>>0x10E                use     nintendo-3ds-version-code
+>>0x10E                leshort x       \b)
+>0x18D         byte    0x15
+>>0x10E                leshort x       (New3DS System Update v
+>>0x10E                use     nintendo-3ds-version-code
+>>0x10E                leshort x       \b)
+>0x18D         byte    !0x05
+>>0x18D                byte    !0x15
+>>>0x112       byte    x       (v
+>>>0x112       use     nintendo-3ds-version-code
+>>>0x112       byte    x       \b)
+>0x18C         byte    2       (New3DS only)
+
+# Type: Nintendo 3DS "SMDH" file. (application description)
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://3dbrew.org/wiki/SMDH
+0              string          SMDH            Nintendo 3DS SMDH file
+>0x208         leshort         !0
+>>0x208                lestring16      x               \b: "%.128s"
+>>0x388                leshort         !0
+>>>0x388       lestring16      x               by %.128s
+>0x208         leshort         0
+>>0x008                leshort         !0
+>>>0x008       lestring16      x               \b: "%.128s"
+>>>0x188       leshort         !0
+>>>>0x188      lestring16      x               by %.128s
+
+# Type: Nintendo 3DS Homebrew Application.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://3dbrew.org/wiki/3DSX_Format
+0      string  3DSX    Nintendo 3DS Homebrew Application (3DSX)
+
+#------------------------------------------------------------------------------
+# a7800: file(1) magic for the Atari 7800 raw ROM format.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://sites.google.com/site/atari7800wiki/a78-header
+
+0      byte    >0
+>0     byte    <3
+>>1    string  ATARI7800       Atari 7800 ROM image
+!:mime application/x-atari-7800-rom
+>>>0x11        string  >\0     \b: "%.32s"
+# Display type.
+>>>0x39        byte    0       (NTSC)
+>>>0x39        byte    1       (PAL)
+>>>0x36        byte&1  1       (POKEY)
+
+#------------------------------------------------------------------------------
+# vectrex: file(1) magic for the GCE Vectrex raw ROM format.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: http://www.playvectrex.com/designit/chrissalo/hello1.htm
+#
+# NOTE: Title is terminated with 0x80, not 0.
+# The header is terminated with a 0, so that will
+# terminate the title as well.
+#
+0      string  g\ GCE  Vectrex ROM image
+>0x11  string  >\0     \b: "%.16s"
+
+#------------------------------------------------------------------------------
+# amiibo: file(1) magic for Nintendo amiibo NFC dumps.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# Reference: https://www.3dbrew.org/wiki/Amiibo
+0x00           byte    0x04
+>0x0A          beshort 0x0FE0
+>>0x0C         belong  0xF110FFEE
+>>>0x208       beshort 0x0100
+>>>>0x020A     byte    0x0F
+>>>>>0x020C    bequad  0x000000045F000000
+>>>>>>0x5B     byte    0x02
+>>>>>>>0x54    belong  x       Nintendo amiibo NFC dump - amiibo ID: %08X-
+>>>>>>>0x58    belong  x       \b%08X
diff --git a/magic/Magdir/convex b/magic/Magdir/convex
new file mode 100644 (file)
index 0000000..4e096b9
--- /dev/null
@@ -0,0 +1,69 @@
+
+#------------------------------------------------------------------------------
+# $File: convex,v 1.7 2009/09/19 16:28:08 christos Exp $
+# convex:  file(1) magic for Convex boxes
+#
+# Convexes are big-endian.
+#
+# /*\
+#  * Below are the magic numbers and tests added for Convex.
+#  * Added at beginning, because they are expected to be used most.
+# \*/
+0      belong  0507    Convex old-style object
+>16    belong  >0      not stripped
+0      belong  0513    Convex old-style demand paged executable
+>16    belong  >0      not stripped
+0      belong  0515    Convex old-style pre-paged executable
+>16    belong  >0      not stripped
+0      belong  0517    Convex old-style pre-paged, non-swapped executable
+>16    belong  >0      not stripped
+0      belong  0x011257        Core file
+#
+# The following are a series of dump format magic numbers.  Each one
+# corresponds to a drastically different dump format.  The first on is
+# the original dump format on a 4.1 BSD or earlier file system.  The
+# second marks the change between the 4.1 file system and the 4.2 file
+# system.  The Third marks the changing of the block size from 1K
+# to 2K to be compatible with an IDC file system.  The fourth indicates
+# a dump that is dependent on Convex Storage Manager, because data in
+# secondary storage is not physically contained within the dump.
+# The restore program uses these number to determine how the data is
+# to be extracted.
+#
+24     belong  =60013  dump format, 4.2 or 4.3 BSD (IDC compatible)
+24     belong  =60014  dump format, Convex Storage Manager by-reference dump
+#
+# what follows is a bunch of bit-mask checks on the flags field of the opthdr.
+# If there is no `=' sign, assume just checking for whether the bit is set?
+#
+0      belong  0601            Convex SOFF
+>88    belong&0x000f0000       =0x00000000     c1
+>88    belong                  &0x00010000     c2
+>88    belong                  &0x00020000     c2mp
+>88    belong                  &0x00040000     parallel
+>88    belong                  &0x00080000     intrinsic
+>88    belong                  &0x00000001     demand paged
+>88    belong                  &0x00000002     pre-paged
+>88    belong                  &0x00000004     non-swapped
+>88    belong                  &0x00000008     POSIX
+#
+>84    belong                  &0x80000000     executable
+>84    belong                  &0x40000000     object
+>84    belong&0x20000000       =0              not stripped
+>84    belong&0x18000000       =0x00000000     native fpmode
+>84    belong&0x18000000       =0x10000000     ieee fpmode
+>84    belong&0x18000000       =0x18000000     undefined fpmode
+#
+0      belong                  0605            Convex SOFF core
+#
+0      belong                  0607            Convex SOFF checkpoint
+>88    belong&0x000f0000       =0x00000000     c1
+>88    belong                  &0x00010000     c2
+>88    belong                  &0x00020000     c2mp
+>88    belong                  &0x00040000     parallel
+>88    belong                  &0x00080000     intrinsic
+>88    belong                  &0x00000008     POSIX
+#
+>84    belong&0x18000000       =0x00000000     native fpmode
+>84    belong&0x18000000       =0x10000000     ieee fpmode
+>84    belong&0x18000000       =0x18000000     undefined fpmode
diff --git a/magic/Magdir/coverage b/magic/Magdir/coverage
new file mode 100644 (file)
index 0000000..69eab70
--- /dev/null
@@ -0,0 +1,91 @@
+
+#------------------------------------------------------------------------------
+# $File: coverage,v 1.2 2019/04/19 00:42:27 christos Exp $
+# xoverage:  file(1) magic for test coverage data
+
+# File formats used to store test coverage data
+# 2016-05-21, Georg Sauthoff <mail@georg.so>
+
+
+# - GCC gcno - written by GCC at compile time when compiling with
+#      gcc -ftest-coverage
+# - GCC gcda - written by a program that was compiled with
+#      gcc -fprofile-arcs
+# - LLVM raw profiles - generated by a program compiled with
+#      clang -fprofile-instr-generate -fcoverage-mapping ...
+# - LLVM indexed profiles - generated by
+#      llvm-profdata
+# - GCOV reports, i.e. the annotated source code
+# - LCOV trace files, i.e. aggregated GCC profiles
+#
+# GCC coverage tracefiles
+# .gcno file are created during compile time,
+# while data collected during runtime is stored in .gcda files
+# cf. gcov-io.h
+# https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Gcov-Data-Files.html
+# Examples:
+# Fedora 23/x86-64/gcc-5.3.1: 6f 6e 63 67 52 33 30 35
+# Debian 8 PPC64/gcc-4.9.2  : 67 63 6e 6f 34 30 39 2a
+0      lelong  0x67636e6f      GCC gcno coverage (-ftest-coverage),
+>&3    byte    x       version %c.
+>&1    byte    x       \b%c
+
+# big endian
+0      belong  0x67636e6f      GCC gcno coverage (-ftest-coverage),
+>&0    byte    x       version %c.
+>&2    byte    x       \b%c (big-endian)
+
+# Examples:
+# Fedora 23/x86-64/gcc-5.3.1: 61 64 63 67 52 33 30 35
+# Debian 8 PPC64/gcc-4.9.2  : 67 63 64 61 34 30 39 2a
+0      lelong  0x67636461      GCC gcda coverage (-fprofile-arcs),
+>&3    byte    x       version %c.
+>&1    byte    x       \b%c
+
+# big endian
+0      belong  0x67636461      GCC gcda coverage (-fprofile-arcs),
+>&0    byte    x       version %c.
+>&2    byte    x       \b%c (big-endian)
+
+
+# LCOV tracefiles
+# cf. http://ltp.sourceforge.net/coverage/lcov/geninfo.1.php
+0      string  TN:
+>&0    search/64       \nSF:/  LCOV coverage tracefile
+
+
+# Coverage reports generated by gcov
+# i.e. source code annoted with coverage information
+0      string  \x20\x20\x20\x20\x20\x20\x20\x20-:\x20\x20\x20\ 0:Source:
+>&0    search/128      \x20\x20\x20\x20\x20\x20\x20\x20-:\x20\x20\x20\ 0:Graph:
+>>&0   search/128      \x20\x20\x20\x20\x20\x20\x20\x20-:\x20\x20\x20\ 0:Data: GCOV coverage report
+
+
+# LLVM coverage files
+
+# raw data after running a program compiled with:
+# `clang -fprofile-instr-generate -fcoverage-mapping ...`
+# default name: default.profraw
+# magic is: \xFF lprofr \x81
+# cf. https://llvm.org/docs/doxygen/html/InstrProfData_8inc_source.html
+0      lequad  0xff6c70726f667281      LLVM raw profile data,
+>&0    byte    x       version %d
+
+# big endian
+0      bequad  0xff6c70726f667281      LLVM raw profile data,
+>&7    byte    x       version %d (big-endian)
+
+
+# LLVM indexed instruction profile (as generated by llvm-profdata)
+# magic is: reverse(\xFF lprofi \x81)
+# cf. https://llvm.org/docs/CoverageMappingFormat.html
+# https://llvm.org/docs/doxygen/html/namespacellvm_1_1IndexedInstrProf.html
+# https://llvm.org/docs/CommandGuide/llvm-cov.html
+# https://llvm.org/docs/CommandGuide/llvm-profdata.html
+0      lequad  0x8169666f72706cff      LLVM indexed profile data,
+>&0    byte    x       version %d
+
+# big endian
+0      bequad  0x8169666f72706cff      LLVM indexed profile data,
+>&7    byte    x       version %d (big-endian)
+
diff --git a/magic/Magdir/cracklib b/magic/Magdir/cracklib
new file mode 100644 (file)
index 0000000..9ed7f65
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# cracklib:  file (1) magic for cracklib v2.7
+
+0      lelong  0x70775631      Cracklib password index, little endian
+>4     long    >0              (%i words)
+>4     long    0               ("64-bit")
+>>8    long    >-1             (%i words)
+0      belong  0x70775631      Cracklib password index, big endian
+>4     belong  >-1             (%i words)
+# really bellong 0x0000000070775631
+0      search/1        \0\0\0\0pwV1    Cracklib password index, big endian ("64-bit")
+>12    belong  >0              (%i words)
diff --git a/magic/Magdir/ctags b/magic/Magdir/ctags
new file mode 100644 (file)
index 0000000..5b67d79
--- /dev/null
@@ -0,0 +1,6 @@
+
+# ----------------------------------------------------------------------------
+# $File$
+# ctags:  file (1) magic for Exuberant Ctags files
+# From: Alexander Mai <mai@migdal.ikp.physik.tu-darmstadt.de>
+0      search/1        =!_TAG  Exuberant Ctags tag file text
diff --git a/magic/Magdir/ctf b/magic/Magdir/ctf
new file mode 100644 (file)
index 0000000..ebea8f3
--- /dev/null
@@ -0,0 +1,23 @@
+
+#--------------------------------------------------------------
+# ctf:  file(1) magic for CTF (Common Trace Format) trace files
+#
+# Specs. available here: <https://www.efficios.com/ctf>
+#--------------------------------------------------------------
+
+# CTF trace data
+0      lelong  0xc1fc1fc1      Common Trace Format (CTF) trace data (LE)
+0      belong  0xc1fc1fc1      Common Trace Format (CTF) trace data (BE)
+
+# CTF metadata (packetized)
+0      lelong  0x75d11d57      Common Trace Format (CTF) packetized metadata (LE)
+>35    byte    x               \b, v%d
+>36    byte    x               \b.%d
+0      belong  0x75d11d57      Common Trace Format (CTF) packetized metadata (BE)
+>35    byte    x               \b, v%d
+>36    byte    x               \b.%d
+
+# CTF metadata (plain text)
+0      string  /*\x20CTF\x20   Common Trace Format (CTF) plain text metadata
+!:strength + 5                 # this is to make sure we beat C
+>&0    regex   [0-9]+\.[0-9]+  \b, v%s
diff --git a/magic/Magdir/cubemap b/magic/Magdir/cubemap
new file mode 100644 (file)
index 0000000..50ab531
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File: cubemaps,v 1.0 2011/12/22 09:01:05 christos Exp $
+# file(1) magic(5) data for cubemaps  Martin Erik Werner <martinerikwerner@gmail.com>
+#
+0      string  ACMP    Map file for the AssaultCube FPS game
+0      string  CUBE    Map file for cube and cube2 engine games
+0      string  MAPZ)   Map file for the Blood Frontier/Red Eclipse FPS games
diff --git a/magic/Magdir/cups b/magic/Magdir/cups
new file mode 100644 (file)
index 0000000..6dd14ac
--- /dev/null
@@ -0,0 +1,56 @@
+
+#------------------------------------------------------------------------------
+# $File: cups,v 1.6 2019/04/19 00:42:27 christos Exp $
+# Cups: file(1) magic for the cups raster file format
+# From: Laurent Martelli <martellilaurent@gmail.com>
+# https://www.cups.org/documentation.php/spec-raster.html
+#
+
+0      name            cups-le
+>280   lelong          x               \b, %d
+>284   lelong          x               \bx%d dpi
+>376   lelong          x               \b, %dx
+>380   lelong          x               \b%d pixels
+>388   lelong          x               %d bits/color
+>392   lelong          x               %d bits/pixel
+>400   lelong          0               ColorOrder=Chunky
+>400   lelong          1               ColorOrder=Banded
+>400   lelong          2               ColorOrder=Planar
+>404   lelong          0               ColorSpace=gray
+>404   lelong          1               ColorSpace=RGB
+>404   lelong          2               ColorSpace=RGBA
+>404   lelong          3               ColorSpace=black
+>404   lelong          4               ColorSpace=CMY
+>404   lelong          5               ColorSpace=YMC
+>404   lelong          6               ColorSpace=CMYK
+>404   lelong          7               ColorSpace=YMCK
+>404   lelong          8               ColorSpace=KCMY
+>404   lelong          9               ColorSpace=KCMYcm
+>404   lelong          10              ColorSpace=GMCK
+>404   lelong          11              ColorSpace=GMCS
+>404   lelong          12              ColorSpace=WHITE
+>404   lelong          13              ColorSpace=GOLD
+>404   lelong          14              ColorSpace=SILVER
+>404   lelong          15              ColorSpace=CIE XYZ
+>404   lelong          16              ColorSpace=CIE Lab
+>404   lelong          17              ColorSpace=RGBW
+>404   lelong          18              ColorSpace=sGray
+>404   lelong          19              ColorSpace=sRGB
+>404   lelong          20              ColorSpace=AdobeRGB
+
+# Cups Raster image format, Big Endian
+0      string          RaS
+>3     string          t               Cups Raster version 1, Big Endian
+>3     string          2               Cups Raster version 2, Big Endian
+>3     string          3               Cups Raster version 3, Big Endian
+!:mime application/vnd.cups-raster
+>0     use             \^cups-le
+
+
+# Cups Raster image format, Little Endian
+1      string          SaR
+>0     string          t               Cups Raster version 1, Little Endian
+>0     string          2               Cups Raster version 2, Little Endian
+>0     string          3               Cups Raster version 3, Little Endian
+!:mime application/vnd.cups-raster
+>0     use             cups-le
diff --git a/magic/Magdir/dact b/magic/Magdir/dact
new file mode 100644 (file)
index 0000000..3c5a407
--- /dev/null
@@ -0,0 +1,11 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# dact:  file(1) magic for DACT compressed files
+#
+0      long            0x444354C3      DACT compressed data
+>4     byte            >-1             (version %i.
+>5     byte            >-1             $BS%i.
+>6     byte            >-1             $BS%i)
+>7     long            >0              $BS, original size: %i bytes
+>15    long            >30             $BS, block size: %i bytes
diff --git a/magic/Magdir/database b/magic/Magdir/database
new file mode 100644 (file)
index 0000000..071a115
--- /dev/null
@@ -0,0 +1,646 @@
+
+#------------------------------------------------------------------------------
+# $File: database,v 1.55 2019/04/19 00:42:27 christos Exp $
+# database:  file(1) magic for various databases
+#
+# extracted from header/code files by Graeme Wilford (eep2gw@ee.surrey.ac.uk)
+#
+#
+# GDBM magic numbers
+#  Will be maintained as part of the GDBM distribution in the future.
+#  <downsj@teeny.org>
+0      belong  0x13579acd      GNU dbm 1.x or ndbm database, big endian, 32-bit
+!:mime application/x-gdbm
+0      belong  0x13579ace      GNU dbm 1.x or ndbm database, big endian, old
+!:mime application/x-gdbm
+0      belong  0x13579acf      GNU dbm 1.x or ndbm database, big endian, 64-bit
+!:mime application/x-gdbm
+0      lelong  0x13579acd      GNU dbm 1.x or ndbm database, little endian, 32-bit
+!:mime application/x-gdbm
+0      lelong  0x13579ace      GNU dbm 1.x or ndbm database, little endian, old
+!:mime application/x-gdbm
+0      lelong  0x13579acf      GNU dbm 1.x or ndbm database, little endian, 64-bit
+!:mime application/x-gdbm
+0      string  GDBM            GNU dbm 2.x database
+!:mime application/x-gdbm
+#
+# Berkeley DB
+#
+# Ian Darwin's file /etc/magic files: big/little-endian version.
+#
+# Hash 1.85/1.86 databases store metadata in network byte order.
+# Btree 1.85/1.86 databases store the metadata in host byte order.
+# Hash and Btree 2.X and later databases store the metadata in host byte order.
+
+0      long    0x00061561      Berkeley DB
+!:mime application/x-dbm
+>8     belong  4321
+>>4    belong  >2              1.86
+>>4    belong  <3              1.85
+>>4    belong  >0              (Hash, version %d, native byte-order)
+>8     belong  1234
+>>4    belong  >2              1.86
+>>4    belong  <3              1.85
+>>4    belong  >0              (Hash, version %d, little-endian)
+
+0      belong  0x00061561      Berkeley DB
+>8     belong  4321
+>>4    belong  >2              1.86
+>>4    belong  <3              1.85
+>>4    belong  >0              (Hash, version %d, big-endian)
+>8     belong  1234
+>>4    belong  >2              1.86
+>>4    belong  <3              1.85
+>>4    belong  >0              (Hash, version %d, native byte-order)
+
+0      long    0x00053162      Berkeley DB 1.85/1.86
+>4     long    >0              (Btree, version %d, native byte-order)
+0      belong  0x00053162      Berkeley DB 1.85/1.86
+>4     belong  >0              (Btree, version %d, big-endian)
+0      lelong  0x00053162      Berkeley DB 1.85/1.86
+>4     lelong  >0              (Btree, version %d, little-endian)
+
+12     long    0x00061561      Berkeley DB
+>16    long    >0              (Hash, version %d, native byte-order)
+12     belong  0x00061561      Berkeley DB
+>16    belong  >0              (Hash, version %d, big-endian)
+12     lelong  0x00061561      Berkeley DB
+>16    lelong  >0              (Hash, version %d, little-endian)
+
+12     long    0x00053162      Berkeley DB
+>16    long    >0              (Btree, version %d, native byte-order)
+12     belong  0x00053162      Berkeley DB
+>16    belong  >0              (Btree, version %d, big-endian)
+12     lelong  0x00053162      Berkeley DB
+>16    lelong  >0              (Btree, version %d, little-endian)
+
+12     long    0x00042253      Berkeley DB
+>16    long    >0              (Queue, version %d, native byte-order)
+12     belong  0x00042253      Berkeley DB
+>16    belong  >0              (Queue, version %d, big-endian)
+12     lelong  0x00042253      Berkeley DB
+>16    lelong  >0              (Queue, version %d, little-endian)
+
+# From Max Bowsher.
+12     long    0x00040988      Berkeley DB
+>16    long    >0              (Log, version %d, native byte-order)
+12     belong  0x00040988      Berkeley DB
+>16    belong  >0              (Log, version %d, big-endian)
+12     lelong  0x00040988      Berkeley DB
+>16    lelong  >0              (Log, version %d, little-endian)
+
+#
+#
+# Round Robin Database Tool by Tobias Oetiker <oetiker@ee.ethz.ch>
+0      string/b        RRD\0           RRDTool DB
+>4     string/b        x               version %s
+
+>>10   short           !0              16bit aligned
+>>>10  bedouble        8.642135e+130   big-endian
+>>>>18 short           x               32bit long (m68k)
+
+>>10   short           0
+>>>12  long            !0              32bit aligned
+>>>>12 bedouble        8.642135e+130   big-endian
+>>>>>20 long           0               64bit long
+>>>>>20 long           !0              32bit long
+>>>>12 ledouble        8.642135e+130   little-endian
+>>>>>24 long           0               64bit long
+>>>>>24 long           !0              32bit long (i386)
+>>>>12 string          \x43\x2b\x1f\x5b\x2f\x25\xc0\xc7        middle-endian
+>>>>>24 short          !0              32bit long (arm)
+
+>>8    quad            0               64bit aligned
+>>>16  bedouble        8.642135e+130   big-endian
+>>>>24 long            0               64bit long (s390x)
+>>>>24 long            !0              32bit long (hppa/mips/ppc/s390/SPARC)
+>>>16  ledouble        8.642135e+130   little-endian
+>>>>28 long            0               64bit long (alpha/amd64/ia64)
+>>>>28 long            !0              32bit long (armel/mipsel)
+
+#----------------------------------------------------------------------
+# ROOT: file(1) magic for ROOT databases
+#
+0       string  root\0  ROOT file
+>4      belong  x       Version %d
+>33     belong  x       (Compression: %d)
+
+# XXX: Weak magic.
+# Alex Ott <ott@jet.msk.su>
+## Paradox file formats
+#2       leshort       0x0800  Paradox
+#>0x39   byte          3       v. 3.0
+#>0x39   byte          4       v. 3.5
+#>0x39   byte          9       v. 4.x
+#>0x39   byte          10      v. 5.x
+#>0x39   byte          11      v. 5.x
+#>0x39   byte          12      v. 7.x
+#>>0x04          byte          0       indexed .DB data file
+#>>0x04          byte          1       primary index .PX file
+#>>0x04          byte          2       non-indexed .DB data file
+#>>0x04          byte          3       non-incrementing secondary index .Xnn file
+#>>0x04          byte          4       secondary index .Ynn file
+#>>0x04          byte          5       incrementing secondary index .Xnn file
+#>>0x04          byte          6       non-incrementing secondary index .XGn file
+#>>0x04          byte          7       secondary index .YGn file
+#>>>0x04         byte          8       incrementing secondary index .XGn file
+
+## XBase database files
+# updated by Joerg Jenderek at Feb 2013
+# https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm
+# https://www.clicketyclick.dk/databases/xbase/format/dbf.html
+# http://home.f1.htw-berlin.de/scheibl/db/intern/dBase.htm
+# inspect VVYYMMDD , where 1<= MM <= 12 and 1<= DD <= 31
+0      ubelong&0x0000FFFF              <0x00000C20
+# skip Infocom game Z-machine
+>2             ubyte                   >0
+# skip Androids *.xml
+>>3            ubyte                   >0
+>>>3           ubyte                   <32
+# 1 < version VV
+>>>>0          ubyte                   >1
+# skip HELP.CA3 by test for reserved byte ( NULL )
+>>>>>27                ubyte                   0
+# reserved bytes not always 0 ; also found 0x3901 (T4.DBF) ,0x7101 (T5.DBF,T6.DBF)
+#>>>>>30               ubeshort                x               30NULL?%x
+# possible production flag,tag numbers(<=0x30),tag length(<=0x20), reserved (NULL)
+>>>>>>24       ubelong&0xffFFFFff      >0x01302000
+# .DBF or .MDX
+>>>>>>24       ubelong&0xffFFFFff      <0x01302001
+# for Xbase Database file (*.DBF) reserved (NULL) for multi-user
+>>>>>>>24      ubelong&0xffFFFFff      =0
+# test for 2 reserved NULL bytes,transaction and encryption byte flag
+>>>>>>>>12     ubelong&0xFFFFfEfE      0
+# test for MDX flag
+>>>>>>>>>28    ubyte                   x
+>>>>>>>>>28    ubyte&0xf8              0
+# header size >= 32
+>>>>>>>>>>8    uleshort                >31
+# skip PIC15736.PCX by test for language driver name or field name
+>>>>>>>>>>>32  ubyte                   >0
+#!:mime        application/x-dbf; charset=unknown-8bit ??
+#!:mime        application/x-dbase
+>>>>>>>>>>>>0  use                     xbase-type
+# database file
+>>>>>>>>>>>>0  ubyte                   x               \b DBF
+>>>>>>>>>>>>4  lelong                  0               \b, no records
+>>>>>>>>>>>>4  lelong                  >0              \b, %d record
+# plural s appended
+>>>>>>>>>>>>>4 lelong                  >1              \bs
+# https://www.clicketyclick.dk/databases/xbase/format/dbf_check.html#CHECK_DBF
+# 1 <= record size <= 4000 (dBase 3,4) or 32 * KB (=0x8000)
+>>>>>>>>>>>>10 uleshort                x               * %d
+# file size = records * record size + header size
+>>>>>>>>>>>>1  ubyte                   x               \b, update-date
+>>>>>>>>>>>>1  use                     xbase-date
+# https://msdn.microsoft.com/de-de/library/cc483186(v=vs.71).aspx
+#>>>>>>>>>>>>29        ubyte                   =0              \b, codepage ID=0x%x
+# 2~cp850 , 3~cp1252 , 0x1b~?? ; what code page is 0x1b ?
+>>>>>>>>>>>>29 ubyte                   >0              \b, codepage ID=0x%x
+#>>>>>>>>>>>>28        ubyte&0x01              0               \b, no index file
+>>>>>>>>>>>>28 ubyte&0x01              1               \b, with index file .MDX
+>>>>>>>>>>>>28 ubyte&0x02              2               \b, with memo .FPT
+>>>>>>>>>>>>28 ubyte&0x04              4               \b, DataBaseContainer
+# 1st record offset + 1 = header size
+>>>>>>>>>>>>8  uleshort                >0
+>>>>>>>>>>>>(8.s+1)    ubyte           >0
+>>>>>>>>>>>>>8         uleshort        >0              \b, at offset %d
+>>>>>>>>>>>>>(8.s+1)   ubyte           >0
+>>>>>>>>>>>>>>&-1      string          >\0             1st record "%s"
+# for multiple index files (*.MDX) Production flag,tag numbers(<=0x30),tag length(<=0x20), reserved (NULL)
+>>>>>>>24      ubelong&0x0133f7ff      >0
+# test for reserved NULL byte
+>>>>>>>>47     ubyte                   0
+# test for valid TAG key format (0x10 or 0)
+>>>>>>>>>559   ubyte&0xeF              0
+# test MM <= 12
+>>>>>>>>>>45   ubeshort                <0x0C20
+>>>>>>>>>>>45  ubyte                   >0
+>>>>>>>>>>>>46 ubyte                   <32
+>>>>>>>>>>>>>46        ubyte                   >0
+#!:mime        application/x-mdx
+>>>>>>>>>>>>>>0                use             xbase-type
+>>>>>>>>>>>>>>0                ubyte           x               \b MDX
+>>>>>>>>>>>>>>1                ubyte           x               \b, creation-date
+>>>>>>>>>>>>>>1                use             xbase-date
+>>>>>>>>>>>>>>44       ubyte           x               \b, update-date
+>>>>>>>>>>>>>>44       use             xbase-date
+# No.of tags in use (1,2,5,12)
+>>>>>>>>>>>>>>28       uleshort        x               \b, %d
+# No. of entries in tag (0x30)
+>>>>>>>>>>>>>>25       ubyte           x               \b/%d tags
+#  Length of tag
+>>>>>>>>>>>>>>26       ubyte           x               * %d
+# 1st tag name_
+>>>>>>>>>>>>>548       string          x               \b, 1st tag "%.11s"
+# 2nd tag name
+#>>>>>>>>>>>>(26.b+548)        string          x               \b, 2nd tag "%.11s"
+#
+#              Print the xBase names of different version variants
+0      name                            xbase-type
+>0     ubyte           <2
+# 1 < version
+>0     ubyte           >1
+>>0    ubyte           0x02            FoxBase
+# FoxBase+/dBaseIII+, no memo
+>>0    ubyte           0x03            FoxBase+/dBase III
+!:mime application/x-dbf
+# dBASE IV no memo file
+>>0    ubyte           0x04            dBase IV
+!:mime application/x-dbf
+# dBASE V no memo file
+>>0    ubyte           0x05            dBase V
+!:mime application/x-dbf
+>>0    ubyte           0x30            Visual FoxPro
+!:mime application/x-dbf
+>>0    ubyte           0x31            Visual FoxPro, autoincrement
+!:mime application/x-dbf
+# Visual FoxPro, with field type Varchar or Varbinary
+>>0    ubyte           0x32            Visual FoxPro, with field type Varchar
+!:mime application/x-dbf
+# dBASE IV SQL, no memo;dbv memo var size (Flagship)
+>>0    ubyte           0x43            dBase IV, with SQL table
+!:mime application/x-dbf
+# https://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx
+#>>0   ubyte           0x62            dBase IV, with SQL table
+#!:mime        application/x-dbf
+# dBASE IV, with memo!!
+>>0    ubyte           0x7b            dBase IV, with memo
+!:mime application/x-dbf
+# https://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx
+#>>0   ubyte           0x82            dBase IV, with SQL system
+#!:mime        application/x-dbf
+# FoxBase+/dBaseIII+ with memo .DBT!
+>>0    ubyte           0x83            FoxBase+/dBase III, with memo .DBT
+!:mime application/x-dbf
+# VISUAL OBJECTS (first 1.0 versions) for the Dbase III files (NTX clipper driver); memo file
+>>0    ubyte           0x87            VISUAL OBJECTS, with memo file
+!:mime application/x-dbf
+# https://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx
+#>>0   ubyte           0x8A            FoxBase+/dBase III, with memo .DBT
+#!:mime        application/x-dbf
+# dBASE IV with memo!
+>>0    ubyte           0x8B            dBase IV, with memo .DBT
+!:mime application/x-dbf
+# dBase IV with SQL Table,no memo?
+>>0    ubyte           0x8E            dBase IV, with SQL table
+!:mime application/x-dbf
+# .dbv and .dbt memo (Flagship)?
+>>0    ubyte           0xB3            Flagship
+# https://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx
+#>>0   ubyte           0xCA            dBase IV with memo .DBT
+#!:mime        application/x-dbf
+# dBASE IV with SQL table, with memo .DBT
+>>0    ubyte           0xCB            dBase IV with SQL table, with memo .DBT
+!:mime application/x-dbf
+# HiPer-Six format;Clipper SIX, with SMT memo file
+>>0    ubyte           0xE5            Clipper SIX with memo
+!:mime application/x-dbf
+# https://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx
+#>>0   ubyte           0xF4            dBase IV, with SQL table, with memo
+#!:mime        application/x-dbf
+>>0    ubyte           0xF5            FoxPro with memo
+!:mime application/x-dbf
+# https://msdn.microsoft.com/en-US/library/st4a0s68(v=vs.80).aspx
+#>>0   ubyte           0xFA            FoxPro 2.x, with memo
+#!:mime        application/x-dbf
+# unknown version (should not happen)
+>>0    default         x               xBase
+!:mime application/x-dbf
+>>>0   ubyte           x               (0x%x)
+# flags in version byte
+# DBT flag (with dBASE III memo .DBT)!!
+# >>0  ubyte&0x80      >0              DBT_FLAG=%x
+# memo flag ??
+# >>0  ubyte&0x08      >0              MEMO_FLAG=%x
+# SQL flag ??
+# >>0  ubyte&0x70      >0              SQL_FLAG=%x
+#              test and print the date of xBase .DBF .MDX
+0      name                            xbase-date
+# inspect YYMMDD , where 1<= MM <= 12 and 1<= DD <= 31
+>0     ubelong         x
+>1     ubyte           <13
+>>1    ubyte           >0
+>>>2   ubyte           >0
+>>>>2  ubyte           <32
+>>>>>0 ubyte           x
+# YY is interpreted as 20YY or 19YY
+>>>>>>0        ubyte           <100            \b %.2d
+# YY is interpreted 1900+YY; TODO: display yy or 20yy instead 1YY
+>>>>>>0        ubyte           >99             \b %d
+>>>>>1 ubyte           x               \b-%d
+>>>>>2 ubyte           x               \b-%d
+
+#      dBase memo files .DBT or .FPT
+# https://msdn.microsoft.com/en-us/library/8599s21w(v=vs.80).aspx
+16             ubyte           <4
+>16            ubyte           !2
+>>16           ubyte           !1
+# next free block index is positive
+>>>0           ulelong         >0
+# skip many JPG. ZIP, BZ2 by test for reserved bytes NULL , 0|2 , 0|1 , low byte of block size
+>>>>17         ubelong&0xFFfdFE00      0x00000000
+# skip many RAR by test for low byte 0 ,high byte 0|2|even of block size, 0|a|e|d7 , 0|64h
+>>>>>20                ubelong&0xFF01209B      0x00000000
+# dBASE III
+>>>>>>16       ubyte           3
+# dBASE III DBT
+>>>>>>>0       use             dbase3-memo-print
+# dBASE III DBT without version, dBASE IV DBT , FoxPro FPT , or many ZIP , DBF garbage
+>>>>>>16       ubyte           0
+# unusual dBASE III DBT like angest.dbt, dBASE IV DBT with block size 0 , FoxPro FPT ,  or garbage PCX DBF
+>>>>>>>20      uleshort        0
+# FoxPro FPT , unusual dBASE III DBT like biblio.dbt or garbage
+>>>>>>>>8      ulong           =0
+>>>>>>>>>6     ubeshort        >0
+# skip emacs.PIF
+>>>>>>>>>>4    ushort          0
+>>>>>>>>>>>0   use             foxpro-memo-print
+# dBASE III DBT , garbage
+>>>>>>>>>6     ubeshort        0
+# skip MM*DD*.bin by test for for reserved NULL byte
+>>>>>>>>>>510  ubeshort        0
+# skip TK-DOS11.img image by looking for memo text
+>>>>>>>>>>>512 ubelong         <0xfeffff03
+# skip EFI executables by looking for memo text
+>>>>>>>>>>>>512        ubelong         >0x1F202020
+>>>>>>>>>>>>>513 ubyte         >0
+# unusual dBASE III DBT like adressen.dbt
+>>>>>>>>>>>>>>0        use             dbase3-memo-print
+# dBASE III DBT like angest.dbt, or garbage PCX DBF
+>>>>>>>>8      ubelong         !0
+# skip PCX and some DBF by test for for reserved NULL bytes
+>>>>>>>>>510   ubeshort        0
+# skip some DBF by test of invalid version
+>>>>>>>>>>0    ubyte           >5
+>>>>>>>>>>>0   ubyte           <48
+>>>>>>>>>>>>0  use             dbase3-memo-print
+# dBASE IV DBT with positive block size
+>>>>>>>20      uleshort        >0
+# dBASE IV DBT with valid block length like 512, 1024
+# multiple of 2 in between 16 and 16 K ,implies upper and lower bits are zero
+>>>>>>>>20     uleshort&0x800f 0
+>>>>>>>>>0     use             dbase4-memo-print
+
+#              Print the information of dBase III DBT memo file
+0      name                            dbase3-memo-print
+>0     ubyte                   x               dBase III DBT
+# instead 3 as version number 0 for unusual examples like biblio.dbt
+>16    ubyte                   !3              \b, version number %u
+# Number of next available block for appending data
+#>0    lelong                  =0              \b, next free block index %u
+>0     lelong                  !0              \b, next free block index %u
+# no positiv block length
+#>20   uleshort                =0              \b, block length %u
+>20    uleshort                !0              \b, block length %u
+# dBase III memo field terminated by \032\032
+>512   string                  >\0             \b, 1st item "%s"
+#              Print the information of dBase IV DBT memo file
+0      name                            dbase4-memo-print
+>0             lelong          x               dBase IV DBT
+!:mime application/x-dbt
+!:ext dbt
+# 8 character shorted main name of coresponding dBASE IV DBF file
+>8             ubelong         >0x20000000
+# skip unusual like for angest.dbt
+>>20           uleshort        >0
+>>>8           string          >\0             \b of %-.8s.DBF
+# value 0 implies 512 as size
+#>4            ulelong         =0              \b, blocks size %u
+# size of blocks not reliable like 0x2020204C in angest.dbt
+>4             ulelong         !0
+>>4            ulelong&0x0000003f      0       \b, blocks size %u
+# dBase IV DBT with positive block length (found 512 , 1024)
+>20            uleshort        >0              \b, block length %u
+# next available block
+#>0            lelong          =0              \b, next free block index %u
+>0             lelong          !0              \b, next free block index %u
+>20            uleshort        >0
+>>(20.s)       ubelong         x
+>>>&-4         use             dbase4-memofield-print
+# unusual dBase IV DBT without block length (implies 512 as length)
+>20            uleshort        =0
+>>512          ubelong         x
+>>>&-4         use                             dbase4-memofield-print
+#              Print the information of dBase IV memo field
+0      name                    dbase4-memofield-print
+# free dBase IV memo field
+>0             ubelong         !0xFFFF0800
+>>0            lelong          x               \b, next free block %u
+>>4            lelong          x               \b, next used block %u
+# used dBase IV memo field
+>0             ubelong         =0xFFFF0800
+# length of memo field
+>>4            lelong          x               \b, field length %d
+>>>8           string          >\0             \b, 1st used item "%s"
+#              Print the information of FoxPro FPT memo file
+0      name                            foxpro-memo-print
+>0             belong          x               FoxPro FPT
+# Size of blocks for FoxPro ( 64,256 )
+>6             ubeshort        x               \b, blocks size %u
+# next available block
+#>0            belong          =0              \b, next free block index %u
+>0             belong          !0              \b, next free block index %u
+# field type ( 0~picture, 1~memo, 2~object )
+>512           ubelong         <3              \b, field type %u
+# length of memo field
+>512           ubelong         1
+>>516          belong          >0              \b, field length %d
+>>>520         string          >\0             \b, 1st item "%s"
+
+# TODO:
+# DBASE index file *.NDX
+# DBASE Compound Index file *.CDX
+# dBASE IV Printer Driver *.PRF
+## End of XBase database stuff
+
+# MS Access database
+4      string  Standard\ Jet\ DB       Microsoft Access Database
+!:mime application/x-msaccess
+4      string  Standard\ ACE\ DB       Microsoft Access Database
+!:mime application/x-msaccess
+
+# From: Joerg Jenderek
+# URL: http://fileformats.archiveteam.org/wiki/Extensible_Storage_Engine
+# Reference: https://github.com/libyal/libesedb/archive/master.zip
+#      libesedb-master/documentation/
+#      Extensible Storage Engine (ESE) Database File (EDB) format.asciidoc
+# Note: also known as "JET Blue". Used by numerous Windows components such as
+# Windows Search, Mail, Exchange and Active Directory.
+4      ubelong         0xefcdab89
+# unknown1
+>132   ubelong         0               Extensible storage engine
+!:mime application/x-ms-ese
+# file_type 0~database 1~stream
+>>12   ulelong         0               DataBase
+# Security DataBase (sdb)
+!:ext  edb/sdb
+>>12   ulelong         1               STreaMing
+!:ext  stm
+# format_version 620h
+>>8    uleshort        x               \b, version 0x%x
+>>10   uleshort        >0              revision 0x%4.4x
+>>0    ubelong         x               \b, checksum 0x%8.8x
+# Page size 4096 8192 32768
+>>236  ulequad         x               \b, page size %lld
+# database_state
+>>52   ulelong         1               \b, JustCreated
+>>52   ulelong         2               \b, DirtyShutdown
+#>>52  ulelong         3               \b, CleanShutdown
+>>52   ulelong         4               \b, BeingConverted
+>>52   ulelong         5               \b, ForceDetach
+# Windows NT major version when the databases indexes were updated.
+>>216  ulelong         x               \b, Windows version %d
+# Windows NT minor version
+>>220  ulelong         x               \b.%d
+
+# From: Joerg Jenderek
+# URL: https://forensicswiki.org/wiki/Windows_Application_Compatibility
+# Note: files contain application compatibility fixes, application compatibility modes and application help messages.
+8      string          sdbf
+>7     ubyte           0
+# TAG_TYPE_LIST+TAG_INDEXES
+>>12   uleshort        0x7802          Windows application compatibility Shim DataBase
+# version? 2 3
+#>>>0  ulelong         x               \b, version %d
+!:mime application/x-ms-sdb
+!:ext  sdb
+
+# TDB database from Samba et al - Martin Pool <mbp@samba.org>
+0      string  TDB\ file               TDB database
+>32    lelong  0x2601196D              version 6, little-endian
+>>36   lelong  x                       hash size %d bytes
+
+# SE Linux policy database
+0       lelong  0xf97cff8c      SE Linux policy
+>16     lelong  x               v%d
+>20     lelong  1      MLS
+>24     lelong  x       %d symbols
+>28     lelong  x       %d ocons
+
+# ICE authority file data (Wolfram Kleff)
+2      string          ICE             ICE authority data
+
+# X11 Xauthority file (Wolfram Kleff)
+10     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+11     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+12     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+13     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+14     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+15     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+16     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+17     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+18     string          MIT-MAGIC-COOKIE-1      X11 Xauthority data
+
+# From: Maxime Henrion <mux@FreeBSD.org>
+# PostgreSQL's custom dump format, Maxime Henrion <mux@FreeBSD.org>
+0      string          PGDMP           PostgreSQL custom database dump
+>5     byte            x               - v%d
+>6     byte            x               \b.%d
+>5     beshort         <0x101          \b-0
+>5     beshort         >0x100
+>>7    byte            x               \b-%d
+
+# Type: Advanced Data Format (ADF) database
+# URL:  https://www.grc.nasa.gov/WWW/cgns/adf/
+# From: Nicolas Chauvat <nicolas.chauvat@logilab.fr>
+0      string  @(#)ADF\ Database       CGNS Advanced Data Format
+
+# Tokyo Cabinet magic data
+# http://tokyocabinet.sourceforge.net/index.html
+0      string          ToKyO\ CaBiNeT\n        Tokyo Cabinet
+>14    string          x                       \b (%s)
+>32    byte            0                       \b, Hash
+!:mime application/x-tokyocabinet-hash
+>32    byte            1                       \b, B+ tree
+!:mime application/x-tokyocabinet-btree
+>32    byte            2                       \b, Fixed-length
+!:mime application/x-tokyocabinet-fixed
+>32    byte            3                       \b, Table
+!:mime application/x-tokyocabinet-table
+>33    byte            &1                      \b, [open]
+>33    byte            &2                      \b, [fatal]
+>34    byte            x                       \b, apow=%d
+>35    byte            x                       \b, fpow=%d
+>36    byte            &0x01                   \b, [large]
+>36    byte            &0x02                   \b, [deflate]
+>36    byte            &0x04                   \b, [bzip]
+>36    byte            &0x08                   \b, [tcbs]
+>36    byte            &0x10                   \b, [excodec]
+>40    lequad          x                       \b, bnum=%lld
+>48    lequad          x                       \b, rnum=%lld
+>56    lequad          x                       \b, fsiz=%lld
+
+# Type:        QDBM Quick Database Manager
+# From:        Benoit Sibaud <bsibaud@april.org>
+0      string          \\[depot\\]\n\f         Quick Database Manager, little endian
+0      string          \\[DEPOT\\]\n\f         Quick Database Manager, big endian
+
+# Type:        TokyoCabinet database
+# URL: http://tokyocabinet.sourceforge.net/
+# From:        Benoit Sibaud <bsibaud@april.org>
+0      string          ToKyO\ CaBiNeT\n        TokyoCabinet database
+>14    string          x                       (version %s)
+
+# From:  Stephane Blondon https://www.yaal.fr
+# Database file for Zope (done by FileStorage)
+0      string  FS21    Zope Object Database File Storage v3 (data)
+0      string  FS30    Zope Object Database File Storage v4 (data)
+
+# Cache file for the database of Zope (done by ClientStorage)
+0      string          ZEC3    Zope Object Database Client Cache File (data)
+
+# IDA (Interactive Disassembler) database
+0      string          IDA1    IDA (Interactive Disassembler) database
+
+# Hopper (reverse engineering tool) https://www.hopperapp.com/
+0      string          hopperdb        Hopper database
+
+# URL: https://en.wikipedia.org/wiki/Panorama_(database_engine)
+# Reference: http://www.provue.com/Panorama/
+# From: Joerg Jenderek
+# NOTE: test only versions 4 and 6.0 with Windows
+# length of Panorama database name
+5      ubyte                           >0
+# look after database name for "some" null bits
+>(5.B+7)       ubelong&0xF3ffF000      0
+# look for first keyword
+>>&1           search/2                DESIGN          Panorama database
+#!:mime        application/x-panorama-database
+!:apple        KASXZEPD
+!:ext  pan
+# database name
+>>>5   pstring                         x               \b, "%s"
+
+#
+#
+# askSam Database by Stefan A. Haubenthal <polluks@web.de>
+0      string  askw40\0        askSam DB
+
+#
+#
+# MUIbase Database Tool by Stefan A. Haubenthal <polluks@web.de>
+0      string  MBSTV\040       MUIbase DB
+>6     string  x               version %s
+
+#
+# CDB database
+0      string  NBCDB\012       NetBSD Constant Database
+>7     byte    x               \b, version %d
+>8     string  x               \b, for '%s'
+>24    lelong  x               \b, datasize %d
+>28    lelong  x               \b, entries %d
+>32    lelong  x               \b, index %d
+>36    lelong  x               \b, seed %#x
+
+#
+# Redis RDB - https://redis.io/topics/persistence
+0      string  REDIS                   Redis RDB file,
+>5     regex   [0-9][0-9][0-9][0-9]    version %s
+
+# Mork database.
+# Used by older versions of Mozilla Suite and Firefox,
+# and current versions of Thunderbird.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+0      string  //\ <!--\ <mdb:mork:z\ v="      Mozilla Mork database
+>23    string  x               \b, version %.3s
diff --git a/magic/Magdir/dataone b/magic/Magdir/dataone
new file mode 100644 (file)
index 0000000..8ef3f79
--- /dev/null
@@ -0,0 +1,47 @@
+
+#------------------------------------------------------------------------------
+# $File: dataone,v 1.2 2019/04/19 00:42:27 christos Exp $
+#
+# DataONE- files from Dave Vieglais <dave.vieglais@gmail.com> &
+#                     Pratik Shrivastava <pratikshrivastava23@gmail.com>
+#
+# file formats:   https://cn.dataone.org/cn/v2/formats
+#------------------------------------------------------------------------------
+
+# EML (Ecological Metadata Language Format)
+0      string  <?xml
+>&0    regex   (eml)-[0-9].[0-9].[0-9]+        eml://ecoinformatics.org/%s
+
+# onedcx (DataONE Dublin Core Extended v1.0)
+>&0    regex   (onedcx/v)[0-9].[0-9]+          https://ns.dataone.org/metadata/schema/onedcx/v1.0
+
+# FGDC-STD-001-1998 (Content Standard for Digital Geospatial Metadata,
+# version 001-1998)
+>&0    regex   fgdc                            FGDC-STD-001-1998
+
+# Mercury (Oak Ridge National Lab Mercury Metadata version 1.0)
+>&0    regex   (mercury/terms/v)[0-9].[0-9]    https://purl.org/ornl/schema/mercury/terms/v1.0
+
+# ISOTC211 (Geographic MetaData (GMD) Extensible Markup Language)
+>&0    regex   isotc211
+>>&0   regex   eng;USA                         https://www.isotc211.org/2005/gmd
+
+# ISOTC211 (NOAA Variant Geographic MetaData (GMD) Extensible Markup Language)
+>>&0   regex   gov.noaa.nodc:[0-9]+            https://www.isotc211.org/2005/gmd-noaa
+
+# ISOTC211 PANGAEA Variant Geographic MetaData (GMD) Extensible Markup Language
+>>&0   regex   pangaea.dataset[0-9][0-9][0-9][0-9][0-9][0-9]+  https://www.isotc211.org/2005/gmd-pangaea
+!:mime text/xml
+
+
+# Object Reuse and Exchange Vocabulary
+0      string  <?xml
+>&0    regex   rdf
+>>&0   regex   openarchives    https://www.openarchives.org/ore/terms
+!:mime application/rdf+xml
+
+
+# Dryad Metadata Application Profile Version 3.1
+0      string  <DryadData
+>&0    regex   (dryad-bibo/v)[0-9].[0-9]       https://datadryad.org/profile/v3.1
+!:mime text/xml
diff --git a/magic/Magdir/dbpf b/magic/Magdir/dbpf
new file mode 100644 (file)
index 0000000..df07ff8
--- /dev/null
@@ -0,0 +1,15 @@
+
+#------------------------------------------------------------------------------
+# $File: dbpf,v 1.3 2019/04/19 00:42:27 christos Exp $
+# dppf:        Maxis Database Packed Files, the stored data file format used by all
+#      Maxis games after the Sims: http://wiki.niotso.org/DBPF
+#      https://www.wiki.sc4devotion.com/index.php?title=DBPF
+#      13 Oct 2017, Kip Warner <kip at thevertigo dot com>
+0      string  DBPF    Maxis Database Packed File
+>4     ulelong x       \b, version: %u.
+>>8    ulelong x       \b%u
+>>>36  ulelong x       \b, files: %u
+>>24   ledate  !0      \b, created: %s
+>>28   ledate  !0      \b, modified: %s
+!:ext  dbpf/package/dat/sc4
+!:mime application/x-maxis-dbpf
diff --git a/magic/Magdir/der b/magic/Magdir/der
new file mode 100644 (file)
index 0000000..9c25f00
--- /dev/null
@@ -0,0 +1,116 @@
+#------------------------------------------------------------------------------
+# $File: der,v 1.2 2017/03/17 21:35:28 christos Exp $
+# der: file(1) magic for DER encoded files
+#
+
+# Certificate information piece
+0      name    certinfo
+>0     der     seq
+>>&0   der     set
+>>>&0  der     seq
+>>>>&0 der     obj_id3=550406
+>>>>&0 der     prt_str=x       \b, countryName=%s
+>>&0   der     set
+>>>&0  der     seq
+>>>>&0 der     obj_id3=550408
+>>>>&0 der     utf8_str=x      \b, stateOrProvinceName=%s
+>>&0   der     set
+>>>&0  der     seq
+>>>>&0 der     obj_id3=55040a
+>>>>&0 der     utf8_str=x      \b, organizationName=%s
+>>&0   der     set
+>>>&0  der     seq
+>>>>&0 der     obj_id3=550403
+>>>>&0 der     utf8_str=x      \b, commonName=%s
+>>&0   der     seq
+
+# Certificate requests
+0      der     seq
+>&0    der     seq
+>>&0   der     int1=00         DER Encoded Certificate request
+>>&0   use     certinfo
+
+# Key Pairs
+0      der     seq
+>&0    der     int1=00
+>&0    der     int65=x
+>&0    der     int3=010001     DER Encoded Key Pair, 512 bits
+
+0      der     seq
+>&0    der     int1=00
+>&0    der     int129=x
+>&0    der     int3=010001     DER Encoded Key Pair, 1024 bits
+
+0      der     seq
+>&0    der     int1=00
+>&0    der     int257=x
+>&0    der     int3=010001     DER Encoded Key Pair, 2048 bits
+
+0      der     seq
+>&0    der     int1=00
+>&0    der     int513=x
+>&0    der     int3=010001     DER Encoded Key Pair, 4096 bits
+
+0      der     seq
+>&0    der     int1=00
+>&0    der     int1025=x
+>&0    der     int3=010001     DER Encoded Key Pair, 8192 bits
+
+0      der     seq
+>&0    der     int1=00
+>&0    der     int2049=x
+>&0    der     int3=010001     DER Encoded Key Pair, 16k bits
+
+0      der     seq
+>&0    der     int1=00
+>&0    der     int4097=x
+>&0    der     int3=010001     DER Encoded Key Pair, 32k bits
+
+# Certificates
+0      der     seq
+>&0    der     seq
+>>&0   der     int2=0dfa       DER Encoded Certificate, 512 bits
+>>&0   der     int2=0dfb       DER Encoded Certificate, 1024 bits
+>>&0   der     int2=0dfc       DER Encoded Certificate, 2048 bits
+>>&0   der     int2=0dfd       DER Encoded Certificate, 4096 bits
+>>&0   der     int2=0dfe       DER Encoded Certificate, 8192 bits
+>>&0   der     int2=0dff       DER Encoded Certificate, 16k bits
+>>&0   der     int2=0e04       DER Encoded Certificate, 32k bits
+>>&0   der     int2=x          DER Encoded Certificate, ? bits (%s)
+>>&0   der     seq
+>>>&0  der     obj_id9=2a864886f70d010105      \b, sha1WithRSAEncryption
+>>>&0  der     obj_id9=x                       \b, ? Encryption (%s)
+>>>&0  der     null
+>>&0   der     seq
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id3=550406
+>>>>>&0        der     prt_str=x       \b, countryName=%s
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id3=550408
+>>>>>&0        der     prt_str=x       \b, stateOrProvinceName=%s
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id3=550407
+>>>>>&0        der     prt_str=x       \b, localityName=%s
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id3=55040a
+>>>>>&0        der     prt_str=x       \b, organizationName=%s
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id3=55040b
+>>>>>&0        der     prt_str=x       \b, organizationUnitName=%s
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id3=550403
+>>>>>&0        der     prt_str=x       \b, commonName=%s
+>>>&0  der     set
+>>>>&0 der     seq
+>>>>>&0        der     obj_id9=2a864886f70d010901
+>>>>>&0        der     ia5_str=x       \b, emailAddress=%s
+>>&0   der     seq
+>>>&0  der     utc_time=x      \b, utcTime=%s
+>>>&0  der     utc_time=x      \b, utcTime=%s
+>>&0   use     certinfo
diff --git a/magic/Magdir/diamond b/magic/Magdir/diamond
new file mode 100644 (file)
index 0000000..30bb9c7
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# diamond:  file(1) magic for Diamond system
+#
+# ... diamond is a multi-media mail and electronic conferencing system....
+#
+# XXX - I think it was either renamed Slate, or replaced by Slate....
+#
+#      The full deal is too long...
+#0     string  <list>\n<protocol\ bbn-multimedia-format>       Diamond Multimedia Document
+0      string  =<list>\n<protocol\ bbn-m       Diamond Multimedia Document
diff --git a/magic/Magdir/diff b/magic/Magdir/diff
new file mode 100644 (file)
index 0000000..cd530d3
--- /dev/null
@@ -0,0 +1,40 @@
+
+#------------------------------------------------------------------------------
+# $File: diff,v 1.16 2017/03/17 22:20:22 christos Exp $
+# diff:  file(1) magic for diff(1) output
+#
+0      search/1        diff\040        diff output text
+!:mime text/x-diff
+0      search/1        ***\040         diff output text
+!:mime text/x-diff
+0      search/1        Only\040in\040  diff output text
+!:mime text/x-diff
+0      search/1        Common\040subdirectories:\040   diff output text
+!:mime text/x-diff
+
+0      search/1        Index:          RCS/CVS diff output text
+!:mime text/x-diff
+
+# bsdiff:  file(1) magic for bsdiff(1) output
+0      string/b                BSDIFF40        bsdiff(1) patch file
+
+
+# unified diff
+0      search/4096     ---\040
+>&0    search/1024 \n
+>>&0   search/1 +++\040
+>>>&0  search/1024 \n
+>>>>&0 search/1 @@     unified diff output text
+!:mime text/x-diff
+!:strength + 90
+
+# librsync -- the library for network deltas
+#
+# Copyright (C) 2001 by Martin Pool.  You may do whatever you want with
+# this file.
+#
+0      belong          0x72730236      rdiff network-delta data
+
+0      belong          0x72730136      rdiff network-delta signature data
+>4     belong          x               (block length=%d,
+>8     belong          x               signature strength=%d)
diff --git a/magic/Magdir/digital b/magic/Magdir/digital
new file mode 100644 (file)
index 0000000..d4c85d0
--- /dev/null
@@ -0,0 +1,58 @@
+
+#------------------------------------------------------------------------------
+# $File: digital,v 1.10 2011/05/03 01:44:17 christos Exp $
+#  Digital UNIX - Info
+#
+0      string  =!<arch>\n________64E   Alpha archive
+>22    string  X                       -- out of date
+#
+
+0      leshort         0603
+>24    leshort         0410            COFF format alpha pure
+>24    leshort         0413            COFF format alpha demand paged
+>>22   leshort&030000  !020000         executable
+>>22   leshort&020000  !0              dynamically linked
+>>16   lelong          !0              not stripped
+>>16   lelong          0               stripped
+>>27   byte            x               - version %d
+>>26   byte            x               \b.%d
+>>28   byte            x               \b-%d
+>24    leshort         0407            COFF format alpha object
+>>22   leshort&030000  020000          shared library
+>>27   byte            x               - version %d
+>>26   byte            x               \b.%d
+>>28   byte            x               \b-%d
+
+# Basic recognition of Digital UNIX core dumps - Mike Bremford <mike@opac.bl.uk>
+#
+# The actual magic number is just "Core", followed by a 2-byte version
+# number; however, treating any file that begins with "Core" as a Digital
+# UNIX core dump file may produce too many false hits, so we include one
+# byte of the version number as well; DU 5.0 appears only to be up to
+# version 2.
+#
+0      string          Core\001        Alpha COFF format core dump (Digital UNIX)
+>24    string          >\0             \b, from '%s'
+0      string          Core\002        Alpha COFF format core dump (Digital UNIX)
+>24    string          >\0             \b, from '%s'
+#
+# The next is incomplete, we could tell more about this format,
+# but its not worth it.
+0      leshort         0x188   Alpha compressed COFF
+0      leshort         0x18f   Alpha u-code object
+#
+#
+# Some other interesting Digital formats,
+0      string  \377\377\177            ddis/ddif
+0      string  \377\377\174            ddis/dots archive
+0      string  \377\377\176            ddis/dtif table data
+0      string  \033c\033               LN03 output
+0      long    04553207                X image
+#
+0      string  =!<PDF>!\n              profiling data file
+#
+# Locale data tables (MIPS and Alpha).
+#
+0      short           0x0501          locale data table
+>6     short           0x24            for MIPS
+>6     short           0x40            for Alpha
diff --git a/magic/Magdir/dolby b/magic/Magdir/dolby
new file mode 100644 (file)
index 0000000..d73e7d3
--- /dev/null
@@ -0,0 +1,69 @@
+
+#------------------------------------------------------------------------------
+# $File: dolby,v 1.9 2019/04/19 00:42:27 christos Exp $
+# ATSC A/53 aka AC-3 aka Dolby Digital <ashitaka@gmx.at>
+# from https://www.atsc.org/standards/a_52a.pdf
+# corrections, additions, etc. are always welcome!
+#
+# syncword
+0      beshort         0x0b77  ATSC A/52 aka AC-3 aka Dolby Digital stream,
+# Proposed audio/ac3 RFC/4184
+!:mime audio/vnd.dolby.dd-raw
+# fscod
+>4     byte&0xc0 = 0x00        48 kHz,
+>4     byte&0xc0 = 0x40        44.1 kHz,
+>4     byte&0xc0 = 0x80        32 kHz,
+# is this one used for 96 kHz?
+>4     byte&0xc0 = 0xc0        reserved frequency,
+#
+>5     byte&0x07 = 0x00        \b, complete main (CM)
+>5     byte&0x07 = 0x01        \b, music and effects (ME)
+>5     byte&0x07 = 0x02        \b, visually impaired (VI)
+>5     byte&0x07 = 0x03        \b, hearing impaired (HI)
+>5     byte&0x07 = 0x04        \b, dialogue (D)
+>5     byte&0x07 = 0x05        \b, commentary (C)
+>5     byte&0x07 = 0x06        \b, emergency (E)
+>5     beshort&0x07e0  0x0720  \b, voiceover (VO)
+>5     beshort&0x07e0 >0x0720  \b, karaoke
+# acmod
+>6     byte&0xe0 = 0x00        1+1 front,
+>>6    byte&0x10 = 0x10        LFE on,
+>6     byte&0xe0 = 0x20        1 front/0 rear,
+>>6    byte&0x10 = 0x10        LFE on,
+>6     byte&0xe0 = 0x40        2 front/0 rear,
+# dsurmod (for stereo only)
+>>6    byte&0x18 = 0x00        Dolby Surround not indicated
+>>6    byte&0x18 = 0x08        not Dolby Surround encoded
+>>6    byte&0x18 = 0x10        Dolby Surround encoded
+>>6    byte&0x18 = 0x18        reserved Dolby Surround mode
+>>6    byte&0x04 = 0x04        LFE on,
+>6     byte&0xe0 = 0x60        3 front/0 rear,
+>>6    byte&0x04 = 0x04        LFE on,
+>6     byte&0xe0 = 0x80        2 front/1 rear,
+>>6    byte&0x04 = 0x04        LFE on,
+>6     byte&0xe0 = 0xa0        3 front/1 rear,
+>>6    byte&0x01 = 0x01        LFE on,
+>6     byte&0xe0 = 0xc0        2 front/2 rear,
+>>6    byte&0x04 = 0x04        LFE on,
+>6     byte&0xe0 = 0xe0        3 front/2 rear,
+>>6    byte&0x01 = 0x01        LFE on,
+#
+>4     byte&0x3e = 0x00        \b, 32 kbit/s
+>4     byte&0x3e = 0x02        \b, 40 kbit/s
+>4     byte&0x3e = 0x04        \b, 48 kbit/s
+>4     byte&0x3e = 0x06        \b, 56 kbit/s
+>4     byte&0x3e = 0x08        \b, 64 kbit/s
+>4     byte&0x3e = 0x0a        \b, 80 kbit/s
+>4     byte&0x3e = 0x0c        \b, 96 kbit/s
+>4     byte&0x3e = 0x0e        \b, 112 kbit/s
+>4     byte&0x3e = 0x10        \b, 128 kbit/s
+>4     byte&0x3e = 0x12        \b, 160 kbit/s
+>4     byte&0x3e = 0x14        \b, 192 kbit/s
+>4     byte&0x3e = 0x16        \b, 224 kbit/s
+>4     byte&0x3e = 0x18        \b, 256 kbit/s
+>4     byte&0x3e = 0x1a        \b, 320 kbit/s
+>4     byte&0x3e = 0x1c        \b, 384 kbit/s
+>4     byte&0x3e = 0x1e        \b, 448 kbit/s
+>4     byte&0x3e = 0x20        \b, 512 kbit/s
+>4     byte&0x3e = 0x22        \b, 576 kbit/s
+>4     byte&0x3e = 0x24        \b, 640 kbit/s
diff --git a/magic/Magdir/dump b/magic/Magdir/dump
new file mode 100644 (file)
index 0000000..cc5644d
--- /dev/null
@@ -0,0 +1,96 @@
+
+#------------------------------------------------------------------------------
+# $File: dump,v 1.17 2018/06/26 01:07:17 christos Exp $
+# dump:  file(1) magic for dump file format--for new and old dump filesystems
+#
+# We specify both byte orders in order to recognize byte-swapped dumps.
+#
+0      name    new-dump-be
+>4     bedate  x               This dump %s,
+>8     bedate  x               Previous dump %s,
+>12    belong  >0              Volume %d,
+>692   belong  0               Level zero, type:
+>692   belong  >0              Level %d, type:
+>0     belong  1               tape header,
+>0     belong  2               beginning of file record,
+>0     belong  3               map of inodes on tape,
+>0     belong  4               continuation of file record,
+>0     belong  5               end of volume,
+>0     belong  6               map of inodes deleted,
+>0     belong  7               end of medium (for floppy),
+>676   string  >\0             Label %s,
+>696   string  >\0             Filesystem %s,
+>760   string  >\0             Device %s,
+>824   string  >\0             Host %s,
+>888   belong  >0              Flags %x
+
+0      name    old-dump-be
+#>4    bedate  x               This dump %s,
+#>8    bedate  x               Previous dump %s,
+>12    belong  >0              Volume %d,
+>692   belong  0               Level zero, type:
+>692   belong  >0              Level %d, type:
+>0     belong  1               tape header,
+>0     belong  2               beginning of file record,
+>0     belong  3               map of inodes on tape,
+>0     belong  4               continuation of file record,
+>0     belong  5               end of volume,
+>0     belong  6               map of inodes deleted,
+>0     belong  7               end of medium (for floppy),
+>676   string  >\0             Label %s,
+>696   string  >\0             Filesystem %s,
+>760   string  >\0             Device %s,
+>824   string  >\0             Host %s,
+>888   belong  >0              Flags %x
+
+0      name    ufs2-dump-be
+>896   beqdate x               This dump %s,
+>904   beqdate x               Previous dump %s,
+>12    belong  >0              Volume %d,
+>692   belong  0               Level zero, type:
+>692   belong  >0              Level %d, type:
+>0     belong  1               tape header,
+>0     belong  2               beginning of file record,
+>0     belong  3               map of inodes on tape,
+>0     belong  4               continuation of file record,
+>0     belong  5               end of volume,
+>0     belong  6               map of inodes deleted,
+>0     belong  7               end of medium (for floppy),
+>676   string  >\0             Label %s,
+>696   string  >\0             Filesystem %s,
+>760   string  >\0             Device %s,
+>824   string  >\0             Host %s,
+>888   belong  >0              Flags %x
+
+24     belong  60012           new-fs dump file (big endian),
+>0     use     new-dump-be
+
+24     belong  60011           old-fs dump file (big endian),
+>0     use     old-dump-be
+
+24     lelong  60012           new-fs dump file (little endian),
+# to correctly recognize '*.mo' GNU message catalog (little endian)
+!:strength - 15
+>0     use     \^new-dump-be
+
+24     lelong  60011           old-fs dump file (little endian),
+>0     use     \^old-dump-be
+
+
+24     belong  0x19540119      new-fs dump file (ufs2, big endian),
+>0     use     ufs2-dump-be
+
+24     lelong  0x19540119      new-fs dump file (ufs2, little endian),
+>0     use     \^ufs2-dump-be
+
+18     leshort 60011           old-fs dump file (16-bit, assuming PDP-11 endianness),
+>2     medate  x               Previous dump %s,
+>6     medate  x               This dump %s,
+>10    leshort >0              Volume %d,
+>0     leshort 1               tape header.
+>0     leshort 2               beginning of file record.
+>0     leshort 3               map of inodes on tape.
+>0     leshort 4               continuation of file record.
+>0     leshort 5               end of volume.
+>0     leshort 6               map of inodes deleted.
+>0     leshort 7               end of medium (for floppy).
diff --git a/magic/Magdir/dyadic b/magic/Magdir/dyadic
new file mode 100644 (file)
index 0000000..c57f81b
--- /dev/null
@@ -0,0 +1,61 @@
+
+#------------------------------------------------------------------------------
+# $File: dyadic,v 1.9 2019/04/19 00:42:27 christos Exp $
+# Dyadic: file(1) magic for Dyalog APL.
+#
+# updated by Joerg Jenderek at Oct 2013
+# https://en.wikipedia.org/wiki/Dyalog_APL
+# https://www.dyalog.com/
+# .DXV Dyalog APL External Variable
+# .DIN Dyalog APL Input Table
+# .DOT Dyalog APL Output Table
+# .DFT Dyalog APL Format File
+0      ubeshort&0xFF60 0xaa00
+# skip biblio.dbt
+>1     byte            !4
+# real Dyalog APL have non zero version numbers like 7.3 or 13.4
+>>2    ubeshort        >0x0000         Dyalog APL
+>>>1   byte            0x00            aplcore
+#>>>1  byte            0x00            incomplete workspace
+# *.DCF Dyalog APL Component File
+>>>1   byte            0x01            component file 32-bit non-journaled non-checksummed
+#>>>1  byte            0x01            component file
+>>>1   byte            0x02            external variable exclusive
+#>>>1  byte            0x02            external variable
+# *.DWS Dyalog APL Workspace
+>>>1   byte            0x03            workspace
+>>>>7  byte&0x28       0x00            32-bit
+>>>>7  byte&0x28       0x20            64-bit
+>>>>7  byte&0x0c       0x00            classic
+>>>>7  byte&0x0c       0x04            unicode
+>>>>7  byte&0x88       0x00            big-endian
+>>>>7  byte&0x88       0x80            little-endian
+>>>1   byte            0x06            external variable shared
+# *.DSE Dyalog APL Session , *.DLF Dyalog APL Session Log File
+>>>1   byte            0x07            session
+>>>1   byte            0x08            mapped file 32-bit
+>>>1   byte            0x09            component file 64-bit non-journaled non-checksummed
+>>>1   byte            0x0a            mapped file 64-bit
+>>>1   byte            0x0b            component file 32-bit level 1 journaled non-checksummed
+>>>1   byte            0x0c            component file 64-bit level 1 journaled non-checksummed
+>>>1   byte            0x0d            component file 32-bit level 1 journaled checksummed
+>>>1   byte            0x0e            component file 64-bit level 1 journaled checksummed
+>>>1   byte            0x0f            component file 32-bit level 2 journaled checksummed
+>>>1   byte            0x10            component file 64-bit level 2 journaled checksummed
+>>>1   byte            0x11            component file 32-bit level 3 journaled checksummed
+>>>1   byte            0x12            component file 64-bit level 3 journaled checksummed
+>>>1   byte            0x13            component file 32-bit non-journaled checksummed
+>>>1   byte            0x14            component file 64-bit non-journaled checksummed
+>>>1   byte            0x15            component file under construction
+>>>1   byte            0x16            DFS component file 64-bit level 1 journaled checksummed
+>>>1   byte            0x17            DFS component file 64-bit level 2 journaled checksummed
+>>>1   byte            0x18            DFS component file 64-bit level 3 journaled checksummed
+>>>1   byte            0x19            external workspace
+>>>1   byte            0x80            DDB
+>>>2   byte            x               version %d
+>>>3   byte            x               \b.%d
+#>>>2  byte            x               type %d
+#>>>3  byte            x               subtype %d
+
+# *.DXF Dyalog APL Transfer File
+0      short           0x6060          Dyalog APL transfer
diff --git a/magic/Magdir/ebml b/magic/Magdir/ebml
new file mode 100644 (file)
index 0000000..d37b5c0
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File: ebml,v 1.2 2019/04/19 00:42:27 christos Exp $
+# ebml:  file(1) magic for various Extensible Binary Meta Language
+# https://www.matroska.org/technical/specs/index.html#track
+0      belong  0x1a45dfa3      EBML file
+>4     search/b/100    \102\202
+>>&1   string  x               \b, creator %.8s
diff --git a/magic/Magdir/edid b/magic/Magdir/edid
new file mode 100644 (file)
index 0000000..a17b6c4
--- /dev/null
@@ -0,0 +1,11 @@
+
+#------------------------------------------------------------------------------
+# $File: edid,v 1.1 2019/03/28 12:36:01 christos Exp $
+# edid:  file(1) magic for EDID dump files
+
+0      quad    0x00ffffffffffff00      Extended display identification data dump
+!:mime application/x-edid-dump
+>18    byte    0x01                    Version 1
+>>19   byte    <0x04                   \b.%d
+>18    byte    0x02                    Version 2
+>>19   byte    0x00                    \b.0
diff --git a/magic/Magdir/editors b/magic/Magdir/editors
new file mode 100644 (file)
index 0000000..78f3a84
--- /dev/null
@@ -0,0 +1,39 @@
+
+#------------------------------------------------------------------------------
+# $File: editors,v 1.11 2017/03/17 21:35:28 christos Exp $
+# T602 editor documents
+# by David Necas <yeti@physics.muni.cz>
+0      string  @CT\    T602 document data,
+>4     string  0       Kamenicky
+>4     string  1       CP 852
+>4     string  2       KOI8-CS
+>4     string  >2      unknown encoding
+
+# Vi IMproved Encrypted file
+# by David Necas <yeti@physics.muni.cz>
+0      string  VimCrypt~       Vim encrypted file data
+
+0      name    vimnanoswap
+>67    byte    0
+>>107  byte    0
+#>>>2  string  x       %s swap file
+>>>24  ulelong x       \b, pid %d
+>>>28  string  >\0     \b, user %s
+>>>68  string  >\0     \b, host %s
+>>>108 string  >\0     \b, file %s
+>>>1007        byte    0x55    \b, modified
+
+# Vi IMproved Swap file
+# by Sven Wegener <swegener@gentoo.org>
+0      string  b0VIM\          Vim swap file
+>&0    string  >\0             \b, version %s
+>0     use     vimnanoswap
+
+
+# Lock/swap file for several editors, at least
+# Vi IMproved and nano
+0      string  b0nano          Nano swap file
+>0     use     vimnanoswap
+
+# kate (K Advanced Text Editor)
+0      string  \x00\x00\x00\x12Kate\ Swap\ File\ 2.0\x00       Kate swap file
diff --git a/magic/Magdir/efi b/magic/Magdir/efi
new file mode 100644 (file)
index 0000000..97ddf6a
--- /dev/null
@@ -0,0 +1,15 @@
+
+#------------------------------------------------------------------------------
+# $File: efi,v 1.4 2009/09/19 16:28:09 christos Exp $
+# efi:  file(1) magic for Universal EFI binaries
+
+0      lelong  0x0ef1fab9
+>4     lelong  1               Universal EFI binary with 1 architecture
+>>&0   lelong  7               \b, i386
+>>&0   lelong  0x01000007      \b, x86_64
+>4     lelong  2               Universal EFI binary with 2 architectures
+>>&0   lelong  7               \b, i386
+>>&0   lelong  0x01000007      \b, x86_64
+>>&20  lelong  7               \b, i386
+>>&20  lelong  0x01000007      \b, x86_64
+>4     lelong  >2              Universal EFI binary with %d architectures
diff --git a/magic/Magdir/elf b/magic/Magdir/elf
new file mode 100644 (file)
index 0000000..85eda78
--- /dev/null
@@ -0,0 +1,333 @@
+
+#------------------------------------------------------------------------------
+# $File: elf,v 1.77 2019/01/16 19:33:35 christos Exp $
+# elf:  file(1) magic for ELF executables
+#
+# We have to check the byte order flag to see what byte order all the
+# other stuff in the header is in.
+#
+# What're the correct byte orders for the nCUBE and the Fujitsu VPP500?
+#
+# Created by: unknown
+# Modified by (1): Daniel Quinlan <quinlan@yggdrasil.com>
+# Modified by (2): Peter Tobias <tobias@server.et-inf.fho-emden.de> (core support)
+# Modified by (3): Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de> (fix of core support)
+# Modified by (4): <gerardo.cacciari@gmail.com> (VMS Itanium)
+# Modified by (5): Matthias Urlichs <smurf@debian.org> (Listing of many architectures)
+
+0      name            elf-mips
+>0     lelong&0xf0000000       0x00000000      MIPS-I
+>0     lelong&0xf0000000       0x10000000      MIPS-II
+>0     lelong&0xf0000000       0x20000000      MIPS-III
+>0     lelong&0xf0000000       0x30000000      MIPS-IV
+>0     lelong&0xf0000000       0x40000000      MIPS-V
+>0     lelong&0xf0000000       0x50000000      MIPS32
+>0     lelong&0xf0000000       0x60000000      MIPS64
+>0     lelong&0xf0000000       0x70000000      MIPS32 rel2
+>0     lelong&0xf0000000       0x80000000      MIPS64 rel2
+>0     lelong&0xf0000000       0x90000000      MIPS32 rel6
+>0     lelong&0xf0000000       0xa0000000      MIPS64 rel6
+
+0      name            elf-sparc
+>0     lelong&0x00ffff00       0x00000100      V8+ Required,
+>0     lelong&0x00ffff00       0x00000200      Sun UltraSPARC1 Extensions Required,
+>0     lelong&0x00ffff00       0x00000400      HaL R1 Extensions Required,
+>0     lelong&0x00ffff00       0x00000800      Sun UltraSPARC3 Extensions Required,
+>0     lelong&0x3              0               total store ordering,
+>0     lelong&0x3              1               partial store ordering,
+>0     lelong&0x3              2               relaxed memory ordering,
+
+0      name            elf-pa-risc
+>2     leshort         0x0208          1.0
+>2     leshort         0x0210          1.1
+>2     leshort         0x0214          2.0
+>0     leshort         &0x0008         (LP64)
+
+0      name            elf-le
+>16    leshort         0               no file type,
+!:mime application/octet-stream
+>16    leshort         1               relocatable,
+!:mime application/x-object
+>16    leshort         2               executable,
+!:mime application/x-executable
+>16    leshort         3               ${x?pie executable:shared object},
+
+!:mime application/x-${x?pie-executable:sharedlib}
+>16    leshort         4               core file,
+!:mime application/x-coredump
+# OS-specific
+>7     byte            202
+>>16   leshort         0xFE01          executable,
+!:mime application/x-executable
+# Core file detection is not reliable.
+#>>>(0x38+0xcc) string >\0             of '%s'
+#>>>(0x38+0x10) lelong >0              (signal %d),
+>16    leshort         &0xff00         processor-specific,
+>18    clear           x
+>18    leshort         0               no machine,
+>18    leshort         1               AT&T WE32100,
+>18    leshort         2               SPARC,
+>18    leshort         3               Intel 80386,
+>18    leshort         4               Motorola m68k,
+>>4    byte            1
+>>>36  lelong          &0x01000000     68000,
+>>>36  lelong          &0x00810000     CPU32,
+>>>36  lelong          0               68020,
+>18    leshort         5               Motorola m88k,
+>18    leshort         6               Intel 80486,
+>18    leshort         7               Intel 80860,
+# The official e_machine number for MIPS is now #8, regardless of endianness.
+# The second number (#10) will be deprecated later. For now, we still
+# say something if #10 is encountered, but only gory details for #8.
+>18    leshort         8               MIPS,
+>>4    byte            1
+>>>36  lelong          &0x20           N32
+>18    leshort         10              MIPS,
+>>4    byte            1
+>>>36  lelong          &0x20           N32
+>18    leshort         8
+# only for 32-bit
+>>4    byte            1
+>>>36  use             elf-mips
+# only for 64-bit
+>>4    byte            2
+>>>48  use             elf-mips
+>18    leshort         9               Amdahl,
+>18    leshort         10              MIPS (deprecated),
+>18    leshort         11              RS6000,
+>18    leshort         15              PA-RISC,
+# only for 32-bit
+>>4    byte            1
+>>>36  use             elf-pa-risc
+# only for 64-bit
+>>4    byte            2
+>>>48  use             elf-pa-risc
+>18    leshort         16              nCUBE,
+>18    leshort         17              Fujitsu VPP500,
+>18    leshort         18              SPARC32PLUS,
+# only for 32-bit
+>>4    byte            1
+>>>36  use             elf-sparc
+>18    leshort         19              Intel 80960,
+>18    leshort         20              PowerPC or cisco 4500,
+>18    leshort         21              64-bit PowerPC or cisco 7500,
+>18    leshort         22              IBM S/390,
+>18    leshort         23              Cell SPU,
+>18    leshort         24              cisco SVIP,
+>18    leshort         25              cisco 7200,
+>18    leshort         36              NEC V800 or cisco 12000,
+>18    leshort         37              Fujitsu FR20,
+>18    leshort         38              TRW RH-32,
+>18    leshort         39              Motorola RCE,
+>18    leshort         40              ARM,
+>>4    byte            1
+>>>36  lelong&0xff000000       0x04000000      EABI4
+>>>36  lelong&0xff000000       0x05000000      EABI5
+>>>36  lelong          &0x00800000     BE8
+>>>36  lelong          &0x00400000     LE8
+>18    leshort         41              Alpha,
+>18    leshort         42              Renesas SH,
+>18    leshort         43              SPARC V9,
+>>4    byte            2
+>>>48  use             elf-sparc
+>18    leshort         44              Siemens Tricore Embedded Processor,
+>18    leshort         45              Argonaut RISC Core, Argonaut Technologies Inc.,
+>18    leshort         46              Renesas H8/300,
+>18    leshort         47              Renesas H8/300H,
+>18    leshort         48              Renesas H8S,
+>18    leshort         49              Renesas H8/500,
+>18    leshort         50              IA-64,
+>18    leshort         51              Stanford MIPS-X,
+>18    leshort         52              Motorola Coldfire,
+>18    leshort         53              Motorola M68HC12,
+>18    leshort         54              Fujitsu MMA,
+>18    leshort         55              Siemens PCP,
+>18    leshort         56              Sony nCPU,
+>18    leshort         57              Denso NDR1,
+>18    leshort         58              Start*Core,
+>18    leshort         59              Toyota ME16,
+>18    leshort         60              ST100,
+>18    leshort         61              Tinyj emb.,
+>18    leshort         62              x86-64,
+>18    leshort         63              Sony DSP,
+>18    leshort         64              DEC PDP-10,
+>18    leshort         65              DEC PDP-11,
+>18    leshort         66              FX66,
+>18    leshort         67              ST9+ 8/16 bit,
+>18    leshort         68              ST7 8 bit,
+>18    leshort         69              MC68HC16,
+>18    leshort         70              MC68HC11,
+>18    leshort         71              MC68HC08,
+>18    leshort         72              MC68HC05,
+>18    leshort         73              SGI SVx or Cray NV1,
+>18    leshort         74              ST19 8 bit,
+>18    leshort         75              Digital VAX,
+>18    leshort         76              Axis cris,
+>18    leshort         77              Infineon 32-bit embedded,
+>18    leshort         78              Element 14 64-bit DSP,
+>18    leshort         79              LSI Logic 16-bit DSP,
+>18    leshort         80              MMIX,
+>18    leshort         81              Harvard machine-independent,
+>18    leshort         82              SiTera Prism,
+>18    leshort         83              Atmel AVR 8-bit,
+>18    leshort         84              Fujitsu FR30,
+>18    leshort         85              Mitsubishi D10V,
+>18    leshort         86              Mitsubishi D30V,
+>18    leshort         87              NEC v850,
+>18    leshort         88              Renesas M32R,
+>18    leshort         89              Matsushita MN10300,
+>18    leshort         90              Matsushita MN10200,
+>18    leshort         91              picoJava,
+>18    leshort         92              OpenRISC,
+>18    leshort         93              ARC Cores Tangent-A5,
+>18    leshort         94              Tensilica Xtensa,
+>18    leshort         95              Alphamosaic VideoCore,
+>18    leshort         96              Thompson Multimedia,
+>18    leshort         97              NatSemi 32k,
+>18    leshort         98              Tenor Network TPC,
+>18    leshort         99              Trebia SNP 1000,
+>18    leshort         100             STMicroelectronics ST200,
+>18    leshort         101             Ubicom IP2022,
+>18    leshort         102             MAX Processor,
+>18    leshort         103             NatSemi CompactRISC,
+>18    leshort         104             Fujitsu F2MC16,
+>18    leshort         105             TI msp430,
+>18    leshort         106             Analog Devices Blackfin,
+>18    leshort         107             S1C33 Family of Seiko Epson,
+>18    leshort         108             Sharp embedded,
+>18    leshort         109             Arca RISC,
+>18    leshort         110             PKU-Unity Ltd.,
+>18    leshort         111             eXcess: 16/32/64-bit,
+>18    leshort         112             Icera Deep Execution Processor,
+>18    leshort         113             Altera Nios II,
+>18    leshort         114             NatSemi CRX,
+>18    leshort         115             Motorola XGATE,
+>18    leshort         116             Infineon C16x/XC16x,
+>18    leshort         117             Renesas M16C series,
+>18    leshort         118             Microchip dsPIC30F,
+>18    leshort         119             Freescale RISC core,
+>18    leshort         120             Renesas M32C series,
+>18    leshort         131             Altium TSK3000 core,
+>18    leshort         132             Freescale RS08,
+>18    leshort         134             Cyan Technology eCOG2,
+>18    leshort         135             Sunplus S+core7 RISC,
+>18    leshort         136             New Japan Radio (NJR) 24-bit DSP,
+>18    leshort         137             Broadcom VideoCore III,
+>18    leshort         138             LatticeMico32,
+>18    leshort         139             Seiko Epson C17 family,
+>18    leshort         140             TI TMS320C6000 DSP family,
+>18    leshort         141             TI TMS320C2000 DSP family,
+>18    leshort         142             TI TMS320C55x DSP family,
+>18    leshort         160             STMicroelectronics 64bit VLIW DSP,
+>18    leshort         161             Cypress M8C,
+>18    leshort         162             Renesas R32C series,
+>18    leshort         163             NXP TriMedia family,
+>18    leshort         164             QUALCOMM DSP6,
+>18    leshort         165             Intel 8051 and variants,
+>18    leshort         166             STMicroelectronics STxP7x family,
+>18    leshort         167             Andes embedded RISC,
+>18    leshort         168             Cyan eCOG1X family,
+>18    leshort         169             Dallas MAXQ30,
+>18    leshort         170             New Japan Radio (NJR) 16-bit DSP,
+>18    leshort         171             M2000 Reconfigurable RISC,
+>18    leshort         172             Cray NV2 vector architecture,
+>18    leshort         173             Renesas RX family,
+>18    leshort         174             META,
+>18    leshort         175             MCST Elbrus,
+>18    leshort         176             Cyan Technology eCOG16 family,
+>18    leshort         177             NatSemi CompactRISC,
+>18    leshort         178             Freescale Extended Time Processing Unit,
+>18    leshort         179             Infineon SLE9X,
+>18    leshort         180             Intel L1OM,
+>18    leshort         181             Intel K1OM,
+>18    leshort         183             ARM aarch64,
+>18    leshort         185             Atmel 32-bit family,
+>18    leshort         186             STMicroeletronics STM8 8-bit,
+>18    leshort         187             Tilera TILE64,
+>18    leshort         188             Tilera TILEPro,
+>18    leshort         189             Xilinx MicroBlaze 32-bit RISC,
+>18    leshort         190             NVIDIA CUDA architecture,
+>18    leshort         191             Tilera TILE-Gx,
+>18    leshort         197             Renesas RL78 family,
+>18    leshort         199             Renesas 78K0R,
+>18    leshort         200             Freescale 56800EX,
+>18    leshort         201             Beyond BA1,
+>18    leshort         202             Beyond BA2,
+>18    leshort         203             XMOS xCORE,
+>18    leshort         204             Microchip 8-bit PIC(r),
+>18    leshort         210             KM211 KM32,
+>18    leshort         211             KM211 KMX32,
+>18    leshort         212             KM211 KMX16,
+>18    leshort         213             KM211 KMX8,
+>18    leshort         214             KM211 KVARC,
+>18    leshort         215             Paneve CDP,
+>18    leshort         216             Cognitive Smart Memory,
+>18    leshort         217             iCelero CoolEngine,
+>18    leshort         218             Nanoradio Optimized RISC,
+>18    leshort         243             UCB RISC-V,
+>18    leshort         247             eBPF,
+>18    leshort         251             NEC VE,
+>18    leshort         0x1057          AVR (unofficial),
+>18    leshort         0x1059          MSP430 (unofficial),
+>18    leshort         0x1223          Adapteva Epiphany (unofficial),
+>18    leshort         0x2530          Morpho MT (unofficial),
+>18    leshort         0x3330          FR30 (unofficial),
+>18    leshort         0x3426          OpenRISC (obsolete),
+>18    leshort         0x4688          Infineon C166 (unofficial),
+>18    leshort         0x5441          Cygnus FRV (unofficial),
+>18    leshort         0x5aa5          DLX (unofficial),
+>18    leshort         0x7650          Cygnus D10V (unofficial),
+>18    leshort         0x7676          Cygnus D30V (unofficial),
+>18    leshort         0x8217          Ubicom IP2xxx (unofficial),
+>18    leshort         0x8472          OpenRISC (obsolete),
+>18    leshort         0x9025          Cygnus PowerPC (unofficial),
+>18    leshort         0x9026          Alpha (unofficial),
+>18    leshort         0x9041          Cygnus M32R (unofficial),
+>18    leshort         0x9080          Cygnus V850 (unofficial),
+>18    leshort         0xa390          IBM S/390 (obsolete),
+>18    leshort         0xabc7          Old Xtensa (unofficial),
+>18    leshort         0xad45          xstormy16 (unofficial),
+>18    leshort         0xbaab          Old MicroBlaze (unofficial),,
+>18    leshort         0xbeef          Cygnus MN10300 (unofficial),
+>18    leshort         0xdead          Cygnus MN10200 (unofficial),
+>18    leshort         0xf00d          Toshiba MeP (unofficial),
+>18    leshort         0xfeb0          Renesas M32C (unofficial),
+>18    leshort         0xfeba          Vitesse IQ2000 (unofficial),
+>18    leshort         0xfebb          NIOS (unofficial),
+>18    leshort         0xfeed          Moxie (unofficial),
+>18    default         x
+>>18   leshort         x               *unknown arch 0x%x*
+>20    lelong          0               invalid version
+>20    lelong          1               version 1
+
+0      string          \177ELF         ELF
+!:strength *2
+>4     byte            0               invalid class
+>4     byte            1               32-bit
+>4     byte            2               64-bit
+>5     byte            0               invalid byte order
+>5     byte            1               LSB
+>>0    use             elf-le
+>5     byte            2               MSB
+>>0    use             \^elf-le
+>7     byte            0               (SYSV)
+>7     byte            1               (HP-UX)
+>7     byte            2               (NetBSD)
+>7     byte            3               (GNU/Linux)
+>7     byte            4               (GNU/Hurd)
+>7     byte            5               (86Open)
+>7     byte            6               (Solaris)
+>7     byte            7               (Monterey)
+>7     byte            8               (IRIX)
+>7     byte            9               (FreeBSD)
+>7     byte            10              (Tru64)
+>7     byte            11              (Novell Modesto)
+>7     byte            12              (OpenBSD)
+>7     byte            13              (OpenVMS)
+>7     byte            14              (HP NonStop Kernel)
+>7     byte            15              (AROS Research Operating System)
+>7     byte            16              (FenixOS)
+>7     byte            17              (Nuxi CloudABI)
+>7     byte            97              (ARM)
+>7     byte            202             (Cafe OS)
+>7     byte            255             (embedded)
diff --git a/magic/Magdir/encore b/magic/Magdir/encore
new file mode 100644 (file)
index 0000000..b7f49a7
--- /dev/null
@@ -0,0 +1,22 @@
+
+#------------------------------------------------------------------------------
+# $File: encore,v 1.6 2009/09/19 16:28:09 christos Exp $
+# encore:  file(1) magic for Encore machines
+#
+# XXX - needs to have the byte order specified (NS32K was little-endian,
+# dunno whether they run the 88K in little-endian mode or not).
+#
+0      short           0x154           Encore
+>20    short           0x107           executable
+>20    short           0x108           pure executable
+>20    short           0x10b           demand-paged executable
+>20    short           0x10f           unsupported executable
+>12    long            >0              not stripped
+>22    short           >0              - version %d
+>22    short           0               -
+#>4    date            x               stamp %s
+0      short           0x155           Encore unsupported executable
+>12    long            >0              not stripped
+>22    short           >0              - version %d
+>22    short           0               -
+#>4    date            x               stamp %s
diff --git a/magic/Magdir/epoc b/magic/Magdir/epoc
new file mode 100644 (file)
index 0000000..2ad4cb0
--- /dev/null
@@ -0,0 +1,62 @@
+
+#------------------------------------------------------------------------------
+# $File: epoc,v 1.8 2012/06/16 14:43:36 christos Exp $
+# EPOC : file(1) magic for EPOC documents [Psion Series 5/Osaris/Geofox 1]
+# Stefan Praszalowicz <hpicollo@worldnet.fr> and Peter Breitenlohner <peb@mppmu.mpg.de>
+# Useful information for improving this file can be found at:
+# http://software.frodo.looijaard.name/psiconv/formats/Index.html
+#------------------------------------------------------------------------------
+0      lelong          0x10000037      Psion Series 5
+>4     lelong          0x10000039      font file
+>4     lelong          0x1000003A      printer driver
+>4     lelong          0x1000003B      clipboard
+>4     lelong          0x10000042      multi-bitmap image
+!:mime image/x-epoc-mbm
+>4     lelong          0x1000006A      application information file
+>4     lelong          0x1000006D
+>>8    lelong          0x1000007D      Sketch image
+!:mime image/x-epoc-sketch
+>>8    lelong          0x1000007E      voice note
+>>8    lelong          0x1000007F      Word file
+!:mime application/x-epoc-word
+>>8    lelong          0x10000085      OPL program (TextEd)
+!:mime application/x-epoc-opl
+>>8    lelong          0x10000087      Comms settings
+>>8    lelong          0x10000088      Sheet file
+!:mime application/x-epoc-sheet
+>>8    lelong          0x100001C4      EasyFax initialisation file
+>4     lelong          0x10000073      OPO module
+!:mime application/x-epoc-opo
+>4     lelong          0x10000074      OPL application
+!:mime application/x-epoc-app
+>4     lelong          0x1000008A      exported multi-bitmap image
+>4     lelong          0x1000016D
+>>8    lelong          0x10000087      Comms names
+
+0      lelong          0x10000041      Psion Series 5 ROM multi-bitmap image
+
+0      lelong          0x10000050      Psion Series 5
+>4     lelong          0x1000006D      database
+>>8    lelong          0x10000084      Agenda file
+!:mime application/x-epoc-agenda
+>>8    lelong          0x10000086      Data file
+!:mime application/x-epoc-data
+>>8    lelong          0x10000CEA      Jotter file
+!:mime application/x-epoc-jotter
+>4     lelong          0x100000E4      ini file
+
+0      lelong          0x10000079      Psion Series 5 binary:
+>4     lelong          0x00000000      DLL
+>4     lelong          0x10000049      comms hardware library
+>4     lelong          0x1000004A      comms protocol library
+>4     lelong          0x1000005D      OPX
+>4     lelong          0x1000006C      application
+>4     lelong          0x1000008D      DLL
+>4     lelong          0x100000AC      logical device driver
+>4     lelong          0x100000AD      physical device driver
+>4     lelong          0x100000E5      file transfer protocol
+>4     lelong          0x100000E5      file transfer protocol
+>4     lelong          0x10000140      printer definition
+>4     lelong          0x10000141      printer definition
+
+0      lelong          0x1000007A      Psion Series 5 executable
diff --git a/magic/Magdir/erlang b/magic/Magdir/erlang
new file mode 100644 (file)
index 0000000..df7aa2a
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File: erlang,v 1.7 2019/04/19 00:42:27 christos Exp $
+# erlang:  file(1) magic for Erlang JAM and BEAM files
+# URL:  https://www.erlang.org/faq/x779.html#AEN812
+
+# OTP R3-R4
+0      string  \0177BEAM!      Old Erlang BEAM file
+>6     short   >0              - version %d
+
+# OTP R5 and onwards
+0      string  FOR1
+>8     string  BEAM            Erlang BEAM file
+
+# 4.2 version may have a copyright notice!
+4      string  Tue\ Jan\ 22\ 14:32:44\ MET\ 1991       Erlang JAM file - version 4.2
+79     string  Tue\ Jan\ 22\ 14:32:44\ MET\ 1991       Erlang JAM file - version 4.2
+
+4      string  1.0\ Fri\ Feb\ 3\ 09:55:56\ MET\ 1995   Erlang JAM file - version 4.3
+
+0      bequad  0x0000000000ABCDEF      Erlang DETS file
diff --git a/magic/Magdir/espressif b/magic/Magdir/espressif
new file mode 100644 (file)
index 0000000..72a0ec9
--- /dev/null
@@ -0,0 +1,57 @@
+
+# $File: espressif,v 1.1 2018/11/20 18:57:17 christos Exp $
+# configuration dump of Tasmota firmware for ESP8266 based devices by Espressif
+# URL: https://github.com/arendst/Sonoff-Tasmota/
+# Reference: https://codeload.github.com/arendst/Sonoff-Tasmota/zip/release-6.2/
+# Sonoff-Tasmota-release-6.2.zip/Sonoff-Tasmota-release-6.2/sonoff/settings.h 
+# From: Joerg Jenderek
+#
+# cfg_holder=4617=0x1209
+0              uleshort        4617
+# remainig settings normally 0x5A+offset XORed; free_1D5[20] empty since 5.12.0e
+>0x1D5         ubequad         0x2f30313233343536      configuration of Tasmota firmware (ESP8266)
+!:mime application/x-tasmota-dmp
+!:ext  dmp
+# version like 6.2.1.0 ~ 0x06020100 XORed to 0x63666262
+>>11           ubyte^0x65      x                       \b, version %u
+>>10           ubyte^0x64      x                       \b.%u
+>>9            ubyte^0x63      x                       \b.%u
+>>8            ubyte^0x62      x                       \b.%u
+#>8            ubelong         x                       (0x%x)
+# hostname[33] XORed
+>>0x165                ubyte^0x1BF     x                       \b, hostname %c
+>>0x166                ubyte^0x1C0     >037                    \b%c
+>>0x167                ubyte^0x1C1     >037                    \b%c
+>>0x168                ubyte^0x1C2     >037                    \b%c
+>>0x169                ubyte^0x1C3     >037                    \b%c
+>>0x16A                ubyte^0x1C4     >037                    \b%c
+>>0x16B                ubyte^0x1C5     >037                    \b%c
+>>0x16C                ubyte^0x1C6     >037                    \b%c
+>>0x16D                ubyte^0x1C7     >037                    \b%c
+>>0x16E                ubyte^0x1C8     >037                    \b%c
+>>0x16F                ubyte^0x1C9     >037                    \b%c
+>>0x170                ubyte^0x1CA     >037                    \b%c
+>>0x171                ubyte^0x1CB     >037                    \b%c
+>>0x172                ubyte^0x1CC     >037                    \b%c
+>>0x173                ubyte^0x1CD     >037                    \b%c
+>>0x174                ubyte^0x1CE     >037                    \b%c
+>>0x175                ubyte^0x1CF     >037                    \b%c
+>>0x176                ubyte^0x1D0     >037                    \b%c
+>>0x177                ubyte^0x1D1     >037                    \b%c
+>>0x178                ubyte^0x1D2     >037                    \b%c
+>>0x179                ubyte^0x1D3     >037                    \b%c
+>>0x17A                ubyte^0x1D4     >037                    \b%c
+>>0x17B                ubyte^0x1D5     >037                    \b%c
+>>0x17C                ubyte^0x1D6     >037                    \b%c
+>>0x17D                ubyte^0x1D7     >037                    \b%c
+>>0x17E                ubyte^0x1D8     >037                    \b%c
+>>0x17F                ubyte^0x1D9     >037                    \b%c
+>>0x180                ubyte^0x1DA     >037                    \b%c
+>>0x181                ubyte^0x1DB     >037                    \b%c
+>>0x182                ubyte^0x1DC     >037                    \b%c
+>>0x183                ubyte^0x1DD     >037                    \b%c
+>>0x184                ubyte^0x1DE     >037                    \b%c
+>>0x185                ubyte^0x1DF     >037                    \b%c
+#>>0x165               string          x                       (%.33s)
+
+
diff --git a/magic/Magdir/esri b/magic/Magdir/esri
new file mode 100644 (file)
index 0000000..e49a7ce
--- /dev/null
@@ -0,0 +1,28 @@
+
+#------------------------------------------------------------------------------
+# $File: esri,v 1.5 2019/04/19 00:42:27 christos Exp $
+# ESRI Shapefile format (.shp .shx .dbf=DBaseIII)
+# Based on info from
+# <URL:https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf>
+0      belong  9994    ESRI Shapefile
+>4     belong  =0
+>8     belong  =0
+>12    belong  =0
+>16    belong  =0
+>20    belong  =0
+>28    lelong  x       version %d
+>24    belong  x       length %d
+>32    lelong  =0      type Null Shape
+>32    lelong  =1      type Point
+>32    lelong  =3      type PolyLine
+>32    lelong  =5      type Polygon
+>32    lelong  =8      type MultiPoint
+>32    lelong  =11     type PointZ
+>32    lelong  =13     type PolyLineZ
+>32    lelong  =15     type PolygonZ
+>32    lelong  =18     type MultiPointZ
+>32    lelong  =21     type PointM
+>32    lelong  =23     type PolyLineM
+>32    lelong  =25     type PolygonM
+>32    lelong  =28     type MultiPointM
+>32    lelong  =31     type MultiPatch
diff --git a/magic/Magdir/etf b/magic/Magdir/etf
new file mode 100644 (file)
index 0000000..bf36362
--- /dev/null
@@ -0,0 +1,33 @@
+#------------------------------------------------------------------------------
+# $File: elf,v 1.68 2014/09/19 19:05:57 christos Exp $
+# elf:  file(1) magic for Erlang External Term Format magic
+# http://erlang.org/doc/apps/erts/erl_ext_dist.html
+# This magic is too weak so it is not enabled by default
+0      byte    131
+>1     byte    80
+>>2    belong  >0      Erlang External Term Format, compressed, original size = %d
+>1     byte    70      Erlang External Term Format, starts with NEW_FLOAT_EXT
+>1     byte    77      Erlang External Term Format, starts with BIT_BINARY_EXT
+>1     byte    97      Erlang External Term Format, starts with SMALL_INTEGER_EXT
+>1     byte    98      Erlang External Term Format, starts with INTEGER_EXT
+>1     byte    99      Erlang External Term Format, starts with FLOAT_EXT
+>1     byte    100     Erlang External Term Format, starts with ATOM_EXT
+>1     byte    101     Erlang External Term Format, starts with REFERENCE_EXT
+>1     byte    102     Erlang External Term Format, starts with PORT_EXT
+>1     byte    103     Erlang External Term Format, starts with PID_EXT
+>1     byte    104     Erlang External Term Format, starts with SMALL_TUPLE_EXT
+>1     byte    105     Erlang External Term Format, starts with LARGE_TUPLE_EXT
+>1     byte    106     Erlang External Term Format, starts with NIL_EXT
+>1     byte    107     Erlang External Term Format, starts with STRING_EXT
+>1     byte    108     Erlang External Term Format, starts with LIST_EXT
+>1     byte    109     Erlang External Term Format, starts with BINARY_EXT
+>1     byte    110     Erlang External Term Format, starts with SMALL_BIG_EXT
+>1     byte    111     Erlang External Term Format, starts with LARGE_BIG_EXT
+>1     byte    112     Erlang External Term Format, starts with NEW_FUN_EXT
+>1     byte    113     Erlang External Term Format, starts with EXPORT_EXT
+>1     byte    114     Erlang External Term Format, starts with NEW_REFERENCE_EXT
+>1     byte    115     Erlang External Term Format, starts with SMALL_ATOM_EXT
+>1     byte    116     Erlang External Term Format, starts with MAP_EXT
+>1     byte    117     Erlang External Term Format, starts with FUN_EXT
+>1     byte    118     Erlang External Term Format, starts with ATOM_UTF8_EXT
+>1     byte    119     Erlang External Term Format, starts with SMALL_ATOM_UTF8_EXT
diff --git a/magic/Magdir/fcs b/magic/Magdir/fcs
new file mode 100644 (file)
index 0000000..c6a6201
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# fcs: file(1) magic for FCS (Flow Cytometry Standard) data files
+# From Roger Leigh <roger@whinlatter.uklinux.net>
+0       string          FCS1.0          Flow Cytometry Standard (FCS) data, version 1.0
+0       string          FCS2.0          Flow Cytometry Standard (FCS) data, version 2.0
+0       string          FCS3.0          Flow Cytometry Standard (FCS) data, version 3.0
+
diff --git a/magic/Magdir/filesystems b/magic/Magdir/filesystems
new file mode 100644 (file)
index 0000000..1920e56
--- /dev/null
@@ -0,0 +1,2445 @@
+#------------------------------------------------------------------------------
+# $File: filesystems,v 1.128 2019/04/23 15:43:27 christos Exp $
+# filesystems:  file(1) magic for different filesystems
+#
+0      name    partid
+>0     ubyte   0x00    Unused
+>0     ubyte   0x01    12-bit FAT
+>0     ubyte   0x02    XENIX /
+>0     ubyte   0x03    XENIX /usr
+>0     ubyte   0x04    16-bit FAT, less than 32M
+>0     ubyte   0x05    extended partition
+>0     ubyte   0x06    16-bit FAT, more than 32M
+>0     ubyte   0x07    OS/2 HPFS, NTFS, QNX2, Adv. UNIX
+>0     ubyte   0x08    AIX or os, or etc.
+>0     ubyte   0x09    AIX boot partition or Coherent
+>0     ubyte   0x0a    O/2 boot manager or Coherent swap
+>0     ubyte   0x0b    32-bit FAT
+>0     ubyte   0x0c    32-bit FAT, LBA-mapped
+>0     ubyte   0x0d    7XXX, LBA-mapped
+>0     ubyte   0x0e    16-bit FAT, LBA-mapped
+>0     ubyte   0x0f    extended partition, LBA-mapped
+>0     ubyte   0x10    OPUS
+>0     ubyte   0x11    OS/2 DOS 12-bit FAT
+>0     ubyte   0x12    Compaq diagnostics
+>0     ubyte   0x14    OS/2 DOS 16-bit FAT <32M
+>0     ubyte   0x16    OS/2 DOS 16-bit FAT >=32M
+>0     ubyte   0x17    OS/2 hidden IFS
+>0     ubyte   0x18    AST Windows swapfile
+>0     ubyte   0x19    Willowtech Photon coS
+>0     ubyte   0x1b    hidden win95 fat 32
+>0     ubyte   0x1c    hidden win95 fat 32 lba
+>0     ubyte   0x1d    hidden win95 fat 16 lba
+>0     ubyte   0x20    Willowsoft OFS1
+>0     ubyte   0x21    reserved
+>0     ubyte   0x23    reserved
+>0     ubyte   0x24    NEC DOS
+>0     ubyte   0x26    reserved
+>0     ubyte   0x31    reserved
+>0     ubyte   0x32    Alien Internet Services NOS
+>0     ubyte   0x33    reserved
+>0     ubyte   0x34    reserved
+>0     ubyte   0x35    JFS on OS2
+>0     ubyte   0x36    reserved
+>0     ubyte   0x38    Theos
+>0     ubyte   0x39    Plan 9, or Theos spanned
+>0     ubyte   0x3a    Theos ver 4 4gb partition
+>0     ubyte   0x3b    Theos ve 4 extended partition
+>0     ubyte   0x3c    PartitionMagic recovery
+>0     ubyte   0x3d    Hidden Netware
+>0     ubyte   0x40    VENIX 286 or LynxOS
+>0     ubyte   0x41    PReP
+>0     ubyte   0x42    linux swap sharing DRDOS disk
+>0     ubyte   0x43    linux sharing DRDOS disk
+>0     ubyte   0x44    GoBack change utility
+>0     ubyte   0x45    Boot US Boot manager
+>0     ubyte   0x46    EUMEL/Elan or Ergos 3
+>0     ubyte   0x47    EUMEL/Elan or Ergos 3
+>0     ubyte   0x48    EUMEL/Elan or Ergos 3
+>0     ubyte   0x4a    ALFX/THIN filesystem for DOS
+>0     ubyte   0x4c    Oberon partition
+>0     ubyte   0x4d    QNX4.x
+>0     ubyte   0x4e    QNX4.x 2nd part
+>0     ubyte   0x4f    QNX4.x 3rd part
+>0     ubyte   0x50    DM (disk manager)
+>0     ubyte   0x51    DM6 Aux1 (or Novell)
+>0     ubyte   0x52    CP/M or Microport SysV/AT
+>0     ubyte   0x53    DM6 Aux3
+>0     ubyte   0x54    DM6 DDO
+>0     ubyte   0x55    EZ-Drive (disk manager)
+>0     ubyte   0x56    Golden Bow (disk manager)
+>0     ubyte   0x57    Drive PRO
+>0     ubyte   0x5c    Priam Edisk (disk manager)
+>0     ubyte   0x61    SpeedStor
+>0     ubyte   0x63    GNU HURD or Mach or Sys V/386
+>0     ubyte   0x64    Novell Netware 2.xx or Speedstore
+>0     ubyte   0x65    Novell Netware 3.xx
+>0     ubyte   0x66    Novell 386 Netware
+>0     ubyte   0x67    Novell
+>0     ubyte   0x68    Novell
+>0     ubyte   0x69    Novell
+>0     ubyte   0x70    DiskSecure Multi-Boot
+>0     ubyte   0x71    reserved
+>0     ubyte   0x73    reserved
+>0     ubyte   0x74    reserved
+>0     ubyte   0x75    PC/IX
+>0     ubyte   0x76    reserved
+>0     ubyte   0x77    M2FS/M2CS partition
+>0     ubyte   0x78    XOSL boot loader filesystem
+>0     ubyte   0x80    MINIX until 1.4a
+>0     ubyte   0x81    MINIX since 1.4b
+>0     ubyte   0x82    Linux swap or Solaris
+>0     ubyte   0x83    Linux native
+>0     ubyte   0x84    OS/2 hidden C: drive
+>0     ubyte   0x85    Linux extended partition
+>0     ubyte   0x86    NT FAT volume set
+>0     ubyte   0x87    NTFS volume set or HPFS mirrored
+>0     ubyte   0x8a    Linux Kernel AiR-BOOT partition
+>0     ubyte   0x8b    Legacy Fault tolerant FAT32
+>0     ubyte   0x8c    Legacy Fault tolerant FAT32 ext
+>0     ubyte   0x8d    Hidden free FDISK FAT12
+>0     ubyte   0x8e    Linux Logical Volume Manager
+>0     ubyte   0x90    Hidden free FDISK FAT16
+>0     ubyte   0x91    Hidden free FDISK DOS EXT
+>0     ubyte   0x92    Hidden free FDISK FAT16 Big
+>0     ubyte   0x93    Amoeba filesystem
+>0     ubyte   0x94    Amoeba bad block table
+>0     ubyte   0x95    MIT EXOPC native partitions
+>0     ubyte   0x97    Hidden free FDISK FAT32
+>0     ubyte   0x98    Datalight ROM-DOS Super-Boot
+>0     ubyte   0x99    Mylex EISA SCSI
+>0     ubyte   0x9a    Hidden free FDISK FAT16 LBA
+>0     ubyte   0x9b    Hidden free FDISK EXT LBA
+>0     ubyte   0x9f    BSDI?
+>0     ubyte   0xa0    IBM Thinkpad hibernation
+>0     ubyte   0xa1    HP Volume expansion (SpeedStor)
+>0     ubyte   0xa3    HP Volume expansion (SpeedStor)
+>0     ubyte   0xa4    HP Volume expansion (SpeedStor)
+>0     ubyte   0xa5    386BSD partition type
+>0     ubyte   0xa6    OpenBSD partition type
+>0     ubyte   0xa7    NeXTSTEP 486
+>0     ubyte   0xa8    Apple UFS
+>0     ubyte   0xa9    NetBSD partition type
+>0     ubyte   0xaa    Olivetty Fat12 1.44MB Service part
+>0     ubyte   0xab    Apple Boot
+>0     ubyte   0xae    SHAG OS filesystem
+>0     ubyte   0xaf    Apple HFS
+>0     ubyte   0xb0    BootStar Dummy
+>0     ubyte   0xb1    reserved
+>0     ubyte   0xb3    reserved
+>0     ubyte   0xb4    reserved
+>0     ubyte   0xb6    reserved
+>0     ubyte   0xb7    BSDI BSD/386 filesystem
+>0     ubyte   0xb8    BSDI BSD/386 swap
+>0     ubyte   0xbb    Boot Wizard Hidden
+>0     ubyte   0xbe    Solaris 8 partition type
+>0     ubyte   0xbf    Solaris partition type
+>0     ubyte   0xc0    CTOS
+>0     ubyte   0xc1    DRDOS/sec (FAT-12)
+>0     ubyte   0xc2    Hidden Linux
+>0     ubyte   0xc3    Hidden Linux swap
+>0     ubyte   0xc4    DRDOS/sec (FAT-16, < 32M)
+>0     ubyte   0xc5    DRDOS/sec (EXT)
+>0     ubyte   0xc6    DRDOS/sec (FAT-16, >= 32M)
+>0     ubyte   0xc7    Syrinx (Cyrnix?) or HPFS disabled
+>0     ubyte   0xc8    Reserved for DR-DOS 8.0+
+>0     ubyte   0xc9    Reserved for DR-DOS 8.0+
+>0     ubyte   0xca    Reserved for DR-DOS 8.0+
+>0     ubyte   0xcb    DR-DOS 7.04+ Secured FAT32 CHS
+>0     ubyte   0xcc    DR-DOS 7.04+ Secured FAT32 LBA
+>0     ubyte   0xcd    CTOS Memdump
+>0     ubyte   0xce    DR-DOS 7.04+ FAT16X LBA
+>0     ubyte   0xcf    DR-DOS 7.04+ EXT LBA
+>0     ubyte   0xd0    REAL/32 secure big partition
+>0     ubyte   0xd1    Old Multiuser DOS FAT12
+>0     ubyte   0xd4    Old Multiuser DOS FAT16 Small
+>0     ubyte   0xd5    Old Multiuser DOS Extended
+>0     ubyte   0xd6    Old Multiuser DOS FAT16 Big
+>0     ubyte   0xd8    CP/M 86
+>0     ubyte   0xdb    CP/M or Concurrent CP/M
+>0     ubyte   0xdd    Hidden CTOS Memdump
+>0     ubyte   0xde    Dell PowerEdge Server utilities
+>0     ubyte   0xdf    DG/UX virtual disk manager
+>0     ubyte   0xe0    STMicroelectronics ST AVFS
+>0     ubyte   0xe1    DOS access or SpeedStor 12-bit
+>0     ubyte   0xe3    DOS R/O or Storage Dimensions
+>0     ubyte   0xe4    SpeedStor 16-bit FAT < 1024 cyl.
+>0     ubyte   0xe5    reserved
+>0     ubyte   0xe6    reserved
+>0     ubyte   0xeb    BeOS
+>0     ubyte   0xee    GPT Protective MBR
+>0     ubyte   0xef    EFI system partition
+>0     ubyte   0xf0    Linux PA-RISC boot loader
+>0     ubyte   0xf1    SpeedStor or Storage Dimensions
+>0     ubyte   0xf2    DOS 3.3+ Secondary
+>0     ubyte   0xf3    reserved
+>0     ubyte   0xf4    SpeedStor large partition
+>0     ubyte   0xf5    Prologue multi-volumen partition
+>0     ubyte   0xf6    reserved
+>0     ubyte   0xf9    pCache: ext2/ext3 persistent cache
+>0     ubyte   0xfa    Bochs x86 emulator
+>0     ubyte   0xfb    VMware File System
+>0     ubyte   0xfc    VMware Swap
+>0     ubyte   0xfd    Linux RAID partition persistent sb
+>0     ubyte   0xfe    LANstep or IBM PS/2 IML
+>0     ubyte   0xff    Xenix Bad Block Table
+
+0      string  \366\366\366\366        PC formatted floppy with no filesystem
+# Sun disk labels
+# From /usr/include/sun/dklabel.h:
+0774   beshort         0xdabe
+# modified by Joerg Jenderek, because original test
+# succeeds for Cabinet archive dao360.dl_ with negative blocks
+>0770  long            >0              Sun disk label
+>>0    string          x               '%s
+>>>31  string          >\0             \b%s
+>>>>63 string          >\0             \b%s
+>>>>>95        string          >\0             \b%s
+>>0    string          x               \b'
+>>0734 short           >0              %d rpm,
+>>0736 short           >0              %d phys cys,
+>>0740 short           >0              %d alts/cyl,
+>>0746 short           >0              %d interleave,
+>>0750 short           >0              %d data cyls,
+>>0752 short           >0              %d alt cyls,
+>>0754 short           >0              %d heads/partition,
+>>0756 short           >0              %d sectors/track,
+>>0764 long            >0              start cyl %d,
+>>0770 long            x               %d blocks
+# Is there a boot block written 1 sector in?
+>512    belong&077777777       0600407 \b, boot block present
+
+# Joerg Jenderek: Smart Boot Manager backup file is 25 (MSDOS) or 41 (LINUX) byte header + first sectors of disk
+# (http://btmgr.sourceforge.net/docs/user-guide-3.html)
+0              string  SBMBAKUP_       Smart Boot Manager backup file
+>9             string  x               \b, version %-5.5s
+>>14           string  =_
+>>>15          string  x               %-.1s
+>>>>16         string  =_              \b.
+>>>>>17                string  x               \b%-.1s
+>>>>>>18       string  =_              \b.
+>>>>>>>19      string  x               \b%-.1s
+>>>22          ubyte   0
+>>>>21         ubyte   x               \b, from drive 0x%x
+>>>22          ubyte   >0
+>>>>21         string  x               \b, from drive %s
+>>>535         search/17       \x55\xAA
+>>>>&-512      indirect        x       \b; contains
+
+# updated by Joerg Jenderek at Nov 2012
+# DOS Emulator image is 128 byte, null right padded header + harddisc image
+0      string  DOSEMU\0
+>0x27E leshort 0xAA55
+#offset is 128
+>>19   ubyte   128
+>>>(19.b-1)    ubyte   0x0     DOS Emulator image
+>>>>7  ulelong >0              \b, %u heads
+>>>>11 ulelong >0              \b, %d sectors/track
+>>>>15 ulelong >0              \b, %d cylinders
+>>>>128        indirect        x       \b; contains
+
+# added by Joerg Jenderek at Nov 2012
+# http://www.thenakedpc.com/articles/v04/08/0408-05.html
+# Symantec (Peter Norton) Image.dat file consists of variable header, bootrecord, part of FAT and root directory data
+0      string  PNCIHISK\0              Norton Utilities disc image data
+# real x86 boot sector with jump instruction
+>509   search/1026     \x55\xAA\xeb
+>>&-1  indirect        x               \b; contains
+# http://file-extension.net/seeker/file_extension_dat
+0      string  PNCIUNDO                Norton Disk Doctor UnDo file
+#
+
+# DOS/MBR boot sector updated by Joerg Jenderek at Sep 2007,May 2011,2013
+# for any allowed sector sizes
+30             search/481      \x55\xAA
+# to display DOS/MBR boot sector (40) before old one (strength=50+21),Syslinux bootloader (71),SYSLINUX MBR (37+36),NetBSD mbr (110),AdvanceMAME mbr (111)
+# DOS BPB information (70) and after DOS floppy (120) like in previous file version
+!:strength +65
+# for sector sizes < 512 Bytes
+>11            uleshort        <512
+>>(11.s-2)     uleshort        0xAA55          DOS/MBR boot sector
+# for sector sizes with 512 or more Bytes
+>0x1FE         leshort         0xAA55          DOS/MBR boot sector
+
+# keep old DOS/MBR boot sector as dummy for mbr and bootloader displaying
+# only for sector sizes with 512 or more Bytes
+0x1FE          leshort         0xAA55          DOS/MBR boot sector
+#
+# to display information (50) before DOS BPB (strength=70) and after DOS floppy (120) like in old file version
+!:strength +65
+>2             string          OSBS            OS/BS MBR
+# added by Joerg Jenderek at Feb 2013 according to https://thestarman.pcministry.com/asm/mbr/
+# and https://en.wikipedia.org/wiki/Master_Boot_Record
+# test for nearly all MS-DOS Master Boot Record initial program loader (IPL) is now done by
+# characteristic assembler instructions: xor ax,ax;mov ss,ax;mov sp,7c00
+>0     search/2        \x33\xc0\x8e\xd0\xbc\x00\x7c    MS-MBR
+# Microsoft Windows 95A and early ( https://thestarman.pcministry.com/asm/mbr/STDMBR.htm )
+# assembler instructions: mov si,sp;push ax;pop es;push ax;pop ds;sti;cld
+>>8    ubequad         0x8bf45007501ffbfc
+# https://thestarman.pcministry.com/asm/mbr/200MBR.htm
+>>>0x16        ubyte           0xF3                            \b,DOS 2
+>>>>219        regex           Author\ -\                      Author:
+# found "David Litton" , "A Pehrsson  "
+>>>>>&0        string          x                               "%s"
+>>>0x16        ubyte           0xF2
+# NEC MS-DOS 3.30 Rev. 3 . See https://thestarman.pcministry.com/asm/mbr/DOS33MBR.htm
+# assembler instructions: mov di,077c;cmp word ptrl[di],a55a;jnz
+>>>>0x22       ubequad 0xbf7c07813d5aa575              \b,NEC 3.3
+# version MS-DOS 3.30 til MS-Windows 95A (WinVer=4.00.1111)
+>>>>0x22       default x                               \b,D0S version 3.3-7.0
+# error messages are printed by assembler instructions: mov si,06nn;...;int 10 (0xBEnn06;...)
+# where nn is string offset varying for different languages
+# "Invalid partition table"                            nn=0x8b for english version
+>>>>>(0x49.b)  string          Invalid\ partition\ table               english
+>>>>>(0x49.b)  string          Ung\201ltige\ Partitionstabelle         german
+>>>>>(0x49.b)  string          Table\ de\ partition\ invalide          french
+>>>>>(0x49.b)  string          Tabela\ de\ parti\207ao\ inv\240lida    portuguese
+>>>>>(0x49.b)  string          Tabla\ de\ partici\242n\ no\ v\240lida  spanish
+>>>>>(0x49.b)  string          Tavola\ delle\ partizioni\ non\ valida  italian
+>>>>>0x49      ubyte           >0                      at offset 0x%x
+>>>>>>(0x49.b) string          >\0                     "%s"
+# "Error loading operating system"                     nn=0xa3 for english version
+# "Fehler beim Laden des Betriebssystems"              nn=0xa7 for german version
+# "Erreur en chargeant syst\212me d'exploitation"      nn=0xa7 for french version
+# "Erro na inicializa\207ao do sistema operacional"    nn=0xa7 for portuguese Brazilian version
+# "Error al cargar sistema operativo"                  nn=0xa8 for spanish version
+# "Errore durante il caricamento del sistema operativo"        nn=0xae for italian version
+>>>>>0x74      ubyte           >0                      at offset 0x%x
+>>>>>>(0x74.b) string          >\0                     "%s"
+# "Missing operating system"                           nn=0xc2 for english version
+# "Betriebssystem fehlt"                               nn=0xcd for german version
+# "Syst\212me d'exploitation absent"                   nn=0xd2 for french version
+# "Sistema operacional nao encontrado"                 nn=0xd4 for portuguese Brazilian version
+# "Falta sistema operativo"                            nn=0xca for spanish version
+# "Sistema operativo mancante"                         nn=0xe2 for italian version
+>>>>>0x79      ubyte           >0                      at offset 0x%x
+>>>>>>(0x79.b) string          >\0                     "%s"
+# Microsoft Windows 95B to XP (https://thestarman.pcministry.com/asm/mbr/95BMEMBR.htm)
+# assembler instructions: push ax;pop es;push  ax;pop ds;cld;mov si,7c1b
+>>8    ubequad         0x5007501ffcbe1b7c
+# assembler instructions: rep;movsb;retf;mov si,07be;mov cl,04
+>>>24          ubequad 0xf3a4cbbebe07b104              9M
+# "Invalid partition table"                            nn=0x10F for english version
+# "Ung\201ltige Partitionstabelle"                             nn=0x10F for german version
+# "Table de partition erron\202e"                              nn=0x10F for french version
+# "\216\257\245\340\240\346\250\256\255\255\240\357 \341\250\341\342\245\254\240 \255\245 \255\240\251\244\245\255\240"        nn=0x10F for russian version
+>>>>(0x3C.b+0x0FF)     string  Invalid\ partition\ table               english
+>>>>(0x3C.b+0x0FF)     string  Ung\201ltige\ Partitionstabelle         german
+>>>>(0x3C.b+0x0FF)     string  Table\ de\ partition\ erron\202e        french
+>>>>(0x3C.b+0x0FF)     string  \215\245\257\340\240\242\250\253\354\255\240\357\ \342\240\241\253\250\346\240  russian
+>>>>0x3C               ubyte   x                       at offset 0x%x+0xFF
+>>>>(0x3C.b+0x0FF)     string  >\0                     "%s"
+# "Error loading operating system"                     nn=0x127 for english version
+# "Fehler beim Laden des Betriebssystems"              nn=0x12b for german version
+# "Erreur lors du chargement du syst\212me d'exploitation"     nn=0x12a for french version
+# "\216\350\250\241\252\240 \257\340\250 \247\240\243\340\343\247\252\245 \256\257\245\340\240\346\250\256\255\255\256\251 \341\250\341\342\245\254\353"       nn=0x12d for russian version
+>>>>0xBD               ubyte   x                       at offset 0x1%x
+>>>>(0xBD.b+0x100)     string  >\0                     "%s"
+# "Missing operating system"                           nn=0x146 for english version
+# "Betriebssystem fehlt"                               nn=0x151 for german version
+# "Syst\212me d'exploitation manquant"                 nn=0x15e for french version
+# "\216\257\245\340\240\346\250\256\255\255\240\357 \341\250\341\342\245\254\240 \255\245 \255\240\251\244\245\255\240"        nn=0x156 for russian version
+>>>>0xA9               ubyte   x                       at offset 0x1%x
+>>>>(0xA9.b+0x100)     string  >\0                     "%s"
+# https://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm
+# assembler instructions: rep;movsb;retf;mov BP,07be;mov cl,04
+>>>24          ubequad 0xf3a4cbbdbe07b104              XP
+# where xxyyzz are lower bits from offsets of error messages varying for different languages
+>>>>0x1B4      ubelong&0x00FFFFFF      0x002c4463      english
+>>>>0x1B4      ubelong&0x00FFFFFF      0x002c486e      german
+# "Invalid partition table"                            xx=0x12C for english version
+# "Ung\201ltige Partitionstabelle"                             xx=0x12C for german version
+>>>>0x1b5      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b5.b+0x100)    string  >\0                     "%s"
+# "Error loading operating system"                     yy=0x144 for english version
+# "Fehler beim Laden des Betriebssystems"              yy=0x148 for german version
+>>>>0x1b6      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b6.b+0x100)    string  >\0                     "%s"
+# "Missing operating system"                           zz=0x163 for english version
+# "Betriebssystem nicht vorhanden"                     zz=0x16e for german version
+>>>>0x1b7      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b7.b+0x100)    string  >\0                     "%s"
+# Microsoft Windows Vista or 7
+# assembler instructions: ..;mov ds,ax;mov si,7c00;mov di,..00
+>>8    ubequad         0xc08ed8be007cbf00
+# Microsoft Windows Vista (https://thestarman.pcministry.com/asm/mbr/VistaMBR.htm)
+# assembler instructions: jnz 0729;cmp ebx,"TCPA"
+>>>0xEC                ubequad 0x753b6681fb544350              Vista
+# where xxyyzz are lower bits from offsets of error messages varying for different languages
+>>>>0x1B4      ubelong&0x00FFFFFF      0x00627a99      english
+#>>>>0x1B4     ubelong&0x00FFFFFF      ?               german
+# "Invalid partition table"                            xx=0x162 for english version
+# "Ung\201ltige Partitionstabelle"                             xx=0x1?? for german version
+>>>>0x1b5      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b5.b+0x100)    string  >\0                     "%s"
+# "Error loading operating system"                     yy=0x17a for english version
+# "Fehler beim Laden des Betriebssystems"              yy= 0x1?? for german version
+>>>>0x1b6      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b6.b+0x100)    string  >\0                     "%s"
+# "Missing operating system"                           zz=0x199 for english version
+# "Betriebssystem nicht vorhanden"                     zz=0x1?? for german version
+>>>>0x1b7      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b7.b+0x100)    string  >\0                     "%s"
+# Microsoft Windows 7 (https://thestarman.pcministry.com/asm/mbr/W7MBR.htm)
+# assembler instructions: cmp ebx,"TCPA";cmp
+>>>0xEC                ubequad 0x6681fb5443504175              Windows 7
+# where xxyyzz are lower bits from offsets of error messages varying for different languages
+>>>>0x1B4      ubelong&0x00FFFFFF      0x00637b9a      english
+#>>>>0x1B4     ubelong&0x00FFFFFF      ?               german
+# "Invalid partition table"                            xx=0x163 for english version
+# "Ung\201ltige Partitionstabelle"                             xx=0x1?? for german version
+>>>>0x1b5      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b5.b+0x100)    string  >\0                     "%s"
+# "Error loading operating system"                     yy=0x17b for english version
+# "Fehler beim Laden des Betriebssystems"              yy=0x1?? for german version
+>>>>0x1b6      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b6.b+0x100)    string  >\0                     "%s"
+# "Missing operating system"                           zz=0x19a for english version
+# "Betriebssystem nicht vorhanden"                     zz=0x1?? for german version
+>>>>0x1b7      ubyte           >0                      at offset 0x1%x
+>>>>(0x1b7.b+0x100)    string  >\0                     "%s"
+# https://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm#DiskSigs
+# https://en.wikipedia.org/wiki/MBR_disk_signature#ID
+>>0x1b8        ulelong         >0                              \b, disk signature 0x%-.4x
+# driveID/timestamp for Win 95B,98,98SE and ME. See https://thestarman.pcministry.com/asm/mbr/mystery.htm
+>>0xDA uleshort                0
+>>>0xDC        ulelong         >0                      \b, created
+# physical drive number (0x80-0xFF) when the Windows wrote that byte to the drive
+>>>>0xDC       ubyte           x                       with driveID 0x%x
+# hours, minutes and seconds
+>>>>0xDf       ubyte           x                       at %x
+>>>>0xDe       ubyte           x                       \b:%x
+>>>>0xDd       ubyte           x                       \b:%x
+# special case for Microsoft MS-DOS 3.21 spanish
+# assembler instructions: cli;mov $0x30,%ax;mov %ax,%ss;mov
+>0     ubequad         0xfab830008ed0bc00
+# assembler instructions: $0x1f00,%sp;mov $0x80cb,%di;add %cl,(%bx,%si);in (%dx),%ax;mov
+>>8    ubequad         0x1fbfcb800008ed8               MS-MBR,D0S version 3.21 spanish
+# Microsoft MBR IPL end
+
+# dr-dos with some upper-, lowercase variants
+>0x9D  string  Invalid\ partition\ table$
+>>181  string  No\ Operating\ System$
+>>>201 string  Operating\ System\ load\ error$ \b, DR-DOS MBR, Version 7.01 to 7.03
+>0x9D  string  Invalid\ partition\ table$
+>>181  string  No\ operating\ system$
+>>>201 string  Operating\ system\ load\ error$ \b, DR-DOS MBR, Version 7.01 to 7.03
+>342   string  Invalid\ partition\ table$
+>>366  string  No\ operating\ system$
+>>>386 string  Operating\ system\ load\ error$ \b, DR-DOS MBR, version 7.01 to 7.03
+>295   string  NEWLDR\0
+>>302  string  Bad\ PT\ $
+>>>310 string  No\ OS\ $
+>>>>317        string  OS\ load\ err$
+>>>>>329       string  Moved\ or\ missing\ IBMBIO.LDR\n\r
+>>>>>>358      string  Press\ any\ key\ to\ continue.\n\r$
+>>>>>>>387     string  Copyright\ (c)\ 1984,1998
+>>>>>>>>411    string  Caldera\ Inc.\0         \b, DR-DOS MBR (IBMBIO.LDR)
+#
+# tests for different MS-DOS Master Boot Records (MBR) moved and merged
+#
+#>0x145        string  Default:\ F                             \b, FREE-DOS MBR
+#>0x14B        string  Default:\ F                             \b, FREE-DOS 1.0 MBR
+>0x145 search/7        Default:\ F                     \b, FREE-DOS MBR
+#>>313         string  F0\ .\ .\ .
+#>>>322                string  disk\ 1
+#>>>>382       string  FAT3
+>64    string  no\ active\ partition\ found
+>>96   string  read\ error\ while\ reading\ drive      \b, FREE-DOS Beta 0.9 MBR
+# Ranish Partition Manager http://www.ranish.com/part/
+>387   search/4        \0\ Error!\r
+>>378  search/7        Virus!
+>>>397 search/4        Booting\040
+>>>>408        search/4        HD1/\0                          \b, Ranish MBR (
+>>>>>416       string  Writing\ changes...             \b2.37
+>>>>>>438      ubyte           x                       \b,0x%x dots
+>>>>>>440      ubyte           >0                      \b,virus check
+>>>>>>441      ubyte           >0                      \b,partition %c
+#2.38,2.42,2.44
+>>>>>416       string  !Writing\ changes...            \b
+>>>>>>418      ubyte   1                               \bvirus check,
+>>>>>>419      ubyte   x                               \b0x%x seconds
+>>>>>>420      ubyte&0x0F      >0                      \b,partition
+>>>>>>>420     ubyte&0x0F      <5                      \b %x
+>>>>>>>420     ubyte&0x0F      0Xf                     \b ask
+>>>>>420       ubyte           x                       \b)
+#
+# SYSLINUX MBR moved
+# https://www.acronis.de/
+>362   string  MBR\ Error\ \0\r
+>>376  string  ress\ any\ key\ to\040
+>>>392 string  boot\ from\ floppy...\0                 \b, Acronis MBR
+# added by Joerg Jenderek
+# https://www.visopsys.org/
+# https://partitionlogic.org.uk/
+>309   string  No\ bootable\ partition\ found\r
+>>339  string  I/O\ Error\ reading\ boot\ sector\r     \b, Visopsys MBR
+>349   string  No\ bootable\ partition\ found\r
+>>379  string  I/O\ Error\ reading\ boot\ sector\r     \b, simple Visopsys MBR
+# bootloader, bootmanager
+>0x40  string  SBML
+# label with 11 characters of FAT 12 bit filesystem
+>>43   string  SMART\ BTMGR
+>>>430 string  SBMK\ Bad!\r                    \b, Smart Boot Manager
+# OEM-ID not always "SBM"
+#>>>>3 strings SBM
+>>>>6  string  >\0                             \b, version %s
+>382   string  XOSLLOADXCF                     \b, eXtended Operating System Loader
+>6     string  LILO                            \b, LInux i386 boot LOader
+>>120  string  LILO                            \b, version 22.3.4 SuSe
+>>172  string  LILO                            \b, version 22.5.8 Debian
+# updated by Joerg Jenderek at Oct 2008
+# variables according to grub-0.97/stage1/stage1.S or
+# https://www.gnu.org/software/grub/manual/grub.html#Embedded-data
+# usual values are marked with comments to get only informations of strange GRUB loaders
+>342           search/60       \0Geom\0
+#>0            ulelong         x               %x=0x009048EB , 0x2a9048EB  0
+>>0x41         ubyte           <2
+>>>0x3E                ubyte           >2              \b; GRand Unified Bootloader
+# 0x3 for 0.5.95,0.93,0.94,0.96 0x4 for 1.90
+>>>>0x3E       ubyte           x               \b, stage1 version 0x%x
+#If it is 0xFF, use a drive passed by BIOS
+>>>>0x40       ubyte           <0xFF           \b, boot drive 0x%x
+# in most case 0,1,0x2e for GRUB 0.5.95
+>>>>0x41       ubyte           >0              \b, LBA flag 0x%x
+>>>>0x42       uleshort        <0x8000         \b, stage2 address 0x%x
+#>>>>0x42      uleshort        =0x8000         \b, stage2 address 0x%x (usual)
+>>>>0x42       uleshort        >0x8000         \b, stage2 address 0x%x
+#>>>>0x44      ulelong         =1              \b, 1st sector stage2 0x%x (default)
+>>>>0x44       ulelong         >1              \b, 1st sector stage2 0x%x
+>>>>0x48       uleshort        <0x800          \b, stage2 segment 0x%x
+#>>>>0x48      uleshort        =0x800          \b, stage2 segment 0x%x (usual)
+>>>>0x48       uleshort        >0x800          \b, stage2 segment 0x%x
+>>>>402                string  Geom\0Hard\ Disk\0Read\0\ Error\0
+>>>>>394       string  stage1                  \b, GRUB version 0.5.95
+>>>>382                string  Geom\0Hard\ Disk\0Read\0\ Error\0
+>>>>>376       string  GRUB\ \0                \b, GRUB version 0.93 or 1.94
+>>>>383                string  Geom\0Hard\ Disk\0Read\0\ Error\0
+>>>>>377       string  GRUB\ \0                \b, GRUB version 0.94
+>>>>385                string  Geom\0Hard\ Disk\0Read\0\ Error\0
+>>>>>379       string  GRUB\ \0                \b, GRUB version 0.95 or 0.96
+>>>>391                string  Geom\0Hard\ Disk\0Read\0\ Error\0
+>>>>>385       string  GRUB\ \0                \b, GRUB version 0.97
+# unknown version
+>>>343         string  Geom\0Read\0\ Error\0
+>>>>321                string  Loading\ stage1.5       \b, GRUB version x.y
+>>>380         string  Geom\0Hard\ Disk\0Read\0\ Error\0
+>>>>374                string  GRUB\ \0                \b, GRUB version n.m
+# SYSLINUX bootloader moved
+>395   string  chksum\0\ ERROR!\0              \b, Gujin bootloader
+# http://www.bcdwb.de/bcdw/index_e.htm
+>3     string  BCDL
+>>498  string  BCDL\ \ \ \ BIN                 \b, Bootable CD Loader (1.50Z)
+# mbr partition table entries updated by Joerg Jenderek at Sep 2013
+# skip Norton Utilities disc image data
+>3             string          !IHISK
+# skip Linux style boot sector starting with assember instructions mov 0x7c0,ax;
+>>0            belong          !0xb8c0078e
+# not Linux kernel
+>>>514         string          !HdrS
+# not BeOS
+>>>>422                string          !Be\ Boot\ Loader
+# jump over BPB instruction implies DOS bootsector or AdvanceMAME mbr
+>>>>>0         ubelong&0xFD000000      =0xE9000000
+# AdvanceMAME mbr
+>>>>>>(1.b+2)  ubequad         0xfa31c08ed88ec08e
+>>>>>>>446     use             partition-table
+# mbr, Norton Utilities disc image data, or 2nd,etc. sector of x86 bootloader
+>>>>>0         ubelong&0xFD000000      !0xE9000000
+# skip FSInfosector
+>>>>>>0                string          !RRaA
+# skip 3rd sector of MS x86 bootloader with assember instructions cli;MOVZX EAX,BYTE PTR [BP+10];MOV ECX,
+# https://thestarman.pcministry.com/asm/mbr/MSWIN41.htm
+>>>>>>>0       ubequad         !0xfa660fb64610668b
+# skip 13rd sector of MS x86 bootloader
+>>>>>>>>0      ubequad         !0x660fb64610668b4e
+# skip sector starting with DOS new line
+>>>>>>>>>0     string          !\r\n
+# allowed active flag 0,80h-FFh
+>>>>>>>>>>446  ubyte           0
+>>>>>>>>>>>446 use             partition-table
+>>>>>>>>>>446  ubyte           >0x7F
+>>>>>>>>>>>446 use             partition-table
+# TODO: test for extended bootrecord (ebr) moved and merged with mbr partition table entries
+# mbr partition table entries end
+# https://www.acronis.de/
+#FAT label=ACRONIS\ SZ
+#OEM-ID=BOOTWIZ0
+>442   string  Non-system\ disk,\040
+>>459  string  press\ any\ key...\x7\0         \b, Acronis Startup Recovery Loader
+# updated by Joerg Jenderek at Nov 2012, Sep 2013
+# DOS names like F11.SYS or BOOTWIZ.SYS are 8 right space padded bytes+3 bytes
+# display 1 space
+>>>447 ubyte   x               \b
+>>>477 use     DOS-filename
+#
+>185   string  FDBOOT\ Version\040
+>>204  string  \rNo\ Systemdisk.\040
+>>>220 string  Booting\ from\ harddisk.\n\r
+>>>245 string  Cannot\ load\ from\ harddisk.\n\r
+>>>>273 string Insert\ Systemdisk\040
+>>>>>291 string and\ press\ any\ key.\n\r              \b, FDBOOT harddisk Bootloader
+>>>>>>200 string       >\0                             \b, version %-3s
+>242   string  Bootsector\ from\ C.H.\ Hochst\204
+# http://freecode.com/projects/dosfstools      dosfstools-n.m/src/mkdosfs.c
+# updated by Joerg Jenderek at Nov 2012. Use search directive with offset instead of string
+# skip name "C.H. Hochstaetter" partly because it is sometimes written without umlaut
+>242   search/127      Bootsector\ from\ C.H.\ Hochst
+>>278  search/127      No\ Systemdisk.\ Booting\ from\ harddisk
+# followed by variants with point,CR-NL or NL-CR
+>>>208 search/261      Cannot\ load\ from\ harddisk.
+# followed by variants CR-NL or NL-CR
+>>>>236        search/235      Insert\ Systemdisk\ and\ press\ any\ key.
+# followed by variants with point,CR-NL or NL-CR
+>>>>>180       search/96       Disk\ formatted\ with\ WinImage\        \b, WinImage harddisk Bootloader
+# followed by string like "6.50 (c) 1993-2004 Gilles Vollant"
+>>>>>>&0       string          x                                       \b, version %-4.4s
+>(1.b+2)       ubyte           0xe
+>>(1.b+3)      ubyte           0x1f
+>>>(1.b+4)     ubyte           0xbe
+# message offset found at (1.b+5) is 0x77 for FAT32 or 0x5b for others
+>>>>(1.b+5)    ubyte&0xd3      0x53
+>>>>>(1.b+6)   ubyte           0x7c
+# assembler instructions: lodsb;and al,al;jz 0xb;push si;mov ah,
+>>>>>>(1.b+7)  ubyte           0xac
+>>>>>>>(1.b+8) ubyte           0x22
+>>>>>>>>(1.b+9)        ubyte           0xc0
+>>>>>>>>>(1.b+10)      ubyte   0x74
+>>>>>>>>>>(1.b+11)     ubyte   0x0b
+>>>>>>>>>>>(1.b+12)    ubyte   0x56
+>>>>>>>>>>>>(1.b+13)   ubyte   0xb4                    \b, mkdosfs boot message display
+# FAT1X version
+>>>>>>>>>>>>>(1.b+5)   ubyte   0x5b
+>>>>>>>>>>>>>>0x5b     string  >\0                     "%-s"
+# FAT32 version
+>>>>>>>>>>>>>(1.b+5)   ubyte   0x77
+>>>>>>>>>>>>>>0x77     string  >\0                     "%-s"
+>214   string  Please\ try\ to\ install\ FreeDOS\      \b, DOS Emulator boot message display
+#>>244 string  from\ dosemu-freedos-*-bin.tgz\r
+#>>>170        string  Sorry,\ could\ not\ load\ an\040
+#>>>>195       string  operating\ system.\r\n
+#
+>103   string  This\ is\ not\ a\ bootable\ disk.\040
+>>132  string  Please\ insert\ a\ bootable\040
+>>>157 string  floppy\ and\r\n
+>>>>169        string  press\ any\ key\ to\ try\ again...\r    \b, FREE-DOS message display
+#
+>66    string  Solaris\ Boot\ Sector
+>>99   string  Incomplete\ MDBoot\ load.
+>>>89  string  Version                                 \b, Sun Solaris Bootloader
+>>>>97 byte    x                                       version %c
+#
+>408   string  OS/2\ !!\ SYS01475\r\0
+>>429  string  OS/2\ !!\ SYS02025\r\0
+>>>450 string  OS/2\ !!\ SYS02027\r\0
+>>>469 string  OS2BOOT\ \ \ \                          \b, IBM OS/2 Warp bootloader
+#
+>409   string  OS/2\ !!\ SYS01475\r\0
+>>430  string  OS/2\ !!\ SYS02025\r\0
+>>>451 string  OS/2\ !!\ SYS02027\r\0
+>>>470 string  OS2BOOT\ \ \ \                          \b, IBM OS/2 Warp Bootloader
+>112           string  This\ disk\ is\ not\ bootable\r
+>>142          string  If\ you\ wish\ to\ make\ it\ bootable
+>>>176         string  run\ the\ DOS\ program\ SYS\040
+>>>200         string  after\ the\r
+>>>>216                string  system\ has\ been\ loaded\r\n
+>>>>>242       string  Please\ insert\ a\ DOS\ diskette\040
+>>>>>271       string  into\r\n\ the\ drive\ and\040
+>>>>>>292      string  strike\ any\ key...\0           \b, IBM OS/2 Warp message display
+# XP
+>430   string  NTLDR\ is\ missing\xFF\r\n
+>>449  string  Disk\ error\xFF\r\n
+>>>462 string  Press\ any\ key\ to\ restart\r          \b, Microsoft Windows XP Bootloader
+# DOS names like NTLDR,CMLDR,$LDR$ are 8 right space padded bytes+3 bytes
+>>>>417                ubyte&0xDF      >0
+>>>>>417       string          x                       %-.5s
+>>>>>>422      ubyte&0xDF      >0
+>>>>>>>422     string          x                       \b%-.3s
+>>>>>425       ubyte&0xDF      >0
+>>>>>>425      string          >\                      \b.%-.3s
+#
+>>>>371                ubyte           >0x20
+>>>>>368       ubyte&0xDF      >0
+>>>>>>368      string          x                       %-.5s
+>>>>>>>373     ubyte&0xDF      >0
+>>>>>>>>373    string          x                       \b%-.3s
+>>>>>>376      ubyte&0xDF      >0
+>>>>>>>376     string          x                       \b.%-.3s
+#
+>430   string  NTLDR\ nicht\ gefunden\xFF\r\n
+>>453  string  Datentr\204gerfehler\xFF\r\n
+>>>473 string  Neustart\ mit\ beliebiger\ Taste\r      \b, Microsoft Windows XP Bootloader (german)
+>>>>417                ubyte&0xDF      >0
+>>>>>417       string          x                       %-.5s
+>>>>>>422      ubyte&0xDF      >0
+>>>>>>>422     string          x                       \b%-.3s
+>>>>>425       ubyte&0xDF      >0
+>>>>>>425      string          >\                      \b.%-.3s
+# offset variant
+>>>>379        string  \0
+>>>>>368       ubyte&0xDF      >0
+>>>>>>368      string          x                       %-.5s
+>>>>>>>373     ubyte&0xDF      >0
+>>>>>>>>373    string          x                       \b%-.3s
+#
+>430   string  NTLDR\ fehlt\xFF\r\n
+>>444  string  Datentr\204gerfehler\xFF\r\n
+>>>464 string  Neustart\ mit\ beliebiger\ Taste\r      \b, Microsoft Windows XP Bootloader (2.german)
+>>>>417                ubyte&0xDF      >0
+>>>>>417       string          x                       %-.5s
+>>>>>>422      ubyte&0xDF      >0
+>>>>>>>422     string          x                       \b%-.3s
+>>>>>425       ubyte&0xDF      >0
+>>>>>>425      string          >\                      \b.%-.3s
+# variant
+>>>>371                ubyte           >0x20
+>>>>>368       ubyte&0xDF      >0
+>>>>>>368      string          x                       %-.5s
+>>>>>>>373     ubyte&0xDF      >0
+>>>>>>>>373    string          x                       \b%-.3s
+>>>>>>376      ubyte&0xDF      >0
+>>>>>>>376     string          x                       \b.%-.3s
+#
+>430   string  NTLDR\ fehlt\xFF\r\n
+>>444  string  Medienfehler\xFF\r\n
+>>>459 string  Neustart:\ Taste\ dr\201cken\r          \b, Microsoft Windows XP Bootloader (3.german)
+>>>>371                ubyte           >0x20
+>>>>>368       ubyte&0xDF      >0
+>>>>>>368      string          x                       %-.5s
+>>>>>>>373     ubyte&0xDF      >0
+>>>>>>>>373    string          x                       \b%-.3s
+>>>>>>376      ubyte&0xDF      >0
+>>>>>>>376     string          x                       \b.%-.3s
+# variant
+>>>>417                ubyte&0xDF      >0
+>>>>>417       string          x                       %-.5s
+>>>>>>422      ubyte&0xDF      >0
+>>>>>>>422     string          x                       \b%-.3s
+>>>>>425       ubyte&0xDF      >0
+>>>>>>425      string          >\                      \b.%-.3s
+#
+>430   string  Datentr\204ger\ entfernen\xFF\r\n
+>>454  string  Medienfehler\xFF\r\n
+>>>469 string  Neustart:\ Taste\ dr\201cken\r          \b, Microsoft Windows XP Bootloader (4.german)
+>>>>379                string          \0
+>>>>>368       ubyte&0xDF      >0
+>>>>>>368      string          x                       %-.5s
+>>>>>>>373     ubyte&0xDF      >0
+>>>>>>>>373    string          x                       \b%-.3s
+>>>>>>376      ubyte&0xDF      >0
+>>>>>>>376     string          x                       \b.%-.3s
+# variant
+>>>>417                ubyte&0xDF      >0
+>>>>>417       string          x                       %-.5s
+>>>>>>422      ubyte&0xDF      >0
+>>>>>>>422     string          x                       \b%-.3s
+>>>>>425       ubyte&0xDF      >0
+>>>>>>425      string          >\                      \b.%-.3s
+#
+
+#>3    string  NTFS\ \ \ \040
+>389   string  Fehler\ beim\ Lesen\040
+>>407  string  des\ Datentr\204gers
+>>>426 string  NTLDR\ fehlt
+>>>>440        string  NTLDR\ ist\ komprimiert
+>>>>>464 string        Neustart\ mit\ Strg+Alt+Entf\r          \b, Microsoft Windows XP Bootloader NTFS (german)
+#>3    string  NTFS\ \ \ \040
+>313   string  A\ disk\ read\ error\ occurred.\r
+>>345  string  A\ kernel\ file\ is\ missing\040
+>>>370 string  from\ the\ disk.\r
+>>>>484        string  NTLDR\ is\ compressed
+>>>>>429 string        Insert\ a\ system\ diskette\040
+>>>>>>454 string and\ restart\r\nthe\ system.\r                \b, Microsoft Windows XP Bootloader NTFS
+# DOS loader variants different languages,offsets
+>472   ubyte&0xDF      >0
+>>389  string  Invalid\ system\ disk\xFF\r\n
+>>>411 string  Disk\ I/O\ error
+>>>>428        string  Replace\ the\ disk,\ and\040
+>>>>>455 string        press\ any\ key                         \b, Microsoft Windows 98 Bootloader
+#IO.SYS
+>>>>>>472      ubyte&0xDF      >0
+>>>>>>>472     string          x                       \b %-.2s
+>>>>>>>>474    ubyte&0xDF      >0
+>>>>>>>>>474   string          x                       \b%-.5s
+>>>>>>>>>>479  ubyte&0xDF      >0
+>>>>>>>>>>>479 string          x                       \b%-.1s
+>>>>>>>480     ubyte&0xDF      >0
+>>>>>>>>480    string          x                       \b.%-.3s
+#MSDOS.SYS
+>>>>>>>483     ubyte&0xDF      >0                      \b+
+>>>>>>>>483    string          x                       \b%-.5s
+>>>>>>>>>488   ubyte&0xDF      >0
+>>>>>>>>>>488  string          x                       \b%-.3s
+>>>>>>>>491    ubyte&0xDF      >0
+>>>>>>>>>491   string          x                       \b.%-.3s
+#
+>>390  string  Invalid\ system\ disk\xFF\r\n
+>>>412 string  Disk\ I/O\ error\xFF\r\n
+>>>>429        string  Replace\ the\ disk,\ and\040
+>>>>>451 string        then\ press\ any\ key\r                 \b, Microsoft Windows 98 Bootloader
+>>388  string  Ungueltiges\ System\ \xFF\r\n
+>>>410 string  E/A-Fehler\ \ \ \ \xFF\r\n
+>>>>427        string  Datentraeger\ wechseln\ und\040
+>>>>>453 string        Taste\ druecken\r                       \b, Microsoft Windows 95/98/ME Bootloader (german)
+#WINBOOT.SYS only not spaces (0xDF)
+>>>>>>497      ubyte&0xDF      >0
+>>>>>>>497     string          x                       %-.5s
+>>>>>>>>502    ubyte&0xDF      >0
+>>>>>>>>>502   string          x                       \b%-.1s
+>>>>>>>>>>503  ubyte&0xDF      >0
+>>>>>>>>>>>503 string          x                       \b%-.1s
+>>>>>>>>>>>>504        ubyte&0xDF      >0
+>>>>>>>>>>>>>504 string                x                       \b%-.1s
+>>>>>>505      ubyte&0xDF      >0
+>>>>>>>505     string          x                       \b.%-.3s
+#IO.SYS
+>>>>>>472      ubyte&0xDF      >0                      or
+>>>>>>>472     string          x                       \b %-.2s
+>>>>>>>>474    ubyte&0xDF      >0
+>>>>>>>>>474   string          x                       \b%-.5s
+>>>>>>>>>>479  ubyte&0xDF      >0
+>>>>>>>>>>>479 string          x                       \b%-.1s
+>>>>>>>480     ubyte&0xDF      >0
+>>>>>>>>480    string          x                       \b.%-.3s
+#MSDOS.SYS
+>>>>>>>483     ubyte&0xDF      >0                      \b+
+>>>>>>>>483    string          x                       \b%-.5s
+>>>>>>>>>488   ubyte&0xDF      >0
+>>>>>>>>>>488  string          x                       \b%-.3s
+>>>>>>>>491    ubyte&0xDF      >0
+>>>>>>>>>491   string          x                       \b.%-.3s
+#
+>>390  string  Ungueltiges\ System\ \xFF\r\n
+>>>412 string  E/A-Fehler\ \ \ \ \xFF\r\n
+>>>>429        string  Datentraeger\ wechseln\ und\040
+>>>>>455 string        Taste\ druecken\r                       \b, Microsoft Windows 95/98/ME Bootloader (German)
+#WINBOOT.SYS only not spaces (0xDF)
+>>>>>>497      ubyte&0xDF      >0
+>>>>>>>497     string          x                       %-.7s
+>>>>>>>>504    ubyte&0xDF      >0
+>>>>>>>>>504   string          x                       \b%-.1s
+>>>>>>505      ubyte&0xDF      >0
+>>>>>>>505     string          x                       \b.%-.3s
+#IO.SYS
+>>>>>>472      ubyte&0xDF      >0                      or
+>>>>>>>472     string          x                       \b %-.2s
+>>>>>>>>474    ubyte&0xDF      >0
+>>>>>>>>>474   string          x                       \b%-.6s
+>>>>>>>480     ubyte&0xDF      >0
+>>>>>>>>480    string          x                       \b.%-.3s
+#MSDOS.SYS
+>>>>>>>483     ubyte&0xDF      >0                      \b+
+>>>>>>>>483    string          x                       \b%-.5s
+>>>>>>>>>488   ubyte&0xDF      >0
+>>>>>>>>>>488  string          x                       \b%-.3s
+>>>>>>>>491    ubyte&0xDF      >0
+>>>>>>>>>491   string          x                       \b.%-.3s
+#
+>>389  string  Ungueltiges\ System\ \xFF\r\n
+>>>411 string  E/A-Fehler\ \ \ \ \xFF\r\n
+>>>>428        string  Datentraeger\ wechseln\ und\040
+>>>>>454 string        Taste\ druecken\r                       \b, Microsoft Windows 95/98/ME Bootloader (GERMAN)
+# DOS names like IO.SYS,WINBOOT.SYS,MSDOS.SYS,WINBOOT.INI are 8 right space padded bytes+3 bytes
+>>>>>>472      string          x                       %-.2s
+>>>>>>>474     ubyte&0xDF      >0
+>>>>>>>>474    string          x                       \b%-.5s
+>>>>>>>>479    ubyte&0xDF      >0
+>>>>>>>>>479   string          x                       \b%-.1s
+>>>>>>480      ubyte&0xDF      >0
+>>>>>>>480     string          x                       \b.%-.3s
+>>>>>>483      ubyte&0xDF      >0                      \b+
+>>>>>>>483     string          x                       \b%-.5s
+>>>>>>>488     ubyte&0xDF      >0
+>>>>>>>>488    string          x                       \b%-.2s
+>>>>>>>>490    ubyte&0xDF      >0
+>>>>>>>>>490   string          x                       \b%-.1s
+>>>>>>>491     ubyte&0xDF      >0
+>>>>>>>>491    string          x                       \b.%-.3s
+>479   ubyte&0xDF      >0
+>>416  string  Kein\ System\ oder\040
+>>>433 string  Laufwerksfehler
+>>>>450        string  Wechseln\ und\ Taste\ dr\201cken        \b, Microsoft DOS Bootloader (german)
+#IO.SYS
+>>>>>479       string          x                       \b %-.2s
+>>>>>>481      ubyte&0xDF      >0
+>>>>>>>481     string          x                       \b%-.6s
+>>>>>487       ubyte&0xDF      >0
+>>>>>>487      string          x                       \b.%-.3s
+#MSDOS.SYS
+>>>>>>490      ubyte&0xDF      >0                      \b+
+>>>>>>>490     string          x                       \b%-.5s
+>>>>>>>>495    ubyte&0xDF      >0
+>>>>>>>>>495   string          x                       \b%-.3s
+>>>>>>>498     ubyte&0xDF      >0
+>>>>>>>>498    string          x                       \b.%-.3s
+#
+>376   search/41       Non-System\ disk\ or\040
+>>395  search/41       disk\ error\r
+>>>407 search/41       Replace\ and\040
+>>>>419        search/41       press\                          \b,
+>>>>419        search/41       strike\                         \b, old
+>>>>426        search/41       any\ key\ when\ ready\r         MS or PC-DOS bootloader
+#449                   Disk\ Boot\ failure\r           MS 3.21
+#466                   Boot\ Failure\r                 MS 3.30
+>>>>>468 search/18     \0
+#IO.SYS,IBMBIO.COM
+>>>>>>&0       string          x                       \b %-.2s
+>>>>>>>&-20    ubyte&0xDF      >0
+>>>>>>>>&-1    string          x                       \b%-.4s
+>>>>>>>>>&-16  ubyte&0xDF      >0
+>>>>>>>>>>&-1  string          x                       \b%-.2s
+>>>>>>&8       ubyte&0xDF      >0                      \b.
+>>>>>>>&-1     string          x                       \b%-.3s
+#MSDOS.SYS,IBMDOS.COM
+>>>>>>&11      ubyte&0xDF      >0                      \b+
+>>>>>>>&-1     string          x                       \b%-.5s
+>>>>>>>>&-6    ubyte&0xDF      >0
+>>>>>>>>>&-1   string          x                       \b%-.1s
+>>>>>>>>>>&-5  ubyte&0xDF      >0
+>>>>>>>>>>>&-1 string          x                       \b%-.2s
+>>>>>>>&7      ubyte&0xDF      >0                      \b.
+>>>>>>>>&-1    string          x                       \b%-.3s
+>441   string  Cannot\ load\ from\ harddisk.\n\r
+>>469  string  Insert\ Systemdisk\040
+>>>487 string  and\ press\ any\ key.\n\r               \b, MS (2.11) DOS bootloader
+#>43   string  \224R-LOADER\ \ SYS                     =label
+>54    string  SYS
+>>324  string  VASKK
+>>>495 string  NEWLDR\0                                \b, DR-DOS Bootloader (LOADER.SYS)
+#
+>98    string  Press\ a\ key\ to\ retry\0\r
+>>120  string  Cannot\ find\ file\ \0\r
+>>>139 string  Disk\ read\ error\0\r
+>>>>156        string  Loading\ ...\0                          \b, DR-DOS (3.41) Bootloader
+#DRBIOS.SYS
+>>>>>44                ubyte&0xDF      >0
+>>>>>>44       string          x                       \b %-.6s
+>>>>>>>50      ubyte&0xDF      >0
+>>>>>>>>50     string          x                       \b%-.2s
+>>>>>>52       ubyte&0xDF      >0
+>>>>>>>52      string          x                       \b.%-.3s
+#
+>70    string  IBMBIO\ \ COM
+>>472  string  Cannot\ load\ DOS!\040
+>>>489 string  Any\ key\ to\ retry                     \b, DR-DOS Bootloader
+>>471  string  Cannot\ load\ DOS\040
+>>487  string  press\ key\ to\ retry                   \b, Open-DOS Bootloader
+#??
+>444   string  KERNEL\ \ SYS
+>>314  string  BOOT\ error!                            \b, FREE-DOS Bootloader
+>499   string  KERNEL\ \ SYS
+>>305  string  BOOT\ err!\0                            \b, Free-DOS Bootloader
+>449   string  KERNEL\ \ SYS
+>>319  string  BOOT\ error!                            \b, FREE-DOS 0.5 Bootloader
+#
+>449   string  Loading\ FreeDOS
+>>0x1AF                ulelong         >0                      \b, FREE-DOS 0.95,1.0 Bootloader
+>>>497         ubyte&0xDF      >0
+>>>>497                string          x                       \b %-.6s
+>>>>>503       ubyte&0xDF      >0
+>>>>>>503      string          x                       \b%-.1s
+>>>>>>>504     ubyte&0xDF      >0
+>>>>>>>>504    string          x                       \b%-.1s
+>>>>505                ubyte&0xDF      >0
+>>>>>505       string          x                       \b.%-.3s
+#
+>331   string  Error!.0                                \b, FREE-DOS 1.0 bootloader
+#
+>125   string  Loading\ FreeDOS...\r
+>>311  string  BOOT\ error!\r                          \b, FREE-DOS bootloader
+>>>441         ubyte&0xDF      >0
+>>>>441                string          x                       \b %-.6s
+>>>>>447       ubyte&0xDF      >0
+>>>>>>447      string          x                       \b%-.1s
+>>>>>>>448     ubyte&0xDF      >0
+>>>>>>>>448    string          x                       \b%-.1s
+>>>>449                ubyte&0xDF      >0
+>>>>>449       string          x                       \b.%-.3s
+>124   string  FreeDOS\0
+>>331  string  \ err\0                                 \b, FREE-DOS BETa 0.9 Bootloader
+# DOS names like KERNEL.SYS,KERNEL16.SYS,KERNEL32.SYS,METAKERN.SYS are 8 right space padded bytes+3 bytes
+>>>497         ubyte&0xDF      >0
+>>>>497                string          x                       \b %-.6s
+>>>>>503       ubyte&0xDF      >0
+>>>>>>503      string          x                       \b%-.1s
+>>>>>>>504     ubyte&0xDF      >0
+>>>>>>>>504    string          x                       \b%-.1s
+>>>>505                ubyte&0xDF      >0
+>>>>>505       string          x                       \b.%-.3s
+>>333  string  \ err\0                                 \b, FREE-DOS BEta 0.9 Bootloader
+>>>497         ubyte&0xDF      >0
+>>>>497                string          x                       \b %-.6s
+>>>>>503       ubyte&0xDF      >0
+>>>>>>503      string          x                       \b%-.1s
+>>>>>>>504     ubyte&0xDF      >0
+>>>>>>>>504    string          x                       \b%-.1s
+>>>>505                ubyte&0xDF      >0
+>>>>>505       string          x                       \b.%-.3s
+>>334  string  \ err\0                                 \b, FREE-DOS Beta 0.9 Bootloader
+>>>497         ubyte&0xDF      >0
+>>>>497                string          x                       \b %-.6s
+>>>>>503       ubyte&0xDF      >0
+>>>>>>503      string          x                       \b%-.1s
+>>>>>>>504     ubyte&0xDF      >0
+>>>>>>>>504    string          x                       \b%-.1s
+>>>>505                ubyte&0xDF      >0
+>>>>>505       string          x                       \b.%-.3s
+>336   string  Error!\040
+>>343  string  Hit\ a\ key\ to\ reboot.                \b, FREE-DOS Beta 0.9sr1 Bootloader
+>>>497         ubyte&0xDF      >0
+>>>>497                string          x                       \b %-.6s
+>>>>>503       ubyte&0xDF      >0
+>>>>>>503      string          x                       \b%-.1s
+>>>>>>>504     ubyte&0xDF      >0
+>>>>>>>>504    string          x                       \b%-.1s
+>>>>505                ubyte&0xDF      >0
+>>>>>505       string          x                       \b.%-.3s
+# added by Joerg Jenderek
+# https://www.visopsys.org/
+# https://partitionlogic.org.uk/
+# OEM-ID=Visopsys
+>478           ulelong 0
+>>(1.b+326)    string  I/O\ Error\ reading\040
+>>>(1.b+344)   string  Visopsys\ loader\r
+>>>>(1.b+361)  string  Press\ any\ key\ to\ continue.\r        \b, Visopsys loader
+# http://alexfru.chat.ru/epm.html#bootprog
+>494   ubyte   >0x4D
+>>495  string  >E
+>>>495 string  <S
+#OEM-ID is not reliable
+>>>>3  string  BootProg
+# It just looks for a program file name at the root directory
+# and loads corresponding file with following execution.
+# DOS names like STARTUP.BIN,STARTUPC.COM,STARTUPE.EXE are 8 right space padded bytes+3 bytes
+>>>>499                        ubyte&0xDF      >0              \b, COM/EXE Bootloader
+>>>>>499               use             DOS-filename
+#If the boot sector fails to read any other sector,
+#it prints a very short message ("RE") to the screen and hangs the computer.
+#If the boot sector fails to find needed program in the root directory,
+#it also hangs with another message ("NF").
+>>>>>492               string          RENF            \b, FAT (12 bit)
+>>>>>495               string          RENF            \b, FAT (16 bit)
+#If the boot sector fails to read any other sector,
+#it prints a very short message ("RE") to the screen and hangs the computer.
+# x86 bootloader end
+
+# added by Joerg Jenderek at Feb 2013 according to https://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#FSINFO
+# and https://en.wikipedia.org/wiki/File_Allocation_Table#FS_Information_Sector
+>0             string          RRaA
+>>0x1E4                string          rrAa            \b, FSInfosector
+#>>0x1FC       uleshort        =0              SHOULD BE ZERO
+>>>0x1E8       ulelong         <0xffffffff     \b, %u free clusters
+>>>0x1EC       ulelong         <0xffffffff     \b, last allocated cluster %u
+
+# updated by Joerg Jenderek at Sep 2007
+>3     ubyte   0
+#no active flag
+>>446  ubyte   0
+# partition 1 not empty
+>>>450 ubyte   >0
+# partitions 3,4 empty
+>>>>482                ubyte   0
+>>>>>498       ubyte   0
+# partition 2 ID=0,5,15
+>>>>>>466      ubyte   <0x10
+>>>>>>>466     ubyte   0x05                    \b, extended partition table
+>>>>>>>466     ubyte   0x0F                    \b, extended partition table (LBA)
+>>>>>>>466     ubyte   0x0                     \b, extended partition table (last)
+
+# DOS x86 sector separated and moved from "DOS/MBR boot sector" by Joerg Jenderek at May 2011
+
+>0x200 lelong  0x82564557              \b, BSD disklabel
+
+# by Joerg Jenderek at Apr 2013
+#      Print the DOS filenames from directory entry form with 8 right space padded bytes + 3 bytes for extension
+#      like IO.SYS. MSDOS.SYS , KERNEL.SYS , DRBIO.SYS
+0      name                    DOS-filename
+# space=0x20 (00100000b) means empty
+>0                     ubyte&0xDF      >0
+>>0                    ubyte           x               \b%c
+>>>1                   ubyte&0xDF      >0
+>>>>1                  ubyte           x               \b%c
+>>>>>2                 ubyte&0xDF      >0
+>>>>>>2                        ubyte           x               \b%c
+>>>>>>>3               ubyte&0xDF      >0
+>>>>>>>>3              ubyte           x               \b%c
+>>>>>>>>>4             ubyte&0xDF      >0
+>>>>>>>>>>4            ubyte           x               \b%c
+>>>>>>>>>>>5           ubyte&0xDF      >0
+>>>>>>>>>>>>5          ubyte           x               \b%c
+>>>>>>>>>>>>>6         ubyte&0xDF      >0
+>>>>>>>>>>>>>>6                ubyte           x               \b%c
+>>>>>>>>>>>>>>>7       ubyte&0xDF      >0
+>>>>>>>>>>>>>>>>7      ubyte           x               \b%c
+# DOS filename extension
+>>8                    ubyte&0xDF      >0              \b.
+>>>8                   ubyte           x               \b%c
+>>>>9                  ubyte&0xDF      >0
+>>>>>9                 ubyte           x               \b%c
+>>>>>>10               ubyte&0xDF      >0
+>>>>>>>10              ubyte           x               \b%c
+#      Print 2 following DOS filenames from directory entry form
+#      like IO.SYS+MSDOS.SYS or ibmbio.com+ibmdos.com
+0      name                    2xDOS-filename
+# display 1 space
+>0                     ubyte           x               \b
+>0                     use             DOS-filename
+>11                    ubyte           x               \b+
+>11                    use             DOS-filename
+
+# https://en.wikipedia.org/wiki/Master_boot_record#PTE
+# display standard partition table
+0      name                            partition-table
+#>0            ubyte           x       PARTITION-TABLE
+# test and display 1st til 4th partition table entry
+>0             use                     partition-entry-test
+>16            use                     partition-entry-test
+>32            use                     partition-entry-test
+>48            use                     partition-entry-test
+#              test for entry of partition table
+0      name                            partition-entry-test
+# partition type ID > 0
+>4             ubyte           >0
+# active flag 0
+>>0            ubyte           0
+>>>0           use             partition-entry
+# active flag 0x80, 0x81, ...
+>>0            ubyte           >0x7F
+>>>0           use             partition-entry
+#              Print entry of partition table
+0      name                            partition-entry
+# partition type ID > 0
+>4             ubyte           >0      \b; partition
+>>64           leshort         0xAA55  1
+>>48           leshort         0xAA55  2
+>>32           leshort         0xAA55  3
+>>16           leshort         0xAA55  4
+>>4            ubyte           x       : ID=0x%x
+>>0            ubyte&0x80      0x80    \b, active
+>>0            ubyte           >0x80   0x%x
+>>1            ubyte           x       \b, start-CHS (
+>>1            use             partition-chs
+>>5            ubyte           x       \b), end-CHS (
+>>5            use             partition-chs
+>>8            ulelong         x       \b), startsector %u
+>>12           ulelong         x       \b, %u sectors
+#              Print cylinder,head,sector (CHS) of partition entry
+0      name                            partition-chs
+# cylinder
+>1             ubyte           x       \b0x
+>1             ubyte&0xC0      0x40    \b1
+>1             ubyte&0xC0      0x80    \b2
+>1             ubyte&0xC0      0xC0    \b3
+>2             ubyte           x       \b%x
+# head
+>0             ubyte           x       \b,%u
+# sector
+>1             ubyte&0x3F      x       \b,%u
+
+# FATX
+0              string          FATX            FATX filesystem data
+
+# romfs filesystems - Juan Cespedes <cespedes@debian.org>
+0      string          -rom1fs-        romfs filesystem, version 1
+>8     belong  x                       %d bytes,
+>16    string  x                       named %s.
+
+# netboot image - Juan Cespedes <cespedes@debian.org>
+0      lelong          0x1b031336L     Netboot image,
+>4     lelong&0xFFFFFF00       0
+>>4    lelong&0x100    0x000           mode 2
+>>4    lelong&0x100    0x100           mode 3
+>4     lelong&0xFFFFFF00       !0      unknown mode
+
+0x18b  string  OS/2    OS/2 Boot Manager
+
+# updated by Joerg Jenderek at Oct 2008 and Sep 2012
+# https://syslinux.zytor.com/iso.php
+# tested with versions 1.47,1.48,1.49,1.50,1.62,1.76,2.00,2.10;3.00,3.11,3.31,;3.70,3.71,3.73,3.75,3.80,3.82,3.84,3.86,4.01,4.03 and 4.05
+# assembler instructions: cli;jmp 0:7Cyy (yy=0x40,0x5e,0x6c,0x6e,0x77);nop;nop
+0      ulequad&0x909000007cc0eafa      0x909000007c40eafa
+>631   search/689      ISOLINUX\       isolinux Loader
+>>&0   string          x               (version %-4.4s)
+# https://syslinux.zytor.com/pxe.php
+# assembler instructions: jmp 7C05
+0      ulelong 0x007c05ea              pxelinux loader (version 2.13 or older)
+# assembler instructions: pushfd;pushad
+0      ulelong 0x60669c66              pxelinux loader
+# assembler instructions: jmp 05
+0      ulelong 0xc00005ea              pxelinux loader (version 3.70 or newer)
+# https://syslinux.zytor.com/wiki/index.php/SYSLINUX
+0      string  LDLINUX\ SYS\           SYSLINUX loader
+>12    string  x                       (older version %-4.4s)
+0      string  \r\nSYSLINUX\           SYSLINUX loader
+>11    string  x                       (version %-4.4s)
+# syslinux updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at Sep 2012
+# assembler instructions: jmp yy (yy=0x3c,0x58);nop;"SYSLINUX"
+0      ulelong&0x80909bEB      0x009018EB
+# OEM-ID not always "SYSLINUX"
+>434   search/47       Boot\ failed
+# followed by \r\n\0 or :\
+>>482  search/132      \0LDLINUX\ SYS          Syslinux bootloader (version 2.13 or older)
+>>1    ubyte           0x58                    Syslinux bootloader (version 3.0-3.9)
+>459   search/30       Boot\ error\r\n\0
+>>1    ubyte           0x58                    Syslinux bootloader (version 3.10 or newer)
+# SYSLINUX MBR updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at Sep 2012
+# assembler instructions: mov di,0600h;mov cx,0100h
+16     search/4        \xbf\x00\x06\xb9\x00\x01
+# to display SYSLINUX MBR (36) before old DOS/MBR boot sector one with partition table (strength=50+21)
+!:strength +36
+>94    search/249      Missing\ operating\ system
+# followed by \r for versions older 3.35 , .\r for versions newer 3.52 and point for other
+# skip Ranish MBR
+>>408  search/4        HD1/\0
+>>408  default         x
+>>>250 search/118      \0Operating\ system\ load               SYSLINUX MBR
+# followed by "ing " or space
+>>>>292        search/98       error
+>>>>>&0        string          \r                                      (version 3.35 or older)
+>>>>>&0        string          .\r                                     (version 3.52 or newer)
+>>>>>&0        default         x                                       (version 3.36-3.51 )
+>368   search/106      \0Disk\ error\ on\ boot\r\n             SYSLINUX GPT-MBR
+>>156  search/10       \0Boot\ partition\ not\ found\r\n
+>>>270 search/10       \0OS\ not\ bootable\r\n                 (version 3.86 or older)
+>>174  search/10       \0Missing\ OS\r\n
+>>>189 search/10       \0Multiple\ active\ partitions\r\n      (version 4.00 or newer)
+# SYSLINUX END
+
+# NetBSD mbr variants (master-boot-code version 1.22) added by Joerg Jenderek at Nov 2012
+# assembler instructions: xor ax,ax;mov        ax,ss;mov sp,0x7c00;mov ax,
+0      ubequad         0x31c08ed0bc007c8e
+# mbr_bootsel magic before partition table not reliable with small ipl fragments
+#>444  uleshort        0xb5e1
+>0004  uleshort        x
+# ERRorTeXT
+>>181  search/166              Error\ \0\r\n                           NetBSD mbr
+# NT Drive Serial Number https://thestarman.pcministry.com/asm/mbr/Win2kmbr.htm#DS
+>>>0x1B8       ubelong         >0                                      \b,Serial 0x%-.8x
+# BOOTSEL definitions contains assembler instructions: int 0x13;pop dx;push dx;push dx
+>>>0xbb                search/71       \xcd\x13\x5a\x52\x52                    \b,bootselector
+# BOOT_EXTENDED definitions contains assembler instructions:
+# xchg ecx,edx;addl ecx,edx;movw lba_info,si;movb 0x42,ah;pop dx;push dx;int 0x13
+>>>0x96        search/1        \x66\x87\xca\x66\x01\xca\x66\x89\x16\x3a\x07\xbe\x32\x07\xb4\x42\x5a\x52\xcd\x13        \b,boot extended
+# COM_PORT_VAL definitions contains assembler instructions: outb al,dx;add 5,dl;inb %dx;test 0x40,al
+>>>0x130       search/55       \xee\x80\xc2\x05\xec\xa8\x40            \b,serial IO
+# not TERSE_ERROR
+>>>196         search/106      No\ active\ partition\0
+>>>>&0         string          Disk\ read\ error\0
+>>>>>&0                string          No\ operating\ system\0                 \b,verbose
+# not NO_CHS definitions contains assembler instructions: pop dx;push dx;movb $8,ah;int0x13
+>>>0x7d                search/7        \x5a\x52\xb4\x08\xcd\x13                \b,CHS
+# not NO_LBA_CHECK definitions contains assembler instructions: movw 0x55aa,bx;movb 0x41,ah;pop        dx;push dx;int 0x13
+>>>0xa4                search/84       \xbb\xaa\x55\xb4\x41\x5a\x52\xcd\x13    \b,LBA-check
+# assembler instructions: movw nametab,bx
+>>>0x26            search/21   \xBB\x94\x07
+# not NO_BANNER definitions contains assembler instructions: mov banner,si;call message_crlf
+>>>>&-9        ubequad&0xBE00f0E800febb94      0xBE0000E80000bb94
+>>>>>181       search/166              Error\ \0
+# "a: disk" , "Fn: diskn" or "NetBSD MBR boot"
+>>>>>>&3       string                  x                               \b,"%s"
+>>>446 use             partition-table
+# Andrea Mazzoleni AdvanceCD mbr loader of http://advancemame.sourceforge.net/boot-readme.html
+# added by Joerg Jenderek at Nov 2012 for versions 1.3 - 1.4
+# assembler instructions: jmp short 0x58;nop;ASCII
+0      ubequad&0xeb58908000000000      0xeb58900000000000
+# assembler instructions: cli;xor ax,ax;mov ds,ax;mov es,ax;mov ss,
+>(1.b+2)       ubequad                 0xfa31c08ed88ec08e
+# Error messages at end of code
+>>376          string  No\ operating\ system\r\n\0
+>>>398         string  Disk\ error\r\n\0FDD\0HDD\0
+>>>>419                string  \ EBIOS\r\n\0                           AdvanceMAME mbr
+
+# Neil Turton mbr loader variant of https://www.chiark.greenend.org.uk/~neilt/mbr/
+# added by Joerg Jenderek at Mar 2011 for versions 1.0.0 - 1.1.11
+# for 1st version assembler instructions:      cld;xor ax,ax;mov DS,ax;MOV ES,AX;mov SI,
+# or                                           cld;xor ax,ax;mov SS,ax;XOR SP,SP;mov DS,
+0      ulequad&0xcE1b40D48EC031FC      0x8E0000D08EC031FC
+# pointer to the data starting with Neil Turton signature string
+>(0x1BC.s)             string          NDTmbr
+>>&-14                 string          1234F\0                 Turton mbr (
+# parameters also viewed by install-mbr --list
+>>>(0x1BC.s+7)         ubyte           x                       \b%u<=
+>>>(0x1BC.s+9)         ubyte           x                       \bVersion<=%u
+#>>>(0x1BC.s+8)                ubyte           x                       asm_flag_%x
+>>>(0x1BC.s+8)         ubyte&1         1                       \b,Y2K-Fix
+# variant used by testdisk of https://www.cgsecurity.org/wiki/Menu_MBRCode
+>>>(0x1BC.s+8)         ubyte&2         2                       \b,TestDisk
+#0x1~1,..,0x8~4,0x10~F,0x80~A enabled
+#>>>(0x1BC.s+10)               ubyte           x                       \b,flags 0x%x
+#0x0~1,0x1~2,...,0x3~4,0x4~F,0x7~D default boot
+#>>>(0x1BC.s+11)               ubyte           x                       \b,cfg_def 0x%x
+# for older versions
+>>>(0x1BC.s+9)         ubyte           <2
+#>>>>(0x1BC.s+12)      ubyte           18                      \b,%hhu/18 seconds
+>>>>(0x1BC.s+12)       ubyte           !18                     \b,%u/18 seconds
+# floppy A: or B:
+>>>>(0x1BC.s+13)       ubyte           <2                      \b,floppy 0x%x
+>>>>(0x1BC.s+13)       ubyte           >1
+# 1st hard disc
+#>>>>>(0x1BC.s+13)     ubyte           0x80                    \b,drive 0x%x
+# not 1st hard disc
+>>>>>(0x1BC.s+13)      ubyte           !0x80                   \b,drive 0x%x
+# for version >= 2 maximal timeout can be 65534
+>>>(0x1BC.s+9)         ubyte           >1
+#>>>>(0x1BC.s+12)      uleshort        18                      \b,%u/18 seconds
+>>>>(0x1BC.s+12)       uleshort        !18                     \b,%u/18 seconds
+# floppy A: or B:
+>>>>(0x1BC.s+14)       ubyte           <2                      \b,floppy 0x%x
+>>>>(0x1BC.s+14)       ubyte           >1
+# 1st hard disc
+#>>>>>(0x1BC.s+14)     ubyte           0x80                    \b,drive 0x%x
+# not 1st hard disc
+>>>>>(0x1BC.s+14)      ubyte           !0x80                   \b,drive 0x%x
+>>>0   ubyte           x                                       \b)
+
+# added by Joerg Jenderek
+# In the second sector (+0x200) are variables according to grub-0.97/stage2/asm.S or
+# grub-1.94/kern/i386/pc/startup.S
+# https://www.gnu.org/software/grub/manual/grub.html#Embedded-data
+# usual values are marked with comments to get only informations of strange GRUB loaders
+0x200  uleshort                0x70EA
+# found only version 3.{1,2}
+>0x206         ubeshort        >0x0300
+# GRUB version (0.5.)95,0.93,0.94,0.96,0.97 > "00"
+>>0x212        ubyte           >0x29
+>>>0x213       ubyte           >0x29
+# not iso9660_stage1_5
+#>>>0  ulelong&0x00BE5652      0x00BE5652
+>>>>0x213      ubyte           >0x29           GRand Unified Bootloader
+# config_file for stage1_5 is 0xffffffff + default "/boot/grub/stage2"
+>>>>0x217      ubyte           0xFF            stage1_5
+>>>>0x217      ubyte           <0xFF           stage2
+>>>>0x206      ubyte           x               \b version %u
+>>>>0x207      ubyte           x               \b.%u
+# module_size for 1.94
+>>>>0x208      ulelong         <0xffffff       \b, installed partition %u
+#>>>>0x208     ulelong         =0xffffff       \b, %lu (default)
+>>>>0x208      ulelong         >0xffffff       \b, installed partition %u
+# GRUB 0.5.95 unofficial
+>>>>0x20C      ulelong&0x2E300000 0x2E300000
+# 0=stage2     1=ffs   2=e2fs  3=fat   4=minix 5=reiserfs
+>>>>>0x20C     ubyte           x               \b, identifier 0x%x
+#>>>>>0x20D    ubyte           =0              \b, LBA flag 0x%x (default)
+>>>>>0x20D     ubyte           >0              \b, LBA flag 0x%x
+# GRUB version as string
+>>>>>0x20E     string          >\0             \b, GRUB version %-s
+# for stage1_5 is 0xffffffff + config_file "/boot/grub/stage2" default
+>>>>>>0x215    ulong           0xffffffff
+>>>>>>>0x219   string          >\0             \b, configuration file %-s
+>>>>>>0x215    ulong           !0xffffffff
+>>>>>>>0x215   string          >\0             \b, configuration file %-s
+# newer GRUB versions
+>>>>0x20C      ulelong&0x2E300000 !0x2E300000
+##>>>>>0x20C   ulelong         =0              \b, saved entry %d (usual)
+>>>>>0x20C     ulelong         >0              \b, saved entry %d
+# for 1.94 contains kernel image size
+# for 0.93,0.94,0.96,0.97
+# 0=stage2     1=ffs   2=e2fs  3=fat   4=minix 5=reiserfs      6=vstafs        7=jfs   8=xfs   9=iso9660       a=ufs2
+>>>>>0x210     ubyte           x               \b, identifier 0x%x
+# The flag for LBA forcing is in most cases 0
+#>>>>>0x211    ubyte           =0              \b, LBA flag 0x%x (default)
+>>>>>0x211     ubyte           >0              \b, LBA flag 0x%x
+# GRUB version as string
+>>>>>0x212     string          >\0             \b, GRUB version %-s
+# for stage1_5 is 0xffffffff + config_file "/boot/grub/stage2" default
+>>>>>0x217     ulong           0xffffffff
+>>>>>>0x21b    string          >\0             \b, configuration file %-s
+>>>>>0x217     ulong           !0xffffffff
+>>>>>>0x217    string          >\0             \b, configuration file %-s
+
+# DOS x86 sector updated and separated from "DOS/MBR boot sector" by Joerg Jenderek at May 2011
+# JuMP short     bootcodeoffset NOP assembler instructions will usually be EB xx 90
+# over BIOS parameter block (BPB)
+# https://thestarman.pcministry.com/asm/2bytejumps.htm#FWD
+# older drives may use Near JuMP instruction E9 xx xx
+# minimal short forward jump found 0x29 for bootloaders or 0x0
+# maximal short forward jump is 0x7f
+# OEM-ID is empty or contain readable bytes
+0              ulelong&0x804000E9      0x000000E9
+!:strength     +60
+# mtools-3.9.8/msdos.h
+# usual values are marked with comments to get only informations of strange FAT systems
+# valid sectorsize must be a power of 2 from 32 to 32768
+>11            uleshort&0x001f 0
+>>11           uleshort        <32769
+>>>11          uleshort        >31
+>>>>21         ubyte&0xf0      0xF0
+>>>>>0         ubyte           0xEB            DOS/MBR boot sector
+>>>>>>1                ubyte           x               \b, code offset 0x%x+2
+>>>>>0         ubyte           0xE9
+>>>>>>1                uleshort        x               \b, code offset 0x%x+3
+>>>>>3         string          >\0             \b, OEM-ID "%-.8s"
+#http://mirror.href.com/thestarman/asm/debug/debug2.htm#IHC
+>>>>>>8                string          IHC             \b cached by Windows 9M
+>>>>>11                uleshort        >512            \b, Bytes/sector %u
+#>>>>>11       uleshort        =512            \b, Bytes/sector %u=512 (usual)
+>>>>>11                uleshort        <512            \b, Bytes/sector %u
+>>>>>13                ubyte           >1              \b, sectors/cluster %u
+#>>>>>13       ubyte           =1              \b, sectors/cluster %u (usual on Floppies)
+# for lazy FAT32 implementation like Transcend digital photo frame PF830
+>>>>>82                string/c        fat32
+>>>>>>14       uleshort        !32             \b, reserved sectors %u
+#>>>>>>14      uleshort        =32             \b, reserved sectors %u (usual Fat32)
+>>>>>82                string/c        !fat32
+>>>>>>14       uleshort        >1              \b, reserved sectors %u
+#>>>>>>14      uleshort        =1              \b, reserved sectors %u (usual FAT12,FAT16)
+#>>>>>>14      uleshort        0               \b, reserved sectors %u (usual NTFS)
+>>>>>16                ubyte           >2              \b, FATs %u
+#>>>>>16       ubyte           =2              \b, FATs %u (usual)
+>>>>>16                ubyte           =1              \b, FAT  %u
+>>>>>16                ubyte           >0
+>>>>>17                uleshort        >0              \b, root entries %u
+#>>>>>17       uleshort        =0              \b, root entries %hu=0 (usual Fat32)
+>>>>>19                uleshort        >0              \b, sectors %u (volumes <=32 MB)
+#>>>>>19       uleshort        =0              \b, sectors %hu=0 (usual Fat32)
+>>>>>21                ubyte           >0xF0           \b, Media descriptor 0x%x
+#>>>>>21       ubyte           =0xF0           \b, Media descriptor 0x%x (usual floppy)
+>>>>>21                ubyte           <0xF0           \b, Media descriptor 0x%x
+>>>>>22                uleshort        >0              \b, sectors/FAT %u
+#>>>>>22       uleshort        =0              \b, sectors/FAT %hu=0 (usual Fat32)
+>>>>>24                uleshort        x               \b, sectors/track %u
+>>>>>26                ubyte           >2              \b, heads %u
+#>>>>>26       ubyte           =2              \b, heads %u (usual floppy)
+>>>>>26                ubyte           =1              \b, heads %u
+# valid only for sector sizes with more then 32 Bytes
+>>>>>11                uleshort        >32
+# https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Extended_BIOS_Parameter_Block
+# skip for values 2,2Ah,70h,73h,DFh
+# and continue for extended boot signature values 0,28h,29h,80h
+>>>>>>38       ubyte&0x56      =0
+>>>>>>>28      ulelong         >0              \b, hidden sectors %u
+#>>>>>>>28     ulelong         =0              \b, hidden sectors %u (usual floppy)
+>>>>>>>32      ulelong         >0              \b, sectors %u (volumes > 32 MB)
+#>>>>>>>32     ulelong         =0              \b, sectors %u (volumes > 32 MB)
+# FAT<32 bit specific
+>>>>>>>82      string/c        !fat32
+#>>>>>>>>36    ubyte           0x80            \b, physical drive 0x%x=0x80 (usual harddisk)
+#>>>>>>>>36    ubyte           0               \b, physical drive 0x%x=0 (usual floppy)
+>>>>>>>>36     ubyte           !0x80
+>>>>>>>>>36    ubyte           !0              \b, physical drive 0x%x
+# VGA-copy CRC or
+# in Windows NT bit 0 is a dirty flag to request chkdsk at boot time. bit 1 requests surface scan too
+>>>>>>>>37     ubyte           >0              \b, reserved 0x%x
+#>>>>>>>>37    ubyte           =0              \b, reserved 0x%x
+# extended boot signatur value is 0x80 for NTFS, 0x28 or 0x29 for others
+>>>>>>>>38     ubyte           !0x29           \b, dos < 4.0 BootSector (0x%x)
+>>>>>>>>38     ubyte&0xFE      =0x28
+>>>>>>>>>39    ulelong         x               \b, serial number 0x%x
+>>>>>>>>38     ubyte           =0x29
+>>>>>>>>>43    string          <NO\ NAME       \b, label: "%11.11s"
+>>>>>>>>>43    string          >NO\ NAME       \b, label: "%11.11s"
+>>>>>>>>>43    string          =NO\ NAME       \b, unlabeled
+# there exist some old floppies without word FAT at offset 54
+# a word like "FATnm   " is only a hint for a FAT size on nm-bits
+# Normally the number of clusters is calculated by the values of BPP.
+# if it is small enough FAT is 12 bit, if it is too big enough FAT is 32 bit,
+# otherwise FAT is 16 bit.
+# http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-fat-widths.html
+>>>>>82                string/c        !fat32
+>>>>>>54       string          FAT12           \b, FAT (12 bit)
+>>>>>>54       string          FAT16           \b, FAT (16 bit)
+>>>>>>54       default         x
+# determinate FAT bit size by media descriptor
+# small floppies implies FAT12
+>>>>>>>21      ubyte           <0xF0           \b, FAT (12 bit by descriptor)
+# with media descriptor F0h floppy or maybe superfloppy with FAT16
+>>>>>>>21      ubyte           =0xF0
+# superfloppy (many sectors) implies FAT16
+>>>>>>>>32     ulelong         >0xFFFF         \b, FAT (16 bit by descriptor+sectors)
+# no superfloppy with media descriptor F0h implies FAT12
+>>>>>>>>32     default         x               \b, FAT (12 bit by descriptor+sectors)
+# with media descriptor F8h floppy or hard disc with FAT12 or FAT16
+>>>>>>>21      ubyte           =0xF8
+# 360 KiB with media descriptor F8h, 9 sectors per track ,single sided floppy implies FAT12
+>>>>>>>>19     ubequad 0xd002f80300090001      \b, FAT (12 bit by descriptor+geometry)
+# hard disc with FAT12 or FAT16
+>>>>>>>>19     default         x               \b, FAT (1Y bit by descriptor)
+# with media descriptor FAh floppy, RAM disc with FAT12 or FAT16 or Tandy hard disc
+>>>>>>>21      ubyte           =0xFA
+# 320 KiB with media descriptor FAh, 8 sectors per track ,single sided floppy implies FAT12
+>>>>>>>>19     ubequad 0x8002fa0200080001      \b, FAT (12 bit by descriptor+geometry)
+# RAM disc with FAT12 or FAT16 or Tandy hard disc
+>>>>>>>>19     default         x               \b, FAT (1Y bit by descriptor)
+# others are floppy
+>>>>>>>21      default         x               \b, FAT (12 bit by descriptor)
+# FAT32 bit specific
+>>>>>82                string/c        fat32           \b, FAT (32 bit)
+>>>>>>36       ulelong         x               \b, sectors/FAT %u
+# https://technet.microsoft.com/en-us/library/cc977221.aspx
+>>>>>>40       uleshort        >0              \b, extension flags 0x%x
+#>>>>>>40      uleshort        =0              \b, extension flags %hu
+>>>>>>42       uleshort        >0              \b, fsVersion %u
+#>>>>>>42      uleshort        =0              \b, fsVersion %u (usual)
+>>>>>>44       ulelong         >2              \b, rootdir cluster %u
+#>>>>>>44      ulelong         =2              \b, rootdir cluster %u
+#>>>>>>44      ulelong         =1              \b, rootdir cluster %u
+>>>>>>48       uleshort        >1              \b, infoSector %u
+#>>>>>>48      uleshort        =1              \b, infoSector %u (usual)
+>>>>>>48       uleshort        <1              \b, infoSector %u
+# 0 or 0xFFFF instead of usual 6 means no backup sector
+>>>>>>50       uleshort        =0xFFFF         \b, no Backup boot sector
+>>>>>>50       uleshort        =0              \b, no Backup boot sector
+#>>>>>>50      uleshort        =6              \b, Backup boot sector %u (usual)
+>>>>>>50       default         x
+>>>>>>>50      uleshort        x               \b, Backup boot sector %u
+# corrected by Joerg Jenderek at Feb 2011 according to https://thestarman.pcministry.com/asm/mbr/MSWIN41.htm#FSINFO
+>>>>>>52       ulelong         >0              \b, reserved1 0x%x
+>>>>>>56       ulelong         >0              \b, reserved2 0x%x
+>>>>>>60       ulelong         >0              \b, reserved3 0x%x
+# same structure as FAT1X
+#>>>>>>64      ubyte           =0x80           \b, physical drive 0x%x=80 (usual harddisk)
+#>>>>>>64      ubyte           =0              \b, physical drive 0x%x=0 (usual floppy)
+>>>>>>64       ubyte           !0x80
+>>>>>>>64      ubyte           >0              \b, physical drive 0x%x
+# in Windows NT bit 0 is a dirty flag to request chkdsk at boot time. bit 1 requests surface scan too
+>>>>>>65       ubyte           >0              \b, reserved 0x%x
+>>>>>>66       ubyte           !0x29           \b, dos < 4.0 BootSector (0x%x)
+>>>>>>66       ubyte           =0x29
+>>>>>>>67      ulelong         x               \b, serial number 0x%x
+>>>>>>>71      string          <NO\ NAME       \b, label: "%11.11s"
+>>>>>>>71      string          >NO\ NAME       \b, label: "%11.11s"
+>>>>>>>71      string          =NO\ NAME       \b, unlabeled
+# additional tests for floppy image added by Joerg Jenderek
+# no fixed disk
+>>>>>21                ubyte           !0xF8
+# floppy media with 12 bit FAT
+>>>>>>54       string          !FAT16
+# test for FAT after bootsector
+>>>>>>>(11.s)  ulelong&0x00ffffF0      0x00ffffF0      \b, followed by FAT
+# floppy image
+!:mime application/x-ima
+# NTFS specific added by Joerg Jenderek at Mar 2011 according to https://thestarman.pcministry.com/asm/mbr/NTFSBR.htm
+# and http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/bios-parameter-block.html
+# 0 FATs
+>>>>>16        ubyte           =0
+# 0 root entries
+>>>>>>17       uleshort        =0
+# 0 DOS sectors
+>>>>>>>19      uleshort        =0
+# 0 sectors/FAT
+# dos < 4.0 BootSector value found is 0x80
+#38    ubyte           =0x80                   \b, dos < 4.0 BootSector (0x%x)
+>>>>>>>>22     uleshort        =0              \b; NTFS
+>>>>>>>>>24    uleshort        >0              \b, sectors/track %u
+>>>>>>>>>36    ulelong         !0x800080       \b, physical drive 0x%x
+>>>>>>>>>40    ulequad         >0              \b, sectors %lld
+>>>>>>>>>48    ulequad         >0              \b, $MFT start cluster %lld
+>>>>>>>>>56    ulequad         >0              \b, $MFTMirror start cluster %lld
+# Values 0 to 127 represent MFT record sizes of 0 to 127 clusters.
+# Values 128 to 255 represent MFT record sizes of 2^(256-N) bytes.
+>>>>>>>>>64    lelong          <256
+>>>>>>>>>>64   lelong          <128            \b, clusters/RecordSegment %d
+>>>>>>>>>>64   ubyte           >127            \b, bytes/RecordSegment 2^(-1*%i)
+# Values 0 to 127 represent index block sizes of 0 to 127 clusters.
+# Values 128 to 255 represent index block sizes of 2^(256-N) byte
+>>>>>>>>>68    ulelong         <256
+>>>>>>>>>>68   ulelong         <128            \b, clusters/index block %d
+#>>>>>>>>>>68  ulelong         >127            \b, bytes/index block 2^(256-%d)
+>>>>>>>>>>68   ubyte           >127            \b, bytes/index block 2^(-1*%i)
+>>>>>>>>>72    ulequad         x               \b, serial number 0%llx
+>>>>>>>>>80    ulelong         >0              \b, checksum 0x%x
+#>>>>>>>>>80   ulelong         =0              \b, checksum 0x%x=0 (usual)
+# unicode loadername size jump
+>>>>>>>>>(0x200.s*2)   ubyte                           x
+# in next sector loadername terminated by unicode CTRL-D and $
+>>>>>>>>>>&0x1FF       ulequad&0x0000FFffFFffFF00      0x0000002400040000 \b; contains
+# if 2nd NTFS sectors is found then assume whole filesystem
+#!:mime                application/x-raw-disk-image
+!:ext          img/bin/ntfs
+>>>>>>>>>>>0x200       use                             ntfs-sector2
+
+# For 2nd NTFS sector added by Joerg Jenderek at Jan 2013, Mar 2019
+# https://thestarman.pcministry.com/asm/mbr/NTFSbrHexEd.htm
+# unused assembler instructions short JMP y2;NOP;NOP
+0x056          ulelong&0xFFFF0FFF      0x909002EB      NTFS
+#!:mime                application/octet-stream
+!:ext          bin
+>0             use             ntfs-sector2
+# https://memory.dataram.com/products-and-services/software/ramdisk
+# assembler instructions JMP C000;NOP
+0x056          ulelong                 0x9000c0e9      NTFS
+#!:mime                application/octet-stream
+!:ext          bin
+>0             use             ntfs-sector2
+# check for characteristics of second NTFS sector and then display loader name
+0              name            ntfs-sector2
+# number of utf16 characters of loadername
+>0             uleshort        <8
+# unused assembler instructions JMP y2;NOP;NOP or JMP C000;NOP
+>>0x056                ulelong&0xFF0000FD      0x900000E9
+# loadernames are NTLDR,CMLDR,PELDR,$LDR$ or BOOTMGR
+>>>0x002               lestring16      x       bootstrap %-5.5s
+# check for 7 character length of loader name like BOOTMGR
+>>>0           uleshort        7
+>>>>0x0c       lestring16      x       \b%-2.2s
+### DOS,NTFS boot sectors end
+
+# ntfsclone-image is a special save format for NTFS volumes,
+# created and restored by the ntfsclone program
+0      string  \0ntfsclone-image       ntfsclone image,
+>0x10  byte    x                       version %d.
+>0x11  byte    x                       \b%d,
+>0x12  lelong  x                       cluster size %d,
+>0x16  lequad  x                       device size %lld,
+>0x1e  lequad  x                       %lld total clusters,
+>0x26  lequad  x                       %lld clusters in use
+
+9564   lelong          0x00011954      Unix Fast File system [v1] (little-endian),
+>8404  string          x               last mounted on %s,
+#>9504 ledate          x               last checked at %s,
+>8224  ledate          x               last written at %s,
+>8401  byte            x               clean flag %d,
+>8228  lelong          x               number of blocks %d,
+>8232  lelong          x               number of data blocks %d,
+>8236  lelong          x               number of cylinder groups %d,
+>8240  lelong          x               block size %d,
+>8244  lelong          x               fragment size %d,
+>8252  lelong          x               minimum percentage of free blocks %d,
+>8256  lelong          x               rotational delay %dms,
+>8260  lelong          x               disk rotational speed %drps,
+>8320  lelong          0               TIME optimization
+>8320  lelong          1               SPACE optimization
+
+42332  lelong          0x19540119      Unix Fast File system [v2] (little-endian)
+>&-1164        string          x               last mounted on %s,
+>&-696 string          >\0             volume name %s,
+>&-304 leqldate        x               last written at %s,
+>&-1167        byte            x               clean flag %d,
+>&-1168        byte            x               readonly flag %d,
+>&-296 lequad          x               number of blocks %lld,
+>&-288 lequad          x               number of data blocks %lld,
+>&-1332        lelong          x               number of cylinder groups %d,
+>&-1328        lelong          x               block size %d,
+>&-1324        lelong          x               fragment size %d,
+>&-180 lelong          x               average file size %d,
+>&-176 lelong          x               average number of files in dir %d,
+>&-272 lequad          x               pending blocks to free %lld,
+>&-264 lelong          x               pending inodes to free %d,
+>&-664 lequad          x               system-wide uuid %0llx,
+>&-1316        lelong          x               minimum percentage of free blocks %d,
+>&-1248        lelong          0               TIME optimization
+>&-1248        lelong          1               SPACE optimization
+
+66908  lelong          0x19540119      Unix Fast File system [v2] (little-endian)
+>&-1164        string          x               last mounted on %s,
+>&-696 string          >\0             volume name %s,
+>&-304 leqldate        x               last written at %s,
+>&-1167        byte            x               clean flag %d,
+>&-1168        byte            x               readonly flag %d,
+>&-296 lequad          x               number of blocks %lld,
+>&-288 lequad          x               number of data blocks %lld,
+>&-1332        lelong          x               number of cylinder groups %d,
+>&-1328        lelong          x               block size %d,
+>&-1324        lelong          x               fragment size %d,
+>&-180 lelong          x               average file size %d,
+>&-176 lelong          x               average number of files in dir %d,
+>&-272 lequad          x               pending blocks to free %lld,
+>&-264 lelong          x               pending inodes to free %d,
+>&-664 lequad          x               system-wide uuid %0llx,
+>&-1316        lelong          x               minimum percentage of free blocks %d,
+>&-1248        lelong          0               TIME optimization
+>&-1248        lelong          1               SPACE optimization
+
+9564   belong          0x00011954      Unix Fast File system [v1] (big-endian),
+>7168   belong         0x4c41424c      Apple UFS Volume
+>>7186  string         x               named %s,
+>>7176  belong         x               volume label version %d,
+>>7180  bedate         x               created on %s,
+>8404  string          x               last mounted on %s,
+#>9504 bedate          x               last checked at %s,
+>8224  bedate          x               last written at %s,
+>8401  byte            x               clean flag %d,
+>8228  belong          x               number of blocks %d,
+>8232  belong          x               number of data blocks %d,
+>8236  belong          x               number of cylinder groups %d,
+>8240  belong          x               block size %d,
+>8244  belong          x               fragment size %d,
+>8252  belong          x               minimum percentage of free blocks %d,
+>8256  belong          x               rotational delay %dms,
+>8260  belong          x               disk rotational speed %drps,
+>8320  belong          0               TIME optimization
+>8320  belong          1               SPACE optimization
+
+42332  belong          0x19540119      Unix Fast File system [v2] (big-endian)
+>&-1164        string          x               last mounted on %s,
+>&-696 string          >\0             volume name %s,
+>&-304 beqldate        x               last written at %s,
+>&-1167        byte            x               clean flag %d,
+>&-1168        byte            x               readonly flag %d,
+>&-296 bequad          x               number of blocks %lld,
+>&-288 bequad          x               number of data blocks %lld,
+>&-1332        belong          x               number of cylinder groups %d,
+>&-1328        belong          x               block size %d,
+>&-1324        belong          x               fragment size %d,
+>&-180 belong          x               average file size %d,
+>&-176 belong          x               average number of files in dir %d,
+>&-272 bequad          x               pending blocks to free %lld,
+>&-264 belong          x               pending inodes to free %d,
+>&-664 bequad          x               system-wide uuid %0llx,
+>&-1316        belong          x               minimum percentage of free blocks %d,
+>&-1248        belong          0               TIME optimization
+>&-1248        belong          1               SPACE optimization
+
+66908  belong          0x19540119      Unix Fast File system [v2] (big-endian)
+>&-1164        string          x               last mounted on %s,
+>&-696 string          >\0             volume name %s,
+>&-304 beqldate        x               last written at %s,
+>&-1167        byte            x               clean flag %d,
+>&-1168        byte            x               readonly flag %d,
+>&-296 bequad          x               number of blocks %lld,
+>&-288 bequad          x               number of data blocks %lld,
+>&-1332        belong          x               number of cylinder groups %d,
+>&-1328        belong          x               block size %d,
+>&-1324        belong          x               fragment size %d,
+>&-180 belong          x               average file size %d,
+>&-176 belong          x               average number of files in dir %d,
+>&-272 bequad          x               pending blocks to free %lld,
+>&-264 belong          x               pending inodes to free %d,
+>&-664 bequad          x               system-wide uuid %0llx,
+>&-1316        belong          x               minimum percentage of free blocks %d,
+>&-1248        belong          0               TIME optimization
+>&-1248        belong          1               SPACE optimization
+
+0      ulequad         0xc8414d4dc5523031      HAMMER filesystem (little-endian),
+>0x90  lelong+1        x                       volume %d
+>0x94  lelong          x                       (of %d),
+>0x50  string          x                       name %s,
+>0x98  ulelong         x                       version %u,
+>0xa0  ulelong         x                       flags 0x%x
+
+# ext2/ext3 filesystems - Andreas Dilger <adilger@dilger.ca>
+# ext4 filesystem - Eric Sandeen <sandeen@sandeen.net>
+# volume label and UUID Russell Coker
+# https://etbe.coker.com.au/2008/07/08/label-vs-uuid-vs-device/
+0x438   leshort         0xEF53          Linux
+>0x44c  lelong          x               rev %d
+>0x43e  leshort         x               \b.%d
+# No journal?  ext2
+>0x45c  lelong          ^0x0000004      ext2 filesystem data
+>>0x43a leshort         ^0x0000001      (mounted or unclean)
+# Has a journal?  ext3 or ext4
+>0x45c  lelong          &0x0000004
+#  and small INCOMPAT?
+>>0x460 lelong          <0x0000040
+#   and small RO_COMPAT?
+>>>0x464 lelong         <0x0000008      ext3 filesystem data
+#   else large RO_COMPAT?
+>>>0x464 lelong         >0x0000007      ext4 filesystem data
+#  else large INCOMPAT?
+>>0x460        lelong          >0x000003f      ext4 filesystem data
+>0x468 belong          x               \b, UUID=%08x
+>0x46c beshort         x               \b-%04x
+>0x46e beshort         x               \b-%04x
+>0x470 beshort         x               \b-%04x
+>0x472 belong          x               \b-%08x
+>0x476 beshort         x               \b%04x
+>0x478 string          >0              \b, volume name "%s"
+# General flags for any ext* fs
+>0x460 lelong          &0x0000004      (needs journal recovery)
+>0x43a leshort         &0x0000002      (errors)
+# INCOMPAT flags
+>0x460 lelong          &0x0000001      (compressed)
+#>0x460        lelong          &0x0000002      (filetype)
+#>0x460        lelong          &0x0000010      (meta bg)
+>0x460 lelong          &0x0000040      (extents)
+>0x460 lelong          &0x0000080      (64bit)
+#>0x460        lelong          &0x0000100      (mmp)
+#>0x460        lelong          &0x0000200      (flex bg)
+# RO_INCOMPAT flags
+#>0x464        lelong          &0x0000001      (sparse super)
+>0x464 lelong          &0x0000002      (large files)
+>0x464 lelong          &0x0000008      (huge files)
+#>0x464        lelong          &0x0000010      (gdt checksum)
+#>0x464        lelong          &0x0000020      (many subdirs)
+#>0x463        lelong          &0x0000040      (extra isize)
+
+# f2fs filesystem - Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
+0x400  lelong          0xF2F52010      F2FS filesystem
+>0x46c belong          x               \b, UUID=%08x
+>0x470 beshort         x               \b-%04x
+>0x472 beshort         x               \b-%04x
+>0x474 beshort         x               \b-%04x
+>0x476 belong          x               \b-%08x
+>0x47a beshort         x               \b%04x
+>0x147c        lestring16      x               \b, volume name "%s"
+
+# Minix filesystems - Juan Cespedes <cespedes@debian.org>
+0x410  leshort         0x137f
+!:strength / 2
+>0x402 beshort         < 100
+>0x402 beshort         > -1            Minix filesystem, V1, 14 char names, %d zones
+>0x1e  string          minix           \b, bootable
+0x410  beshort         0x137f
+!:strength / 2
+>0x402 beshort         < 100
+>0x402 beshort         > -1            Minix filesystem, V1 (big endian), %d zones
+>0x1e  string          minix           \b, bootable
+0x410  leshort         0x138f
+!:strength / 2
+>0x402 beshort         < 100
+>0x402 beshort         > -1            Minix filesystem, V1, 30 char names, %d zones
+>0x1e  string          minix           \b, bootable
+0x410  beshort         0x138f
+!:strength / 2
+>0x402 beshort         < 100
+>0x402 beshort         > -1            Minix filesystem, V1, 30 char names (big endian), %d zones
+>0x1e  string          minix           \b, bootable
+# Weak Magic: this is $x
+#0x410 leshort         0x2468
+#>0x402        beshort         < 100
+#>>0x402       beshort         > -1            Minix filesystem, V2, 14 char names
+#>0x1e string          minix           \b, bootable
+#0x410 beshort         0x2468
+#>0x402        beshort         < 100
+#>0x402        beshort         > -1            Minix filesystem, V2 (big endian)
+#>0x1e string          minix           \b, bootable
+#0x410 leshort         0x2478
+#>0x402        beshort         < 100
+#>0x402        beshort         > -1            Minix filesystem, V2, 30 char names
+#>0x1e string          minix           \b, bootable
+#0x410 leshort         0x2478
+#>0x402        beshort         < 100
+#>0x402        beshort         > -1            Minix filesystem, V2, 30 char names
+#>0x1e string          minix           \b, bootable
+#0x410 beshort         0x2478
+#>0x402        beshort         !0              Minix filesystem, V2, 30 char names (big endian)
+#>0x1e string          minix           \b, bootable
+# Weak Magic! this is MD
+#0x418 leshort         0x4d5a
+#>0x402        beshort         <100
+#>>0x402       beshort         > -1            Minix filesystem, V3, 60 char names
+
+# SGI disk labels - Nathan Scott <nathans@debian.org>
+0      belong          0x0BE5A941      SGI disk label (volume header)
+
+# SGI XFS filesystem - Nathan Scott <nathans@debian.org>
+0      belong          0x58465342      SGI XFS filesystem data
+>0x4   belong          x               (blksz %d,
+>0x68  beshort         x               inosz %d,
+>0x64  beshort         ^0x2004         v1 dirs)
+>0x64  beshort         &0x2004         v2 dirs)
+
+############################################################################
+# Minix-ST kernel floppy
+0x800  belong          0x46fc2700      Atari-ST Minix kernel image
+# https://en.wikipedia.org/wiki/BIOS_parameter_block
+# floppies with valid BPB and any instruction at beginning
+>19    string          \240\005\371\005\0\011\0\2\0    \b, 720k floppy
+>19    string          \320\002\370\005\0\011\0\1\0    \b, 360k floppy
+
+############################################################################
+# Hmmm, is this a better way of detecting _standard_ floppy images ?
+19     string          \320\002\360\003\0\011\0\1\0    DOS floppy 360k
+>0x1FE leshort         0xAA55          \b, DOS/MBR hard disk boot sector
+19     string          \240\005\371\003\0\011\0\2\0    DOS floppy 720k
+>0x1FE leshort         0xAA55          \b, DOS/MBR hard disk boot sector
+19     string          \100\013\360\011\0\022\0\2\0    DOS floppy 1440k
+>0x1FE leshort         0xAA55          \b, DOS/MBR hard disk boot sector
+
+19     string          \240\005\371\005\0\011\0\2\0    DOS floppy 720k, IBM
+>0x1FE leshort         0xAA55          \b, DOS/MBR hard disk boot sector
+19     string          \100\013\371\005\0\011\0\2\0    DOS floppy 1440k, mkdosfs
+>0x1FE leshort         0xAA55          \b, DOS/MBR hard disk boot sector
+
+19     string          \320\002\370\005\0\011\0\1\0    Atari-ST floppy 360k
+19     string          \240\005\371\005\0\011\0\2\0    Atari-ST floppy 720k
+#                      |       |   |     |     |
+#                      |       |   |     |     heads
+#                      |       |   |     sectors/track
+#                      |       |   sectors/FAT
+#                      |       media descriptor
+#              BPB:    sectors
+
+#  Valid media descriptor bytes for MS-DOS:
+#
+#     Byte   Capacity   Media Size and Type
+#     -------------------------------------------------
+#
+#     F0     2.88 MB    3.5-inch, 2-sided, 36-sector
+#     F0     1.44 MB    3.5-inch, 2-sided, 18-sector
+#     F9     720K       3.5-inch, 2-sided, 9-sector
+#     F9     1.2 MB     5.25-inch, 2-sided, 15-sector
+#     FD     360K       5.25-inch, 2-sided, 9-sector
+#     FF     320K       5.25-inch, 2-sided, 8-sector
+#     FC     180K       5.25-inch, 1-sided, 9-sector
+#     FE     160K       5.25-inch, 1-sided, 8-sector
+#     FE     250K       8-inch, 1-sided, single-density
+#     FD     500K       8-inch, 2-sided, single-density
+#     FE     1.2 MB     8-inch, 2-sided, double-density
+#     F8     -----      Fixed disk
+#
+#     FC     xxxK       Apricot 70x1x9 boot disk.
+#
+# Originally a bitmap:
+#  xxxxxxx0    Not two sided
+#  xxxxxxx1    Double sided
+#  xxxxxx0x    Not 8 SPT
+#  xxxxxx1x    8 SPT
+#  xxxxx0xx    Not Removable drive
+#  xxxxx1xx    Removable drive
+#  11111xxx    Must be one.
+#
+# But now it's rather random:
+#  111111xx    Low density disk
+#        00    SS, Not 8 SPT
+#        01    DS, Not 8 SPT
+#        10    SS, 8 SPT
+#        11    DS, 8 SPT
+#
+#  11111001    Double density 3 1/2 floppy disk, high density 5 1/4
+#  11110000    High density 3 1/2 floppy disk
+#  11111000    Hard disk any format
+#
+
+# all FAT12 (strength=70) floppies with sectorsize 512 added by Joerg Jenderek at Jun 2013
+# https://en.wikipedia.org/wiki/File_Allocation_Table#Exceptions
+# Too Weak.
+#512           ubelong&0xE0ffff00      0xE0ffff00
+# without valid Media descriptor in place of BPB, cases with are done at other places
+#>21           ubyte                   <0xE5                   floppy with old FAT filesystem
+# but valid Media descriptor at begin of FAT
+#>>512         ubyte                   =0xed                   720k
+#>>512         ubyte                   =0xf0                   1440k
+#>>512         ubyte                   =0xf8                   720k
+#>>512         ubyte                   =0xf9                   1220k
+#>>512         ubyte                   =0xfa                   320k
+#>>512         ubyte                   =0xfb                   640k
+#>>512         ubyte                   =0xfc                   180k
+# look like an old DOS directory entry
+#>>>0xA0E      ubequad                 0
+#>>>>0xA00     ubequad                 !0
+#!:mime application/x-ima
+#>>512         ubyte                   =0xfd
+# look for 2nd FAT at different location to distinguish between 360k and 500k
+#>>>0x600      ubelong&0xE0ffff00      0xE0ffff00              360k
+#>>>0x500      ubelong&0xE0ffff00      0xE0ffff00              500k
+#>>>0xA0E      ubequad                 0
+#!:mime application/x-ima
+#>>512         ubyte                   =0xfe
+#>>>0x400      ubelong&0xE0ffff00      0xE0ffff00              160k
+#>>>>0x60E     ubequad                 0
+#>>>>>0x600    ubequad                 !0
+#!:mime application/x-ima
+#>>>0xC00      ubelong&0xE0ffff00      0xE0ffff00              1200k
+#>>512         ubyte                   =0xff                   320k
+#>>>0x60E      ubequad                 0
+#>>>>0x600     ubequad                 !0
+#!:mime application/x-ima
+#>>512         ubyte                   x                       \b, Media descriptor 0x%x
+# without x86 jump instruction
+#>>0           ulelong&0x804000E9      !0x000000E9
+# assembler instructions: CLI;MOV SP,1E7;MOV AX;07c0;MOV
+#>>>0  ubequad                         0xfabce701b8c0078e      \b, MS-DOS 1.12 bootloader
+# IOSYS.COM+MSDOS.COM
+#>>>>0xc4      use                     2xDOS-filename
+#>>0           ulelong&0x804000E9      =0x000000E9
+# only x86 short jump instruction found
+#>>>0          ubyte                   =0xEB
+#>>>>1         ubyte                   x                       \b, code offset 0x%x+2
+# https://thestarman.pcministry.com/DOS/ibm100/Boot.htm
+# assembler instructions: CLI;MOV AX,CS;MOV DS,AX;MOV DX,0
+#>>>>(1.b+2)   ubequad                 0xfa8cc88ed8ba0000      \b, PC-DOS 1.0 bootloader
+# ibmbio.com+ibmdos.com
+#>>>>>0x176    use                     DOS-filename
+#>>>>>0x181    ubyte                   x                       \b+
+#>>>>>0x182    use                     DOS-filename
+# https://thestarman.pcministry.com/DOS/ibm110/Boot.htm
+# assembler instructions: CLI;MOV AX,CS;MOV DS,AX;XOR DX,DX;MOV
+#>>>>(1.b+2)   ubequad                 0xfa8cc88ed833d28e      \b, PC-DOS 1.1 bootloader
+# ibmbio.com+ibmdos.com
+#>>>>>0x18b    use                     DOS-filename
+#>>>>>0x196    ubyte                   x                       \b+
+#>>>>>0x197    use                     DOS-filename
+# https://en.wikipedia.org/wiki/Zenith_Data_Systems
+# assembler instructions: MOV BX,07c0;MOV SS,BX;MOV SP,01c6
+#>>>>(1.b+2)   ubequad                 0xbbc0078ed3bcc601      \b, Zenith Data Systems MS-DOS 1.25 bootloader
+# IO.SYS+MSDOS.SYS
+#>>>>>0x20     use                     2xDOS-filename
+# https://en.wikipedia.org/wiki/Corona_Data_Systems
+# assembler instructions: MOV AX,CS;MOV DS,AX;CLI;MOV SS,AX;
+#>>>>(1.b+2)   ubequad                 0x8cc88ed8fa8ed0bc      \b, MS-DOS 1.25 bootloader
+# IO.SYS+MSDOS.SYS
+#>>>>>0x69     use                     2xDOS-filename
+# assembler instructions: CLI;PUSH CS;POP SS;MOV SP,7c00;
+#>>>>(1.b+2)   ubequad                 0xfa0e17bc007cb860      \b, MS-DOS 2.11 bootloader
+# defect IO.SYS+MSDOS.SYS ?
+#>>>>>0x162    use                     2xDOS-filename
+
+0      name                            cdrom
+>38913 string   !NSR0      ISO 9660 CD-ROM filesystem data
+!:mime application/x-iso9660-image
+!:ext  iso/iso9660
+>38913 string    NSR0      UDF filesystem data
+!:mime application/x-iso9660-image
+!:ext  iso/udf
+>>38917        string    1         (version 1.0)
+>>38917        string    2         (version 1.5)
+>>38917        string    3         (version 2.0)
+>>38917        byte     >0x33      (unknown version, ID 0x%X)
+>>38917        byte     <0x31      (unknown version, ID 0x%X)
+# The next line is not necessary because the MBR staff is done looking for boot signature
+>0x1FE leshort  0xAA55     (DOS/MBR boot sector)
+# "application id" which appears to be used as a volume label
+>32808 string/T  >\0       '%s'
+>34816 string    \000CD001\001EL\ TORITO\ SPECIFICATION    (bootable)
+37633  string    CD001     ISO 9660 CD-ROM filesystem data (raw 2352 byte sectors)
+!:mime application/x-iso9660-image
+32777  string    CDROM     High Sierra CD-ROM filesystem data
+
+# CDROM Filesystems
+# https://en.wikipedia.org/wiki/ISO_9660
+# Modified for UDF by gerardo.cacciari@gmail.com
+32769  string    CD001
+# mime line at that position does not work
+# to display CD-ROM (70=81-11) after MBR (113=40+72+1), partition-table (71=50+21) and before Apple Driver Map (51)
+#!:strength -11
+# to display CD-ROM (114=81+33) before MBR (113=40+72+1), partition-table (71=50+21) and Apple Driver Map (51)
+!:strength +34
+>0     use     cdrom
+
+# URL: https://en.wikipedia.org/wiki/NRG_(file_format)
+# Reference: https://dl.opendesktop.org/api/files/download/id/1460731811/
+#      11577-mount-iso-0.9.5.tar.bz2/mount-iso-0.9.5/install.sh
+# From: Joerg Jenderek
+# Note:        Only for nero disc with once (DAO) type after 300 KB header
+339969 string    CD001 Nero CD image at 0x4B000
+!:mime application/x-nrg
+!:ext  nrg
+>307200        use cdrom
+
+# .cso files
+# Reference: https://pismotec.com/ciso/ciso.h
+# NOTE: There are two other formats with the same magic but
+# completely incompatible specifications:
+# - GameCube/Wii CISO: https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/DiscIO/CISOBlob.h
+# - PSP CISO: https://github.com/jamie/ciso/blob/master/ciso.h
+0    string    CISO
+# Other fields are used to determine what type of CISO this is:
+# - 0x04 == 0x00200000: GameCube/Wii CISO (block_size)
+# - 0x10 == 0x00000800: PSP CISO (ISO-9660 sector size)
+# - 0x10 == 0x00004000: For >2GB files using maxcso...
+#                      https://github.com/unknownbrackets/maxcso/issues/26
+# - None of the above: Compact ISO.
+>4     lelong  !0
+>>4    lelong  !0x200000
+>>>16  lelong  !0x800
+>>>>16 lelong  !0x4000         Compressed ISO CD image
+
+# cramfs filesystem - russell@coker.com.au
+0       lelong    0x28cd3d45      Linux Compressed ROM File System data, little endian
+>4      lelong  x size %u
+>8      lelong  &1 version #2
+>8      lelong  &2 sorted_dirs
+>8      lelong  &4 hole_support
+>32     lelong  x CRC 0x%x,
+>36     lelong  x edition %u,
+>40     lelong  x %u blocks,
+>44     lelong  x %u files
+
+0       belong    0x28cd3d45      Linux Compressed ROM File System data, big endian
+>4      belong  x size %u
+>8      belong  &1 version #2
+>8      belong  &2 sorted_dirs
+>8      belong  &4 hole_support
+>32     belong  x CRC 0x%x,
+>36     belong  x edition %u,
+>40     belong  x %u blocks,
+>44     belong  x %u files
+
+# reiserfs - russell@coker.com.au
+0x10034                string  ReIsErFs        ReiserFS V3.5
+0x10034                string  ReIsEr2Fs       ReiserFS V3.6
+0x10034                string  ReIsEr3Fs       ReiserFS V3.6.19
+>0x1002c       leshort x               block size %d
+>0x10032       leshort &2              (mounted or unclean)
+>0x10000       lelong  x               num blocks %d
+>0x10040       lelong  1               tea hash
+>0x10040       lelong  2               yura hash
+>0x10040       lelong  3               r5 hash
+
+# JFFS - russell@coker.com.au
+0      lelong  0x34383931      Linux Journalled Flash File system, little endian
+0      belong  0x34383931      Linux Journalled Flash File system, big endian
+
+# EST flat binary format (which isn't, but anyway)
+# From: Mark Brown <broonie@sirena.org.uk>
+0      string  ESTFBINR        EST flat binary
+
+# Aculab VoIP firmware
+# From: Mark Brown <broonie@sirena.org.uk>
+0      string  VoIP\ Startup\ and      Aculab VoIP firmware
+>35    string  x       format %s
+
+# From: Mark Brown <broonie@sirena.org.uk> [old]
+# From: Behan Webster <behanw@websterwood.com>
+0      belong  0x27051956      u-boot legacy uImage,
+>32    string  x               %s,
+>28    byte    0               Invalid os/
+>28    byte    1               OpenBSD/
+>28    byte    2               NetBSD/
+>28    byte    3               FreeBSD/
+>28    byte    4               4.4BSD/
+>28    byte    5               Linux/
+>28    byte    6               SVR4/
+>28    byte    7               Esix/
+>28    byte    8               Solaris/
+>28    byte    9               Irix/
+>28    byte    10              SCO/
+>28    byte    11              Dell/
+>28    byte    12              NCR/
+>28    byte    13              LynxOS/
+>28    byte    14              VxWorks/
+>28    byte    15              pSOS/
+>28    byte    16              QNX/
+>28    byte    17              Firmware/
+>28    byte    18              RTEMS/
+>28    byte    19              ARTOS/
+>28    byte    20              Unity OS/
+>28    byte    21              INTEGRITY/
+>29    byte    0               \bInvalid CPU,
+>29    byte    1               \bAlpha,
+>29    byte    2               \bARM,
+>29    byte    3               \bIntel x86,
+>29    byte    4               \bIA64,
+>29    byte    5               \bMIPS,
+>29    byte    6               \bMIPS 64-bit,
+>29    byte    7               \bPowerPC,
+>29    byte    8               \bIBM S390,
+>29    byte    9               \bSuperH,
+>29    byte    10              \bSparc,
+>29    byte    11              \bSparc 64-bit,
+>29    byte    12              \bM68K,
+>29    byte    13              \bNios-32,
+>29    byte    14              \bMicroBlaze,
+>29    byte    15              \bNios-II,
+>29    byte    16              \bBlackfin,
+>29    byte    17              \bAVR32,
+>29    byte    18              \bSTMicroelectronics ST200,
+>29    byte    19              \bSandbox architecture,
+>29    byte    20              \bANDES Technology NDS32,
+>29    byte    21              \bOpenRISC 1000,
+>29    byte    22              \bARM 64-bit,
+>29    byte    23              \bDesignWare ARC,
+>29    byte    24              \bx86_64,
+>29    byte    25              \bXtensa,
+>30    byte    0               Invalid Image
+>30    byte    1               Standalone Program
+>30    byte    2               OS Kernel Image
+>30    byte    3               RAMDisk Image
+>30    byte    4               Multi-File Image
+>30    byte    5               Firmware Image
+>30    byte    6               Script File
+>30    byte    7               Filesystem Image (any type)
+>30    byte    8               Binary Flat Device Tree BLOB
+>31    byte    0               (Not compressed),
+>31    byte    1               (gzip),
+>31    byte    2               (bzip2),
+>31    byte    3               (lzma),
+>12    belong  x               %d bytes,
+>8     bedate  x               %s,
+>16    belong  x               Load Address: 0x%08X,
+>20    belong  x               Entry Point: 0x%08X,
+>4     belong  x               Header CRC: 0x%08X,
+>24    belong  x               Data CRC: 0x%08X
+
+# JFFS2 file system
+0      leshort 0x1984          Linux old jffs2 filesystem data little endian
+0      leshort 0x1985          Linux jffs2 filesystem data little endian
+
+# Squashfs
+0      string  sqsh    Squashfs filesystem, big endian,
+>28    beshort x       version %d.
+>30    beshort x       \b%d,
+>28    beshort <3
+>>8    belong  x       %d bytes,
+>28    beshort >2
+>>28 beshort <4
+>>>63  bequad x        %lld bytes,
+>>28 beshort >3
+>>>40  bequad x        %lld bytes,
+#>>67  belong  x       %d bytes,
+>4     belong  x       %d inodes,
+>28    beshort <2
+>>32   beshort x       blocksize: %d bytes,
+>28    beshort >1
+>>28 beshort <4
+>>>51  belong  x       blocksize: %d bytes,
+>>28 beshort >3
+>>>12  belong  x       blocksize: %d bytes,
+>28 beshort <4
+>>39   bedate  x       created: %s
+>28 beshort >3
+>>8    bedate  x       created: %s
+0      string  hsqs    Squashfs filesystem, little endian,
+>28    leshort x       version %d.
+>30    leshort x       \b%d,
+>28    leshort <3
+>>8    lelong  x       %d bytes,
+>28    leshort >2
+>>28 leshort <4
+>>>63  lequad x        %lld bytes,
+>>28 leshort >3
+>>>40  lequad x        %lld bytes,
+#>>63  lelong  x       %d bytes,
+>4     lelong  x       %d inodes,
+>28    leshort <2
+>>32   leshort x       blocksize: %d bytes,
+>28    leshort >1
+>>28 leshort <4
+>>>51  lelong  x       blocksize: %d bytes,
+>>28 leshort >3
+>>>12  lelong  x       blocksize: %d bytes,
+>28 leshort <4
+>>39   ledate  x       created: %s
+>28 leshort >3
+>>8    ledate  x       created: %s
+
+# AFS Dump Magic
+# From: Ty Sarna <tsarna@sarna.org>
+0       string                  \x01\xb3\xa1\x13\x22    AFS Dump
+>&0     belong                  x                       (v%d)
+>>&0    byte                    0x76
+>>>&0   belong                  x                       Vol %d,
+>>>>&0  byte                    0x6e
+>>>>>&0 string                  x                       %s
+>>>>>>&1        byte            0x74
+>>>>>>>&0       beshort         2
+>>>>>>>>&4      bedate          x                       on: %s
+>>>>>>>>&0      bedate          =0                      full dump
+>>>>>>>>&0      bedate          !0                      incremental since: %s
+
+#----------------------------------------------------------
+#delta ISO    Daniel Novotny (dnovotny@redhat.com)
+0      string  DISO    Delta ISO data
+!:strength +50
+>4     belong  x       version %d
+
+# VMS backup savesets - gerardo.cacciari@gmail.com
+#
+4            string  \x01\x00\x01\x00\x01\x00
+>(0.s+16)    string  \x01\x01
+>>&(&0.b+8)  byte    0x42       OpenVMS backup saveset data
+>>>40        lelong  x          (block size %d,
+>>>49        string  >\0        original name '%s',
+>>>2         short   1024       VAX generated)
+>>>2         short   2048       AXP generated)
+>>>2         short   4096       I64 generated)
+
+# Summary: Oracle Clustered Filesystem
+# Created by: Aaron Botsis <redhat@digitalmafia.org>
+8      string          OracleCFS       Oracle Clustered Filesystem,
+>4     long            x               rev %d
+>0     long            x               \b.%d,
+>560   string          x               label: %.64s,
+>136   string          x               mountpoint: %.128s
+
+# Summary: Oracle ASM tagged volume
+# Created by: Aaron Botsis <redhat@digitalmafia.org>
+32     string          ORCLDISK        Oracle ASM Volume,
+>40    string          x               Disk Name: %0.12s
+32     string          ORCLCLRD        Oracle ASM Volume (cleared),
+>40    string          x               Disk Name: %0.12s
+
+# Oracle Clustered Filesystem - Aaron Botsis <redhat@digitalmafia.org>
+8      string          OracleCFS       Oracle Clustered Filesystem,
+>4     long            x               rev %d
+>0     long            x               \b.%d,
+>560   string          x               label: %.64s,
+>136   string          x               mountpoint: %.128s
+
+# Oracle ASM tagged volume - Aaron Botsis <redhat@digitalmafia.org>
+32     string          ORCLDISK        Oracle ASM Volume,
+>40    string          x               Disk Name: %0.12s
+32     string          ORCLCLRD        Oracle ASM Volume (cleared),
+>40    string          x               Disk Name: %0.12s
+
+# Compaq/HP RILOE floppy image
+# From: Dirk Jagdmann <doj@cubic.org>
+0      string  CPQRFBLO        Compaq/HP RILOE floppy image
+
+#------------------------------------------------------------------------------
+# Files-11 On-Disk Structure (File system for various RSX-11 and VMS flavours).
+# These bits come from LBN 1 (home block) of ODS-1, ODS-2 and ODS-5 volumes,
+# which is mapped to VBN 2 of [000000]INDEXF.SYS;1 - gerardo.cacciari@gmail.com
+#
+1008    string          DECFILE11       Files-11 On-Disk Structure
+>525    byte            x               (ODS-%d);
+>1017   string          A               RSX-11, VAX/VMS or OpenVMS VAX file system;
+>1017   string          B
+>>525   byte            2               VAX/VMS or OpenVMS file system;
+>>525   byte            5               OpenVMS Alpha or Itanium file system;
+>984    string          x               volume label is '%-12.12s'
+
+# From: Thomas Klausner <wiz@NetBSD.org>
+# https://filext.com/file-extension/DAA
+# describes the daa file format. The magic would be:
+0      string          DAA\x0\x0\x0\x0\x0      PowerISO Direct-Access-Archive
+
+# From Albert Cahalan <acahalan@gmail.com>
+# really le32 operation,destination,payloadsize (but quite predictable)
+# 01 00 00 00 00 00 00 c0 00 02 00 00
+0      string          \1\0\0\0\0\0\0\300\0\2\0\0      Marvell Libertas firmware
+
+# From Eric Sandeen
+# GFS2
+0x10000         belong          0x01161970
+>0x10018        belong          0x0000051d      GFS1 Filesystem
+>>0x10024        belong          x               (blocksize %d,
+>>0x10060        string          >\0             lockproto %s)
+>0x10018        belong          0x00000709      GFS2 Filesystem
+>>0x10024        belong          x               (blocksize %d,
+>>0x10060        string          >\0             lockproto %s)
+
+# Russell Coker <russell@coker.com.au>
+0x10040                string  _BHRfS_M        BTRFS Filesystem
+>0x1012b       string  >\0             label "%s",
+>0x10090       lelong  x               sectorsize %d,
+>0x10094       lelong  x               nodesize %d,
+>0x10098       lelong  x               leafsize %d,
+>0x10020       belong  x               UUID=%08x-
+>0x10024       beshort x               \b%04x-
+>0x10026       beshort x               \b%04x-
+>0x10028       beshort x               \b%04x-
+>0x1002a       beshort x               \b%04x
+>0x1002c       belong  x               \b%08x,
+>0x10078       lequad  x               %lld/
+>0x10070       lequad  x               \b%lld bytes used,
+>0x10088       lequad  x               %lld devices
+
+# dvdisaster's .ecc
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0      string  *dvdisaster*    dvdisaster error correction file
+
+# xfs metadump image
+# mb_magic XFSM at 0; superblock magic XFSB at 1 << mb_blocklog
+# but can we do the << ?  For now it's always 512 (0x200) anyway.
+0      string XFSM
+>0x200 string XFSB     XFS filesystem metadump image
+
+# Type:        CROM filesystem
+# From:        Werner Fink <werner@suse.de>
+0      string  CROMFS  CROMFS
+>6     string  >\0     \b version %2.2s,
+>8     ulequad >0      \b block data at %lld,
+>16    ulequad >0      \b fblock table at %lld,
+>24    ulequad >0      \b inode table at %lld,
+>32    ulequad >0      \b root at %lld,
+>40    ulelong >0      \b fblock size = %d,
+>44    ulelong >0      \b block size = %d,
+>48    ulequad >0      \b bytes = %lld
+
+# Type:        xfs metadump image
+# From:        Daniel Novotny <dnovotny@redhat.com>
+# mb_magic XFSM at 0; superblock magic XFSB at 1 << mb_blocklog
+# but can we do the << ? For now it's always 512 (0x200) anyway.
+0      string  XFSM
+>0x200 string  XFSB    XFS filesystem metadump image
+
+# Type:        delta ISO
+# From:        Daniel Novotny <dnovotny@redhat.com>
+0      string  DISO    Delta ISO data,
+>4     belong  x       version %d
+
+# JFS2 (Journaling File System) image. (Old JFS1 has superblock at 0x1000.)
+# See linux/fs/jfs/jfs_superblock.h for layout; see jfs_filsys.h for flags.
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+0x8000 string  JFS1
+# Because it's text-only magic, check a binary value (version) to be sure.
+# Should always be 2, but mkfs.jfs writes it as 1. Needs to be 2 or 1 to be
+# mountable.
+>&0    lelong  <3      JFS2 filesystem image
+# Label is followed by a UUID; we have to limit string length to avoid
+# appending the UUID in the case of a 16-byte label.
+>>&144 regex   [\x20-\x7E]{1,16}       (label "%s")
+>>&0   lequad  x       \b, %lld blocks
+>>&8   lelong  x       \b, blocksize %d
+>>&32  lelong&0x00000006       >0      (dirty)
+>>&36  lelong  >0      (compressed)
+
+# LFS
+0      lelong  0x070162        LFS filesystem image
+>4     lelong  1               version 1,
+>>8    lelong  x               \b blocks %u,
+>>12   lelong  x               \b blocks per segment %u,
+>4     lelong  2               version 2,
+>>8    lelong  x               \b fragments %u,
+>>12   lelong  x               \b bytes per segment %u,
+>16    lelong  x               \b disk blocks %u,
+>20    lelong  x               \b block size %u,
+>24    lelong  x               \b fragment size %u,
+>28    lelong  x               \b fragments per block %u,
+>32    lelong  x               \b start for free list %u,
+>36    lelong  x               \b number of free blocks %d,
+>40    lelong  x               \b number of files %u,
+>44    lelong  x               \b blocks available for writing %d,
+>48    lelong  x               \b inodes in cache %d,
+>52    lelong  x               \b inode file disk address 0x%x,
+>56    lelong  x               \b inode file inode number %u,
+>60    lelong  x               \b address of last segment written 0x%x,
+>64    lelong  x               \b address of next segment to write 0x%x,
+>68    lelong  x               \b address of current segment written 0x%x
+
+0      string  td\000          floppy image data (TeleDisk, compressed)
+0      string  TD\000          floppy image data (TeleDisk)
+
+0      string  CQ\024          floppy image data (CopyQM,
+>16    leshort x               %d sectors,
+>18    leshort x               %d heads.)
+
+0      string  ACT\020Apricot\020disk\020image\032\004 floppy image data (ApriDisk)
+
+0      beshort 0xAA58          floppy image data (IBM SaveDskF, old)
+0      beshort 0xAA59          floppy image data (IBM SaveDskF)
+0      beshort 0xAA5A          floppy image data (IBM SaveDskF, compressed)
+
+0      string  \074CPM_Disk\076        disk image data (YAZE)
+
+# ReFS
+# Richard W.M. Jones <rjones@redhat.com>
+0      string  \0\0\0ReFS\0    ReFS filesystem image
+
+# EFW encase image file format:
+# Gregoire Passault
+# http://www.forensicswiki.org/wiki/Encase_image_file_format
+0      string  EVF\x09\x0d\x0a\xff\x00 EWF/Expert Witness/EnCase image file format
+
+# UBIfs
+# Linux kernel sources: fs/ubifs/ubifs-media.h
+0      lelong  0x06101831
+>0x16  leshort 0               UBIfs image
+>0x08  lequad  x               \b, sequence number %llu
+>0x10  leshort x               \b, length %u
+>0x04  lelong  x               \b, CRC 0x%08x
+
+0      lelong  0x23494255
+>0x04  leshort <2
+>0x05  string  \0\0\0
+>0x1c  string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>0x04  leshort x               UBI image, version %u
+
+# NEC PC-88 2D disk image
+# From Fabio R. Schmidlin <sd-snatcher@users.sourceforge.net>
+0x20           ulelong&0xFFFFFEFF      0x2A0
+>0x10          string                  \0\0\0\0\0\0\0\0\0\0
+>>0x280                string                  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>>>0x1A                ubyte&0xEF              0
+>>>>0x1B       ubyte&0x8F              0
+>>>>>0x1B      ubyte&70                <0x40
+>>>>>>0x1C     ulelong                 >0x21
+>>>>>>>0       regex   [[:print:]]*    NEC PC-88 disk image, name=%s
+>>>>>>>>0x1B   ubyte   0               \b, media=2D
+>>>>>>>>0x1B   ubyte   0x10            \b, media=2DD
+>>>>>>>>0x1B   ubyte   0x20            \b, media=2HD
+>>>>>>>>0x1B   ubyte   0x30            \b, media=1D
+>>>>>>>>0x1B   ubyte   0x40            \b, media=1DD
+>>>>>>>>0x1A   ubyte   0x10            \b, write-protected
+
+# HDD Raw Copy Tool disk image, file extension: .imgc
+# From Benjamin Vanheuverzwijn <bvanheu@gmail.com>
+0      pstring HDD\ Raw\ Copy\ Tool    %s
+>0x100 pstring x                       %s
+>0x200 pstring x                       - HD model: %s
+#>0x300        pstring x                       unknown %s
+>0x400 pstring x                       serial: %s
+#>0x500        pstring x                       unknown: %s
+!:ext  imgc
diff --git a/magic/Magdir/finger b/magic/Magdir/finger
new file mode 100644 (file)
index 0000000..ab43ac6
--- /dev/null
@@ -0,0 +1,16 @@
+
+#------------------------------------------------------------------------------
+# $File: finger,v 1.3 2019/04/19 00:42:27 christos Exp $
+# fingerprint:  file(1) magic for fingerprint data
+# XPM bitmaps)
+#
+
+# https://cgit.freedesktop.org/libfprint/libfprint/tree/libfprint/data.c
+
+0      string  FP1             libfprint fingerprint data V1
+>3     beshort x               \b, driver_id %x
+>5     belong  x               \b, devtype %x
+
+0      string  FP2             libfprint fingerprint data V2
+>3     beshort x               \b, driver_id %x
+>5     belong  x               \b, devtype %x
diff --git a/magic/Magdir/flash b/magic/Magdir/flash
new file mode 100644 (file)
index 0000000..33b7344
--- /dev/null
@@ -0,0 +1,62 @@
+
+#------------------------------------------------------------------------------
+# $File: flash,v 1.15 2019/04/19 00:42:27 christos Exp $
+# flash:       file(1) magic for Macromedia Flash file format
+#
+# See
+#
+#      https://www.macromedia.com/software/flash/open/
+#      https://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/\
+#      en/devnet/swf/pdf/swf-file-format-spec.pdf page 27
+#
+
+0   name       swf-details
+
+>0     string          F
+>>8    byte&0xfd       0x08            Macromedia Flash data
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+>>8    byte&0xfe       0x10            Macromedia Flash data
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+>>8    byte            0x18            Macromedia Flash data
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+>>8    beshort&0xff87  0x2000          Macromedia Flash data
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+>>8    beshort&0xffe0  0x3000          Macromedia Flash data
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+>>8    byte&0x7        0
+>>>8   ubyte           >0x2f
+>>>>9  ubyte           <0x20           Macromedia Flash data
+!:mime application/x-shockwave-flash
+>>>>>3 byte            x               \b, version %d
+
+>0     string          C
+>>8    byte            0x78            Macromedia Flash data (compressed)
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+
+>0     string          Z
+>>8    byte            0x5d            Macromedia Flash data (lzma compressed)
+!:mime application/x-shockwave-flash
+>>>3   byte            x               \b, version %d
+
+
+1      string          WS
+>4     ulelong         >14
+>>3    ubyte           !0
+>>>0   use             swf-details
+
+# From: Cal Peake <cp@absolutedigital.net>
+0      string          FLV\x01         Macromedia Flash Video
+!:mime video/x-flv
+
+#
+# Yosu Gomez
+0      string  AGD2\xbe\xb8\xbb\xcd\x00        Macromedia Freehand 7 Document
+0      string  AGD3\xbe\xb8\xbb\xcc\x00        Macromedia Freehand 8 Document
+# From Dave Wilson
+0      string  AGD4\xbe\xb8\xbb\xcb\x00        Macromedia Freehand 9 Document
diff --git a/magic/Magdir/flif b/magic/Magdir/flif
new file mode 100644 (file)
index 0000000..c77551e
--- /dev/null
@@ -0,0 +1,36 @@
+
+#------------------------------------------------------------------------------
+#      $File:  images,v        1.112   2015/11/13      00:38:33        christos        Exp     $
+#      flif:   Magic   data    for     file(1) command.
+#      FLIF    (Free   Lossless        Image   Format)
+
+0      string  FLIF    FLIF
+>4     string  <H      image data
+>>6    beshort x       \b, %u
+>>8    beshort x       \bx%u
+>>5    string  1       \b, 8-bit/color,
+>>5    string  2       \b, 16-bit/color,
+>>4    string  1       \b, grayscale, non-interlaced
+>>4    string  3       \b, RGB, non-interlaced
+>>4    string  4       \b, RGBA, non-interlaced
+>>4    string  A       \b, grayscale
+>>4    string  C       \b, RGB, interlaced
+>>4    string  D       \b, RGBA, interlaced
+>4     string  >H      \b, animation data
+>>5    ubyte   <255    \b, %i frames
+>>>7   beshort x       \b, %u
+>>>9   beshort x       \bx%u
+>>>6   string  =1      \b, 8-bit/color
+>>>6   string  =2      \b, 16-bit/color
+>>5    ubyte   0xFF
+>>>6   beshort x       \b, %i frames,
+>>>9   beshort x       \b, %u
+>>>11  beshort x       \bx%u
+>>>8   string  =1      \b, 8-bit/color
+>>>8   string  =2      \b, 16-bit/color
+>>4    string  =Q      \b, grayscale, non-interlaced
+>>4    string  =S      \b, RGB, non-interlaced
+>>4    string  =T      \b, RGBA, non-interlaced
+>>4    string  =a      \b, grayscale
+>>4    string  =c      \b, RGB, interlaced
+>>4    string  =d      \b, RGBA, interlaced
diff --git a/magic/Magdir/fonts b/magic/Magdir/fonts
new file mode 100644 (file)
index 0000000..f47736f
--- /dev/null
@@ -0,0 +1,382 @@
+
+#------------------------------------------------------------------------------
+# $File: fonts,v 1.41 2019/05/05 16:44:04 christos Exp $
+# fonts:  file(1) magic for font data
+#
+0      search/1        FONT            ASCII vfont text
+0      short           0436            Berkeley vfont data
+0      short           017001          byte-swapped Berkeley vfont data
+
+# PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com
+0      string          %!PS-AdobeFont-1.       PostScript Type 1 font text
+>20    string          >\0                     (%s)
+6      string          %!PS-AdobeFont-1.       PostScript Type 1 font program data
+0      string          %!FontType1     PostScript Type 1 font program data
+6      string          %!FontType1     PostScript Type 1 font program data
+0      string          %!PS-Adobe-3.0\ Resource-Font   PostScript Type 1 font text
+
+# Summary:     PostScript Type 1 Printer Font Metrics
+# URL:         https://en.wikipedia.org/wiki/PostScript_fonts
+# Reference:   https://partners.adobe.com/public/developer/en/font/5178.PFM.pdf
+# Modified by: Joerg Jenderek
+# Note:                moved from ./msdos magic
+# dfVersion 256=0100h
+0              uleshort        0x0100
+# GRR: line above is too general as it catches also TrueType font,
+# raw G3 data FAX, WhatsApp encrypted and Panorama database
+# dfType 129=0081h
+>66            uleshort        0x0081
+# dfVertRes 300=012Ch not needed as additional test
+#>>70          uleshort        0x012c
+# dfHorizRes 300=012Ch
+#>>>72         uleshort        0x012c
+# dfDriverInfo points to postscript information section
+>>(101.l)      string/c        Postscript      Printer Font Metrics
+# above labeled "PFM data" by ./msdos (version 5.28) or "Adobe Printer Font Metrics" by TrID
+!:mime application/x-font-pfm
+# AppleShare Print Server
+#!:apple       ASPS????
+!:ext  pfm
+# dfCopyright 60 byte null padded Copyright string. uncomment it to get old looking
+#>>>6          string          >\060           - %-.60s
+# dfDriverInfo
+>>>139         ulelong         >0
+# often abbreviated and same as filename
+>>>>(139.l)    string          x               %s
+# dfSize
+>>>2           ulelong         x               \b, %d bytes
+# dfFace 210=D2h 9Eh
+>>>105         ulelong         >0
+# Windows font name
+>>>>(105.l)    string          x               \b, %s
+# dfItalic
+>>>80          ubyte           1               italic
+# dfUnderline
+>>>81          ubyte           1               underline
+# dfStrikeOut
+>>>82          ubyte           1               strikeout
+# dfWeight 400=0x0190 300=0x012c 500=0x01f4 600=0x0258 700=0x02bc
+>>>83          uleshort        >699            bold
+# dfPitchAndFamily 16 17 48 49 64 65
+>>>90          ubyte           16              serif
+>>>90          ubyte           17              serif proportional
+#>>>90         ubyte           48              other
+>>>90          ubyte           49              proportional
+>>>90          ubyte           64              script
+>>>90          ubyte           65              script proportional
+
+# X11 font files in SNF (Server Natural Format) format
+# updated by Joerg Jenderek at Feb 2013
+# http://computer-programming-forum.com/51-perl/8f22fb96d2e34bab.htm
+0      belong          00000004                X11 SNF font data, MSB first
+#>104  belong          00000004                X11 SNF font data, MSB first
+!:mime application/x-font-sfn
+# GRR: line below too general as it catches also Xbase index file t3-CHAR.NDX
+0      lelong          00000004
+>104   lelong          00000004                X11 SNF font data, LSB first
+!:mime application/x-font-sfn
+
+# X11 Bitmap Distribution Format, from Daniel Quinlan (quinlan@yggdrasil.com)
+0      search/1        STARTFONT\              X11 BDF font text
+
+# From: Joerg Jenderek
+# URL: https://grub.gibibit.com/New_font_format
+# Reference: util/grub-mkfont.c
+#              include/grub/fontformat.h
+# FONT_FORMAT_SECTION_NAMES_FILE
+0                      string          FILE
+# FONT_FORMAT_PFF2_MAGIC
+>8                     string          PFF2
+# leng 4 only at the moment
+>>4                    ubelong         4
+# FONT_FORMAT_SECTION_NAMES_FONT_NAME
+>>>12                  string          NAME            GRUB2 font
+!:mime                 application/x-font-pf2
+!:ext                  pf2
+# length of font_name
+>>>>16                 ubelong         >0
+# font_name
+>>>>>20                        string          >\0             "%-s"
+
+# X11 fonts, from Daniel Quinlan (quinlan@yggdrasil.com)
+# PCF must come before SGI additions ("MIPSEL MIPS-II COFF" collides)
+0      string          \001fcp                 X11 Portable Compiled Font data,
+>12    lelong          ^0x08                   bit: LSB,
+>12    lelong          &0x08                   bit: MSB,
+>12    lelong          ^0x04                   byte: LSB first
+>12    lelong          &0x04                   byte: MSB first
+0      string          D1.0\015                X11 Speedo font data
+
+#------------------------------------------------------------------------------
+# FIGlet fonts and controlfiles
+# From figmagic supplied with Figlet version 2.2
+# "David E. O'Brien" <obrien@FreeBSD.ORG>
+0      string          flf             FIGlet font
+>3     string          >2a             version %-2.2s
+0      string          flc             FIGlet controlfile
+>3     string          >2a             version %-2.2s
+
+# libGrx graphics lib fonts, from Albert Cahalan (acahalan@cs.uml.edu)
+# Used with djgpp (DOS Gnu C++), sometimes Linux or Turbo C++
+0      belong          0x14025919      libGrx font data,
+>8     leshort         x               %dx
+>10    leshort         x               \b%d
+>40    string          x               %s
+# Misc. DOS VGA fonts, from Albert Cahalan (acahalan@cs.uml.edu)
+0      belong          0xff464f4e      DOS code page font data collection
+7      belong          0x00454741      DOS code page font data
+7      belong          0x00564944      DOS code page font data (from Linux?)
+4098   string          DOSFONT         DOSFONT2 encrypted font data
+
+# From: Joerg Jenderek
+# URL: http://fileformats.archiveteam.org/wiki/GEM_bitmap_font
+# Reference: http://cd.textfiles.com/ataricompendium/BOOK/HTML/APPENDC.HTM#cnt
+#
+# usual case with lightening mask and skewing mask 5555h~UU
+62     ulelong         0x55555555
+>0     use             gdos-font
+# BOX18.GFT COWBOY30.GFT ROYALK30.GFT
+62     ulelong         0
+# skip ISO 9660 CD-ROM ./filesystem by looking for low positive face size
+>2     uleshort        >2
+# skip DOS 2.0 backup id file ./msdos by looking for face size lower/equal 48
+>>2    uleshort        <49
+# skip MS Windows ICO ./msdos by looking for valid face name
+>>>4   ubeshort        >0x1F00
+# skip DOS executable BACKM212.COM by looking for horizontal offset table after header
+#>>>>68        ulelong         >87             OFFSET_OK
+>>>>0  use             gdos-font
+0      name            gdos-font
+>0     uleshort        x               GEM GDOS font
+!:mime application/x-font-gdos
+# also .eps found like AA070GEP.EPS AI360GEP.EPS
+!:ext  fnt/gtf
+# font name like University Bold
+>4     string          x               %.32s
+# face size in points 3-48
+>2     uleshort        x               %u
+# face ID (must be unique)
+>0     uleshort        x               \b, ID 0x%4.4x
+# lowest character index in face (usually 32 for disk-loaded fonts).
+#>36   uleshort        x               \b, low character index %u
+# width of the widest character
+#>50   uleshort        x               \b, %u char width
+# width of the widest character cell
+#>52   uleshort        x               \b, %u cell width
+# thickening size
+#>58   uleshort        x               \b, %u thick
+# lightening mask to eliminate pixels, usually 5555h
+>62    uleshort        !0x5555         \b, lightening mask 0x%x
+# skewing mask to determine when to perform additional rotation when skewing, usually 5555h
+>64    uleshort        !0x5555         \b, skewing mask 0x%x
+# offset to horizontal offset table 58h~88 5eh
+#>68   ulelong         >88             \b, 0x%x horizontal table offset
+# offset character offset table
+#>72   ulelong         x               \b, 0x%x coffset
+# offset to font data
+#>72   ulelong         x               \b, 0x%x foffset
+# form width in bytes
+#>80   uleshort        x               \b, %u fwidth
+# pointer to the next font, set by GDOS after loading
+#>84   ulelong         x               \b, 0x%x noffset
+
+# downloadable fonts for browser (prints type) anthon@mnt.org
+# https://tools.ietf.org/html/rfc3073
+0      string          PFR1            Portable Font Resource font data (new)
+>102   string          >0              \b: %s
+0      string          PFR0            Portable Font Resource font data (old)
+>4     beshort         >0              version %d
+
+# True Type fonts
+# Modified by: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/TrueType
+# Reference: https://developer.apple.com/fonts/TrueType-Reference-Manual/
+#
+# sfnt version "typ1" used by some Apple, but no example found
+0      string  typ1
+>0     use             sfnt-font
+>0     use             sfnt-names
+# sfnt version "true" used by some Apple
+0      string  true
+>0     use             sfnt-font
+>0     use             sfnt-names
+# GRR: below test is too general
+# sfnt version often 0x00010000
+0      string  \000\001\000\000
+>0     use             sfnt-font
+>0     use             sfnt-names
+#      validate and display sfnt font data like number of tables
+0      name            sfnt-font
+# file 5.30 version assumes 00FFh as maximal number of tables
+#>4    ubeshort        <0x0100         
+# maximal 27 tables found like in Skia.ttf
+# 46 different table names mentioned on Apple specification
+# skip 1st sequence of DOS 2 backup with path separator (\~92 or /~47) misinterpreted as table number
+>4     ubeshort        <47             
+# skip bad examples with garbage table names like in a5.show HYPERC MAC
+# tag names consist of up to four characters padded with spaces at end like
+# BASE DSIG OS/2 Zapf acnt glyf cvt vmtx xref ...
+>>12   regex/4l        \^[A-Za-z][A-Za-z][A-Za-z/][A-Za-z2\ ]  
+#>>>0  ubelong x       \b, sfnt version 0x%x
+>>>0   ubelong !0x4f54544f     TrueType
+!:mime font/sfnt
+!:apple        ????tfil
+# .ttf for TrueType font
+# EUDC.tte created by privat character editor %WINDIR%\system32\eudcedit.exe
+!:ext  ttf/tte
+# sfnt version 4F54544Fh~OTTO
+>>>0   ubelong =0x4f54544f     OpenType
+!:mime font/otf
+!:apple        ????OTTO
+!:ext  otf
+>>>0   ubelong x               Font data
+# DSIG=44454947h table name implies a digitally signed font
+# search range = number of tables * 16 =< maximal number of tables * 16 = 27 * 16 = 432
+>>>12  search/432      DSIG            \b, digitally signed
+>>>4   ubeshort        x               \b, %d tables
+# minimal 9 tables found like in NISC18030.ttf
+#>>>4  ubeshort        <10             TMIN
+#>>>4  ubeshort        >24             TBIG
+# table directory entries
+>>>12  string          x               \b, 1st "%4.4s"
+
+#      search and display 1st name in sfnt font which is often copyright text
+#      does not work inside font collections
+0      name            sfnt-names
+# search for naming table
+>12    search/432/s    name            
+# biggest offset 0x0100bd28 like Windows10 Fonts\simsunb.ttf
+#>>>>&8        ubelong         >0x0100bd27     BIGGEST OFFSET
+>>&8   ubelong         >0x00100000     
+# offset of name table
+>>>&-4 ubelong         x               \b, name offset 0x%x
+# GRR: pointer to name table only works if offset ~< FILE_BYTES_MAX = 100000h defined in src\file.h
+>>&8   ubelong         <0x00100000     
+>>>&-16        ubelong         x               
+# name table
+>>>>(&8.L)     ubequad x               
+# invalid format selector 
+#>>>>>&-8      ubeshort        !0      \b, invalid selector %x
+# minimal 3 name records found like in c:\Program Files (x86)\Tesseract-OCR\tessdata\pdf.ttf
+# maximal 1227 name records found like in Apple Chancery.ttf
+#>>>>>&-6      ubeshort        <0x4    mincount
+#>>>>>&-6      ubeshort        >130    maxcount
+>>>>>&-6       ubeshort        x       \b, %d names
+# offset to start of string storage from start of table
+#>>>>>&-4      ubeshort        x       \b, record offset %d
+# 1st name record
+# string offset from start of storage area 
+#>>>>>&8               ubeshort        x       \b, string offset %d
+# string length
+#>>>>>&6               ubeshort        x       \b, string length %d
+# minimal name string 7 like in c:\Program Files (x86)\Kodi\addons\webinterface.default\lib\video-js\font\VideoJS.ttf
+# also found 0 like in SWZCONLN.TTF
+#>>>>>&6               ubeshort        <8      MIN STRING
+# maximal name string 806 like in c:\Windows\Fonts\palabi.ttf
+#>>>>>&6               ubeshort        >805    MAX STRING
+# platform identifier: 0~Apple Unicode, 1~Macintosh, 3~Microsoft
+#>>>>>&-2      ubeshort        >3      BAD PLATFORM
+>>>>>&-2       ubeshort        0       \b, Unicode
+>>>>>&-2       ubeshort        1       \b, Macintosh
+>>>>>&-2       ubeshort        3       \b, Microsoft
+# languageID (0~english Macintosh, 0409h~english Microsoft, ...)
+>>>>>&2                ubeshort        >0      \b, language 0x%x
+# name identifiers
+# often 0~copyright, 1~font, 2~font subfamily, 5~version, 13~license, 19~sample, ...
+>>>>>&4                ubeshort        >0      \b, type %d string
+# platform specific encoding:
+# 0~undefined character set, 1~UGL set with Unicode, 3~Unicode 2.0 BMP only, 4~Unicode 2.0
+#>>>>>&0               ubeshort        x       \b, %d encoding
+>>>>>&0                ubeshort        0       
+# handle only name string offset 0 because do not know how to add 2 relative offsets
+>>>>>>&6               ubeshort        0       
+>>>>>>>&(&-14.S-18)    ubyte           !0      
+# GRR: instead 806 only first MAXstring = 96 characters are displayed as defined in src\file.h
+# often copyright string that starts like \251 2006 The Monotype Corporation
+>>>>>>>>&-1            string          x       \b, %-11.96s
+# test for unicode string
+>>>>>>>&(&-14.S-18)    ubyte           0       
+>>>>>>>>&0             lestring16      x       \b, %-11.96s
+# unicode encoding
+>>>>>&0                ubeshort        >0      
+>>>>>>&6               ubeshort        0       
+>>>>>>>&(&-14.S-17)    lestring16      x       \b, %-11.96s
+
+0      string          \007\001\001\000Copyright\ (c)\ 199     Adobe Multiple Master font
+0      string          \012\001\001\000Copyright\ (c)\ 199     Adobe Multiple Master font
+
+# TrueType/OpenType font collections (.ttc)
+# URL: https://en.wikipedia.org/wiki/OpenType
+# https://www.microsoft.com/typography/otspec/otff.htm
+# Modified by: Joerg Jenderek
+# Note:        container for TrueType, OpenType font
+0      string          ttcf
+# skip ASCII text
+>4     ubyte           0               
+# sfnt version often 0x00010000 of 1st table is TrueType
+>>(12.L)       ubelong !0x4f54544f     TrueType
+!:mime font/ttf
+!:apple        ????tfil
+!:ext  ttc
+# sfnt version 4F54544Fh~OTTO of 1st table is OpenType font 
+>>(12.L)       ubelong =0x4f54544f     OpenType
+!:mime font/otf
+!:apple        ????OTTO
+# no example found for otc
+!:ext  ttc/otc
+>>4    ubyte           x               font collection data
+#!:mime        font/collection
+# TCC version
+>>4    belong          0x00010000      \b, 1.0
+>>4    belong          0x00020000      \b, 2.0
+>>8    ubelong         >0              \b, %d fonts
+# array offset size = fonts * offsetsize = fonts * 4
+>>(8.L*4) ubequad      x               
+# 0x44454947 = 'DSIG'
+>>>&4  belong          0x44534947      \b, digitally signed
+# offset to 1st font
+>>12   ubelong         x               \b, at 0x%x
+# point to 1st font that starts with sfnt version
+>>(12.L) use           sfnt-font
+
+# Opentype font data from Avi Bercovich
+0      string          OTTO            OpenType font data
+!:mime application/vnd.ms-opentype
+
+# From: Alex Myczko <alex@aiei.ch>
+0      string          SplineFontDB:   Spline Font Database
+!:mime application/vnd.font-fontforge-sfd
+>14    string          x               version %s
+
+# EOT
+0x40   string          \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>0x22  string          LP              Embedded OpenType (EOT)
+# workaround until there's lepstring16
+# >>0x52       lepstring16/h   >\0             \b, %s family
+>>0x52 short   !0
+>>>0x54        lestring16      x               \b, %s family
+!:mime application/vnd.ms-fontobject
+
+# Web Open Font Format (.woff)
+0      name            woff
+>4     belong          0x00010000      \b, TrueType
+>4     belong          0x4F54544F      \b, CFF
+>4     belong          0x74727565      \b, TrueType
+>4     default         x
+>>4    belong          x               \b, flavor %d
+>8     belong          x               \b, length %d
+#>12   beshort         x               \b, numTables %d
+#>14   beshort         x               \b, reserved %d
+#>16   belong          x               \b, totalSfntSize %d
+
+# https://www.w3.org/TR/WOFF/
+0      string          wOFF    Web Open Font Format
+>0     use             woff
+>20    beshort         x       \b, version %d
+>22    beshort         x       \b.%d
+# https://www.w3.org/TR/WOFF2/
+0      string          wOF2    Web Open Font Format (Version 2)
+>0     use             woff
+#>20   belong          x       \b, totalCompressedSize %d
+>24    beshort         x       \b, version %d
+>26    beshort         x       \b.%d
diff --git a/magic/Magdir/fortran b/magic/Magdir/fortran
new file mode 100644 (file)
index 0000000..70102df
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File: fortran,v 1.9 2015/06/17 19:55:27 christos Exp $
+# FORTRAN source
+# Check that the first 100 lines start with C or whitespace first.
+0       regex/100l      !\^[^Cc\ \t].*$
+>0     regex/100l      \^[Cc][\ \t]    FORTRAN program text
+!:mime text/x-fortran
+!:strength - 5
diff --git a/magic/Magdir/frame b/magic/Magdir/frame
new file mode 100644 (file)
index 0000000..d3f9687
--- /dev/null
@@ -0,0 +1,50 @@
+
+#------------------------------------------------------------------------------
+# $File: frame,v 1.12 2009/09/19 16:28:09 christos Exp $
+# frame:  file(1) magic for FrameMaker files
+#
+# This stuff came on a FrameMaker demo tape, most of which is
+# copyright, but this file is "published" as witness the following:
+#
+# Note that this is the Framemaker Maker Interchange Format, not the
+# Normal format which would be application/vnd.framemaker.
+#
+0      string          \<MakerFile     FrameMaker document
+!:mime application/x-mif
+>11    string          5.5              (5.5
+>11    string          5.0              (5.0
+>11    string          4.0              (4.0
+>11    string          3.0              (3.0
+>11    string          2.0              (2.0
+>11    string          1.0              (1.0
+>14    byte            x                 %c)
+0      string          \<MIFFile       FrameMaker MIF (ASCII) file
+!:mime application/x-mif
+>9     string          4.0              (4.0)
+>9     string          3.0              (3.0)
+>9     string          2.0              (2.0)
+>9     string          1.0              (1.x)
+0      search/1        \<MakerDictionary       FrameMaker Dictionary text
+!:mime application/x-mif
+>17    string          3.0              (3.0)
+>17    string          2.0              (2.0)
+>17    string          1.0              (1.x)
+0      string          \<MakerScreenFont       FrameMaker Font file
+!:mime application/x-mif
+>17    string          1.01             (%s)
+0      string          \<MML           FrameMaker MML file
+!:mime application/x-mif
+0      string          \<BookFile      FrameMaker Book file
+!:mime application/x-mif
+>10    string          3.0              (3.0
+>10    string          2.0              (2.0
+>10    string          1.0              (1.0
+>13    byte            x                 %c)
+# XXX - this book entry should be verified, if you find one, uncomment this
+#0     string          \<Book\040      FrameMaker Book (ASCII) file
+#!:mime        application/x-mif
+#>6    string          3.0              (3.0)
+#>6    string          2.0              (2.0)
+#>6    string          1.0              (1.0)
+0      string          \<Maker\040Intermediate\040Print\040File        FrameMaker IPL file
+!:mime application/x-mif
diff --git a/magic/Magdir/freebsd b/magic/Magdir/freebsd
new file mode 100644 (file)
index 0000000..b0ab4bf
--- /dev/null
@@ -0,0 +1,144 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# freebsd:  file(1) magic for FreeBSD objects
+#
+# All new-style FreeBSD magic numbers are in host byte order (i.e.,
+# little-endian on x86).
+#
+# XXX - this comes from the file "freebsd" in a recent FreeBSD version of
+# "file"; it, and the NetBSD stuff in "netbsd", appear to use different
+# schemes for distinguishing between executable images, shared libraries,
+# and object files.
+#
+# FreeBSD says:
+#
+#    Regardless of whether it's pure, demand-paged, or none of the
+#    above:
+#
+#      if the entry point is < 4096, then it's a shared library if
+#      the "has run-time loader information" bit is set, and is
+#      position-independent if the "is position-independent" bit
+#      is set;
+#
+#      if the entry point is >= 4096 (or >4095, same thing), then it's
+#      an executable, and is dynamically-linked if the "has run-time
+#      loader information" bit is set.
+#
+# On x86, NetBSD says:
+#
+#    If it's neither pure nor demand-paged:
+#
+#      if it has the "has run-time loader information" bit set, it's
+#      a dynamically-linked executable;
+#
+#      if it doesn't have that bit set, then:
+#
+#          if it has the "is position-independent" bit set, it's
+#          position-independent;
+#
+#          if the entry point is non-zero, it's an executable, otherwise
+#          it's an object file.
+#
+#    If it's pure:
+#
+#      if it has the "has run-time loader information" bit set, it's
+#      a dynamically-linked executable, otherwise it's just an
+#      executable.
+#
+#    If it's demand-paged:
+#
+#      if it has the "has run-time loader information" bit set,
+#      then:
+#
+#          if the entry point is < 4096, it's a shared library;
+#
+#          if the entry point is = 4096 or > 4096 (i.e., >= 4096),
+#          it's a dynamically-linked executable);
+#
+#      if it doesn't have the "has run-time loader information" bit
+#      set, then it's just an executable.
+#
+# (On non-x86, NetBSD does much the same thing, except that it uses
+# 8192 on 68K - except for "68k4k", which is presumably "68K with 4K
+# pages - SPARC, and MIPS, presumably because Sun-3's and Sun-4's
+# had 8K pages; dunno about MIPS.)
+#
+# I suspect the two will differ only in perverse and uninteresting cases
+# ("shared" libraries that aren't demand-paged and whose pages probably
+# won't actually be shared, executables with entry points <4096).
+#
+# I leave it to those more familiar with FreeBSD and NetBSD to figure out
+# what the right answer is (although using ">4095", FreeBSD-style, is
+# probably better than separately checking for "=4096" and ">4096",
+# NetBSD-style).  (The old "netbsd" file analyzed FreeBSD demand paged
+# executables using the NetBSD technique.)
+#
+0      lelong&0377777777       041400407       FreeBSD/i386
+>20    lelong                  <4096
+>>3    byte&0xC0               &0x80           shared library
+>>3    byte&0xC0               0x40            PIC object
+>>3    byte&0xC0               0x00            object
+>20    lelong                  >4095
+>>3    byte&0x80               0x80            dynamically linked executable
+>>3    byte&0x80               0x00            executable
+>16    lelong                  >0              not stripped
+
+0      lelong&0377777777       041400410       FreeBSD/i386 pure
+>20    lelong                  <4096
+>>3    byte&0xC0               &0x80           shared library
+>>3    byte&0xC0               0x40            PIC object
+>>3    byte&0xC0               0x00            object
+>20    lelong                  >4095
+>>3    byte&0x80               0x80            dynamically linked executable
+>>3    byte&0x80               0x00            executable
+>16    lelong                  >0              not stripped
+
+0      lelong&0377777777       041400413       FreeBSD/i386 demand paged
+>20    lelong                  <4096
+>>3    byte&0xC0               &0x80           shared library
+>>3    byte&0xC0               0x40            PIC object
+>>3    byte&0xC0               0x00            object
+>20    lelong                  >4095
+>>3    byte&0x80               0x80            dynamically linked executable
+>>3    byte&0x80               0x00            executable
+>16    lelong                  >0              not stripped
+
+0      lelong&0377777777       041400314       FreeBSD/i386 compact demand paged
+>20    lelong                  <4096
+>>3    byte&0xC0               &0x80           shared library
+>>3    byte&0xC0               0x40            PIC object
+>>3    byte&0xC0               0x00            object
+>20    lelong                  >4095
+>>3    byte&0x80               0x80            dynamically linked executable
+>>3    byte&0x80               0x00            executable
+>16    lelong                  >0              not stripped
+
+# XXX gross hack to identify core files
+# cores start with a struct tss; we take advantage of the following:
+# byte 7:     highest byte of the kernel stack pointer, always 0xfe
+#      8/9:   kernel (ring 0) ss value, always 0x0010
+#      10 - 27: ring 1 and 2 ss/esp, unused, thus always 0
+#      28:    low order byte of the current PTD entry, always 0 since the
+#             PTD is page-aligned
+#
+7      string  \357\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0        FreeBSD/i386 a.out core file
+>1039  string  >\0     from '%s'
+
+# /var/run/ld.so.hints
+# What are you laughing about?
+0      lelong                  011421044151    ld.so hints file (Little Endian
+>4     lelong                  >0              \b, version %d)
+>4     belong                  <1              \b)
+0      belong                  011421044151    ld.so hints file (Big Endian
+>4     belong                  >0              \b, version %d)
+>4     belong                  <1              \b)
+
+#
+# Files generated by FreeBSD scrshot(1)/vidcontrol(1) utilities
+#
+0      string  SCRSHOT_        scrshot(1) screenshot,
+>8     byte    x               version %d,
+>9     byte    2               %d bytes in header,
+>>10   byte    x               %d chars wide by
+>>11   byte    x               %d chars high
diff --git a/magic/Magdir/fsav b/magic/Magdir/fsav
new file mode 100644 (file)
index 0000000..7ea0941
--- /dev/null
@@ -0,0 +1,128 @@
+
+#------------------------------------------------------------------------------
+# $File: fsav,v 1.19 2019/04/19 00:42:27 christos Exp $
+# fsav:  file(1) magic for datafellows fsav virus definition files
+# Anthon van der Neut (anthon@mnt.org)
+
+# ftp://ftp.f-prot.com/pub/{macrdef2.zip,nomacro.def}
+0      beshort         0x1575          fsav macro virus signatures
+>8     leshort         >0              (%d-
+>11    byte            >0              \b%02d-
+>10    byte            >0              \b%02d)
+# ftp://ftp.f-prot.com/pub/sign.zip
+#10    ubyte           <12
+#>9    ubyte           <32
+#>>8   ubyte           0x0a
+#>>>12 ubyte           0x07
+#>>>>11        uleshort        >0              fsav DOS/Windows virus signatures (%d-
+#>>>>10        byte            0               \b01-
+#>>>>10        byte            1               \b02-
+#>>>>10        byte            2               \b03-
+#>>>>10        byte            3               \b04-
+#>>>>10        byte            4               \b05-
+#>>>>10        byte            5               \b06-
+#>>>>10        byte            6               \b07-
+#>>>>10        byte            7               \b08-
+#>>>>10        byte            8               \b09-
+#>>>>10        byte            9               \b10-
+#>>>>10        byte            10              \b11-
+#>>>>10        byte            11              \b12-
+#>>>>9 ubyte           >0              \b%02d)
+# ftp://ftp.f-prot.com/pub/sign2.zip
+#0     ubyte           0x62
+#>1    ubyte           0xF5
+#>>2   ubyte           0x1
+#>>>3  ubyte           0x1
+#>>>>4 ubyte           0x0e
+#>>>>>13               ubyte   >0              fsav virus signatures
+#>>>>>>11      ubyte   x               size 0x%02x
+#>>>>>>12      ubyte   x               \b%02x
+#>>>>>>13      ubyte   x               \b%02x bytes
+
+# Joerg Jenderek: joerg dot jenderek at web dot de
+# clamav-0.100.2\docs\html\node60.html 
+# https://github.com/vrtadmin/clamav-faq/raw/master/manual/clamdoc.pdf
+# ClamAV virus database files start with a 512 bytes colon separated header
+# ClamAV-VDB:buildDate:version:signaturesNumbers:functionalityLevelRequired:MD5:Signature:builder:buildTime
+# + gzipped (optional) tarball files
+# output can often be verified by `sigtool --info=FILE`
+0      string          ClamAV-VDB:     Clam AntiVirus
+# padding spaces implies database
+>511   ubyte           =0x20           database
+!:mime application/x-clamav-database
+# empty build time
+>>10   string          =::             (unsigned)
+# sigtool(1) man page
+!:ext  cud
+# display some text to avoid error like:
+# Magdir/fsav, 78: Warning: Current entry does not yet have a description for adding a EXTENSION type
+# file: could not find any valid magic files! (No error)
+>>10   default         x               (with buildtime)
+#>>10  default         x
+# clamtmp is used for temporily database like update process
+# for pure tar database only cld extension found
+!:ext  cld/cvd/clamtmp/cud
+>511   default         x               file
+!:mime application/x-clamav
+!:ext  info
+>11    string          >\0
+# buildDate empty or like "22 Mar 2017 12-57 -0400"; verified by `sigtool -i FILE`
+>>11   regex           \^[^:]{0,23}    \b, %s
+# version like 25170
+>>>&1  regex           \^[^:]{1,6}     \b, version %s
+# signaturesNumbers like 4566249
+>>>>&1 regex           \^[^:]{1,10}    \b, %s signatures
+# functionalityLevelRequired like 60
+>>>>>&1        regex           \^[^:]{1,4}     \b, level %s
+# X for nothing or MD5
+#>>>>>>&1      regex   \^[^:]{1,32}    \b, MD5 "%s"
+>>>>>>&1       regex   \^[^:]{1,32}
+# X for nothing or digital signature starting like AIzk/LYbX
+#>>>>>>>&1     regex   \^[^:]{1,255}   \b, signature "%s"
+>>>>>>>&1      regex   \^[^:]{1,255}
+# builder like neo
+>>>>>>>>&1     regex   \^[^:]{1,32}    \b, builder %s
+# buildTime like 1506611558
+#>>>>>>>>>&1   regex   \^[^:]{1,10}    \b, %s
+>>>>>>>>>&1    regex   \^[^:]{1,10}    
+# padding with spaces
+#>>>>>>>>>>&1  ubequad x               \b, padding 0x%16.16llx
+>510   ubyte           =0x20
+# inspect real database content
+#>>512 ubeshort        x               \b, database MAGIC 0x%x
+# ./archive handle pure tar archives
+>>1012 quad            =0              \b, with
+>>>512 use             tar-file
+# not pure tar
+>>1012 quad            !0
+# one space at the end of text and then handles gziped archives by ./compress
+>>>512 string          \037\213        \b, with 
+>>>>512        indirect        x
+
+# Type: Grisoft AVG AntiVirus
+# From: David Newgas <david@newgas.net>
+0      string  AVG7_ANTIVIRUS_VAULT_FILE       AVG 7 Antivirus vault file data
+
+0      string  X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR
+>33    string  -STANDARD-ANTIVIRUS-TEST-FILE!$H+H*     EICAR virus test files
+
+# From: Joerg Jenderek
+# URL: https://www.avira.com/
+# Note: found in directory %ProgramData%\Avira\Antivirus\INFECTED (Windows)
+# tested with version 15.0.43.23 at November 2019
+0      string          AntiVir\ Qua    Avira AntiVir quarantined
+!:mime application/x-avira-qua
+#!:mime        application/octet-stream
+!:ext  qua
+>156   string          SUSPICIOUS_FILE
+# file path of suspicious file
+>>220  lestring16      x               %s
+>156   string          !SUSPICIOUS_FILE
+# file path of virus file
+>>228  lestring16      x               %s
+# quarantined date
+>60    ldate           x               at %s
+# virus/danger name
+>156   string          !SUSPICIOUS_FILE
+>>156  string          x               \b, category "%s"
+
diff --git a/magic/Magdir/fusecompress b/magic/Magdir/fusecompress
new file mode 100644 (file)
index 0000000..ecb73b7
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: mcrypt,v 1.5 2009/09/19 16:28:10 christos Exp $
+# fusecompress:   file(1) magic for fusecompress
+0      string  \037\135\211    FuseCompress(ed) data
+>3     byte    0x00    (none format)
+>3     byte    0x01    (bz2 format)
+>3     byte    0x02    (gz format)
+>3     byte    0x03    (lzo format)
+>3     byte    0x04    (xor format)
+>3     byte    >0x04   (unknown format)
+>4     long    x       uncompressed size: %d
diff --git a/magic/Magdir/games b/magic/Magdir/games
new file mode 100644 (file)
index 0000000..30e6159
--- /dev/null
@@ -0,0 +1,301 @@
+
+#------------------------------------------------------------------------------
+# $File: games,v 1.17 2019/04/19 00:42:27 christos Exp $
+# games:  file(1) for games
+
+# Fabio Bonelli <fabiobonelli@libero.it>
+# Quake II - III data files
+0       string  IDP2           Quake II 3D Model file,
+>20     long    x               %u skin(s),
+>8      long    x               (%u x
+>12     long    x              %u),
+>40     long    x               %u frame(s),
+>16     long    x               Frame size %u bytes,
+>24     long   x               %u vertices/frame,
+>28     long    x              %u texture coordinates,
+>32     long    x               %u triangles/frame
+
+0       string  IBSP            Quake
+>4      long    0x26            II Map file (BSP)
+>4      long    0x2E           III Map file (BSP)
+
+0       string  IDS2            Quake II SP2 sprite file
+
+#---------------------------------------------------------------------------
+# Doom and Quake
+# submitted by Nicolas Patrois
+
+0       string  \xcb\x1dBoom\xe6\xff\x03\x01    Boom or linuxdoom demo
+# some doom lmp files don't match, I've got one beginning with \x6d\x02\x01\x01
+
+24      string  LxD\ 203        Linuxdoom save
+>0      string  x       , name=%s
+>44     string  x       , world=%s
+
+# Quake
+
+# Update: Joerg Jenderek
+# URL: http://fileformats.archiveteam.org/wiki/PAK
+# reference: https://quakewiki.org/wiki/.pak
+# GRR: line below is too general as it matches also Acorn PackDir compressed Archive
+# and Git pack ./revision
+0       string  PACK    
+# real Quake examples like pak0.pak have only some hundreds like 150 files
+# So test for few files
+>8     ulelong <0x01000000     
+# in file version 5.32 test for null terminator is only true for
+# offset ~< FILE_BYTES_MAX = 1 MB defined in ../../src/file.h 
+# look for null terminator of 1st entry name
+>>(4.l+55)     ubyte   0       Quake I or II world or extension
+!:mime application/x-dzip
+!:ext  pak
+#>>>8  ulelong x       \b, table size %u
+# dividing this by entry size (64) gives number of files
+>>>8   ulelong/64 x    \b, %u files
+# offset to the beginning of the file table
+>>>4   ulelong x       \b, offset 0x%x
+# 1st file entry
+>>>(4.l)       use     pak-entry
+# 2nd file entry
+#>>>4  ulelong+64      x       \b, offset 0x%x
+#>>>(4.l+64)   use     pak-entry
+#
+#      display file table entry of Quake PAK archive
+0      name            pak-entry
+# normally entry start after header which implies offset 12 or higher
+>56    ulelong >11     
+# the offset from the beginning of pak to beginning of this entry file contents
+>>56   ulelong x       at 0x%x
+# the size of file for this entry 
+>>60   ulelong x       %u bytes
+# 56 byte null-terminated entry name string includes path like maps/e1m1.bsp
+>>0    string  x       '%-.56s'
+# inspect entry content by jumping to entry offset
+>>(56) indirect x      \b: 
+
+#0       string  -1\x0a  Quake I demo
+#>30     string  x        version %.4s
+#>61     string  x        level %s
+
+#0       string  5\x0a   Quake I save
+
+# The levels
+
+# Quake 1
+
+0      string  5\x0aIntroduction             Quake I save: start Introduction
+0      string  5\x0athe_Slipgate_Complex     Quake I save: e1m1 The slipgate complex
+0      string  5\x0aCastle_of_the_Damned     Quake I save: e1m2 Castle of the damned
+0      string  5\x0athe_Necropolis           Quake I save: e1m3 The necropolis
+0      string  5\x0athe_Grisly_Grotto        Quake I save: e1m4 The grisly grotto
+0      string  5\x0aZiggurat_Vertigo         Quake I save: e1m8 Ziggurat vertigo (secret)
+0      string  5\x0aGloom_Keep               Quake I save: e1m5 Gloom keep
+0      string  5\x0aThe_Door_To_Chthon       Quake I save: e1m6 The door to Chthon
+0      string  5\x0aThe_House_of_Chthon      Quake I save: e1m7 The house of Chthon
+0      string  5\x0athe_Installation         Quake I save: e2m1 The installation
+0      string  5\x0athe_Ogre_Citadel         Quake I save: e2m2 The ogre citadel
+0      string  5\x0athe_Crypt_of_Decay       Quake I save: e2m3 The crypt of decay (dopefish lives!)
+0      string  5\x0aUnderearth               Quake I save: e2m7 Underearth (secret)
+0      string  5\x0athe_Ebon_Fortress        Quake I save: e2m4 The ebon fortress
+0      string  5\x0athe_Wizard's_Manse       Quake I save: e2m5 The wizard's manse
+0      string  5\x0athe_Dismal_Oubliette     Quake I save: e2m6 The dismal oubliette
+0      string  5\x0aTermination_Central      Quake I save: e3m1 Termination central
+0      string  5\x0aVaults_of_Zin            Quake I save: e3m2 Vaults of Zin
+0      string  5\x0athe_Tomb_of_Terror       Quake I save: e3m3 The tomb of terror
+0      string  5\x0aSatan's_Dark_Delight     Quake I save: e3m4 Satan's dark delight
+0      string  5\x0athe_Haunted_Halls        Quake I save: e3m7 The haunted halls (secret)
+0      string  5\x0aWind_Tunnels             Quake I save: e3m5 Wind tunnels
+0      string  5\x0aChambers_of_Torment      Quake I save: e3m6 Chambers of torment
+0      string  5\x0athe_Sewage_System        Quake I save: e4m1 The sewage system
+0      string  5\x0aThe_Tower_of_Despair     Quake I save: e4m2 The tower of despair
+0      string  5\x0aThe_Elder_God_Shrine     Quake I save: e4m3 The elder god shrine
+0      string  5\x0athe_Palace_of_Hate       Quake I save: e4m4 The palace of hate
+0      string  5\x0aHell's_Atrium            Quake I save: e4m5 Hell's atrium
+0      string  5\x0athe_Nameless_City        Quake I save: e4m8 The nameless city (secret)
+0      string  5\x0aThe_Pain_Maze            Quake I save: e4m6 The pain maze
+0      string  5\x0aAzure_Agony              Quake I save: e4m7 Azure agony
+0      string  5\x0aShub-Niggurath's_Pit     Quake I save: end Shub-Niggurath's pit
+
+# Quake DeathMatch levels
+
+0      string  5\x0aPlace_of_Two_Deaths         Quake I save: dm1 Place of two deaths
+0      string  5\x0aClaustrophobopolis          Quake I save: dm2 Claustrophobopolis
+0      string  5\x0aThe_Abandoned_Base          Quake I save: dm3 The abandoned base
+0      string  5\x0aThe_Bad_Place               Quake I save: dm4 The bad place
+0      string  5\x0aThe_Cistern                 Quake I save: dm5 The cistern
+0      string  5\x0aThe_Dark_Zone               Quake I save: dm6 The dark zone
+
+# Scourge of Armagon
+
+0      string  5\x0aCommand_HQ               Quake I save: start Command HQ
+0      string  5\x0aThe_Pumping_Station      Quake I save: hip1m1 The pumping station
+0      string  5\x0aStorage_Facility         Quake I save: hip1m2 Storage facility
+0      string  5\x0aMilitary_Complex         Quake I save: hip1m5 Military complex (secret)
+0      string  5\x0athe_Lost_Mine            Quake I save: hip1m3 The lost mine
+0      string  5\x0aResearch_Facility        Quake I save: hip1m4 Research facility
+0      string  5\x0aAncient_Realms           Quake I save: hip2m1 Ancient realms
+0      string  5\x0aThe_Gremlin's_Domain     Quake I save: hip2m6 The gremlin's domain (secret)
+0      string  5\x0aThe_Black_Cathedral      Quake I save: hip2m2 The black cathedral
+0      string  5\x0aThe_Catacombs            Quake I save: hip2m3 The catacombs
+0      string  5\x0athe_Crypt__              Quake I save: hip2m4 The crypt
+0      string  5\x0aMortum's_Keep            Quake I save: hip2m5 Mortum's keep
+0      string  5\x0aTur_Torment              Quake I save: hip3m1 Tur torment
+0      string  5\x0aPandemonium              Quake I save: hip3m2 Pandemonium
+0      string  5\x0aLimbo                    Quake I save: hip3m3 Limbo
+0      string  5\x0athe_Edge_of_Oblivion     Quake I save: hipdm1 The edge of oblivion (secret)
+0      string  5\x0aThe_Gauntlet             Quake I save: hip3m4 The gauntlet
+0      string  5\x0aArmagon's_Lair           Quake I save: hipend Armagon's lair
+
+# Malice
+
+0      string  5\x0aThe_Academy      Quake I save: start The academy
+0      string  5\x0aThe_Lab          Quake I save: d1 The lab
+0      string  5\x0aArea_33          Quake I save: d1b Area 33
+0      string  5\x0aSECRET_MISSIONS  Quake I save: d3b Secret missions
+0      string  5\x0aThe_Hospital     Quake I save: d10 The hospital (secret)
+0      string  5\x0aThe_Genetics_Lab Quake I save: d11 The genetics lab (secret)
+0      string  5\x0aBACK_2_MALICE    Quake I save: d4b Back to Malice
+0      string  5\x0aArea44           Quake I save: d1c Area 44
+0      string  5\x0aTakahiro_Towers  Quake I save: d2 Takahiro towers
+0      string  5\x0aA_Rat's_Life     Quake I save: d3 A rat's life
+0      string  5\x0aInto_The_Flood   Quake I save: d4 Into the flood
+0      string  5\x0aThe_Flood        Quake I save: d5 The flood
+0      string  5\x0aNuclear_Plant    Quake I save: d6 Nuclear plant
+0      string  5\x0aThe_Incinerator_Plant    Quake I save: d7 The incinerator plant
+0      string  5\x0aThe_Foundry              Quake I save: d7b The foundry
+0      string  5\x0aThe_Underwater_Base      Quake I save: d8 The underwater base
+0      string  5\x0aTakahiro_Base            Quake I save: d9 Takahiro base
+0      string  5\x0aTakahiro_Laboratories    Quake I save: d12 Takahiro laboratories
+0      string  5\x0aStayin'_Alive    Quake I save: d13 Stayin' alive
+0      string  5\x0aB.O.S.S._HQ      Quake I save: d14 B.O.S.S. HQ
+0      string  5\x0aSHOWDOWN!        Quake I save: d15 Showdown!
+
+# Malice DeathMatch levels
+
+0      string  5\x0aThe_Seventh_Precinct        Quake I save: ddm1 The seventh precinct
+0      string  5\x0aSub_Station                 Quake I save: ddm2 Sub station
+0      string  5\x0aCrazy_Eights!               Quake I save: ddm3 Crazy eights!
+0      string  5\x0aEast_Side_Invertationa      Quake I save: ddm4 East side invertationa
+0      string  5\x0aSlaughterhouse              Quake I save: ddm5 Slaughterhouse
+0      string  5\x0aDOMINO                      Quake I save: ddm6 Domino
+0      string  5\x0aSANDRA'S_LADDER             Quake I save: ddm7 Sandra's ladder
+
+
+0      string  MComprHD        MAME CHD compressed hard disk image,
+>12    belong  x               version %u
+
+# doom - submitted by Jon Dowland
+
+0      string  =IWAD           doom main IWAD data
+>4     lelong  x               containing %d lumps
+0      string  =PWAD           doom patch PWAD data
+>4     lelong  x               containing %d lumps
+
+# Build engine group files (Duke Nukem, Shadow Warrior, ...)
+# Extension: .grp
+# Created by: "Ganael Laplanche" <ganael.laplanche@martymac.org>
+0      string  KenSilverman    Build engine group file
+>12    lelong  x               containing %d files
+
+# Summary: Warcraft 3 save
+# Extension: .w3g
+# Created by: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0      string          Warcraft\ III\ recorded\ game   %s
+
+
+# Summary: Warcraft 3 map
+# Extension: .w3m
+# Created by: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0      string          HM3W            Warcraft III map file
+
+
+# Summary: SGF Smart Game Format
+# Extension: .sgf
+# Reference: https://www.red-bean.com/sgf/
+# Created by: Eduardo Sabbatella <eduardo_sabbatella@yahoo.com.ar>
+# Modified by (1): Abel Cheung (regex, more game format)
+# FIXME: Some games don't have GM (game type)
+0      regex           \\(;.*GM\\[[0-9]{1,2}\\]        Smart Game Format
+>2     search/0x200/b  GM[
+>>&0   string          1]      (Go)
+>>&0   string          2]      (Othello)
+>>&0   string          3]      (chess)
+>>&0   string          4]      (Gomoku+Renju)
+>>&0   string          5]      (Nine Men's Morris)
+>>&0   string          6]      (Backgammon)
+>>&0   string          7]      (Chinese chess)
+>>&0   string          8]      (Shogi)
+>>&0   string          9]      (Lines of Action)
+>>&0   string          10]     (Ataxx)
+>>&0   string          11]     (Hex)
+>>&0   string          12]     (Jungle)
+>>&0   string          13]     (Neutron)
+>>&0   string          14]     (Philosopher's Football)
+>>&0   string          15]     (Quadrature)
+>>&0   string          16]     (Trax)
+>>&0   string          17]     (Tantrix)
+>>&0   string          18]     (Amazons)
+>>&0   string          19]     (Octi)
+>>&0   string          20]     (Gess)
+>>&0   string          21]     (Twixt)
+>>&0   string          22]     (Zertz)
+>>&0   string          23]     (Plateau)
+>>&0   string          24]     (Yinsh)
+>>&0   string          25]     (Punct)
+>>&0   string          26]     (Gobblet)
+>>&0   string          27]     (hive)
+>>&0   string          28]     (Exxit)
+>>&0   string          29]     (Hnefatal)
+>>&0   string          30]     (Kuba)
+>>&0   string          31]     (Tripples)
+>>&0   string          32]     (Chase)
+>>&0   string          33]     (Tumbling Down)
+>>&0   string          34]     (Sahara)
+>>&0   string          35]     (Byte)
+>>&0   string          36]     (Focus)
+>>&0   string          37]     (Dvonn)
+>>&0   string          38]     (Tamsk)
+>>&0   string          39]     (Gipf)
+>>&0   string          40]     (Kropki)
+
+##############################################
+# NetImmerse/Gamebryo game engine entries
+
+# Summary: Gamebryo game engine file
+# Extension: .nif, .kf
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0              string          Gamebryo\ File\ Format,\ Version\       Gamebryo game engine file
+>&0            regex           [0-9a-z.]+                              \b, version %s
+
+# Summary: Gamebryo game engine file
+# Extension: .kfm
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0              string          ;Gamebryo\ KFM\ File\ Version\          Gamebryo game engine animation File
+>&0            regex           [0-9a-z.]+                              \b, version %s
+
+# Summary: NetImmerse game engine file
+# Extension .nif
+# Created by: Abel Cheung <abelcheung@gmail.com>
+0              string          NetImmerse\ File\ Format,\ Versio
+>&0            string          n\                                      NetImmerse game engine file
+>>&0           regex           [0-9a-z.]+                              \b, version %s
+
+# Type:        SGF Smart Game Format
+# URL: https://www.red-bean.com/sgf/
+# From:        Eduardo Sabbatella <eduardo_sabbatella@yahoo.com.ar>
+2      regex/c \\(;.*GM\\[[0-9]{1,2}\\]        Smart Game Format
+>2     regex/c GM\\[1\\]                       - Go Game
+>2     regex/c GM\\[6\\]                       - BackGammon Game
+>2     regex/c GM\\[11\\]                      - Hex Game
+>2     regex/c GM\\[18\\]                      - Amazons Game
+>2     regex/c GM\\[19\\]                      - Octi Game
+>2     regex/c GM\\[20\\]                      - Gess Game
+>2     regex/c GM\\[21\\]                      - twix Game
+
+# Epic Games/Unreal Engine Package
+#
+0      lelong          0x9E2A83C1      Unreal Engine Package,
+>4     leshort         x               version: %i
+>12    lelong          !0              \b, names: %i
+>28    lelong          !0              \b, imports: %i
+>20    lelong          !0              \b, exports: %i
diff --git a/magic/Magdir/gcc b/magic/Magdir/gcc
new file mode 100644 (file)
index 0000000..9ddbb47
--- /dev/null
@@ -0,0 +1,17 @@
+
+#------------------------------------------------------------------------------
+# $File: gcc,v 1.4 2009/09/19 16:28:09 christos Exp $
+# gcc:  file(1) magic for GCC special files
+#
+0      string          gpch            GCC precompiled header
+
+# The version field is annoying.  It's 3 characters, not zero-terminated.
+>5     byte            x                       (version %c
+>6     byte            x                       \b%c
+>7     byte            x                       \b%c)
+
+# 67 = 'C', 111 = 'o', 43 = '+', 79 = 'O'
+>4     byte            67                      for C
+>4     byte            111                     for Objective-C
+>4     byte            43                      for C++
+>4     byte            79                      for Objective-C++
diff --git a/magic/Magdir/gconv b/magic/Magdir/gconv
new file mode 100644 (file)
index 0000000..eec5ddc
--- /dev/null
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# $File: gconv
+# gconv: file(1) magic for iconv/gconv module configuration cache
+#
+# Magic number defined in glibc/iconv/iconvconfig.h as GCONVCACHE_MAGIC
+#
+# From: Marek Cermak <macermak@redhat.com>
+#
+0              lelong          0x20010324      gconv module configuration cache data
diff --git a/magic/Magdir/geo b/magic/Magdir/geo
new file mode 100644 (file)
index 0000000..d72e514
--- /dev/null
@@ -0,0 +1,130 @@
+
+#------------------------------------------------------------------------------
+# $File: geo,v 1.7 2019/04/19 00:42:27 christos Exp $
+# Geo- files from Kurt Schwehr <schwehr@ccom.unh.edu>
+
+######################################################################
+#
+# Acoustic Doppler Current Profilers (ADCP)
+#
+######################################################################
+
+0      beshort 0x7f7f  RDI Acoustic Doppler Current Profiler (ADCP)
+
+######################################################################
+#
+# Metadata
+#
+######################################################################
+
+0      string  Identification_Information      FGDC ASCII metadata
+
+######################################################################
+#
+# Seimsic / Subbottom
+#
+######################################################################
+
+# Knudsen subbottom chirp profiler - Binary File Format: B9
+# KEB D409-03167 V1.75 Huffman
+0      string  KEB\    Knudsen seismic KEL binary (KEB) -
+>4     regex   [-A-Z0-9]*      Software: %s
+>>&1   regex   V[0-9]*\.[0-9]* version %s
+
+######################################################################
+#
+# LIDAR - Laser altimetry or bathy
+#
+######################################################################
+
+
+# Caris LIDAR format for LADS comes as two parts... ascii location file and binary waveform data
+0      string  HCA     LADS Caris Ascii Format (CAF) bathymetric lidar
+>4     regex [0-9]*\.[0-9]*    version %s
+
+0      string  HCB     LADS Caris Binary Format (CBF) bathymetric lidar waveform data
+>3      byte    x      version %d .
+>4     byte    x       %d
+
+
+######################################################################
+#
+# MULTIBEAM SONARS https://www.ldeo.columbia.edu/res/pi/MB-System/formatdoc/
+#
+######################################################################
+
+# GeoAcoustics - GeoSwath Plus
+4      beshort 0x2002  GeoSwath RDF
+0      string  Start:- GeoSwatch auf text file
+
+# Seabeam 2100
+# mbsystem code mb41
+0      string SB2100   SeaBeam 2100 multibeam sonar
+0      string SB2100DR SeaBeam 2100 DR multibeam sonar
+0      string SB2100PR SeaBeam 2100 PR multibeam sonar
+
+# This corresponds to MB-System format 94, L-3/ELAC/SeaBeam XSE vendor
+# format. It is the format of our upgraded SeaBeam 2112 on R/V KNORR.
+0    string $HSF    XSE multibeam
+
+# mb121 https://www.saic.com/maritime/gsf/
+8      string  GSF-v   SAIC generic sensor format (GSF) sonar data,
+>&0    regex [0-9]*\.[0-9]*    version %s
+
+# MGD77 - https://www.ngdc.noaa.gov/mgg/dat/geodas/docs/mgd77.htm
+# mb161
+9      string MGD77    MGD77 Header, Marine Geophysical Data Exchange Format
+
+# MBSystem processing caches the mbinfo output
+1      string  Swath\ Data\ File:      mbsystem info cache
+
+# Caris John Hughes Clark format
+0      string  HDCS    Caris multibeam sonar related data
+1      string  Start/Stop\ parameter\ header:  Caris ASCII project summary
+
+######################################################################
+#
+# Visualization and 3D modeling
+#
+######################################################################
+
+# IVS - IVS3d.com Tagged Data Represetation
+0      string  %%\ TDR\ 2.0    IVS Fledermaus TDR file
+
+# http://www.ecma-international.org/publications/standards/Ecma-363.htm
+# 3D in PDFs
+0      string  U3D     ECMA-363, Universal 3D
+
+######################################################################
+#
+# Support files
+#
+######################################################################
+
+# https://midas.psi.ch/elog/
+0      string  $@MID@$ elog journal entry
+
+# Geospatial Designs https://www.geospatialdesigns.com/surfer6_format.htm
+0      string          DSBB    Surfer 6 binary grid file
+>4     leshort         x       \b, %d
+>6     leshort         x       \bx%d
+>8     ledouble        x       \b, minx=%g
+>16    ledouble        x       \b, maxx=%g
+>24    ledouble        x       \b, miny=%g
+>32    ledouble        x       \b, maxy=%g
+>40    ledouble        x       \b, minz=%g
+>48    ledouble        x       \b, maxz=%g
+
+# magic for LAS format files
+# alex myczko <alex@aiei.ch>
+# https://www.asprs.org/wp-content/uploads/2010/12/LAS_1_3_r11.pdf
+0      string          LASF    LIDAR point data records
+>24    byte            >0      \b, version %u
+>25    byte            >0      \b.%u
+>26    string          >\0     \b, SYSID %s
+>58    string          >\0     \b, Generating Software %s
+
+# magic for PCD format files
+# alex myczko <alex@aiei.ch>
+# http://pointclouds.org/documentation/tutorials/pcd_file_format.php
+0      string          #\ .PCD Point Cloud Data
diff --git a/magic/Magdir/geos b/magic/Magdir/geos
new file mode 100644 (file)
index 0000000..c1c456e
--- /dev/null
@@ -0,0 +1,20 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# GEOS files (Vidar Madsen, vidar@gimp.org)
+# semi-commonly used in embedded and handheld systems.
+0      belong  0xc745c153      GEOS
+>40    byte    1       executable
+>40    byte    2       VMFile
+>40    byte    3       binary
+>40    byte    4       directory label
+>40    byte    <1      unknown
+>40    byte    >4      unknown
+>4     string  >\0     \b, name "%s"
+#>44   short   x       \b, version %d
+#>46   short   x       \b.%d
+#>48   short   x       \b, rev %d
+#>50   short   x       \b.%d
+#>52   short   x       \b, proto %d
+#>54   short   x       \br%d
+#>168  string  >\0     \b, copyright "%s"
diff --git a/magic/Magdir/gimp b/magic/Magdir/gimp
new file mode 100644 (file)
index 0000000..2e263fc
--- /dev/null
@@ -0,0 +1,47 @@
+
+#------------------------------------------------------------------------------
+# $File: gimp,v 1.8 2013/12/21 14:29:45 christos Exp $
+# GIMP Gradient: file(1) magic for the GIMP's gradient data files (.ggr)
+# by Federico Mena <federico@nuclecu.unam.mx>
+
+0       string/t        GIMP\ Gradient  GIMP gradient data
+
+# GIMP palette (.gpl)
+# From: Markus Heidelberg <markus.heidelberg@web.de>
+0       string/t        GIMP\ Palette   GIMP palette data
+
+#------------------------------------------------------------------------------
+# XCF:  file(1) magic for the XCF image format used in the GIMP (.xcf) developed
+#       by Spencer Kimball and Peter Mattis
+#       ('Bucky' LaDieu, nega@vt.edu)
+
+0      string          gimp\ xcf       GIMP XCF image data,
+!:mime image/x-xcf
+>9     string          file            version 0,
+>9     string          v               version
+>>10   string          >\0             %s,
+>14    belong          x               %u x
+>18    belong          x               %u,
+>22     belong          0               RGB Color
+>22     belong          1               Greyscale
+>22     belong          2               Indexed Color
+>22    belong          >2              Unknown Image Type.
+
+#------------------------------------------------------------------------------
+# XCF:  file(1) magic for the patterns used in the GIMP (.pat), developed
+#       by Spencer Kimball and Peter Mattis
+#       ('Bucky' LaDieu, nega@vt.edu)
+
+20      string          GPAT            GIMP pattern data,
+>24     string          x               %s
+
+#------------------------------------------------------------------------------
+# XCF:  file(1) magic for the brushes used in the GIMP (.gbr), developed
+#       by Spencer Kimball and Peter Mattis
+#       ('Bucky' LaDieu, nega@vt.edu)
+
+20      string          GIMP            GIMP brush data
+
+# GIMP Curves File
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+0      string  #\040GIMP\040Curves\040File     GIMP curve file
diff --git a/magic/Magdir/glibc b/magic/Magdir/glibc
new file mode 100644 (file)
index 0000000..3b856f3
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File: glibc,v 1.1 2018/10/11 15:35:43 christos Exp $
+# glibc locale files
+#
+# https://sourceware.org/git/?p=glibc.git;f=locale/localeinfo.h;h=68822a63#l32
+
+0      belong  0x20070920      glibc locale file LC_CTYPE
+0      belong  0x14110320      glibc locale file LC_NUMERIC
+0      belong  0x17110320      glibc locale file LC_TIME
+0      belong  0x17100520      glibc locale file LC_COLLATE
+0      belong  0x11110320      glibc locale file LC_MONETARY
+0      belong  0x10110320      glibc locale file LC_MESSAGES
+0      belong  0x13110320      glibc locale file LC_ALL
+0      belong  0x12110320      glibc locale file LC_PAPER
+0      belong  0x1d110320      glibc locale file LC_NAME
+0      belong  0x1c110320      glibc locale file LC_ADDRESS
+0      belong  0x1f110320      glibc locale file LC_TELEPHONE
+0      belong  0x1e110320      glibc locale file LC_MEASUREMENT
+0      belong  0x19110320      glibc locale file LC_IDENTIFICATION
+
diff --git a/magic/Magdir/gnome b/magic/Magdir/gnome
new file mode 100644 (file)
index 0000000..2905340
--- /dev/null
@@ -0,0 +1,59 @@
+
+#------------------------------------------------------------------------------
+# $File: gnome,v 1.6 2019/04/19 00:42:27 christos Exp $
+# GNOME related files
+
+# Contributed by Josh Triplett
+# FIXME: Could be simplified if pstring supported two-byte counts
+0         string   GnomeKeyring\n\r\0\n GNOME keyring
+>&0       ubyte    0                    \b, major version 0
+>>&0      ubyte    0                    \b, minor version 0
+>>>&0     ubyte    0                    \b, crypto type 0 (AES)
+>>>&0     ubyte    >0                   \b, crypto type %u (unknown)
+>>>&1     ubyte    0                    \b, hash type 0 (MD5)
+>>>&1     ubyte    >0                   \b, hash type %u (unknown)
+>>>&2     ubelong  0xFFFFFFFF           \b, name NULL
+>>>&2     ubelong  !0xFFFFFFFF
+>>>>&-4   ubelong  >255                 \b, name too long for file's pstring type
+>>>>&-4   ubelong  <256
+>>>>>&-1  pstring  x                    \b, name "%s"
+>>>>>>&0  ubeqdate x                    \b, last modified %s
+>>>>>>&8  ubeqdate x                    \b, created %s
+>>>>>>&16 ubelong  &1
+>>>>>>>&0 ubelong  x                    \b, locked if idle for %u seconds
+>>>>>>&16 ubelong  ^1                   \b, not locked if idle
+>>>>>>&24 ubelong  x                    \b, hash iterations %u
+>>>>>>&28 ubequad  x                    \b, salt %llu
+>>>>>>&52 ubelong  x                    \b, %u item(s)
+
+# From: Alex Beregszaszi <alex@fsn.hu>
+4      string  gtktalog                GNOME Catalogue (gtktalog)
+>13    string  >\0                     version %s
+
+# Summary: GStreamer binary registry
+# Extension: .bin
+# Submitted by: Josh Triplett <josh@joshtriplett.org>
+0      belong  0xc0def00d              GStreamer binary registry
+>4     string  x                       \b, version %s
+
+# GVariant Database file
+# By Elan Ruusamae <glen@delfi.ee>
+# https://github.com/GNOME/gvdb/blob/master/gvdb-format.h
+# It's always "GVariant", it's byte swapped on incompatible archs
+# See https://github.com/GNOME/gvdb/blob/master/gvdb-builder.c
+# file_builder_serialise()
+# https://developer.gnome.org/glib/2.34/glib-GVariant.html#GVariant
+0      string  GVariant        GVariant Database file,
+# version is never filled. probably future extension
+>8     lelong  x               version %d
+# not sure are these usable, so commented out
+#>>16  lelong  x               start %d,
+#>>>20 lelong  x               end %d
+
+# G-IR database made by gobject-introspect toolset,
+# https://live.gnome.org/GObjectIntrospection
+0      string          GOBJ\nMETADATA\r\n\032  G-IR binary database
+>16    byte            x                       \b, v%d
+>17    byte            x                       \b.%d
+>20    leshort         x                       \b, %d entries
+>22    leshort         x                       \b/%d local
diff --git a/magic/Magdir/gnu b/magic/Magdir/gnu
new file mode 100644 (file)
index 0000000..bf6b93d
--- /dev/null
@@ -0,0 +1,178 @@
+
+#------------------------------------------------------------------------------
+# $File: gnu,v 1.21 2019/04/19 00:42:27 christos Exp $
+# gnu:  file(1) magic for various GNU tools
+#
+# GNU nlsutils message catalog file format
+#
+# GNU message catalog (.mo and .gmo files)
+
+# Update: Joerg Jenderek
+# URL: https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html
+# Reference: ftp://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.tar.gz/
+#      gettext-0.19.8.1/gettext-runtime/intl/gmo.h
+# Note: maybe call it like "GNU translation gettext machine object"
+0      string          \336\22\4\225   GNU message catalog (little endian),
+#0     ulelong 0x950412DE              GNU-format message catalog data
+# TODO: write lines in such a way that code can also be called for big endian variant
+#>0    use             gettext-object
+#0     name            gettext-object
+>4     ulelong         x               revision
+!:mime application/x-gettext-translation
+# mo extension is also used for Easeus Partition Master PE32 executable module
+# like ConvertFatToNTFS.mo
+!:ext  gmo/mo
+# only found three revision combinations 0.0 0.1 1.1 as unsigned 32-bit
+# major revision
+>4     ulelong/0xFFff  x               %u.
+# minor revision
+>4     ulelong&0x0000FFff      x       \b%u
+>>8    ulelong         x               \b, %u message
+# plural s
+>>8    ulelong         >1              \bs
+# size of hashing table
+#>20   ulelong         x               \b, %u hash
+#>20   ulelong         >1              \bes
+#>24   ulelong         x               at 0x%x
+# for revsion x.0 offset of table with originals is 1Ch if directly after header
+>4     ulelong&0x0000FFff      =0
+>>12   ulelong         !0x1C           \b, at 0x%x string table
+# but for x.1 table offset i found is 30h. That means directly after bigger header
+>4     ulelong&0x0000FFff      >0
+>>12   ulelong         !0x30           \b, at 0x%x string table
+# The following variables are only used in .mo files with minor revision >= 1
+# number of system dependent segments
+#>>28  ulelong         x               \b, %u segment
+#>>28  ulelong         >1              \bs
+# offset of table describing system dependent segments
+#>>32  ulelong         x               at 0x%x
+# number of system dependent strings pairs
+>>36   ulelong         x               \b, %u sysdep message
+>>36   ulelong         >1              \bs
+# offset of table with start offsets of original sysdep strings
+#>>40  ulelong         x               \b, at 0x%x sysdep strings
+# offset of table with start offsets of translated sysdep strings
+#>>44  ulelong         x               \b, at 0x%x sysdep translations
+# >>(44.l)     ulelong x               0x%x chars
+# >>>&0                ulelong x               at 0x%x
+# >>>>(&-4)    string  x               "%s"
+# string table after big header
+#>>48  ubequad         x               \b, string table 0x%llx
+#
+# 0th string length seems to be always 0
+#>(12.l)       ulelong x               \b, %u chars
+#>>&0          ulelong x               at 0x%x
+# if 1st string length positiv inspect offset and string
+#>(12.l+8)     ulelong >0              \b, %u chars
+#>>&0          ulelong x               at 0x%x
+# if 2nd string length positiv inspect offset and string
+# >(12.l+16)   ulelong >0              \b, %u chars
+# >>&0         ulelong x               at 0x%x
+# skip newline byte
+#>>>(&-4)      ubyte   =0x0A
+#>>>>&0                string  x               "%s"
+#>>>(&-4)      ubyte   !0x0A
+#>>>>&-1               string  x               '%s'
+# offset of table with translation strings
+#>16   ulelong         x               \b, at 0x%x translation table
+# check translation 0 length and offset
+>(16.l)                ulelong >0
+>>&0           ulelong x
+# translation 0 seems to be often Project-Id with name and version
+>>>(&-4)       string  x               \b, %s
+# trans. 1 with bytes >= 1 unlike icoutils-0.31.0\po\en@boldquot.gmo with 1 NL
+>(16.l+8)      ulelong >1
+>>&0           ulelong x
+>>>(&-4)       ubyte   !0x0A
+>>>>&-1                string  x               '%s'
+# 1 New Line like in tar-1.29\po\de.gmo
+>>>(&-4)       ubyte   =0x0A
+>>>>&0         ubyte   !0x0A
+>>>>>&-1       string  x               '%s'
+# 2nd New Line like in parted-3.1\po\de.gmo
+>>>>&0         ubyte   =0x0A
+>>>>>&0                string  x               '%s'
+
+0      string          \225\4\22\336   GNU message catalog (big endian),
+#0     ubelong 0x950412DE              GNU-format message catalog data
+!:mime application/x-gettext-translation
+!:ext  gmo/mo
+# TODO: for big endian use same code as for little endian
+#>0    use             \^gettext-object
+# DEBUG code
+#>16   ubelong         x               \b, at 0x%x translation table
+#>(16.L)               ubelong x               0x%x chars
+#>>&0          ubelong x               at 0x%x
+# unexpected value HERE!
+#>>>(&-4)      ubequad x               0x%llx
+#
+>4     beshort         x               revision %d.
+>6     beshort         >0              \b%d,
+>>8    belong          x               %d messages,
+>>36   belong          x               %d sysdep messages
+>6     beshort         =0              \b%d,
+>>8    belong          x               %d messages
+
+
+# GnuPG
+# The format is very similar to pgp
+0      string          \001gpg                 GPG key trust database
+>4     byte            x                       version %d
+# Note: magic.mime had 0x8501 for the next line instead of 0x8502
+0      beshort         0x8502                  GPG encrypted data
+!:mime text/PGP # encoding: data
+
+# Update: Joerg Jenderek
+# Note:        PGP and GPG use same data structure.
+#      So recognition is now done by ./pgp with start test for byte 0x99
+# This magic is not particularly good, as the keyrings don't have true
+# magic. Nevertheless, it covers many keyrings.
+# 0    ubeshort-0x9901 <2
+# >3   byte            4
+# >>4  bedate          x               GPG key public ring, created %s
+# !:mime application/x-gnupg-keyring
+
+# Symmetric encryption
+0      leshort         0x0d8c
+>4     leshort         0x0203
+>>2    leshort         0x0204          GPG symmetrically encrypted data (3DES cipher)
+>>2    leshort         0x0304          GPG symmetrically encrypted data (CAST5 cipher)
+>>2    leshort         0x0404          GPG symmetrically encrypted data (BLOWFISH cipher)
+>>2    leshort         0x0704          GPG symmetrically encrypted data (AES cipher)
+>>2    leshort         0x0804          GPG symmetrically encrypted data (AES192 cipher)
+>>2    leshort         0x0904          GPG symmetrically encrypted data (AES256 cipher)
+>>2    leshort         0x0a04          GPG symmetrically encrypted data (TWOFISH cipher)
+>>2    leshort         0x0b04          GPG symmetrically encrypted data (CAMELLIA128 cipher)
+>>2    leshort         0x0c04          GPG symmetrically encrypted data (CAMELLIA192 cipher)
+>>2    leshort         0x0d04          GPG symmetrically encrypted data (CAMELLIA256 cipher)
+
+
+# GnuPG Keybox file
+# <https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=kbx/keybox-blob.c;hb=HEAD>
+# From: Philipp Hahn <hahn@univention.de>
+0      belong  32
+>4     byte    1
+>>8    string  KBXf    GPG keybox database
+>>>5   byte    1       version %d
+>>>16  bedate  x       \b, created-at %s
+>>>20  bedate  x       \b, last-maintained %s
+
+
+# Gnumeric spreadsheet
+# This entry is only semi-helpful, as Gnumeric compresses its files, so
+# they will ordinarily reported as "compressed", but at least -z helps
+39      string          =<gmr:Workbook           Gnumeric spreadsheet
+
+# From: James Youngman <jay@gnu.org>
+# gnu find magic
+0      string  \0LOCATE        GNU findutils locate database data
+>7     string  >\0             \b, format %s
+>7     string  02              \b (frcode)
+
+# Files produced by GNU gettext
+
+# gettext message catalogue
+0      search/1024     \nmsgid
+>&0    search/1024     \nmsgstr        GNU gettext message catalogue text
+!:strength +100
+!:mime text/x-po
diff --git a/magic/Magdir/gnumeric b/magic/Magdir/gnumeric
new file mode 100644 (file)
index 0000000..6dcfc10
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# gnumeric:  file(1) magic for Gnumeric spreadsheet
+# This entry is only semi-helpful, as Gnumeric compresses its files, so
+# they will ordinarily reported as "compressed", but at least -z helps
+39     string  =<gmr:Workbook  Gnumeric spreadsheet
+!:mime application/x-gnumeric
diff --git a/magic/Magdir/gpt b/magic/Magdir/gpt
new file mode 100644 (file)
index 0000000..76a223c
--- /dev/null
@@ -0,0 +1,240 @@
+
+#------------------------------------------------------------------------------
+# $File: gpt,v 1.4 2017/03/17 21:35:28 christos Exp $
+#
+# GPT Partition table patterns.
+# Author: Rogier Goossens (goossens.rogier@gmail.com)
+# Note that a GPT-formatted disk must contain an MBR as well.
+#
+
+# The initial segment (up to >>>>>>>>422) was copied from the X86
+# partition table code (aka MBR).
+# This is kept separate, so that MBR partitions are not reported as well.
+# (use -k if you do want them as well)
+
+# First, detect the MBR partiton table
+# If more than one GPT protective MBR partition exists, don't print anything
+# (the other MBR detection code will then just print the MBR partition table)
+0x1FE                  leshort         0xAA55
+>3                     string          !MS
+>>3                    string          !SYSLINUX
+>>>3                   string          !MTOOL
+>>>>3                  string          !NEWLDR
+>>>>>5                 string          !DOS
+# not FAT (32 bit)
+>>>>>>82               string          !FAT32
+#not Linux kernel
+>>>>>>>514             string          !HdrS
+#not BeOS
+>>>>>>>>422            string          !Be\ Boot\ Loader
+# GPT with protective MBR entry in partition 1 (only)
+>>>>>>>>>450           ubyte           0xee
+>>>>>>>>>>466          ubyte           !0xee
+>>>>>>>>>>>482         ubyte           !0xee
+>>>>>>>>>>>>498                ubyte           !0xee
+#>>>>>>>>>>>>>446      use             gpt-mbr-partition
+>>>>>>>>>>>>>(454.l*8192)      string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>0                        use             gpt-mbr-type
+>>>>>>>>>>>>>>&-8              use             gpt-table
+>>>>>>>>>>>>>>0                        ubyte           x               of 8192 bytes
+>>>>>>>>>>>>>(454.l*8192)      string          !EFI\ PART
+>>>>>>>>>>>>>>(454.l*4096)     string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>0               use             gpt-mbr-type
+>>>>>>>>>>>>>>>&-8             use             gpt-table
+>>>>>>>>>>>>>>>0               ubyte           x               of 4096 bytes
+>>>>>>>>>>>>>>(454.l*4096)     string          !EFI\ PART
+>>>>>>>>>>>>>>>(454.l*2048)    string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>0              use             gpt-mbr-type
+>>>>>>>>>>>>>>>>&-8            use             gpt-table
+>>>>>>>>>>>>>>>>0              ubyte           x               of 2048 bytes
+>>>>>>>>>>>>>>>(454.l*2048)    string          !EFI\ PART
+>>>>>>>>>>>>>>>>(454.l*1024)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>0             use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>&-8           use             gpt-table
+>>>>>>>>>>>>>>>>>0             ubyte           x               of 1024 bytes
+>>>>>>>>>>>>>>>>(454.l*1024)   string          !EFI\ PART
+>>>>>>>>>>>>>>>>>(454.l*512)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>>0            use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>>&-8          use             gpt-table
+>>>>>>>>>>>>>>>>>>0            ubyte           x               of 512 bytes
+# GPT with protective MBR entry in partition 2 (only)
+>>>>>>>>>450           ubyte           !0xee
+>>>>>>>>>>466          ubyte           0xee
+>>>>>>>>>>>482         ubyte           !0xee
+>>>>>>>>>>>>498                ubyte           !0xee
+#>>>>>>>>>>>>>462      use             gpt-mbr-partition
+>>>>>>>>>>>>>(470.l*8192)      string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>0                        use             gpt-mbr-type
+>>>>>>>>>>>>>>&-8              use             gpt-table
+>>>>>>>>>>>>>>0                        ubyte           x               of 8192 bytes
+>>>>>>>>>>>>>(470.l*8192)      string          !EFI\ PART
+>>>>>>>>>>>>>>(470.l*4096)     string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>0               use             gpt-mbr-type
+>>>>>>>>>>>>>>>&-8             use             gpt-table
+>>>>>>>>>>>>>>>0               ubyte           x               of 4096 bytes
+>>>>>>>>>>>>>>(470.l*4096)     string          !EFI\ PART
+>>>>>>>>>>>>>>>(470.l*2048)    string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>0              use             gpt-mbr-type
+>>>>>>>>>>>>>>>>&-8            use             gpt-table
+>>>>>>>>>>>>>>>>0              ubyte           x               of 2048 bytes
+>>>>>>>>>>>>>>>(470.l*2048)    string          !EFI\ PART
+>>>>>>>>>>>>>>>>(470.l*1024)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>0             use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>&-8           use             gpt-table
+>>>>>>>>>>>>>>>>>0             ubyte           x               of 1024 bytes
+>>>>>>>>>>>>>>>>(470.l*1024)   string          !EFI\ PART
+>>>>>>>>>>>>>>>>>(470.l*512)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>>0            use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>>&-8          use             gpt-table
+>>>>>>>>>>>>>>>>>>0            ubyte           x               of 512 bytes
+# GPT with protective MBR entry in partition 3 (only)
+>>>>>>>>>450           ubyte           !0xee
+>>>>>>>>>>466          ubyte           !0xee
+>>>>>>>>>>>482         ubyte           0xee
+>>>>>>>>>>>>498                ubyte           !0xee
+#>>>>>>>>>>>>>478      use             gpt-mbr-partition
+>>>>>>>>>>>>>(486.l*8192)      string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>0                        use             gpt-mbr-type
+>>>>>>>>>>>>>>&-8              use             gpt-table
+>>>>>>>>>>>>>>0                        ubyte           x               of 8192 bytes
+>>>>>>>>>>>>>(486.l*8192)      string          !EFI\ PART
+>>>>>>>>>>>>>>(486.l*4096)     string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>0               use             gpt-mbr-type
+>>>>>>>>>>>>>>>&-8             use             gpt-table
+>>>>>>>>>>>>>>>0               ubyte           x               of 4096 bytes
+>>>>>>>>>>>>>>(486.l*4096)     string          !EFI\ PART
+>>>>>>>>>>>>>>>(486.l*2048)    string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>0              use             gpt-mbr-type
+>>>>>>>>>>>>>>>>&-8            use             gpt-table
+>>>>>>>>>>>>>>>>0              ubyte           x               of 2048 bytes
+>>>>>>>>>>>>>>>(486.l*2048)    string          !EFI\ PART
+>>>>>>>>>>>>>>>>(486.l*1024)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>0             use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>&-8           use             gpt-table
+>>>>>>>>>>>>>>>>>0             ubyte           x               of 1024 bytes
+>>>>>>>>>>>>>>>>(486.l*1024)   string          !EFI\ PART
+>>>>>>>>>>>>>>>>>(486.l*512)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>>0            use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>>&-8          use             gpt-table
+>>>>>>>>>>>>>>>>>>0            ubyte           x               of 512 bytes
+# GPT with protective MBR entry in partition 4 (only)
+>>>>>>>>>450           ubyte           !0xee
+>>>>>>>>>>466          ubyte           !0xee
+>>>>>>>>>>>482         ubyte           !0xee
+>>>>>>>>>>>>498                ubyte           0xee
+#>>>>>>>>>>>>>494      use             gpt-mbr-partition
+>>>>>>>>>>>>>(502.l*8192)      string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>0                        use             gpt-mbr-type
+>>>>>>>>>>>>>>&-8              use             gpt-table
+>>>>>>>>>>>>>>0                        ubyte           x               of 8192 bytes
+>>>>>>>>>>>>>(502.l*8192)      string          !EFI\ PART
+>>>>>>>>>>>>>>(502.l*4096)     string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>0               use             gpt-mbr-type
+>>>>>>>>>>>>>>>&-8             use             gpt-table
+>>>>>>>>>>>>>>>0               ubyte           x               of 4096 bytes
+>>>>>>>>>>>>>>(502.l*4096)     string          !EFI\ PART
+>>>>>>>>>>>>>>>(502.l*2048)    string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>0              use             gpt-mbr-type
+>>>>>>>>>>>>>>>>&-8            use             gpt-table
+>>>>>>>>>>>>>>>>0              ubyte           x               of 2048 bytes
+>>>>>>>>>>>>>>>(502.l*2048)    string          !EFI\ PART
+>>>>>>>>>>>>>>>>(502.l*1024)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>0             use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>&-8           use             gpt-table
+>>>>>>>>>>>>>>>>>0             ubyte           x               of 1024 bytes
+>>>>>>>>>>>>>>>>(502.l*1024)   string          !EFI\ PART
+>>>>>>>>>>>>>>>>>(502.l*512)   string          EFI\ PART       GPT partition table
+>>>>>>>>>>>>>>>>>>0            use             gpt-mbr-type
+>>>>>>>>>>>>>>>>>>&-8          use             gpt-table
+>>>>>>>>>>>>>>>>>>0            ubyte           x               of 512 bytes
+
+# The following code does GPT detection and processing, including
+# sector size detection.
+# It has to be duplicated above because the top-level pattern
+# (i.e. not called using 'use') must print *something* for file
+# to count it as a match. Text only printed in named patterns is
+# not counted, and causes file to continue, and try and match
+# other patterns.
+#
+# Unfortunately, when assuming sector sizes >=16k, if the sector size
+# happens to be 512 instead, we may find confusing data after the GPT
+# table...  If the GPT table has less than 128 entries, this may even
+# happen for assumed sector sizes as small as 4k
+# This could be solved by checking for the presence of the backup GPT
+# header as well, but that makes the logic extremely complex
+##0            name            gpt-mbr-partition
+##>(8.l*8192)  string          EFI\ PART
+##>>(8.l*8192) use             gpt-mbr-type
+##>>&-8                use             gpt-table
+##>>0          ubyte           x               of 8192 bytes
+##>(8.l*8192)  string          !EFI\ PART
+##>>(8.l*4096) string          EFI\ PART       GPT partition table
+##>>>0         use             gpt-mbr-type
+##>>>&-8               use             gpt-table
+##>>>0         ubyte           x               of 4096 bytes
+##>>(8.l*4096) string          !EFI\ PART
+##>>>(8.l*2048)        string          EFI\ PART       GPT partition table
+##>>>>0                use             gpt-mbr-type
+##>>>>&-8              use             gpt-table
+##>>>>0                ubyte           x               of 2048 bytes
+##>>>(8.l*2048)        string          !EFI\ PART
+##>>>>(8.l*1024)       string          EFI\ PART       GPT partition table
+##>>>>>0               use             gpt-mbr-type
+##>>>>>&-8     use             gpt-table
+##>>>>>0               ubyte           x               of 1024 bytes
+##>>>>(8.l*1024)       string          !EFI\ PART
+##>>>>>(8.l*512)       string          EFI\ PART       GPT partition table
+##>>>>>>0              use             gpt-mbr-type
+##>>>>>>&-8    use             gpt-table
+##>>>>>>0              ubyte           x               of 512 bytes
+
+# Print details of MBR type for a GPT-disk
+# Calling code ensures that there is only one 0xee partition.
+0              name            gpt-mbr-type
+# GPT with protective MBR entry in partition 1
+>450           ubyte           0xee
+>>454          ulelong         1
+>>>462         string          !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0       \b (with hybrid MBR)
+>>454          ulelong         !1                                                                                                      \b (nonstandard: not at LBA 1)
+# GPT with protective MBR entry in partition 2
+>466           ubyte           0xee
+>>470          ulelong         1
+>>>478         string          \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>>>>446                string          !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0                                       \b (with hybrid MBR)
+>>>478         string          !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0       \b (with hybrid MBR)
+>>470          ulelong         !1                                                                      \b (nonstandard: not at LBA 1)
+# GPT with protective MBR entry in partition 3
+>482           ubyte           0xee
+>>486          ulelong         1
+>>>494         string          \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>>>>446                string          !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0       \b (with hybrid MBR)
+>>>494         string          !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0                                       \b (with hybrid MBR)
+>>486          ulelong         !1                                                                      \b (nonstandard: not at LBA 1)
+# GPT with protective MBR entry in partition 4
+>498           ubyte           0xee
+>>502          ulelong         1
+>>>446         string          !\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0       \b (with hybrid MBR)
+>>502          ulelong         !1                                                                                                      \b (nonstandard: not at LBA 1)
+
+# Print the information from a GPT partition table structure
+0              name            gpt-table
+>10            uleshort        x               \b, version %u
+>8             uleshort        x               \b.%u
+>56            ulelong         x               \b, GUID: %08x
+>60            uleshort        x               \b-%04x
+>62            uleshort        x               \b-%04x
+>64            ubeshort        x               \b-%04x
+>66            ubeshort        x               \b-%04x
+>68            ubelong         x               \b%08x
+#>80           uleshort        x               \b, %d partition entries
+>32            ulequad+1       x               \b, disk size: %lld sectors
+
+# In case a GPT data-structure is at LBA 0, report it as well
+# This covers systems which are not GPT-aware, and which show
+# and allow access to the protective partition. This code will
+# detect the contents of such a partition.
+0              string          EFI\ PART       GPT data structure (nonstandard: at LBA 0)
+>0             use             gpt-table
+>0             ubyte           x               (sector size unknown)
+
+
diff --git a/magic/Magdir/gpu b/magic/Magdir/gpu
new file mode 100644 (file)
index 0000000..62e30d0
--- /dev/null
@@ -0,0 +1,28 @@
+
+#------------------------------------------------------------------------------
+# $File: gpu,v 1.2 2017/03/23 22:11:53 christos Exp $
+# gpu: file(1) magic for GPU input files
+
+# Standard Portable Intermediate Representation (SPIR)
+# Documentation: https://www.khronos.org/spir
+# Typical file extension: .spv
+
+0      belong  0x07230203      Khronos SPIR-V binary, big-endian
+>4     belong  x               \b, version 0x%08x
+>8     belong  x               \b, generator 0x%08x
+
+0      lelong  0x07230203      Khronos SPIR-V binary, little-endian
+>4     lelong  x               \b, version 0x%08x
+>8     lelong  x               \b, generator 0x%08x
+
+# Vulkan Trace file
+# Documentation:
+# https://github.com/LunarG/VulkanTools/blob/master/vktrace/vktrace_common/\
+# vktrace_trace_packet_identifiers.h
+# Typical file extension: .vktrace
+
+8      lequad  0xABADD068ADEAFD0C      Vulkan trace file, little-endian
+>0     leshort x                       \b, version %d
+
+8      bequad  0xABADD068ADEAFD0C      Vulkan trace file, big-endian
+>0     beshort x                       \b, version %d
diff --git a/magic/Magdir/grace b/magic/Magdir/grace
new file mode 100644 (file)
index 0000000..d6dcb30
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# ACE/gr and Grace type files - PLEASE DO NOT REMOVE THIS LINE
+#
+# ACE/gr binary
+0      string  \000\000\0001\000\000\0000\000\000\0000\000\000\0002\000\000\0000\000\000\0000\000\000\0003             old ACE/gr binary file
+>39    byte    >0                      - version %c
+# ACE/gr ascii
+0      string  #\ xvgr\ parameter\ file        ACE/gr ascii file
+0      string  #\ xmgr\ parameter\ file        ACE/gr ascii file
+0      string  #\ ACE/gr\ parameter\ file      ACE/gr ascii file
+# Grace projects
+0      string  #\ Grace\ project\ file         Grace project file
+>23    string  @version\                       (version
+>>32   byte    >0                              %c
+>>33   string  >\0                             \b.%.2s
+>>35   string  >\0                             \b.%.2s)
+# ACE/gr fit description files
+0      string  #\ ACE/gr\ fit\ description\    ACE/gr fit description file
+# end of ACE/gr and Grace type files - PLEASE DO NOT REMOVE THIS LINE
diff --git a/magic/Magdir/graphviz b/magic/Magdir/graphviz
new file mode 100644 (file)
index 0000000..d8bf22d
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: graphviz,v 1.9 2019/04/30 04:01:40 christos Exp $
+# graphviz:  file(1) magic for https://www.graphviz.org/
+
+# FIXME: These patterns match too generally. For example, the first
+# line matches a LaTeX file containing the word "graph" (with a {
+# following later) and the second line matches this file.
+#0     regex/100l      [\r\n\t\ ]*graph[\r\n\t\ ]+.*\\{        graphviz graph text
+#!:mime        text/vnd.graphviz
+#0     regex/100l      [\r\n\t\ ]*digraph[\r\n\t\ ]+.*\\{      graphviz digraph text
+#!:mime        text/vnd.graphviz
diff --git a/magic/Magdir/gringotts b/magic/Magdir/gringotts
new file mode 100644 (file)
index 0000000..b674754
--- /dev/null
@@ -0,0 +1,48 @@
+
+#------------------------------------------------------------------------------
+# $File: gringotts,v 1.6 2017/03/17 21:35:28 christos Exp $
+# gringotts:  file(1) magic for Gringotts
+# http://devel.pluto.linux.it/projects/Gringotts/
+# author: Germano Rizzo <mano@pluto.linux.it>
+#GRG3????Y
+0      string  GRG             Gringotts data file
+#file format 1
+>3     string          1               v.1, MCRYPT S2K, SERPENT crypt, SHA-256 hash, ZLib lvl.9
+#file format 2
+>3     string          2               v.2, MCRYPT S2K,
+>>8    byte&0x70       0x00            RIJNDAEL-128 crypt,
+>>8    byte&0x70       0x10            SERPENT crypt,
+>>8    byte&0x70       0x20            TWOFISH crypt,
+>>8    byte&0x70       0x30            CAST-256 crypt,
+>>8    byte&0x70       0x40            SAFER+ crypt,
+>>8    byte&0x70       0x50            LOKI97 crypt,
+>>8    byte&0x70       0x60            3DES crypt,
+>>8    byte&0x70       0x70            RIJNDAEL-256 crypt,
+>>8    byte&0x08       0x00            SHA1 hash,
+>>8    byte&0x08       0x08            RIPEMD-160 hash,
+>>8    byte&0x04       0x00            ZLib
+>>8    byte&0x04       0x04            BZip2
+>>8    byte&0x03       0x00            lvl.0
+>>8    byte&0x03       0x01            lvl.3
+>>8    byte&0x03       0x02            lvl.6
+>>8    byte&0x03       0x03            lvl.9
+#file format 3
+>3     string          3               v.3, OpenPGP S2K,
+>>8    byte&0x70       0x00            RIJNDAEL-128 crypt,
+>>8    byte&0x70       0x10            SERPENT crypt,
+>>8    byte&0x70       0x20            TWOFISH crypt,
+>>8    byte&0x70       0x30            CAST-256 crypt,
+>>8    byte&0x70       0x40            SAFER+ crypt,
+>>8    byte&0x70       0x50            LOKI97 crypt,
+>>8    byte&0x70       0x60            3DES crypt,
+>>8    byte&0x70       0x70            RIJNDAEL-256 crypt,
+>>8    byte&0x08       0x00            SHA1 hash,
+>>8    byte&0x08       0x08            RIPEMD-160 hash,
+>>8    byte&0x04       0x00            ZLib
+>>8    byte&0x04       0x04            BZip2
+>>8    byte&0x03       0x00            lvl.0
+>>8    byte&0x03       0x01            lvl.3
+>>8    byte&0x03       0x02            lvl.6
+>>8    byte&0x03       0x03            lvl.9
+#file format >3
+>3     string          >3              v.%.1s (unknown details)
diff --git a/magic/Magdir/guile b/magic/Magdir/guile
new file mode 100644 (file)
index 0000000..99f8371
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File: guile,v 1.2 2019/04/19 00:42:27 christos Exp $
+# Guile file magic from <dalepsmith@gmail.com>
+# https://www.gnu.org/s/guile/
+# https://git.savannah.gnu.org/gitweb/?p=guile.git;f=libguile/_scm.h;hb=HEAD#l250
+
+0      string  GOOF----        Guile Object
+>8     string  LE              \b, little endian
+>8     string  BE              \b, big endian
+>11    string  4               \b, 32bit
+>11    string  8               \b, 64bit
+>13    regex   .\..            \b, bytecode v%s
diff --git a/magic/Magdir/hardware b/magic/Magdir/hardware
new file mode 100644 (file)
index 0000000..e92986c
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: hardware,v 1.1 2018/08/02 06:32:52 christos Exp $
+# hardware magic
+
+# EDID
+# https://en.wikipedia.org/wiki/Extended_Display_Identification_Data
+0      string          \x00\xFF\xFF\xFF\xFF\xFF\xFF\x00
+>19    byte            x
+>>18   byte            x       EDID data, version %u.
+>>19   byte            x       \b%u
+#>>17  ubyte+1990      <255    \b, manufactured %u
diff --git a/magic/Magdir/hitachi-sh b/magic/Magdir/hitachi-sh
new file mode 100644 (file)
index 0000000..18d8384
--- /dev/null
@@ -0,0 +1,30 @@
+
+#------------------------------------------------------------------------------
+# $File: hitachi-sh,v 1.9 2018/08/21 12:48:41 christos Exp $
+# hitach-sh: file(1) magic for Hitachi Super-H
+#
+# Super-H COFF
+#
+# updated by Joerg Jenderek at Oct 2015
+# https://en.wikipedia.org/wiki/COFF
+# https://de.wikipedia.org/wiki/Common_Object_File_Format
+# http://www.delorie.com/djgpp/doc/coff/filhdr.html
+# below test line conflicts with 2nd NTFS filesystem sector
+# 2nd NTFS filesystem sector often starts with 0x05004e00 for unicode string 5 NTLDR
+# and Portable Gaming Notation Compressed format (*.WID http://pgn.freeservers.com/)
+0      beshort         0x0500
+# test for unused flag bits (0x8000,0x0800,0x0400,0x0200,x0080) in f_flags
+>18    ubeshort&0x8E80 0
+# use big endian variant of subroutine to display name+variables+flags
+# for common object formated files
+>>0    use                             \^display-coff
+!:strength -10
+
+0      leshort         0x0550
+# test for unused flag bits in f_flags
+>18    uleshort&0x8E80 0
+# use little endian variant of subroutine to
+# display name+variables+flags for common object formated files
+>>0    use                             display-coff
+!:strength -10
+
diff --git a/magic/Magdir/hp b/magic/Magdir/hp
new file mode 100644 (file)
index 0000000..d57169e
--- /dev/null
@@ -0,0 +1,433 @@
+
+#------------------------------------------------------------------------------
+# $File: hp,v 1.25 2019/01/13 00:32:38 christos Exp $
+# hp:  file(1) magic for Hewlett Packard machines (see also "printer")
+#
+# XXX - somebody should figure out whether any byte order needs to be
+# applied to the "TML" stuff; I'm assuming the Apollo stuff is
+# big-endian as it was mostly 68K-based.
+#
+# I think the 500 series was the old stack-based machines, running a
+# UNIX environment atop the "SUN kernel"; dunno whether it was
+# big-endian or little-endian.
+#
+# Daniel Quinlan (quinlan@yggdrasil.com): hp200 machines are 68010 based;
+# hp300 are 68020+68881 based; hp400 are also 68k.  The following basic
+# HP magic is useful for reference, but using "long" magic is a better
+# practice in order to avoid collisions.
+#
+# Guy Harris (guy@netapp.com): some additions to this list came from
+# HP-UX 10.0's "/usr/include/sys/unistd.h" (68030, 68040, PA-RISC 1.1,
+# 1.2, and 2.0).  The 1.2 and 2.0 stuff isn't in the HP-UX 10.0
+# "/etc/magic", though, except for the "archive file relocatable library"
+# stuff, and the 68030 and 68040 stuff isn't there at all - are they not
+# used in executables, or have they just not yet updated "/etc/magic"
+# completely?
+#
+# 0    beshort         200             hp200 (68010) BSD binary
+# 0    beshort         300             hp300 (68020+68881) BSD binary
+# 0    beshort         0x20c           hp200/300 HP-UX binary
+# 0    beshort         0x20d           hp400 (68030) HP-UX binary
+# 0    beshort         0x20e           hp400 (68040?) HP-UX binary
+# 0    beshort         0x20b           PA-RISC1.0 HP-UX binary
+# 0    beshort         0x210           PA-RISC1.1 HP-UX binary
+# 0    beshort         0x211           PA-RISC1.2 HP-UX binary
+# 0    beshort         0x214           PA-RISC2.0 HP-UX binary
+
+#
+# The "misc" stuff needs a byte order; the archives look suspiciously
+# like the old 177545 archives (0xff65 = 0177545).
+#
+#### Old Apollo stuff
+0      beshort         0627            Apollo m68k COFF executable
+>18    beshort         ^040000         not stripped
+>22    beshort         >0              - version %d
+0      beshort         0624            apollo a88k COFF executable
+>18    beshort         ^040000         not stripped
+>22    beshort         >0              - version %d
+0       long            01203604016     TML 0123 byte-order format
+0       long            01702407010     TML 1032 byte-order format
+0       long            01003405017     TML 2301 byte-order format
+0       long            01602007412     TML 3210 byte-order format
+#### PA-RISC 1.1
+0      belong          0x02100106      PA-RISC1.1 relocatable object
+0      belong          0x02100107      PA-RISC1.1 executable
+>168   belong          &0x00000004     dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0      belong          0x02100108      PA-RISC1.1 shared executable
+>168   belong&0x4      0x4             dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0      belong          0x0210010b      PA-RISC1.1 demand-load executable
+>168   belong&0x4      0x4             dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0      belong          0x0210010e      PA-RISC1.1 shared library
+>96    belong          >0              - not stripped
+
+0      belong          0x0210010d      PA-RISC1.1 dynamic load library
+>96    belong          >0              - not stripped
+
+#### PA-RISC 2.0
+0      belong          0x02140106      PA-RISC2.0 relocatable object
+
+0       belong         0x02140107      PA-RISC2.0 executable
+>168   belong          &0x00000004     dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0       belong         0x02140108      PA-RISC2.0 shared executable
+>168   belong          &0x00000004     dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0       belong         0x0214010b      PA-RISC2.0 demand-load executable
+>168   belong          &0x00000004     dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0       belong         0x0214010e      PA-RISC2.0 shared library
+>96    belong          >0              - not stripped
+
+0       belong         0x0214010d      PA-RISC2.0 dynamic load library
+>96    belong          >0              - not stripped
+
+#### 800
+0      belong          0x020b0106      PA-RISC1.0 relocatable object
+
+0      belong          0x020b0107      PA-RISC1.0 executable
+>168   belong&0x4      0x4             dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0      belong          0x020b0108      PA-RISC1.0 shared executable
+>168   belong&0x4      0x4             dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0      belong          0x020b010b      PA-RISC1.0 demand-load executable
+>168   belong&0x4      0x4             dynamically linked
+>(144) belong          0x054ef630      dynamically linked
+>96    belong          >0              - not stripped
+
+0      belong          0x020b010e      PA-RISC1.0 shared library
+>96    belong          >0              - not stripped
+
+0      belong          0x020b010d      PA-RISC1.0 dynamic load library
+>96    belong          >0              - not stripped
+
+#### 500
+0      long            0x02080106      HP s500 relocatable executable
+>16    long            >0              - version %d
+
+0      long            0x02080107      HP s500 executable
+>16    long            >0              - version %d
+
+0      long            0x02080108      HP s500 pure executable
+>16    long            >0              - version %d
+
+#### 200
+0      belong          0x020c0108      HP s200 pure executable
+>4     beshort         >0              - version %d
+>8     belong          &0x80000000     save fp regs
+>8     belong          &0x40000000     dynamically linked
+>8     belong          &0x20000000     debuggable
+>36    belong          >0              not stripped
+
+0      belong          0x020c0107      HP s200 executable
+>4     beshort         >0              - version %d
+>8     belong          &0x80000000     save fp regs
+>8     belong          &0x40000000     dynamically linked
+>8     belong          &0x20000000     debuggable
+>36    belong          >0              not stripped
+
+0      belong          0x020c010b      HP s200 demand-load executable
+>4     beshort         >0              - version %d
+>8     belong          &0x80000000     save fp regs
+>8     belong          &0x40000000     dynamically linked
+>8     belong          &0x20000000     debuggable
+>36    belong          >0              not stripped
+
+0      belong          0x020c0106      HP s200 relocatable executable
+>4     beshort         >0              - version %d
+>6     beshort         >0              - highwater %d
+>8     belong          &0x80000000     save fp regs
+>8     belong          &0x20000000     debuggable
+>8     belong          &0x10000000     PIC
+
+0      belong          0x020a0108      HP s200 (2.x release) pure executable
+>4     beshort         >0              - version %d
+>36    belong          >0              not stripped
+
+0      belong          0x020a0107      HP s200 (2.x release) executable
+>4     beshort         >0              - version %d
+>36    belong          >0              not stripped
+
+0      belong          0x020c010e      HP s200 shared library
+>4     beshort         >0              - version %d
+>6     beshort         >0              - highwater %d
+>36    belong          >0              not stripped
+
+0      belong          0x020c010d      HP s200 dynamic load library
+>4     beshort         >0              - version %d
+>6     beshort         >0              - highwater %d
+>36    belong          >0              not stripped
+
+#### MISC
+0      long            0x0000ff65      HP old archive
+0      long            0x020aff65      HP s200 old archive
+0      long            0x020cff65      HP s200 old archive
+0      long            0x0208ff65      HP s500 old archive
+
+0      long            0x015821a6      HP core file
+
+0      long            0x4da7eee8      HP-WINDOWS font
+>8     byte            >0              - version %d
+0      string          Bitmapfile      HP Bitmapfile
+
+0      string          IMGfile CIS     compimg HP Bitmapfile
+# XXX - see "lif"
+#0     short           0x8000          lif file
+0      long            0x020c010c      compiled Lisp
+
+0      string          msgcat01        HP NLS message catalog,
+>8     long            >0              %d messages
+
+# Summary: HP-48/49 calculator
+# Created by: phk@data.fls.dk
+# Modified by (1): AMAKAWA Shuhei <sa264@cam.ac.uk>
+# Modified by (2): Samuel Thibault <samuel.thibault@ens-lyon.org> (HP49 support)
+0      string          HPHP            HP
+>4     string          48              48 binary
+>4     string          49              49 binary
+>7     byte            >64             - Rev %c
+>8     leshort         0x2911          (ADR)
+>8     leshort         0x2933          (REAL)
+>8     leshort         0x2955          (LREAL)
+>8     leshort         0x2977          (COMPLX)
+>8     leshort         0x299d          (LCOMPLX)
+>8     leshort         0x29bf          (CHAR)
+>8     leshort         0x29e8          (ARRAY)
+>8     leshort         0x2a0a          (LNKARRAY)
+>8     leshort         0x2a2c          (STRING)
+>8     leshort         0x2a4e          (HXS)
+>8     leshort         0x2a74          (LIST)
+>8     leshort         0x2a96          (DIR)
+>8     leshort         0x2ab8          (ALG)
+>8     leshort         0x2ada          (UNIT)
+>8     leshort         0x2afc          (TAGGED)
+>8     leshort         0x2b1e          (GROB)
+>8     leshort         0x2b40          (LIB)
+>8     leshort         0x2b62          (BACKUP)
+>8     leshort         0x2b88          (LIBDATA)
+>8     leshort         0x2d9d          (PROG)
+>8     leshort         0x2dcc          (CODE)
+>8     leshort         0x2e48          (GNAME)
+>8     leshort         0x2e6d          (LNAME)
+>8     leshort         0x2e92          (XLIB)
+
+0      string          %%HP:           HP text
+>6     string          T(0)            - T(0)
+>6     string          T(1)            - T(1)
+>6     string          T(2)            - T(2)
+>6     string          T(3)            - T(3)
+>10    string          A(D)            A(D)
+>10    string          A(R)            A(R)
+>10    string          A(G)            A(G)
+>14    string          F(.)            F(.);
+>14    string          F(,)            F(,);
+
+
+# Summary: HP-38/39 calculator
+# Created by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+0      string          HP3
+>3     string          8               HP 38
+>3     string          9               HP 39
+>4     string          Bin             binary
+>4     string          Asc             ASCII
+>7     string          A               (Directory List)
+>7     string          B               (Zaplet)
+>7     string          C               (Note)
+>7     string          D               (Program)
+>7     string          E               (Variable)
+>7     string          F               (List)
+>7     string          G               (Matrix)
+>7     string          H               (Library)
+>7     string          I               (Target List)
+>7     string          J               (ASCII Vector specification)
+>7     string          K               (wildcard)
+
+# Summary: HP-38/39 calculator
+# Created by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+0      string          HP3
+>3     string          8               HP 38
+>3     string          9               HP 39
+>4     string          Bin             binary
+>4     string          Asc             ASCII
+>7     string          A               (Directory List)
+>7     string          B               (Zaplet)
+>7     string          C               (Note)
+>7     string          D               (Program)
+>7     string          E               (Variable)
+>7     string          F               (List)
+>7     string          G               (Matrix)
+>7     string          H               (Library)
+>7     string          I               (Target List)
+>7     string          J               (ASCII Vector specification)
+>7     string          K               (wildcard)
+
+# hpBSD magic numbers
+0      beshort         200             hp200 (68010) BSD
+>2     beshort         0407            impure binary
+>2     beshort         0410            read-only binary
+>2     beshort         0413            demand paged binary
+0      beshort         300             hp300 (68020+68881) BSD
+>2     beshort         0407            impure binary
+>2     beshort         0410            read-only binary
+>2     beshort         0413            demand paged binary
+#
+# From David Gero <dgero@nortelnetworks.com>
+# HP-UX 10.20 core file format from /usr/include/sys/core.h
+# Unfortunately, HP-UX uses corehead blocks without specifying the order
+# There are four we care about:
+#     CORE_KERNEL, which starts with the string "HP-UX"
+#     CORE_EXEC, which contains the name of the command
+#     CORE_PROC, which contains the signal number that caused the core dump
+#     CORE_FORMAT, which contains the version of the core file format (== 1)
+# The only observed order in real core files is KERNEL, EXEC, FORMAT, PROC
+# but we include all 6 variations of the order of the first 3, and
+# assume that PROC will always be last
+# Order 1: KERNEL, EXEC, FORMAT, PROC
+0x10           string  HP-UX
+>0             belong  2
+>>0xC          belong  0x3C
+>>>0x4C                belong  0x100
+>>>>0x58       belong  0x44
+>>>>>0xA0      belong  1
+>>>>>>0xAC     belong  4
+>>>>>>>0xB0    belong  1
+>>>>>>>>0xB4   belong  4               core file
+>>>>>>>>>0x90  string  >\0             from '%s'
+>>>>>>>>>0xC4  belong  3               - received SIGQUIT
+>>>>>>>>>0xC4  belong  4               - received SIGILL
+>>>>>>>>>0xC4  belong  5               - received SIGTRAP
+>>>>>>>>>0xC4  belong  6               - received SIGABRT
+>>>>>>>>>0xC4  belong  7               - received SIGEMT
+>>>>>>>>>0xC4  belong  8               - received SIGFPE
+>>>>>>>>>0xC4  belong  10              - received SIGBUS
+>>>>>>>>>0xC4  belong  11              - received SIGSEGV
+>>>>>>>>>0xC4  belong  12              - received SIGSYS
+>>>>>>>>>0xC4  belong  33              - received SIGXCPU
+>>>>>>>>>0xC4  belong  34              - received SIGXFSZ
+# Order 2: KERNEL, FORMAT, EXEC, PROC
+>>>0x4C                belong  1
+>>>>0x58       belong  4
+>>>>>0x5C      belong  1
+>>>>>>0x60     belong  0x100
+>>>>>>>0x6C    belong  0x44
+>>>>>>>>0xB4   belong  4               core file
+>>>>>>>>>0xA4  string  >\0             from '%s'
+>>>>>>>>>0xC4  belong  3               - received SIGQUIT
+>>>>>>>>>0xC4  belong  4               - received SIGILL
+>>>>>>>>>0xC4  belong  5               - received SIGTRAP
+>>>>>>>>>0xC4  belong  6               - received SIGABRT
+>>>>>>>>>0xC4  belong  7               - received SIGEMT
+>>>>>>>>>0xC4  belong  8               - received SIGFPE
+>>>>>>>>>0xC4  belong  10              - received SIGBUS
+>>>>>>>>>0xC4  belong  11              - received SIGSEGV
+>>>>>>>>>0xC4  belong  12              - received SIGSYS
+>>>>>>>>>0xC4  belong  33              - received SIGXCPU
+>>>>>>>>>0xC4  belong  34              - received SIGXFSZ
+# Order 3: FORMAT, KERNEL, EXEC, PROC
+0x24           string  HP-UX
+>0             belong  1
+>>0xC          belong  4
+>>>0x10                belong  1
+>>>>0x14       belong  2
+>>>>>0x20      belong  0x3C
+>>>>>>0x60     belong  0x100
+>>>>>>>0x6C    belong  0x44
+>>>>>>>>0xB4   belong  4               core file
+>>>>>>>>>0xA4  string  >\0             from '%s'
+>>>>>>>>>0xC4  belong  3               - received SIGQUIT
+>>>>>>>>>0xC4  belong  4               - received SIGILL
+>>>>>>>>>0xC4  belong  5               - received SIGTRAP
+>>>>>>>>>0xC4  belong  6               - received SIGABRT
+>>>>>>>>>0xC4  belong  7               - received SIGEMT
+>>>>>>>>>0xC4  belong  8               - received SIGFPE
+>>>>>>>>>0xC4  belong  10              - received SIGBUS
+>>>>>>>>>0xC4  belong  11              - received SIGSEGV
+>>>>>>>>>0xC4  belong  12              - received SIGSYS
+>>>>>>>>>0xC4  belong  33              - received SIGXCPU
+>>>>>>>>>0xC4  belong  34              - received SIGXFSZ
+# Order 4: EXEC, KERNEL, FORMAT, PROC
+0x64           string  HP-UX
+>0             belong  0x100
+>>0xC          belong  0x44
+>>>0x54                belong  2
+>>>>0x60       belong  0x3C
+>>>>>0xA0      belong  1
+>>>>>>0xAC     belong  4
+>>>>>>>0xB0    belong  1
+>>>>>>>>0xB4   belong  4               core file
+>>>>>>>>>0x44  string  >\0             from '%s'
+>>>>>>>>>0xC4  belong  3               - received SIGQUIT
+>>>>>>>>>0xC4  belong  4               - received SIGILL
+>>>>>>>>>0xC4  belong  5               - received SIGTRAP
+>>>>>>>>>0xC4  belong  6               - received SIGABRT
+>>>>>>>>>0xC4  belong  7               - received SIGEMT
+>>>>>>>>>0xC4  belong  8               - received SIGFPE
+>>>>>>>>>0xC4  belong  10              - received SIGBUS
+>>>>>>>>>0xC4  belong  11              - received SIGSEGV
+>>>>>>>>>0xC4  belong  12              - received SIGSYS
+>>>>>>>>>0xC4  belong  33              - received SIGXCPU
+>>>>>>>>>0xC4  belong  34              - received SIGXFSZ
+# Order 5: FORMAT, EXEC, KERNEL, PROC
+0x78           string  HP-UX
+>0             belong  1
+>>0xC          belong  4
+>>>0x10                belong  1
+>>>>0x14       belong  0x100
+>>>>>0x20      belong  0x44
+>>>>>>0x68     belong  2
+>>>>>>>0x74    belong  0x3C
+>>>>>>>>0xB4   belong  4               core file
+>>>>>>>>>0x58  string  >\0             from '%s'
+>>>>>>>>>0xC4  belong  3               - received SIGQUIT
+>>>>>>>>>0xC4  belong  4               - received SIGILL
+>>>>>>>>>0xC4  belong  5               - received SIGTRAP
+>>>>>>>>>0xC4  belong  6               - received SIGABRT
+>>>>>>>>>0xC4  belong  7               - received SIGEMT
+>>>>>>>>>0xC4  belong  8               - received SIGFPE
+>>>>>>>>>0xC4  belong  10              - received SIGBUS
+>>>>>>>>>0xC4  belong  11              - received SIGSEGV
+>>>>>>>>>0xC4  belong  12              - received SIGSYS
+>>>>>>>>>0xC4  belong  33              - received SIGXCPU
+>>>>>>>>>0xC4  belong  34              - received SIGXFSZ
+# Order 6: EXEC, FORMAT, KERNEL, PROC
+>0             belong  0x100
+>>0xC          belong  0x44
+>>>0x54                belong  1
+>>>>0x60       belong  4
+>>>>>0x64      belong  1
+>>>>>>0x68     belong  2
+>>>>>>>0x74    belong  0x2C
+>>>>>>>>0xB4   belong  4               core file
+>>>>>>>>>0x44  string  >\0             from '%s'
+>>>>>>>>>0xC4  belong  3               - received SIGQUIT
+>>>>>>>>>0xC4  belong  4               - received SIGILL
+>>>>>>>>>0xC4  belong  5               - received SIGTRAP
+>>>>>>>>>0xC4  belong  6               - received SIGABRT
+>>>>>>>>>0xC4  belong  7               - received SIGEMT
+>>>>>>>>>0xC4  belong  8               - received SIGFPE
+>>>>>>>>>0xC4  belong  10              - received SIGBUS
+>>>>>>>>>0xC4  belong  11              - received SIGSEGV
+>>>>>>>>>0xC4  belong  12              - received SIGSYS
+>>>>>>>>>0xC4  belong  33              - received SIGXCPU
+>>>>>>>>>0xC4  belong  34              - received SIGXFSZ
+
+
diff --git a/magic/Magdir/human68k b/magic/Magdir/human68k
new file mode 100644 (file)
index 0000000..b12a302
--- /dev/null
@@ -0,0 +1,26 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# human68k:  file(1) magic for Human68k (X680x0 DOS) binary formats
+# Magic too short!
+#0             string  HU              Human68k
+#>68           string  LZX             LZX compressed
+#>>72          string  >\0             (version %s)
+#>(8.L+74)     string  LZX             LZX compressed
+#>>(8.L+78)    string  >\0             (version %s)
+#>60           belong  >0              binded
+#>(8.L+66)     string  #HUPAIR         hupair
+#>0            string  HU              X executable
+#>(8.L+74)     string  #LIBCV1         - linked PD LIBC ver 1
+#>4            belong  >0              - base address 0x%x
+#>28           belong  >0              not stripped
+#>32           belong  >0              with debug information
+#0             beshort 0x601a          Human68k Z executable
+#0             beshort 0x6000          Human68k object file
+#0             belong  0xd1000000      Human68k ar binary archive
+#0             belong  0xd1010000      Human68k ar ascii archive
+#0             beshort 0x0068          Human68k lib archive
+#4             string  LZX             Human68k LZX compressed
+#>8            string  >\0             (version %s)
+#>4            string  LZX             R executable
+#2             string  #HUPAIR         Human68k hupair R executable
diff --git a/magic/Magdir/ibm370 b/magic/Magdir/ibm370
new file mode 100644 (file)
index 0000000..a49b28f
--- /dev/null
@@ -0,0 +1,48 @@
+
+#------------------------------------------------------------------------------
+# $File: ibm370,v 1.10 2017/03/17 21:35:28 christos Exp $
+# ibm370:  file(1) magic for IBM 370 and compatibles.
+#
+# "ibm370" said that 0x15d == 0535 was "ibm 370 pure executable".
+# What the heck *is* "USS/370"?
+# AIX 4.1's "/etc/magic" has
+#
+#      0       short           0535            370 sysV executable
+#      >12     long            >0              not stripped
+#      >22     short           >0              - version %d
+#      >30     long            >0              - 5.2 format
+#      0       short           0530            370 sysV pure executable
+#      >12     long            >0              not stripped
+#      >22     short           >0              - version %d
+#      >30     long            >0              - 5.2 format
+#
+# instead of the "USS/370" versions of the same magic numbers.
+#
+0      beshort         0537            370 XA sysV executable
+>12    belong          >0              not stripped
+>22    beshort         >0              - version %d
+>30    belong          >0              - 5.2 format
+0      beshort         0532            370 XA sysV pure executable
+>12    belong          >0              not stripped
+>22    beshort         >0              - version %d
+>30    belong          >0              - 5.2 format
+0      beshort         054001          370 sysV pure executable
+>12    belong          >0              not stripped
+0      beshort         055001          370 XA sysV pure executable
+>12    belong          >0              not stripped
+0      beshort         056401          370 sysV executable
+>12    belong          >0              not stripped
+0      beshort         057401          370 XA sysV executable
+>12    belong          >0              not stripped
+0       beshort                0531            SVR2 executable (Amdahl-UTS)
+>12    belong          >0              not stripped
+>24     belong         >0              - version %d
+0      beshort         0534            SVR2 pure executable (Amdahl-UTS)
+>12    belong          >0              not stripped
+>24    belong          >0              - version %d
+0      beshort         0530            SVR2 pure executable (USS/370)
+>12    belong          >0              not stripped
+>24    belong          >0              - version %d
+0      beshort         0535            SVR2 executable (USS/370)
+>12    belong          >0              not stripped
+>24    belong          >0              - version %d
diff --git a/magic/Magdir/ibm6000 b/magic/Magdir/ibm6000
new file mode 100644 (file)
index 0000000..2112e71
--- /dev/null
@@ -0,0 +1,33 @@
+
+#------------------------------------------------------------------------------
+# $File: ibm6000,v 1.14 2019/03/07 17:21:54 christos Exp $
+# ibm6000:  file(1) magic for RS/6000 and the RT PC.
+#
+0      beshort         0x01df          executable (RISC System/6000 V3.1) or obj module
+>12    belong          >0              not stripped
+# Breaks sun4 statically linked execs.
+#0      beshort                0x0103          executable (RT Version 2) or obj module
+#>2    byte            0x50            pure
+#>28   belong          >0              not stripped
+#>6    beshort         >0              - version %ld
+0      beshort         0x0104          shared library
+0      beshort         0x0105          ctab data
+0      beshort         0xfe04          structured file
+0      string          0xabcdef        AIX message catalog
+0      belong          0x000001f9      AIX compiled message catalog
+0      string          \<aiaff>        archive
+0      string          \<bigaf>        archive (big format)
+0      belong          0x09006bea      AIX backup/restore format file
+0      belong          0x09006fea      AIX backup/restore format file
+
+0      beshort         0x01f7          64-bit XCOFF executable or object module
+>20    belong          0               not stripped
+# GRR: this test is still too general as it catches also many FATs of DOS filesystems
+4      belong          &0x0feeddb0
+# real core dump could not be 32-bit and 64-bit together
+>7     byte&0x03       !3              AIX core file
+>>1    byte            &0x01           fulldump
+>>7    byte            &0x01           32-bit
+>>>0x6e0       string  >\0             \b, %s
+>>7    byte            &0x02           64-bit
+>>>0x524       string  >\0             \b, %s
diff --git a/magic/Magdir/icc b/magic/Magdir/icc
new file mode 100644 (file)
index 0000000..55583b7
--- /dev/null
@@ -0,0 +1,214 @@
+
+#------------------------------------------------------------------------------
+# $File: icc,v 1.5 2017/08/13 00:21:47 christos Exp $
+# icc:  file(1) magic for International Color Consortium file formats
+
+#
+# Color profiles as per the ICC's "Image technology colour management -
+# Architecture, profile format, and data structure" specification.
+# See
+#
+#      http://www.color.org/specification/ICC1v43_2010-12.pdf
+#
+# for Specification ICC.1:2010 (Profile version 4.3.0.0).
+# URL: http://fileformats.archiveteam.org/wiki/ICC_profile
+# Reference: http://www.color.org/iccmax/ICC.2-2016-7.pdf
+# Update: Joerg Jenderek
+#
+# Bytes 36 to 39 contain a generic profile file signature of "acsp";
+# bytes 40 to 43 "may be used to identify the primary platform/operating
+# system framework for which the profile was created".
+#
+#      check and display ICC/ICM color profile
+0      name    color-profile
+>36    string          acsp
+# skip ASCII like Cognacspirit.txt by month <= 12
+>>26   ubeshort        <13
+# platform/operating system. Only 5 mentioned
+
+#
+# This appears to be what's used for Apple ColorSync profiles.
+# Instead of adding that, Apple just changed the generic "acsp" entry
+# to be for "ColorSync ICC Color Profile" rather than "Kodak Color
+# Management System, ICC Profile".
+# Yes, it's "APPL", not "AAPL"; see the spec.
+>>>40  string          APPL            ColorSync
+
+# Microsoft ICM color profile
+>>>40  string          MSFT            Microsoft
+
+# Yes, that's a blank after "SGI".
+>>>40  string          SGI\            SGI
+
+# XXX - is this what's used for the Sun KCMS or not?  The standard file
+# uses just "acsp" for that, but Apple's file uses it for "ColorSync",
+# and there *is* an identified "primary platform" value of SUNW.
+>>>40  string          SUNW            Sun KCMS
+
+# 5th platform
+>>>40  string          TGNT            Taligent
+
+# remaining "l" "e" of "color profile" printed later to avoid error
+>>>40  string          x               color profi
+#>>>40 string          x               (%.4s)
+!:mime application/vnd.iccprofile
+# for "ICM" extension only versions 2.x and for Kodak "CC" 2.0 is found
+>>>8   ubyte           =2
+# do not use empty message text to a avoid error like
+# icc, 82: Warning: Current entry does not yet have a description for adding a EXTENSION type
+# file.exe: could not find any valid magic files!
+>>>>9  ubyte           !0              \ble
+!:ext  icc/icm
+# minor version
+>>>>9  ubyte           =0              \bl
+# Kodak colour management system
+>>>>>4 string          =KCMS           \be
+!:ext  icc/icm/cc
+>>>>>4 string          !KCMS           \be
+!:ext  icc/icm
+>>>8   ubyte           !2              \ble
+!:ext  icc
+# Profile version major.4bit-minor.sub1.sub2 like 4.3.0.0 (04300000h)
+>>>8   ubyte           x               %u
+>>>9   ubyte/16        x               \b.%u
+# reserved and shall be null but 205.205 in umx1220u.icm
+>>>10  ubyte           >0              \b.%u
+>>>>11 ubyte           >0              \b.%u
+# preferred colour management module like appl CCMS KCMS Lino UCCM "Win " "FF  "
+# skip space like in brmsl08f.icm and null like in brmsl09f.icm, brmsl07f.icm
+>>>4   string          >\              \b, type %.2s
+>>>>6  string          >\              \b%.1s
+>>>>>7 string          >\              \b%.1s
+# colour space "XYZ " "Lab " "RGB " CMYK GRAY ...
+>>>16  string          x               \b, %.3s
+>>>19  string          >\              \b%.1s
+# Profile Connection Space (PCS) field usually "XYZ " or "Lab " but sometimes
+# null or CMYK like in ISOcoated_v2_to_PSOcoated_v3_DeviceLink.icc
+>>>20  string          >\0             \b/%.3s
+>>>>23 string          >\              \b%.1s
+# eleven device classes
+>>>12  string          x               \b-%.4s device
+# skip 00001964h in hpf69000.icc or 0h in XRDC50Q.ICM or " ROT" in brmsl05f.icm
+>>>52  string          >\040
+# skip "none" model like in "Trinitron Compatible 9300K G2.2.icm"
+>>>>52 ubelong         !0x6e6f6e65
+# device manufacturer field like "HP  " "IBM " EPSO
+>>>>>48        string          x               \b, %.2s
+>>>>>50        string          >\              \b%.1s
+>>>>>51        string          >\              \b%.1s
+# model like "ADI " "A265" and skip 20000404h in IS330.icm for RICOH RUSSIAN-SC
+>>>>>52        string          >\ \            \b/%.3s
+>>>>>>55 string                >\              \b%.1s
+>>>>>52        string          x               model
+# creator (often same as manufacture) like HP SONY XROX or null like in A925A.icm
+>>>80  string          >\0             by %.2s
+>>>>82 string          >\              \b%.1s
+>>>>>83        string          >\              \b%.1s
+# profile size
+>>>0   ubelong         x               \b, %u bytes
+# skip invalid date 0 like in linearSRGB.icc
+>>>24  ubequad         !0
+# datetime dd-mm-yyyy hh:mm:ss
+>>>>28 ubeshort        x               \b, %u
+# month <= 12
+>>>>26 ubeshort        x               \b-%u
+# year
+>>>>24 ubeshort        x               \b-%u
+# do not display midnight time like in CNHP8308.ICC
+>>>>30 ubequad&0xFFffFFffFFff0000      !0
+# hour <= 24
+>>>>>30        ubeshort        x               %u
+# minutes <= 59
+>>>>>32        ubeshort        x               \b:%.2u
+# seconds <= 59
+>>>>>34        ubeshort        x               \b:%.2u
+# vendor specific flags like 2 in HPCLJ5.ICM
+>>>44  ubeshort        >0              \b, 0x%x vendor flags
+# profile flags bits 0-2 of least 16 used by ICC
+#>>>44 ubelong         >0              \b, 0x%x flags
+# icEmbeddedProfileTrue
+>>>44  ubelong         &1              \b, embedded
+# icEmbeddedProfileFalse
+#>>>44 ubelong         ^1              \b, not embedded
+# icUseWithEmbeddedDataOnly
+>>>44  ubelong         &2              \b, dependently
+# icUseAnywhere
+#>>>44 ubelong         ^2              \b, independently
+>>>44  ubelong         &4              \b, MCS
+#>>>44 ubelong         ^4              \b, no MCS
+# vendor specific device attributes 1~srgb.icc
+# E000D00h~CNB7QEDA.ICM C000A00h~CNB5FCAA.ICM 01040401h~CNB25PE3.ICM
+>>>56  ubelong         >0              \b, 0x%x vendor attribute
+# ICC device attributes bits 0-7 used
+#>>>60 ubelong         x               \b, 0x%x attribute
+# http://www.color.org/icc34.h
+>>>60  ubelong         &0x01           \b, transparent
+#>>>60 ubelong         ^0x01           \b, reflective
+>>>60  ubelong         &0x02           \b, matte
+#>>>60 ubelong         ^0x02           \b, glossy
+>>>60  ubelong         &0x04           \b, negative
+#>>>60 ubelong         ^0x04           \b, positive
+>>>60  ubelong         &0x08           \b, black&white
+#>>>60 ubelong         ^0x08           \b, colour
+>>>60  ubelong         &0x10           \b, non-paper
+#>>>60 ubelong         ^0x10           \b, paper
+>>>60  ubelong         &0x20           \b, non-textured
+#>>>60 ubelong         ^0x20           \b, textured
+>>>60  ubelong         &0x40           \b, non-isotropic
+#>>>60 ubelong         ^0x40           \b, isotropic
+>>>60  ubelong         &0x80           \b, self-luminous
+#>>>60 ubelong         ^0x80           \b, non-self-luminous
+# rendering intent 0-3 but 7AEA5027h in EE051__1.ICM 6CB1BCh in EE061__1.ICM
+>>>64  ubelong         >3              \b, 0x%x rendering intent
+#>>>64 ubelong         =0              \b, perceptual
+>>>64  ubelong         =1              \b, relative colorimetric
+>>>64  ubelong         =2              \b, saturation
+>>>64  ubelong         =3              \b, absolute colorimetric
+# PCS illuminant (3*s15Fixed16Numbers) often 0000f6d6 00010000 0000d32d
+>>>71  ubequad         !0xd6000100000000d3     \b, PCS
+# usually X~0.9642*65536=63189.8112~63190=F6D5h ; but also found
+# often F6D6 in gt5000r.icm, F6B8 in kodakce.icm, F6CA in RSWOP.icm
+>>>>68 ubelong                 !0x0000f6d5     X=0x%x
+# usually Y=1.0~00010000h but Y=0 in brmsl07f.icm
+>>>>72 ubelong                 !0x00010000     Y=0x%x
+# usually Z~0.8249*65536=54060.6464~54061=D32Dh ; but also found
+# D2F7 in hp1200c.icm, often D32C in A925A.icm, D309 in RSWOP.icm , D2F8 in kodak_dc.icm
+>>>>76 ubelong                 !0x0000d32d     Z=0x%x
+# Profile ID. MD5 fingerprinting method as defined in Internet RFC 1321.
+>>>84  ubequad         >0              \b, 0x%llx MD5
+# reserved in older versions should be zero but also found CDCDCDCDCDCDCDCD
+#>>100 ubequad         x               \b 0x%llx reserved
+# tag table
+# 6 <= tags count <= 43
+#>>>128        ubelong         >43             \b, %u tags
+>>>128 ubelong         x
+# shall contain the profileDescriptionTag "desc" , copyrightTag "cprt"
+# search range = tags count * 12 -8=< maximal tag count * 12 -8= 43 * 12 -8= 508
+>>>>132        search/508      cprt
+# but no copyright tag in linearSRGB.icc
+# beneath /System/Library/Frameworks/WebKit.framework/
+# Versions/A/Frameworks/WebCore.framework/Versions/A/Resources
+>>>>132        default         x               \b, no copyright tag
+# 1st tag
+#>>>132        string          x               \b, 1st tag %.4s
+#>>>136        ubelong         x               0x%x offset
+#>>>140        ubelong         x               0x%x len
+# 2nd tag,...
+# look also for profileDescriptionTag "desc"
+>>>132 search/508      desc
+# look further for TextDescriptionType "desc" signature
+>>>>(&0.L)     string          =desc
+>>>>>&4                pstring/l       x       "%s"
+# look alternative for multiLocalizedUnicodeType "mluc" signature like in VideoPAL.icc
+>>>>(&0.L)     string          =mluc
+>>>>>&(&8.L)   ubequad         x
+>>>>>>&4       bestring16      x       '%s'
+
+# Any other profile.
+# XXX - should we use "acsp\0\0\0\0" for "no primary platform" profiles,
+# and use "acsp" for everything else and dump the "primary platform"
+# string in those cases?
+36     string          acsp
+>0     use             color-profile
+
+
diff --git a/magic/Magdir/iff b/magic/Magdir/iff
new file mode 100644 (file)
index 0000000..5c1705a
--- /dev/null
@@ -0,0 +1,73 @@
+
+#------------------------------------------------------------------------------
+# $File: iff,v 1.13 2011/09/06 11:00:06 christos Exp $
+# iff: file(1) magic for Interchange File Format (see also "audio" & "images")
+#
+# Daniel Quinlan (quinlan@yggdrasil.com) -- IFF was designed by Electronic
+# Arts for file interchange.  It has also been used by Apple, SGI, and
+# especially Commodore-Amiga.
+#
+# IFF files begin with an 8 byte FORM header, followed by a 4 character
+# FORM type, which is followed by the first chunk in the FORM.
+
+0      string          FORM            IFF data
+#>4    belong          x               \b, FORM is %d bytes long
+# audio formats
+>8     string          AIFF            \b, AIFF audio
+!:mime audio/x-aiff
+>8     string          AIFC            \b, AIFF-C compressed audio
+!:mime audio/x-aiff
+>8     string          8SVX            \b, 8SVX 8-bit sampled sound voice
+!:mime audio/x-aiff
+>8     string          16SV            \b, 16SV 16-bit sampled sound voice
+>8     string          SAMP            \b, SAMP sampled audio
+>8     string          MAUD            \b, MAUD MacroSystem audio
+>8     string          SMUS            \b, SMUS simple music
+>8     string          CMUS            \b, CMUS complex music
+# image formats
+>8     string          ILBMBMHD        \b, ILBM interleaved image
+>>20   beshort         x               \b, %d x
+>>22   beshort         x               %d
+>8     string          RGBN            \b, RGBN 12-bit RGB image
+>8     string          RGB8            \b, RGB8 24-bit RGB image
+>8     string          DEEP            \b, DEEP TVPaint/XiPaint image
+>8     string          DR2D            \b, DR2D 2-D object
+>8     string          TDDD            \b, TDDD 3-D rendering
+>8     string          LWOB            \b, LWOB 3-D object
+>8     string          LWO2            \b, LWO2 3-D object, v2
+>8     string          LWLO            \b, LWLO 3-D layered object
+>8     string          REAL            \b, REAL Real3D rendering
+>8     string          MC4D            \b, MC4D MaxonCinema4D rendering
+>8     string          ANIM            \b, ANIM animation
+>8     string          YAFA            \b, YAFA animation
+>8     string          SSA\            \b, SSA super smooth animation
+>8     string          ACBM            \b, ACBM continuous image
+>8     string          FAXX            \b, FAXX fax image
+# other formats
+>8     string          FTXT            \b, FTXT formatted text
+>8     string          CTLG            \b, CTLG message catalog
+>8     string          PREF            \b, PREF preferences
+>8     string          DTYP            \b, DTYP datatype description
+>8     string          PTCH            \b, PTCH binary patch
+>8     string          AMFF            \b, AMFF AmigaMetaFile format
+>8     string          WZRD            \b, WZRD StormWIZARD resource
+>8     string          DOC\            \b, DOC desktop publishing document
+>8     string          WVQA            \b, Westwood Studios VQA Multimedia,
+>>24   leshort         x               %d video frames,
+>>26   leshort         x               %d x
+>>28   leshort         x               %d
+>8     string          MOVE            \b, Wing Commander III Video
+>>12   string          _PC_            \b, PC version
+>>12   string          3DO_            \b, 3DO version
+
+# These go at the end of the iff rules
+#
+# David Griffith <dave@661.org>
+# I don't see why these might collide with anything else.
+#
+# Interactive Fiction related formats
+#
+>8     string          IFRS            \b, Blorb Interactive Fiction
+>>24   string          Exec            with executable chunk
+>8     string          IFZS            \b, Z-machine or Glulx saved game file (Quetzal)
+!:mime application/x-blorb
diff --git a/magic/Magdir/images b/magic/Magdir/images
new file mode 100644 (file)
index 0000000..0e314ad
--- /dev/null
@@ -0,0 +1,1962 @@
+
+#------------------------------------------------------------------------------
+# $File: images,v 1.160 2019/04/19 00:42:27 christos Exp $
+# images:  file(1) magic for image formats (see also "iff", and "c-lang" for
+# XPM bitmaps)
+#
+# originally from jef@helios.ee.lbl.gov (Jef Poskanzer),
+# additions by janl@ifi.uio.no as well as others. Jan also suggested
+# merging several one- and two-line files into here.
+#
+# little magic: PCX (first byte is 0x0a)
+
+# Targa - matches `povray', `ppmtotga' and `xv' outputs
+# by Philippe De Muyter <phdm@macqel.be>
+# URL: http://justsolve.archiveteam.org/wiki/TGA
+# Reference: http://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
+# Update: Joerg Jenderek
+# at 2, byte ImgType must be 1, 2, 3, 9, 10 or 11
+#      ,32 or 33 (both not observed)
+# at 1, byte CoMapType must be 1 if ImgType is 1 or 9, 0 otherwise
+#      or theoretically 2-128 reserved for use by Truevision or 128-255 may be used for developer applications
+# at 3, leshort Index is 0 for povray, ppmtotga and xv outputs
+# `xv' recognizes only a subset of the following (RGB with pixelsize = 24)
+# `tgatoppm' recognizes a superset (Index may be anything)
+#
+# test of Color Map Type 0~no 1~color map
+# and Image Type 1 2 3 9 10 11 32 33
+# and Color Map Entry Size 0 15 16 24 32
+0      ubequad&0x00FeC400000000C0      0
+# Prevent conflicts with CRI ADX.
+>(2.S-2) belong        !0x28632943
+# skip more garbage like *.iso by looking for positive image type
+>>2    ubyte                   >0
+# skip some compiled terminfo like xterm+tmux by looking for image type less equal 33
+>>>2   ubyte                   <34
+# skip arches.3200 , Finder.Root , Slp.1 by looking for low pixel depth 1 8 15 16 24 32
+>>>>16 ubyte                   1
+>>>>>0         use             tga-image
+>>>>16 ubyte                   8
+>>>>>0         use             tga-image
+>>>>16 ubyte                   15
+>>>>>0         use             tga-image
+>>>>16 ubyte                   16
+>>>>>0         use             tga-image
+>>>>16 ubyte                   24
+>>>>>0         use             tga-image
+>>>>16 ubyte                   32
+>>>>>0         use             tga-image
+#      display tga bitmap image information
+0      name                            tga-image
+>2     ubyte           <34             Targa image data
+!:mime image/x-tga
+!:apple        ????TPIC
+# normal extension .tga but some Truevision products used others:
+# tpic (Apple),icb (Image Capture Board),vda (Video Display Adapter),vst (NuVista),win (UNSURE about that)
+!:ext  tga/tpic/icb/vda/vst
+# image type 1 2 3 9 10 11 32 33
+>2     ubyte&0xF7      1               - Map
+>2     ubyte&0xF7      2               - RGB
+# alpha channel
+>>17   ubyte&0x0F      >0              \bA
+>2     ubyte&0xF7      3               - Mono
+# type not found, but by http://www.fileformat.info/format/tga/corion.htm
+# Compressed color-mapped data, using Huffman, Delta, and runlength encoding
+>2     ubyte           32              - Color
+# Compressed color-mapped data, using Huffman, Delta, and RLE. 4-pass quadtree- type process
+>2     ubyte           33              - Color
+# Color Map Type 0~no 1~color map
+>1     ubyte           1               (
+# first color map entry, 0 normal
+>>3    uleshort        >0              \b%d-
+# color map length 0 2 1dh 3bh d9h 100h
+>>5    uleshort        x               \b%d)
+# 8~run length encoding bit
+>2     ubyte&0x08      8               - RLE
+# gimp can create big pictures!
+>12    uleshort        >0              %d x
+>12    uleshort        =0              65536 x
+# image height. 0 interpreted as 65536
+>14    uleshort        >0              %d
+>14    uleshort        =0              65536
+# Image Pixel depth 1 8 15 16 24 32
+>16    ubyte           x               x %d
+# X origin of image. 0 normal
+>8     uleshort        >0              +%d
+# Y origin of image. 0 normal; positive for top
+>10    uleshort        >0              +%d
+# Image descriptor: bits 3-0 give the alpha channel depth, bits 5-4 give direction
+>17    ubyte&0x0F      >0              - %d-bit alpha
+# bits 5-4 give direction. normal bottom left
+>17    ubyte           &0x20           - top
+#>17   ubyte           ^0x20           - bottom
+>17    ubyte           &0x10           - right
+#>17   ubyte           ^0x10           - left
+# some info say other bits 6-7 should be zero
+# but data storage interleave by http://www.fileformat.info/format/tga/corion.htm
+# 00 - no interleave;01 - even/odd interleave; 10 - four way interleave; 11 - reserved
+#>17   ubyte&0xC0      0x00            - no interleave
+>17    ubyte&0xC0      0x40            - interleave
+>17    ubyte&0xC0      0x80            - four way interleave
+>17    ubyte&0xC0      0xC0            - reserved
+# positive length implies identification field
+>0     ubyte           >0
+>>18   string          x               "%s"
+# last 18 bytes of newer tga file footer signature
+>18    search/4261301/s        TRUEVISION-XFILE.\0
+# extension area offset if not 0
+>>&-8          ulelong                 >0
+# length of the extension area. normal 495 for version 2.0
+>>>(&-4.l)     uleshort                0x01EF
+# AuthorName[41]
+>>>>&0         string                  >\0             - author "%-.40s"
+# Comment[324]=4 * 80 null terminated
+>>>>&41                string                  >\0             - comment "%-.80s"
+# date
+>>>>&365       ubequad&0xffffFFFFffff0000      !0
+# Day
+>>>>>&-6               uleshort                x               %d
+# Month
+>>>>>&-8               uleshort                x               \b-%d
+# Year
+>>>>>&-4               uleshort                x               \b-%d
+# time
+>>>>&371       ubequad&0xffffFFFFffff0000      !0
+# hour
+>>>>>&-8               uleshort                x               %d
+# minutes
+>>>>>&-6               uleshort                x               \b:%.2d
+# second
+>>>>>&-4               uleshort                x               \b:%.2d
+# JobName[41]
+>>>>&377               string                  >\0             - job "%-.40s"
+# JobHour Jobminute Jobsecond
+>>>>&418       ubequad&0xffffFFFFffff0000      !0
+>>>>>&-8               uleshort                x               %d
+>>>>>&-6               uleshort                x               \b:%.2d
+>>>>>&-4               uleshort                x               \b:%.2d
+# SoftwareId[41]
+>>>>&424               string                  >\0             - %-.40s
+# SoftwareVersionNumber
+>>>>&424       ubyte                           >0
+>>>>>&40               uleshort/100            x               %d
+>>>>>&40               uleshort%100            x               \b.%d
+# VersionLetter
+>>>>>&42               ubyte                   >0x20           \b%c
+# KeyColor
+>>>>&468               ulelong                 >0              - keycolor 0x%8.8x
+# Denominator of Pixel ratio. 0~no pixel aspect
+>>>>&474       uleshort                        >0
+# Numerator
+>>>>>&-4               uleshort                >0              - aspect %d
+>>>>>&-2               uleshort                x               \b/%d
+# Denominator of Gamma ratio. 0~no Gamma value
+>>>>&478       uleshort                        >0
+# Numerator
+>>>>>&-4               uleshort                >0              - gamma %d
+>>>>>&-2               uleshort                x               \b/%d
+# ColorOffset
+#>>>>&480      ulelong                 x               - col offset 0x%8.8x
+# StampOffset
+#>>>>&484      ulelong                 x               - stamp offset 0x%8.8x
+# ScanOffset
+#>>>>&488      ulelong                 x               - scan offset 0x%8.8x
+# AttributesType
+#>>>>&492      ubyte                   x               - Attributes 0x%x
+## EndOfTGA
+
+# PBMPLUS images
+# The next byte following the magic is always whitespace.
+# strength is changed to try these patterns before "x86 boot sector"
+0      name            netpbm
+>3     regex/s         =[0-9]{1,50}\ [0-9]{1,50}       Netpbm image data
+>>&0   regex           =[0-9]{1,50}                    \b, size = %s x
+>>>&0  regex           =[0-9]{1,50}                    \b %s
+
+0      search/1        P1
+>0     regex/4         P1[\040\t\f\r\n]
+>>0    use             netpbm
+>>0    string          x       \b, bitmap
+!:strength + 65
+!:mime image/x-portable-bitmap
+
+0      search/1        P2
+>0     regex/4         P2[\040\t\f\r\n]
+>>0    use             netpbm
+>>0    string          x       \b, greymap
+!:strength + 65
+!:mime image/x-portable-greymap
+
+0      search/1        P3
+>0     regex/4         P3[\040\t\f\r\n]
+>>0    use             netpbm
+>>0    string          x       \b, pixmap
+!:strength + 65
+!:mime image/x-portable-pixmap
+
+0      string          P4
+>0     regex/4         P4[\040\t\f\r\n]
+>>0    use             netpbm
+>>0    string          x       \b, rawbits, bitmap
+!:strength + 65
+!:mime image/x-portable-bitmap
+
+0      string          P5
+>0     regex/4         P5[\040\t\f\r\n]
+>>0    use             netpbm
+>>0    string          x       \b, rawbits, greymap
+!:strength + 65
+!:mime image/x-portable-greymap
+
+0      string          P6
+>0     regex/4         P6[\040\t\f\r\n]
+>>0    use             netpbm
+>>0    string          x       \b, rawbits, pixmap
+!:strength + 65
+!:mime image/x-portable-pixmap
+
+0      string          P7              Netpbm PAM image file
+!:mime image/x-portable-pixmap
+
+# From: bryanh@giraffe-data.com (Bryan Henderson)
+0      string          \117\072        Solitaire Image Recorder format
+>4     string          \013            MGI Type 11
+>4     string          \021            MGI Type 17
+0      string          .MDA            MicroDesign data
+>21    byte            48              version 2
+>21    byte            51              version 3
+0      string          .MDP            MicroDesign page data
+>21    byte            48              version 2
+>21    byte            51              version 3
+
+# NIFF (Navy Interchange File Format, a modification of TIFF) images
+# [GRR:  this *must* go before TIFF]
+0      string          IIN1            NIFF image data
+!:mime image/x-niff
+
+# Canon RAW version 1 (CRW) files are a type of Canon Image File Format
+# (CIFF) file. These are apparently all little-endian.
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# URL: https://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html
+0      string          II\x1a\0\0\0HEAPCCDR    Canon CIFF raw image data
+!:mime image/x-canon-crw
+>16    leshort         x       \b, version %d.
+>14    leshort         x       \b%d
+
+# Canon RAW version 2 (CR2) files are a kind of TIFF with an extra magic
+# number. Put this above the TIFF test to make sure we detect them.
+# These are apparently all little-endian.
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# URL: https://libopenraw.freedesktop.org/wiki/Canon_CR2
+0      string          II\x2a\0\x10\0\0\0CR    Canon CR2 raw image data
+!:mime image/x-canon-cr2
+!:strength +80
+>10    byte            x       \b, version %d.
+>11    byte            x       \b%d
+
+# Tag Image File Format, from Daniel Quinlan (quinlan@yggdrasil.com)
+# The second word of TIFF files is the TIFF version number, 42, which has
+# never changed.  The TIFF specification recommends testing for it.
+0      string          MM\x00\x2a      TIFF image data, big-endian
+!:strength +70
+!:mime image/tiff
+>(4.L) use             \^tiff_ifd
+0      string          II\x2a\x00      TIFF image data, little-endian
+!:mime image/tiff
+!:strength +70
+>(4.l) use             tiff_ifd
+
+0      name            tiff_ifd
+>0     leshort         x               \b, direntries=%d
+>2     use             tiff_entry
+
+0      name            tiff_entry
+# NewSubFileType
+>0     leshort         0xfe
+>>12   use             tiff_entry
+>0     leshort         0x100
+>>4    lelong          1
+>>>12  use             tiff_entry
+>>>8   leshort         x               \b, width=%d
+>0     leshort         0x101
+>>4    lelong          1
+>>>8   leshort         x               \b, height=%d
+>>>12  use             tiff_entry
+>0     leshort         0x102
+>>8    leshort         x               \b, bps=%d
+>>12   use             tiff_entry
+>0     leshort         0x103
+>>4    lelong          1               \b, compression=
+>>>8   leshort         1               \bnone
+>>>8   leshort         2               \bhuffman
+>>>8   leshort         3               \bbi-level group 3
+>>>8   leshort         4               \bbi-level group 4
+>>>8   leshort         5               \bLZW
+>>>8   leshort         6               \bJPEG (old)
+>>>8   leshort         7               \bJPEG
+>>>8   leshort         8               \bdeflate
+>>>8   leshort         9               \bJBIG, ITU-T T.85
+>>>8   leshort         0xa             \bJBIG, ITU-T T.43
+>>>8   leshort         0x7ffe          \bNeXT RLE 2-bit
+>>>8   leshort         0x8005          \bPackBits (Macintosh RLE)
+>>>8   leshort         0x8029          \bThunderscan RLE
+>>>8   leshort         0x807f          \bRasterPadding (CT or MP)
+>>>8   leshort         0x8080          \bRLE (Line Work)
+>>>8   leshort         0x8081          \bRLE (High-Res Cont-Tone)
+>>>8   leshort         0x8082          \bRLE (Binary Line Work)
+>>>8   leshort         0x80b2          \bDeflate (PKZIP)
+>>>8   leshort         0x80b3          \bKodak DCS
+>>>8   leshort         0x8765          \bJBIG
+>>>8   leshort         0x8798          \bJPEG2000
+>>>8   leshort         0x8799          \bNikon NEF Compressed
+>>>8   default         x
+>>>>8  leshort         x               \b(unknown 0x%x)
+>>>12  use             tiff_entry
+>0     leshort         0x106           \b, PhotometricIntepretation=
+>>8    clear           x
+>>8    leshort         0               \bWhiteIsZero
+>>8    leshort         1               \bBlackIsZero
+>>8    leshort         2               \bRGB
+>>8    leshort         3               \bRGB Palette
+>>8    leshort         4               \bTransparency Mask
+>>8    leshort         5               \bCMYK
+>>8    leshort         6               \bYCbCr
+>>8    leshort         8               \bCIELab
+>>8    default         x
+>>>8   leshort         x               \b(unknown=0x%x)
+>>12   use             tiff_entry
+# FillOrder
+>0     leshort         0x10a
+>>4    lelong          1
+>>>12  use             tiff_entry
+# DocumentName
+>0     leshort         0x10d
+>>(8.l)        string          x               \b, name=%s
+>>>12  use             tiff_entry
+# ImageDescription
+>0     leshort         0x10e
+>>(8.l)        string          x               \b, description=%s
+>>>12  use             tiff_entry
+# Make
+>0     leshort         0x10f
+>>(8.l)        string          x               \b, manufacturer=%s
+>>>12  use             tiff_entry
+# Model
+>0     leshort         0x110
+>>(8.l)        string          x               \b, model=%s
+>>>12  use             tiff_entry
+# StripOffsets
+>0     leshort         0x111
+>>12   use             tiff_entry
+# Orientation
+>0     leshort         0x112           \b, orientation=
+>>8    leshort         1               \bupper-left
+>>8    leshort         3               \blower-right
+>>8    leshort         6               \bupper-right
+>>8    leshort         8               \blower-left
+>>8    leshort         9               \bundefined
+>>8    default         x
+>>>8   leshort         x               \b[*%d*]
+>>12   use             tiff_entry
+# XResolution
+>0     leshort         0x11a
+>>8    lelong          x               \b, xresolution=%d
+>>12   use             tiff_entry
+# YResolution
+>0     leshort         0x11b
+>>8    lelong          x               \b, yresolution=%d
+>>12   use             tiff_entry
+# ResolutionUnit
+>0     leshort         0x128
+>>8    leshort         x               \b, resolutionunit=%d
+>>12   use             tiff_entry
+# Software
+>0     leshort         0x131
+>>(8.l)        string          x               \b, software=%s
+>>12   use             tiff_entry
+# Datetime
+>0     leshort         0x132
+>>(8.l)        string          x               \b, datetime=%s
+>>12   use             tiff_entry
+# HostComputer
+>0     leshort         0x13c
+>>(8.l)        string          x               \b, hostcomputer=%s
+>>12   use             tiff_entry
+# WhitePoint
+>0     leshort         0x13e
+>>12   use             tiff_entry
+# PrimaryChromaticities
+>0     leshort         0x13f
+>>12   use             tiff_entry
+# YCbCrCoefficients
+>0     leshort         0x211
+>>12   use             tiff_entry
+# YCbCrPositioning
+>0     leshort         0x213
+>>12   use             tiff_entry
+# ReferenceBlackWhite
+>0     leshort         0x214
+>>12   use             tiff_entry
+# Copyright
+>0     leshort         0x8298
+>>(8.l)        string          x               \b, copyright=%s
+>>12   use             tiff_entry
+# ExifOffset
+>0     leshort         0x8769
+>>12   use             tiff_entry
+# GPS IFD
+>0     leshort         0x8825          \b, GPS-Data
+>>12   use             tiff_entry
+
+#>0    leshort         x               \b, unknown=0x%x
+#>>12  use             tiff_entry
+
+0      string          MM\x00\x2b      Big TIFF image data, big-endian
+!:mime image/tiff
+0      string          II\x2b\x00      Big TIFF image data, little-endian
+!:mime image/tiff
+
+# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
+# (Greg Roelofs, newt@uchicago.edu)
+# (Albert Cahalan, acahalan@cs.uml.edu)
+#
+# 137 P N G \r \n ^Z \n [4-byte length] I H D R [HEAD data] [HEAD crc] ...
+#
+
+# IHDR parser
+0      name            png-ihdr
+>0     belong          x               \b, %d x
+>4     belong          x               %d,
+>8     byte            x               %d-bit
+>9     byte            0               grayscale,
+>9     byte            2               \b/color RGB,
+>9     byte            3               colormap,
+>9     byte            4               gray+alpha,
+>9     byte            6               \b/color RGBA,
+#>10   byte            0               deflate/32K,
+>12    byte            0               non-interlaced
+>12    byte            1               interlaced
+
+# Standard PNG image.
+0      string          \x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0DIHDR     PNG image data
+!:mime image/png
+!:ext   png
+!:strength +10
+>16    use             png-ihdr
+
+# Apple CgBI PNG image.
+0      string          \x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x04CgBI
+>24    string          \x00\x00\x00\x0DIHDR    PNG image data (CgBI)
+!:mime image/png
+!:ext   png
+!:strength +10
+>>32   use             png-ihdr
+
+# possible GIF replacements; none yet released!
+# (Greg Roelofs, newt@uchicago.edu)
+#
+# GRR 950115:  this was mine ("Zip GIF"):
+0      string          GIF94z          ZIF image (GIF+deflate alpha)
+!:mime image/x-unknown
+#
+# GRR 950115:  this is Jeremy Wohl's Free Graphics Format (better):
+#
+0      string          FGF95a          FGF image (GIF+deflate beta)
+!:mime image/x-unknown
+#
+# GRR 950115:  this is Thomas Boutell's Portable Bitmap Format proposal
+# (best; not yet implemented):
+#
+0      string          PBF             PBF image (deflate compression)
+!:mime image/x-unknown
+
+# GIF
+# Strength set up to beat 0x55AA DOS/MBR signature word lookups (+65)
+0      string          GIF8            GIF image data
+!:strength +80
+!:mime image/gif
+!:apple        8BIMGIFf
+>4     string          7a              \b, version 8%s,
+>4     string          9a              \b, version 8%s,
+>6     leshort         >0              %d x
+>8     leshort         >0              %d
+#>10   byte            &0x80           color mapped,
+#>10   byte&0x07       =0x00           2 colors
+#>10   byte&0x07       =0x01           4 colors
+#>10   byte&0x07       =0x02           8 colors
+#>10   byte&0x07       =0x03           16 colors
+#>10   byte&0x07       =0x04           32 colors
+#>10   byte&0x07       =0x05           64 colors
+#>10   byte&0x07       =0x06           128 colors
+#>10   byte&0x07       =0x07           256 colors
+
+# ITC (CMU WM) raster files.  It is essentially a byte-reversed Sun raster,
+# 1 plane, no encoding.
+0      string          \361\0\100\273  CMU window manager raster image data
+>4     lelong          >0              %d x
+>8     lelong          >0              %d,
+>12    lelong          >0              %d-bit
+
+# Magick Image File Format
+0      string          id=ImageMagick  MIFF image data
+
+# Artisan
+0      long            1123028772      Artisan image data
+>4     long            1               \b, rectangular 24-bit
+>4     long            2               \b, rectangular 8-bit with colormap
+>4     long            3               \b, rectangular 32-bit (24-bit with matte)
+
+# FIG (Facility for Interactive Generation of figures), an object-based format
+0      search/1        #FIG            FIG image text
+>5     string          x               \b, version %.3s
+
+# PHIGS
+0      string          ARF_BEGARF              PHIGS clear text archive
+0      string          @(#)SunPHIGS            SunPHIGS
+# version number follows, in the form m.n
+>40    string          SunBin                  binary
+>32    string          archive                 archive
+
+# GKS (Graphics Kernel System)
+0      string          GKSM            GKS Metafile
+>24    string          SunGKS          \b, SunGKS
+
+# CGM image files
+0      string          BEGMF           clear text Computer Graphics Metafile
+
+# MGR bitmaps  (Michael Haardt, u31b3hs@pool.informatik.rwth-aachen.de)
+0      string  yz      MGR bitmap, modern format, 8-bit aligned
+0      string  zz      MGR bitmap, old format, 1-bit deep, 16-bit aligned
+0      string  xz      MGR bitmap, old format, 1-bit deep, 32-bit aligned
+0      string  yx      MGR bitmap, modern format, squeezed
+
+# Fuzzy Bitmap (FBM) images
+0      string          %bitmap\0       FBM image data
+>30    long            0x31            \b, mono
+>30    long            0x33            \b, color
+
+# facsimile data
+1      string          PC\ Research,\ Inc      group 3 fax data
+>29    byte            0               \b, normal resolution (204x98 DPI)
+>29    byte            1               \b, fine resolution (204x196 DPI)
+# From: Herbert Rosmanith <herp@wildsau.idv.uni.linz.at>
+0      string          Sfff            structured fax file
+
+# From: Joerg Jenderek <joerg.jen.der.ek@gmx.net>
+# most files with the extension .EPA and some with .BMP
+0      string          \x11\x06        Award BIOS Logo, 136 x 84
+!:mime image/x-award-bioslogo
+0      string          \x11\x09        Award BIOS Logo, 136 x 126
+!:mime image/x-award-bioslogo
+#0     string          \x07\x1f        BIOS Logo corrupted?
+# http://www.blackfiveservices.co.uk/awbmtools.shtml
+# http://biosgfx.narod.ru/v3/
+# http://biosgfx.narod.ru/abr-2/
+0      string          AWBM
+>4     leshort         <1981           Award BIOS bitmap
+!:mime image/x-award-bmp
+# image width is a multiple of 4
+>>4    leshort&0x0003  0
+>>>4           leshort x               \b, %d
+>>>6           leshort x               x %d
+>>4    leshort&0x0003  >0              \b,
+>>>4   leshort&0x0003  =1
+>>>>4          leshort x               %d+3
+>>>4   leshort&0x0003  =2
+>>>>4          leshort x               %d+2
+>>>4   leshort&0x0003  =3
+>>>>4          leshort x               %d+1
+>>>6           leshort x               x %d
+# at offset 8 starts imagedata followed by "RGB " marker
+
+# PC bitmaps (OS/2, Windows BMP files)  (Greg Roelofs, newt@uchicago.edu)
+# https://en.wikipedia.org/wiki/BMP_file_format#DIB_header_.\
+# 28bitmap_information_header.29
+0      string          BM
+>14    leshort         12              PC bitmap, OS/2 1.x format
+!:mime image/x-ms-bmp
+>>18   leshort         x               \b, %d x
+>>20   leshort         x               %d
+>14    leshort         64              PC bitmap, OS/2 2.x format
+!:mime image/x-ms-bmp
+>>18   leshort         x               \b, %d x
+>>20   leshort         x               %d
+>14    leshort         40              PC bitmap, Windows 3.x format
+!:mime image/x-ms-bmp
+>>18   lelong          x               \b, %d x
+>>22   lelong          x               %d x
+>>28   leshort         x               %d
+>14    leshort         124             PC bitmap, Windows 98/2000 and newer format
+!:mime image/x-ms-bmp
+>>18   lelong          x               \b, %d x
+>>22   lelong          x               %d x
+>>28   leshort         x               %d
+>14    leshort         108             PC bitmap, Windows 95/NT4 and newer format
+!:mime image/x-ms-bmp
+>>18   lelong          x               \b, %d x
+>>22   lelong          x               %d x
+>>28   leshort         x               %d
+>14    leshort         128             PC bitmap, Windows NT/2000 format
+!:mime image/x-ms-bmp
+>>18   lelong          x               \b, %d x
+>>22   lelong          x               %d x
+>>28   leshort         x               %d
+# Too simple - MPi
+#0     string          IC              PC icon data
+#0     string          PI              PC pointer image data
+#0     string          CI              PC color icon data
+#0     string          CP              PC color pointer image data
+# Conflicts with other entries [BABYL]
+#0     string          BA              PC bitmap array data
+
+# XPM icons (Greg Roelofs, newt@uchicago.edu)
+0      search/1        /*\ XPM\ */     X pixmap image text
+!:mime image/x-xpmi
+
+# Utah Raster Toolkit RLE images (janl@ifi.uio.no)
+0      leshort         0xcc52          RLE image data,
+>6     leshort         x               %d x
+>8     leshort         x               %d
+>2     leshort         >0              \b, lower left corner: %d
+>4     leshort         >0              \b, lower right corner: %d
+>10    byte&0x1        =0x1            \b, clear first
+>10    byte&0x2        =0x2            \b, no background
+>10    byte&0x4        =0x4            \b, alpha channel
+>10    byte&0x8        =0x8            \b, comment
+>11    byte            >0              \b, %d color channels
+>12    byte            >0              \b, %d bits per pixel
+>13    byte            >0              \b, %d color map channels
+
+# image file format (Robert Potter, potter@cs.rochester.edu)
+0      string          Imagefile\ version-     iff image data
+# this adds the whole header (inc. version number), informative but longish
+>10    string          >\0             %s
+
+# Sun raster images, from Daniel Quinlan (quinlan@yggdrasil.com)
+0      belong          0x59a66a95      Sun raster image data
+>4     belong          >0              \b, %d x
+>8     belong          >0              %d,
+>12    belong          >0              %d-bit,
+#>16   belong          >0              %d bytes long,
+>20    belong          0               old format,
+#>20   belong          1               standard,
+>20    belong          2               compressed,
+>20    belong          3               RGB,
+>20    belong          4               TIFF,
+>20    belong          5               IFF,
+>20    belong          0xffff          reserved for testing,
+>24    belong          0               no colormap
+>24    belong          1               RGB colormap
+>24    belong          2               raw colormap
+#>28   belong          >0              colormap is %d bytes long
+
+# SGI image file format, from Daniel Quinlan (quinlan@yggdrasil.com)
+#
+# See
+#      http://reality.sgi.com/grafica/sgiimage.html
+#
+0      beshort         474             SGI image data
+#>2    byte            0               \b, verbatim
+>2     byte            1               \b, RLE
+#>3    byte            1               \b, normal precision
+>3     byte            2               \b, high precision
+>4     beshort         x               \b, %d-D
+>6     beshort         x               \b, %d x
+>8     beshort         x               %d
+>10    beshort         x               \b, %d channel
+>10    beshort         !1              \bs
+>80    string          >0              \b, "%s"
+
+0      string          IT01            FIT image data
+>4     belong          x               \b, %d x
+>8     belong          x               %d x
+>12    belong          x               %d
+#
+0      string          IT02            FIT image data
+>4     belong          x               \b, %d x
+>8     belong          x               %d x
+>12    belong          x               %d
+#
+2048   string          PCD_IPI         Kodak Photo CD image pack file
+>0xe02 byte&0x03       0x00            , landscape mode
+>0xe02 byte&0x03       0x01            , portrait mode
+>0xe02 byte&0x03       0x02            , landscape mode
+>0xe02 byte&0x03       0x03            , portrait mode
+0      string          PCD_OPA         Kodak Photo CD overview pack file
+
+# FITS format.  Jeff Uphoff <juphoff@tarsier.cv.nrao.edu>
+# FITS is the Flexible Image Transport System, the de facto standard for
+# data and image transfer, storage, etc., for the astronomical community.
+# (FITS floating point formats are big-endian.)
+0      string  SIMPLE\ \ =     FITS image data
+!:mime image/fits
+!:ext  fits/fts
+>109   string  8               \b, 8-bit, character or unsigned binary integer
+>108   string  16              \b, 16-bit, two's complement binary integer
+>107   string  \ 32            \b, 32-bit, two's complement binary integer
+>107   string  -32             \b, 32-bit, floating point, single precision
+>107   string  -64             \b, 64-bit, floating point, double precision
+
+# other images
+0      string  This\ is\ a\ BitMap\ file       Lisp Machine bit-array-file
+
+# From SunOS 5.5.1 "/etc/magic" - appeared right before Sun raster image
+# stuff.
+#
+0      beshort         0x1010          PEX Binary Archive
+
+# DICOM medical imaging data
+# URL:         https://en.wikipedia.org/wiki/DICOM#Data_format
+# Note:                "dcm" is the official file name extension
+#              XnView mention also "dc3" and "acr" as file name extension
+128    string  DICM                    DICOM medical imaging data
+!:mime application/dicom
+!:ext dcm/dicom/dic
+
+# XWD - X Window Dump file.
+#   As described in /usr/X11R6/include/X11/XWDFile.h
+#   used by the xwd program.
+#   Bradford Castalia, idaeim, 1/01
+#   updated by Adam Buchbinder, 2/09
+# The following assumes version 7 of the format; the first long is the length
+# of the header, which is at least 25 4-byte longs, and the one at offset 8
+# is a constant which is always either 1 or 2. Offset 12 is the pixmap depth,
+# which is a maximum of 32.
+0      belong  >100
+>8     belong  <3
+>>12   belong  <33
+>>>4   belong  7                       XWD X Window Dump image data
+!:mime image/x-xwindowdump
+>>>>100        string  >\0                     \b, "%s"
+>>>>16 belong  x                       \b, %dx
+>>>>20 belong  x                       \b%dx
+>>>>12 belong  x                       \b%d
+
+# PDS - Planetary Data System
+#   These files use Parameter Value Language in the header section.
+#   Unfortunately, there is no certain magic, but the following
+#   strings have been found to be most likely.
+0      string  NJPL1I00                PDS (JPL) image data
+2      string  NJPL1I                  PDS (JPL) image data
+0      string  CCSD3ZF                 PDS (CCSD) image data
+2      string  CCSD3Z                  PDS (CCSD) image data
+0      string  PDS_                    PDS image data
+0      string  LBLSIZE=                PDS (VICAR) image data
+
+# pM8x: ATARI STAD compressed bitmap format
+#
+# from Oskar Schirmer <schirmer@scara.com> Feb 2, 2001
+# p M 8 5/6 xx yy zz data...
+# Atari ST STAD bitmap is always 640x400, bytewise runlength compressed.
+# bytes either run horizontally (pM85) or vertically (pM86). yy is the
+# most frequent byte, xx and zz are runlength escape codes, where xx is
+# used for runs of yy.
+#
+0      string  pM85            Atari ST STAD bitmap image data (hor)
+>5     byte    0x00            (white background)
+>5     byte    0xFF            (black background)
+0      string  pM86            Atari ST STAD bitmap image data (vert)
+>5     byte    0x00            (white background)
+>5     byte    0xFF            (black background)
+
+# From: Alex Myczko <alex@aiei.ch>
+# https://www.atarimax.com/jindroush.atari.org/afmtatr.html
+0      leshort 0x0296          Atari ATR image
+
+# XXX:
+# This is bad magic 0x5249 == 'RI' conflicts with RIFF and other
+# magic.
+# SGI RICE image file <mpruett@sgi.com>
+#0     beshort 0x5249          RICE image
+#>2    beshort x               v%d
+#>4    beshort x               (%d x
+#>6    beshort x               %d)
+#>8    beshort 0               8 bit
+#>8    beshort 1               10 bit
+#>8    beshort 2               12 bit
+#>8    beshort 3               13 bit
+#>10   beshort 0               4:2:2
+#>10   beshort 1               4:2:2:4
+#>10   beshort 2               4:4:4
+#>10   beshort 3               4:4:4:4
+#>12   beshort 1               RGB
+#>12   beshort 2               CCIR601
+#>12   beshort 3               RP175
+#>12   beshort 4               YUV
+
+# PCX image files
+# From: Dan Fandrich <dan@coneharvesters.com>
+# updated by Joerg Jenderek at Feb 2013 by https://de.wikipedia.org/wiki/PCX
+# https://web.archive.org/web/20100206055706/http://www.qzx.com/pc-gpe/pcx.txt
+# GRR: original test was still too general as it catches xbase examples T5.DBT,T6.DBT with 0xa000000
+# test for bytes 0x0a,version byte (0,2,3,4,5),compression byte flag(0,1), bit depth (>0) of PCX or T5.DBT,T6.DBT
+0      ubelong&0xffF8fe00      0x0a000000
+# for PCX bit depth > 0
+>3     ubyte           >0
+# test for valid versions
+>>1    ubyte           <6
+>>>1   ubyte           !1      PCX
+!:mime image/x-pcx
+#!:mime        image/pcx
+>>>>1  ubyte           0       ver. 2.5 image data
+>>>>1  ubyte           2       ver. 2.8 image data, with palette
+>>>>1  ubyte           3       ver. 2.8 image data, without palette
+>>>>1  ubyte           4       for Windows image data
+>>>>1  ubyte           5       ver. 3.0 image data
+>>>>4  uleshort        x       bounding box [%d,
+>>>>6  uleshort        x       %d] -
+>>>>8  uleshort        x       [%d,
+>>>>10 uleshort        x       %d],
+>>>>65 ubyte           >1      %d planes each of
+>>>>3  ubyte           x       %d-bit
+>>>>68 byte            1       colour,
+>>>>68 byte            2       grayscale,
+# this should not happen
+>>>>68 default         x       image,
+>>>>12 leshort         >0      %d x
+>>>>>14        uleshort        x       %d dpi,
+>>>>2  byte            0       uncompressed
+>>>>2  byte            1       RLE compressed
+
+# Adobe Photoshop
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+0      string          8BPS Adobe Photoshop Image
+!:mime image/vnd.adobe.photoshop
+>4   beshort 2 (PSB)
+>18  belong  x \b, %d x
+>14  belong  x %d,
+>24  beshort 0 bitmap
+>24  beshort 1 grayscale
+>>12 beshort 2 with alpha
+>24  beshort 2 indexed
+>24  beshort 3 RGB
+>>12 beshort 4 \bA
+>24  beshort 4 CMYK
+>>12 beshort 5 \bA
+>24  beshort 7 multichannel
+>24  beshort 8 duotone
+>24  beshort 9 lab
+>12  beshort > 1
+>>12  beshort x \b, %dx
+>12  beshort 1 \b,
+>22  beshort x %d-bit channel
+>12  beshort > 1 \bs
+
+# XV thumbnail indicator (ThMO)
+0      string          P7\ 332         XV thumbnail image data
+
+# NITF is defined by United States MIL-STD-2500A
+0      string  NITF    National Imagery Transmission Format
+>25    string  >\0     dated %.14s
+
+# GEM Image: Version 1, Headerlen 8 (Wolfram Kleff)
+# Format variations from: Bernd Nuernberger <bernd.nuernberger@web.de>
+# Update: Joerg Jenderek
+# See http://fileformats.archiveteam.org/wiki/GEM_Raster
+# For variations, also see:
+#    https://www.seasip.info/Gem/ff_img.html (Ventura)
+#    http://www.atari-wiki.com/?title=IMG_file (XIMG, STTT)
+#    http://www.fileformat.info/format/gemraster/spec/index.htm (XIMG, STTT)
+#    http://sylvana.net/1stguide/1STGUIDE.ENG (TIMG)
+0       beshort     0x0001
+# header_size
+>2      beshort     0x0008
+>>0     use gem_info
+>2      beshort     0x0009
+>>0     use gem_info
+# no example for NOSIG
+>2      beshort     24
+>>0     use gem_info
+# no example for HYPERPAINT
+>2      beshort     25
+>>0     use gem_info
+16      string      XIMG\0
+>0      use gem_info
+# no example
+16      string      STTT\0\x10
+>0      use gem_info
+# no example or description
+16      string      TIMG\0
+>0      use gem_info
+
+0   name        gem_info
+# version is 2 for some XIMG and 1 for all others
+>0     beshort         <0x0003         GEM
+# https://www.snowstone.org.uk/riscos/mimeman/mimemap.txt
+!:mime image/x-gem
+# header_size 24 25 27 59 779 words for colored bitmaps
+>>2    beshort         >9
+>>>16  string          STTT\0\x10      STTT
+>>>16  string          TIMG\0          TIMG
+# HYPERPAINT or NOSIG variant
+>>>16  string          \0\x80
+>>>>2  beshort         =24             NOSIG
+>>>>2  beshort         !24             HYPERPAINT
+# NOSIG or XIMG variant
+>>>16  default         x
+>>>>16 string          !XIMG\0         NOSIG
+>>16   string          =XIMG\0         XIMG Image data
+!:ext  img/ximg
+# to avoid Warning: Current entry does not yet have a description for adding a EXTENSION type
+>>16   string          !XIMG\0         Image data
+!:ext  img
+# header_size is 9 for Ventura files and 8 for other GEM Paint files
+>>2    beshort         9               (Ventura)
+#>>2   beshort         8               (Paint)
+>>12   beshort         x               %d x
+>>14   beshort         x               %d,
+# 1 4 8
+>>4    beshort         x               %d planes,
+# in tenths of a millimetre
+>>8    beshort         x               %d x
+>>10   beshort         x               %d pixelsize
+# pattern_size 1-8. 2 for GEM Paint
+>>6    beshort         !2              \b, pattern size %d
+
+# GEM Metafile (Wolfram Kleff)
+0      lelong          0x0018FFFF      GEM Metafile data
+>4     leshort         x               version %d
+
+#
+# SMJPEG. A custom Motion JPEG format used by Loki Entertainment
+# Software Torbjorn Andersson <d91tan@Update.UU.SE>.
+#
+0      string  \0\nSMJPEG      SMJPEG
+>8     belong  x               %d.x data
+# According to the specification you could find any number of _TXT
+# headers here, but I can't think of any way of handling that. None of
+# the SMJPEG files I tried it on used this feature. Even if such a
+# file is encountered the output should still be reasonable.
+>16    string  _SND            \b,
+>>24   beshort >0              %d Hz
+>>26   byte    8               8-bit
+>>26   byte    16              16-bit
+>>28   string  NONE            uncompressed
+# >>28 string  APCM            ADPCM compressed
+>>27   byte    1               mono
+>>28   byte    2               stereo
+# Help! Isn't there any way to avoid writing this part twice?
+>>32   string  _VID            \b,
+# >>>48        string  JFIF            JPEG
+>>>40  belong  >0              %d frames
+>>>44  beshort >0              (%d x
+>>>46  beshort >0              %d)
+>16    string  _VID            \b,
+# >>32 string  JFIF            JPEG
+>>24   belong  >0              %d frames
+>>28   beshort >0              (%d x
+>>30   beshort >0              %d)
+
+0      string  Paint\ Shop\ Pro\ Image\ File   Paint Shop Pro Image File
+
+# "thumbnail file" (icon)
+# descended from "xv", but in use by other applications as well (Wolfram Kleff)
+0       string          P7\ 332         XV "thumbnail file" (icon) data
+
+# taken from fkiss: (<yav@mte.biglobe.ne.jp> ?)
+0       string          KiSS            KISS/GS
+>4      byte            16              color
+>>5     byte            x               %d bit
+>>8     leshort         x               %d colors
+>>10    leshort         x               %d groups
+>4      byte            32              cell
+>>5     byte            x               %d bit
+>>8     leshort         x               %d x
+>>10    leshort         x               %d
+>>12    leshort         x               +%d
+>>14    leshort         x               +%d
+
+# Webshots (www.webshots.com), by John Harrison
+0       string          C\253\221g\230\0\0\0 Webshots Desktop .wbz file
+
+# Hercules DASD image files
+# From Jan Jaeger <jj@septa.nl>
+0       string  CKD_P370        Hercules CKD DASD image file
+>8      long    x               \b, %d heads per cylinder
+>12     long    x               \b, track size %d bytes
+>16     byte    x               \b, device type 33%2.2X
+
+0       string  CKD_C370        Hercules compressed CKD DASD image file
+>8      long    x               \b, %d heads per cylinder
+>12     long    x               \b, track size %d bytes
+>16     byte    x               \b, device type 33%2.2X
+
+0       string  CKD_S370        Hercules CKD DASD shadow file
+>8      long    x               \b, %d heads per cylinder
+>12     long    x               \b, track size %d bytes
+>16     byte    x               \b, device type 33%2.2X
+
+# Squeak images and programs - etoffi@softhome.net
+0      string          \146\031\0\0    Squeak image data
+0      search/1        'From\040Squeak Squeak program text
+
+# partimage: file(1) magic for PartImage files (experimental, incomplete)
+# Author: Hans-Joachim Baader <hjb@pro-linux.de>
+0              string  PaRtImAgE-VoLuMe        PartImage
+>0x0020                string  0.6.1           file version %s
+>>0x0060       lelong  >-1             volume %d
+#>>0x0064 8 byte identifier
+#>>0x007c reserved
+>>0x0200       string  >\0             type %s
+>>0x1400       string  >\0             device %s,
+>>0x1600       string  >\0             original filename %s,
+# Some fields omitted
+>>0x2744       lelong  0               not compressed
+>>0x2744       lelong  1               gzip compressed
+>>0x2744       lelong  2               bzip2 compressed
+>>0x2744       lelong  >2              compressed with unknown algorithm
+>0x0020                string  >0.6.1          file version %s
+>0x0020                string  <0.6.1          file version %s
+
+# DCX is multi-page PCX, using a simple header of up to 1024
+# offsets for the respective PCX components.
+# From: Joerg Wunsch <joerg_wunsch@uriah.heep.sax.de>
+0      lelong  987654321       DCX multi-page PCX image data
+
+# Simon Walton <simonw@matteworld.com>
+# Kodak Cineon format for scanned negatives
+# http://www.kodak.com/US/en/motion/support/dlad/
+0      lelong  0xd75f2a80      Cineon image data
+>200   belong  >0              \b, %d x
+>204   belong  >0              %d
+
+
+# Bio-Rad .PIC is an image format used by microscope control systems
+# and related image processing software used by biologists.
+# From: Vebjorn Ljosa <vebjorn@ljosa.com>
+# BOOL values are two-byte integers; use them to rule out false positives.
+# https://web.archive.org/web/20050317223257/www.cs.ubc.ca/spider/ladic/text/biorad.txt
+# Samples: https://www.loci.wisc.edu/software/sample-data
+14     leshort <2
+>62    leshort <2
+>>54   leshort 12345           Bio-Rad .PIC Image File
+>>>0   leshort >0              %d x
+>>>2   leshort >0              %d,
+>>>4   leshort =1              1 image in file
+>>>4   leshort >1              %d images in file
+
+# From Jan "Yenya" Kasprzak <kas@fi.muni.cz>
+# The description of *.mrw format can be found at
+# http://www.dalibor.cz/minolta/raw_file_format.htm
+0      string  \000MRM                 Minolta Dimage camera raw image data
+
+# Summary: DjVu image / document
+# Extension: .djvu
+# Reference: http://djvu.org/docs/DjVu3Spec.djvu
+# Submitted by: Stephane Loeuillet <stephane.loeuillet@tiscali.fr>
+# Modified by (1): Abel Cheung <abelcheung@gmail.com>
+0      string  AT&TFORM
+>12    string  DJVM            DjVu multiple page document
+!:mime image/vnd.djvu
+>12    string  DJVU            DjVu image or single page document
+!:mime image/vnd.djvu
+>12    string  DJVI            DjVu shared document
+!:mime image/vnd.djvu
+>12    string  THUM            DjVu page thumbnails
+!:mime image/vnd.djvu
+
+# Originally by Marc Espie
+# Modified by Robert Minsk <robertminsk at yahoo.com>
+# https://www.openexr.com/openexrfilelayout.pdf
+0      lelong          20000630        OpenEXR image data,
+!:mime image/x-exr
+>4     lelong&0x000000ff x             version %d,
+>4     lelong          ^0x00000200     storage: scanline
+>4     lelong          &0x00000200     storage: tiled
+>8     search/0x1000   compression\0   \b, compression:
+>>&16  byte            0               none
+>>&16  byte            1               rle
+>>&16  byte            2               zips
+>>&16  byte            3               zip
+>>&16  byte            4               piz
+>>&16  byte            5               pxr24
+>>&16  byte            6               b44
+>>&16  byte            7               b44a
+>>&16  byte            8               dwaa
+>>&16  byte            9               dwab
+>>&16  byte            >9              unknown
+>8      search/0x1000  dataWindow\0    \b, dataWindow:
+>>&10  lelong          x               (%d
+>>&14  lelong          x               %d)-
+>>&18  lelong          x               \b(%d
+>>&22  lelong          x               %d)
+>8     search/0x1000   displayWindow\0 \b, displayWindow:
+>>&10  lelong          x               (%d
+>>&14  lelong          x               %d)-
+>>&18  lelong          x               \b(%d
+>>&22  lelong          x               %d)
+>8     search/0x1000   lineOrder\0      \b, lineOrder:
+>>&14  byte            0               increasing y
+>>&14  byte            1               decreasing y
+>>&14  byte            2               random y
+>>&14  byte            >2              unknown
+
+# SMPTE Digital Picture Exchange Format, SMPTE DPX
+#
+# ANSI/SMPTE 268M-1994, SMPTE Standard for File Format for Digital
+# Moving-Picture Exchange (DPX), v1.0, 18 February 1994
+# Robert Minsk <robertminsk at yahoo.com>
+# Modified by Harry Mallon <hjmallon at gmail.com>
+0      string          SDPX    DPX image data, big-endian,
+!:mime image/x-dpx
+>0     use             dpx_info
+0      string          XPDS    DPX image data, little-endian,
+!:mime image/x-dpx
+>0     use             \^dpx_info
+
+0      name            dpx_info
+>768   beshort         <4
+>>772  belong          x       %dx
+>>776  belong          x       \b%d,
+>768   beshort         >3
+>>776  belong          x       %dx
+>>772  belong          x       \b%d,
+>768   beshort         0       left to right/top to bottom
+>768   beshort         1       right to left/top to bottom
+>768   beshort         2       left to right/bottom to top
+>768   beshort         3       right to left/bottom to top
+>768   beshort         4       top to bottom/left to right
+>768   beshort         5       top to bottom/right to left
+>768   beshort         6       bottom to top/left to right
+>768   beshort         7       bottom to top/right to left
+
+# From: Tom Hilinski <tom.hilinski@comcast.net>
+# https://www.unidata.ucar.edu/packages/netcdf/
+0      string  CDF\001                 NetCDF Data Format data
+
+#-----------------------------------------------------------------------
+# Hierarchical Data Format, used to facilitate scientific data exchange
+# specifications at http://hdf.ncsa.uiuc.edu/
+0      belong  0x0e031301      Hierarchical Data Format (version 4) data
+!:mime application/x-hdf
+0      string  \211HDF\r\n\032\n       Hierarchical Data Format (version 5) data
+!:mime application/x-hdf
+512    string  \211HDF\r\n\032\n       Hierarchical Data Format (version 5) with 512 bytes user block
+!:mime application/x-hdf
+1024   string  \211HDF\r\n\032\n       Hierarchical Data Format (version 5) with 1k user block
+!:mime application/x-hdf
+2048   string  \211HDF\r\n\032\n       Hierarchical Data Format (version 5) with 2k user block
+!:mime application/x-hdf
+4096   string  \211HDF\r\n\032\n       Hierarchical Data Format (version 5) with 4k user block
+!:mime application/x-hdf
+
+
+# From: Tobias Burnus <burnus@net-b.de>
+# Xara (for a while: Corel Xara) is a graphic package, see
+# http://www.xara.com/ for Windows and as GPL application for Linux
+0      string  XARA\243\243    Xara graphics file
+
+# https://www.cartesianinc.com/Tech/
+0      string  CPC\262         Cartesian Perceptual Compression image
+!:mime image/x-cpi
+
+# From Albert Cahalan <acahalan@gmail.com>
+# puredigital used it for the CVS disposable camcorder
+#8       lelong  4       ZBM bitmap image data
+#>4      leshort x       %u x
+#>6      leshort x       %u
+
+# From Albert Cahalan <acahalan@gmail.com>
+# uncompressed 5:6:5 HighColor image for OLPC XO firmware icons
+0       string C565     OLPC firmware icon image data
+>4      leshort x       %u x
+>6      leshort x       %u
+
+# Applied Images - Image files from Cytovision
+# Gustavo Junior Alves <gjalves@gjalves.com.br>
+0      string  \xce\xda\xde\xfa        Cytovision Metaphases file
+0      string  \xed\xad\xef\xac        Cytovision Karyotype file
+0      string  \x0b\x00\x03\x00        Cytovision FISH Probe file
+0      string  \xed\xfe\xda\xbe        Cytovision FLEX file
+0      string  \xed\xab\xed\xfe        Cytovision FLEX file
+0      string  \xad\xfd\xea\xad        Cytovision RATS file
+
+# Wavelet Scalar Quantization format used in gray-scale fingerprint images
+# From Tano M Fotang <mfotang@quanteq.com>
+0      string  \xff\xa0\xff\xa8\x00    Wavelet Scalar Quantization image data
+
+# Type:                PCO B16 image files
+# URL:         http://www.pco.de/fileadmin/user_upload/db/download/MA_CWDCOPIE_0412b.pdf
+# From:                Florian Philipp <florian.philipp@binarywings.net>
+# Extension:   .b16
+# Description: Pixel image format produced by PCO Camware, typically used
+#              together with PCO cameras.
+# Note:                Different versions exist for e.g. 8 bit and 16 bit images.
+#              Documentation is incomplete.
+0      string/b        PCO-    PCO B16 image data
+>12    lelong          x       \b, %dx
+>16    lelong          x       \b%d
+>20    lelong          0       \b, short header
+>20    lelong          -1      \b, extended header
+>>24   lelong          0       \b, grayscale
+>>>36  lelong          0       linear LUT
+>>>36  lelong          1       logarithmic LUT
+>>>28  lelong          x       [%d
+>>>32  lelong          x       \b,%d]
+>>24   lelong          1       \b, color
+>>>64  lelong          0       linear LUT
+>>>64  lelong          1       logarithmic LUT
+>>>40  lelong          x       r[%d
+>>>44  lelong          x       \b,%d]
+>>>48  lelong          x       g[%d
+>>>52  lelong          x       \b,%d]
+>>>56  lelong          x       b[%d
+>>>60  lelong          x       \b,%d]
+
+# Polar Monitor Bitmap (.pmb) used as logo for Polar Electro watches
+# From: Markus Heidelberg <markus.heidelberg at web.de>
+0      string/t        [BitmapInfo2]   Polar Monitor Bitmap text
+!:mime image/x-polar-monitor-bitmap
+
+# From: Rick Richardson <rickrich@gmail.com>
+# updated by: Joerg Jenderek
+# URL: http://techmods.net/nuvi/
+0      string  GARMIN\ BITMAP\ 01      Garmin Bitmap file
+# extension is also used for
+# Sony SRF raw image (image/x-sony-srf)
+# SRF map
+# Terragen Surface Map (https://www.planetside.co.uk/terragen)
+# FileLocator Pro search criteria file (https://www.mythicsoft.com/filelocatorpro)
+!:ext srf
+#!:mime        image/x-garmin-srf
+# version 1.00,2.00,2.10,2.40,2.50
+>0x2f  string          >0              \b, version %4.4s
+# width (2880,2881,3240)
+>0x55  uleshort        >0              \b, %dx
+# height (80,90)
+>>0x53 uleshort        x               \b%d
+
+# Type:        Ulead Photo Explorer5 (.pe5)
+# URL: http://www.jisyo.com/cgibin/view.cgi?EXT=pe5 (Japanese)
+# From:        Simon Horman <horms@debian.org>
+0      string  IIO2H                   Ulead Photo Explorer5
+
+# Type:        X11 cursor
+# URL: http://webcvs.freedesktop.org/mime/shared-mime-info/freedesktop.org.xml.in?view=markup
+# From:        Mathias Brodala <info@noctus.net>
+0      string  Xcur                    X11 cursor
+
+# Type:        Olympus ORF raw images.
+# URL: https://libopenraw.freedesktop.org/wiki/Olympus_ORF
+# From:        Adam Buchbinder <adam.buchbinder@gmail.com>
+0      string          MMOR            Olympus ORF raw image data, big-endian
+!:mime image/x-olympus-orf
+0      string          IIRO            Olympus ORF raw image data, little-endian
+!:mime image/x-olympus-orf
+0      string          IIRS            Olympus ORF raw image data, little-endian
+!:mime image/x-olympus-orf
+
+# Type: files used in modern AVCHD camcoders to store clip information
+# Extension: .cpi
+# From: Alexander Danilov <alexander.a.danilov@gmail.com>
+0      string  HDMV0100        AVCHD Clip Information
+
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# URL: http://local.wasp.uwa.edu.au/~pbourke/dataformats/pic/
+# Radiance HDR; usually has .pic or .hdr extension.
+0      string  #?RADIANCE\n    Radiance HDR image data
+#!mime image/vnd.radiance
+
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# URL: https://www.mpi-inf.mpg.de/resources/pfstools/pfs_format_spec.pdf
+# Used by the pfstools packages. The regex matches for the image size could
+# probably use some work. The MIME type is made up; if there's one in
+# actual common use, it should replace the one below.
+0      string  PFS1\x0a        PFS HDR image data
+#!mime image/x-pfs
+>1     regex   [0-9]*\                 \b, %s
+>>1    regex   \ [0-9]{4}              \bx%s
+
+# Type: Foveon X3F
+# URL:  https://www.photofo.com/downloads/x3f-raw-format.pdf
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# Note that the MIME type isn't defined anywhere that I can find; if
+# there's a canonical type for this format, it should replace this one.
+0      string  FOVb    Foveon X3F raw image data
+!:mime image/x-x3f
+>6     leshort x       \b, version %d.
+>4     leshort x       \b%d
+>28    lelong  x       \b, %dx
+>32    lelong  x       \b%d
+
+# Paint.NET file
+# From Adam Buchbinder <adam.buchbinder@gmail.com>
+0      string  PDN3    Paint.NET image data
+!:mime image/x-paintnet
+
+# Not really an image.
+# From: "Tano M. Fotang" <mfotang@quanteq.com>
+0      string  \x46\x4d\x52\x00        ISO/IEC 19794-2 Format Minutiae Record (FMR)
+
+# doc: https://www.shikino.co.jp/eng/products/images/FLOWER.jpg.zip
+# example: https://www.shikino.co.jp/eng/products/images/FLOWER.wdp.zip
+90     bequad          0x574D50484F544F00      JPEG-XR Image
+>98    byte&0x08       =0x08                   \b, hard tiling
+>99    byte&0x80       =0x80                   \b, tiling present
+>99    byte&0x40       =0x40                   \b, codestream present
+>99    byte&0x38       x                       \b, spatial xform=
+>99    byte&0x38       0x00                    \bTL
+>99    byte&0x38       0x08                    \bBL
+>99    byte&0x38       0x10                    \bTR
+>99    byte&0x38       0x18                    \bBR
+>99    byte&0x38       0x20                    \bBT
+>99    byte&0x38       0x28                    \bRB
+>99    byte&0x38       0x30                    \bLT
+>99    byte&0x38       0x38                    \bLB
+>100   byte&0x80       =0x80                   \b, short header
+>>102  beshort+1       x                       \b, %d
+>>104  beshort+1       x                       \bx%d
+>100   byte&0x80       =0x00                   \b, long header
+>>102  belong+1        x                       \b, %x
+>>106  belong+1        x                       \bx%x
+>101   beshort&0xf     x                       \b, bitdepth=
+>>101  beshort&0xf     0x0                     \b1-WHITE=1
+>>101  beshort&0xf     0x1                     \b8
+>>101  beshort&0xf     0x2                     \b16
+>>101  beshort&0xf     0x3                     \b16-SIGNED
+>>101  beshort&0xf     0x4                     \b16-FLOAT
+>>101  beshort&0xf     0x5                     \b(reserved 5)
+>>101  beshort&0xf     0x6                     \b32-SIGNED
+>>101  beshort&0xf     0x7                     \b32-FLOAT
+>>101  beshort&0xf     0x8                     \b5
+>>101  beshort&0xf     0x9                     \b10
+>>101  beshort&0xf     0xa                     \b5-6-5
+>>101  beshort&0xf     0xb                     \b(reserved %d)
+>>101  beshort&0xf     0xc                     \b(reserved %d)
+>>101  beshort&0xf     0xd                     \b(reserved %d)
+>>101  beshort&0xf     0xe                     \b(reserved %d)
+>>101  beshort&0xf     0xf                     \b1-BLACK=1
+>101   beshort&0xf0    x                       \b, colorfmt=
+>>101  beshort&0xf0    0x00                    \bYONLY
+>>101  beshort&0xf0    0x10                    \bYUV240
+>>101  beshort&0xf0    0x20                    \bYWV422
+>>101  beshort&0xf0    0x30                    \bYWV444
+>>101  beshort&0xf0    0x40                    \bCMYK
+>>101  beshort&0xf0    0x50                    \bCMYKDIRECT
+>>101  beshort&0xf0    0x60                    \bNCOMPONENT
+>>101  beshort&0xf0    0x70                    \bRGB
+>>101  beshort&0xf0    0x80                    \bRGBE
+>>101  beshort&0xf0    >0x80                   \b(reserved 0x%x)
+
+# From: Johan van der Knijff <johan.vanderknijff@kb.nl>
+#
+# BPG (Better Portable Graphics) format
+# https://bellard.org/bpg/
+# http://fileformats.archiveteam.org/wiki/BPG
+#
+0      string  \x42\x50\x47\xFB        BPG (Better Portable Graphics)
+!:mime  image/bpg
+
+# From: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Apple_Icon_Image_format
+0      string          icns            Mac OS X icon
+!:mime image/x-icns
+!:apple        ????icns
+!:ext icns
+>4     ubelong         >0
+# file size
+>>4    ubelong         x               \b, %d bytes
+# icon type
+>>8    string          x               \b, "%4.4s" type
+
+# TIM images
+0              lelong          0x00000010      TIM image,
+>4             lelong          0x8             4-Bit,
+>4             lelong          0x9             8-Bit,
+>4             lelong          0x2             15-Bit,
+>4             lelong          0x3             24-Bit,
+>4             lelong          &8
+>>(8.l+12)     leshort         x               Pixel at (%d,
+>>(8.l+14)     leshort         x               \b%d)
+>>(8.l+16)     leshort         x               Size=%dx
+>>(8.l+18)     leshort         x               \b%d,
+>>4            lelong          0x8             16 CLUT Entries at
+>>4            lelong          0x9             256 CLUT Entries at
+>>12           leshort         x               (%d,
+>>14           leshort         x               \b%d)
+>4             lelong          ^8
+>>12           leshort         x               Pixel at (%d,
+>>14           leshort         x               \b%d)
+>>16           leshort         x               Size=%dx
+>>18           leshort         x               \b%d
+
+# MDEC streams
+0              lelong          0x80010160      MDEC video stream,
+>16            leshort         x               %dx
+>18            leshort         x               \b%d
+#>8            lelong          x               %d frames
+#>4            leshort         x               secCount=%d;
+#>6            leshort         x               nSectors=%d;
+#>12           lelong          x               frameSize=%d;
+
+# BS encoded bitstreams
+2              leshort         0x3800          BS image,
+>6             leshort         x               Version %d,
+>4             leshort         x               Quantization %d,
+>0             leshort         x               (Decompresses to %d words)
+
+# Type: farbfeld image.
+# Url: http://tools.suckless.org/farbfeld/
+# From: Ian D. Scott <ian@iandouglasscott.com>
+#
+0              string          farbfeld        farbfeld image data,
+>8             ubelong         x               %dx
+>12            ubelong         x               \b%d
+
+# Type: Microsoft DirectDraw Surface (common data)
+# URL: https://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/DDSFileReference/ddsfileformat.asp
+# From: Morten Hustveit <morten@debian.org>
+# Updated by: David Korth <gerbilsoft@gerbilsoft.com>
+0      name    ms-directdraw-surface
+>0x10  ulelong x                       %u x
+>0x0C  ulelong x                       %u
+# Color depth.
+>0x58  ulelong >0                      \b, %u-bit color
+# Determine the pixel format.
+>0x50  ulelong&0x4     4
+# FIXME: Handle DX10 and XBOX formats.
+>>0x54 string  x                       \b, compressed using %.4s
+>0x50  ulelong&0x2     0x2             \b, alpha only
+>0x50  ulelong&0x200   0x200           \b, YUV
+>0x50  ulelong&0x20000 0x20000         \b, luminance
+# RGB pixel format
+>0x50  ulelong&0x40    0x40
+
+# Determine the RGB format using the color masks.
+# ulequad order: 0xGGGGGGGGRRRRRRRR, 0xAAAAAAAABBBBBBBB
+
+>>0x58         ulelong 16
+
+# NOTE: 15-bit color formats usually have 16-bit listed as the color depth.
+>>>0x5C                ulequad 0x000003E000007C00
+>>>>0x64       ulequad 0x000000000000001F      \b, RGB555
+>>>0x5C                ulequad 0x000003E000001F00
+>>>>0x64       ulequad 0x000000000000007C      \b, BGR555
+
+>>>0x5C                ulequad 0x000007E00000F800
+>>>>0x64       ulequad 0x000000000000001F      \b, RGB565
+>>>0x5C                ulequad 0x000007E000001F00
+>>>>0x64       ulequad 0x00000000000000F8      \b, BGR565
+
+>>>0x5C                ulequad 0x000000F000000F00
+>>>>0x64       ulequad 0x0000F0000000000F      \b, ARGB4444
+>>>0x5C                ulequad 0x000000F00000000F
+>>>>0x64       ulequad 0x0000F00000000F00      \b, ABGR4444
+
+>>>0x5C                ulequad 0x00000F000000F000
+>>>>0x64       ulequad 0x0000000F000000F0      \b, RGBA4444
+>>>0x5C                ulequad 0x00000F00000000F0
+>>>>0x64       ulequad 0x0000000F0000F000      \b, BGRA4444
+
+>>>0x5C                ulequad 0x000000F000000F00
+>>>>0x64       ulequad 0x000000000000000F      \b, xRGB4444
+>>>0x5C                ulequad 0x000000F00000000F
+>>>>0x64       ulequad 0x0000000000000F00      \b, xBGR4444
+
+>>>0x5C                ulequad 0x00000F000000F000
+>>>>0x64       ulequad 0x00000000000000F0      \b, RGBx4444
+>>>0x5C                ulequad 0x00000F00000000F0
+>>>>0x64       ulequad 0x000000000000F000      \b, BGRx4444
+
+>>>0x5C                ulequad 0x000003E000007C00
+>>>>0x64       ulequad 0x000080000000001F      \b, ARGB1555
+>>>0x5C                ulequad 0x000003E000001F00
+>>>>0x64       ulequad 0x000080000000007C      \b, ABGR1555
+>>>0x5C                ulequad 0x000007C00000F800
+>>>>0x64       ulequad 0x000000010000003E      \b, RGBA5551
+>>>0x5C                ulequad 0x000007C00000003E
+>>>>0x64       ulequad 0x000000010000F800      \b, BGRA5551
+
+>>88           ulelong 24
+>>>0x5C                ulequad 0x0000FF0000FF0000
+>>>>0x64       ulequad 0x00000000000000FF      \b, RGB888
+>>>0x5C                ulequad 0x0000FF00000000FF
+>>>>0x64       ulequad 0x0000000000FF0000      \b, BGR888
+
+>>88           ulelong 32
+>>>0x5C                ulequad 0x0000FF0000FF0000
+>>>>0x64       ulequad 0xFF000000000000FF      \b, ARGB8888
+>>>0x5C                ulequad 0x0000FF00000000FF
+>>>>0x64       ulequad 0xFF00000000FF0000      \b, ABGR8888
+
+>>>0x5C                ulequad 0x00FF0000FF000000
+>>>>0x64       ulequad 0x000000FF0000FF00      \b, RGBA8888
+>>>0x5C                ulequad 0x00FF00000000FF00
+>>>>0x64       ulequad 0x000000FFFF000000      \b, BGBA8888
+
+>>>0x5C                ulequad 0x0000FF0000FF0000
+>>>>0x64       ulequad 0x00000000000000FF      \b, xRGB8888
+>>>0x5C                ulequad 0x0000FF00000000FF
+>>>>0x64       ulequad 0x0000000000FF0000      \b, xBGR8888
+
+>>>0x5C                ulequad 0x00FF0000FF000000
+>>>>0x64       ulequad 0x000000000000FF00      \b, RGBx8888
+>>>0x5C                ulequad 0x00FF00000000FF00
+>>>>0x64       ulequad 0x00000000FF000000      \b, BGBx8888
+
+# Less common 32-bit color formats.
+>>>0x5C                ulequad 0xFFFF00000000FFFF
+>>>>0x64       ulequad 0x0000000000000000      \b, G16R16
+>>>0x5C                ulequad 0x0000FFFFFFFF0000
+>>>>0x64       ulequad 0x0000000000000000      \b, R16G16
+
+>>>0x5C                ulequad 0x000FFC003FF00000
+>>>>0x64       ulequad 0xC0000000000003FF      \b, A2R10G10B10
+>>>0x5C                ulequad 0x000FFC00000003FF
+>>>>0x64       ulequad 0xC00000003FF00000      \b, A2B10G10R10
+
+# Type: Microsoft DirectDraw Surface
+# URL: https://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/DDSFileReference/ddsfileformat.asp
+# From: Morten Hustveit <morten@debian.org>
+# Updated by: David Korth <gerbilsoft@gerbilsoft.com>
+0      string/b        DDS\040\174\000\000\000 Microsoft DirectDraw Surface (DDS):
+>0     use     ms-directdraw-surface
+
+# Type: Sega PVR image.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://fabiensanglard.net/Mykaruga/tools/segaPVRFormat.txt
+# - https://github.com/yazgoo/pvrx2png
+# - https://github.com/nickworonekin/puyotools
+
+# Sega PVR header.
+0      name    sega-pvr-image-header
+>0x0C  leshort x       %u x
+>0x0E  leshort x       %u
+# Image format.
+>0x08  byte    0       \b, ARGB1555
+>0x08  byte    1       \b, RGB565
+>0x08  byte    2       \b, ARGB4444
+>0x08  byte    3       \b, YUV442
+>0x08  byte    4       \b, Bump
+>0x08  byte    5       \b, 4bpp
+>0x08  byte    6       \b, 8bpp
+# Image data type.
+>0x09  byte    0x01    \b, square twiddled
+>0x09  byte    0x02    \b, square twiddled & mipmap
+>0x09  byte    0x03    \b, VQ
+>0x09  byte    0x04    \b, VQ & mipmap
+>0x09  byte    0x05    \b, 8-bit CLUT twiddled
+>0x09  byte    0x06    \b, 4-bit CLUT twiddled
+>0x09  byte    0x07    \b, 8-bit direct twiddled
+>0x09  byte    0x08    \b, 4-bit direct twiddled
+>0x09  byte    0x09    \b, rectangle
+>0x09  byte    0x0B    \b, rectangular stride
+>0x09  byte    0x0D    \b, rectangular twiddled
+>0x09  byte    0x10    \b, small VQ
+>0x09  byte    0x11    \b, small VQ & mipmap
+>0x09  byte    0x12    \b, square twiddled & mipmap
+
+# Sega PVR image.
+0      string  PVRT
+>0x10  string  DDS\040\174\000\000\000 Sega PVR (Xbox) image:
+>>0x20 use     ms-directdraw-surface
+>0x10  belong  !0x44445320             Sega PVR image:
+>>0    use     sega-pvr-image-header
+
+# Sega PVR image with GBIX.
+0      string  GBIX
+>0x10  string  PVRT
+>>0x10 string  DDS\040\174\000\000\000 Sega PVR (Xbox) image:
+>>>0x20        use     ms-directdraw-surface
+>>0x10 belong  !0x44445320             Sega PVR image:
+>>>0x10        use     sega-pvr-image-header
+>>0x08 lelong  x       \b, global index = %u
+
+# Sega GVR header.
+0      name    sega-gvr-image-header
+>0x0C  beshort x       %u x
+>0x0E  beshort x       %u
+# Image data format.
+>0x0B  byte    0       \b, I4
+>0x0B  byte    1       \b, I8
+>0x0B  byte    2       \b, IA4
+>0x0B  byte    3       \b, IA8
+>0x0B  byte    4       \b, RGB565
+>0x0B  byte    5       \b, RGB5A3
+>0x0B  byte    6       \b, ARGB8888
+>0x0B  byte    8       \b, CI4
+>0x0B  byte    9       \b, CI8
+>0x0B  byte    14      \b, DXT1
+
+# Sega GVR image.
+0      string  GVRT    Sega GVR image:
+>0x10  use     sega-gvr-image-header
+
+# Sega GVR image with GBIX.
+0      string  GBIX
+>0x10  string  GVRT    Sega GVR image:
+>>0x10 use     sega-gvr-image-header
+>>0x08 belong  x       \b, global index = %u
+
+# Sega GVR image with GCIX. (Wii)
+0      string  GCIX
+>0x10  string  GVRT    Sega GVR image:
+>>0x10 use     sega-gvr-image-header
+>>0x08 belong  x       \b, global index = %u
+
+# Light Field Picture
+# Documentation: http://optics.miloush.net/lytro/TheFileFormat.aspx
+# Typical file extensions: .lfp .lfr .lfx
+
+0      belong  0x894C4650
+>4     belong  0x0D0A1A0A
+>12    belong  0x00000000      Lytro Light Field Picture
+>8     belong  x               \b, version %d
+
+# Type: Vision Research Phantom CINE Format
+# URL: https://www.phantomhighspeed.com/
+# URL2: http://phantomhighspeed.force.com/vriknowledge/servlet/fileField?id=0BEU0000000Cfyk
+# From: Harry Mallon <hjmallon at gmail.com>
+#
+# This has a short "CI" code but the 44 is the size of the struct which is
+# stable
+0      string  CI
+>2     leshort 44              Vision Research CINE Video,
+>>4    leshort 0               Grayscale,
+>>4    leshort 1               JPEG Compressed,
+>>4    leshort 2               RAW,
+>>6    leshort x               version %d,
+>>20   lelong  x               %d frames,
+>>48   lelong  x               %dx
+>>52   lelong  x               \b%d
+
+# Type: ARRI Raw Image
+# Info: SMPTE RDD30:2014
+# From: Harry Mallon <hjmallon at gmail.com>
+0      string ARRI             ARRI ARI image data,
+>4     lelong 0x78563412       little-endian,
+>4     lelong 0x12345678       big-endian,
+>12    lelong x                version %d,
+>20    lelong x                %dx
+>24    lelong x                \b%d
+
+# Type: Khronos KTX texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
+
+# glEnum decoding.
+# NOTE: Only the most common formats are listed here.
+0      name    khronos-ktx-glEnum
+>0     lelong  0x1907  \b, RGB
+>0     lelong  0x1908  \b, RGBA
+>0     lelong  0x1909  \b, LUMINANCE
+>0     lelong  0x190A  \b, LUMINANCE_ALPHA
+>0     lelong  0x80E1  \b, BGR
+>0     lelong  0x80E2  \b, BGRA
+>0     lelong  0x83A0  \b, RGB_S3TC
+>0     lelong  0x83A1  \b, RGB4_S3TC
+>0     lelong  0x83A2  \b, RGBA_S3TC
+>0     lelong  0x83A3  \b, RGBA4_S3TC
+>0     lelong  0x83A4  \b, RGBA_DXT5_S3TC
+>0     lelong  0x83A5  \b, RGBA4_DXT5_S3TC
+>0     lelong  0x8D64  \b, ETC1_RGB8_OES
+>0     lelong  0x9270  \b, COMPRESSED_R11_EAC
+>0     lelong  0x9271  \b, COMPRESSED_SIGNED_R11_EAC
+>0     lelong  0x9272  \b, COMPRESSED_RG11_EAC
+>0     lelong  0x9273  \b, COMPRESSED_SIGNED_RG11_EAC
+>0     lelong  0x9274  \b, COMPRESSED_RGB8_ETC2
+>0     lelong  0x9275  \b, COMPRESSED_SRGB8_ETC2
+>0     lelong  0x9276  \b, COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+>0     lelong  0x9277  \b, COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
+>0     lelong  0x9278  \b, COMPRESSED_RGBA2_ETC2_EAC
+>0     lelong  0x9279  \b, COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+>0     lelong  0x93B0  \b, COMPRESSED_RGBA_ASTC_4x4_KHR
+>0     lelong  0x93B1  \b, COMPRESSED_RGBA_ASTC_5x4_KHR
+>0     lelong  0x93B2  \b, COMPRESSED_RGBA_ASTC_5x5_KHR
+>0     lelong  0x93B3  \b, COMPRESSED_RGBA_ASTC_6x5_KHR
+>0     lelong  0x93B4  \b, COMPRESSED_RGBA_ASTC_6x6_KHR
+>0     lelong  0x93B5  \b, COMPRESSED_RGBA_ASTC_8x5_KHR
+>0     lelong  0x93B6  \b, COMPRESSED_RGBA_ASTC_8x6_KHR
+>0     lelong  0x93B7  \b, COMPRESSED_RGBA_ASTC_8x8_KHR
+>0     lelong  0x93B8  \b, COMPRESSED_RGBA_ASTC_10x5_KHR
+>0     lelong  0x93B9  \b, COMPRESSED_RGBA_ASTC_10x6_KHR
+>0     lelong  0x93BA  \b, COMPRESSED_RGBA_ASTC_10x8_KHR
+>0     lelong  0x93BB  \b, COMPRESSED_RGBA_ASTC_10x10_KHR
+>0     lelong  0x93BC  \b, COMPRESSED_RGBA_ASTC_12x10_KHR
+>0     lelong  0x93BD  \b, COMPRESSED_RGBA_ASTC_12x12_KHR
+>0     lelong  0x93D0  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
+>0     lelong  0x93D1  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
+>0     lelong  0x93D2  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
+>0     lelong  0x93D3  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
+>0     lelong  0x93D4  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
+>0     lelong  0x93D5  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
+>0     lelong  0x93D6  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
+>0     lelong  0x93D7  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
+>0     lelong  0x93D8  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
+>0     lelong  0x93D9  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
+>0     lelong  0x93DA  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
+>0     lelong  0x93DB  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
+>0     lelong  0x93DC  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
+>0     lelong  0x93DD  \b, COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
+
+# Endian-specific KTX header.
+# TODO: glType (all textures I've seen so far are GL_UNSIGNED_BYTE)
+0      name    khronos-ktx-endian-header
+>20    lelong  x       \b, %u
+>24    lelong  >1      x %u
+>28    lelong  >1      x %u
+>8     lelong  >0
+>>8    use     khronos-ktx-glEnum
+>8     lelong  0
+>>12   use     khronos-ktx-glEnum
+
+# Main KTX header.
+# Determine endianness, then check the rest of the header.
+0      string  \xABKTX\ 11\xBB\r\n\x1A\n       Khronos KTX texture
+>12    lelong  0x04030201                      (little-endian)
+>>16   use     khronos-ktx-endian-header
+>12    belong  0x04030201                      (big-endian)
+>>16   use     \^khronos-ktx-endian-header
+
+# Type: Valve VTF texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://developer.valvesoftware.com/wiki/Valve_Texture_Format
+
+# VTF image formats.
+0      name    vtf-image-format
+>0     lelong  0       RGBA8888
+>0     lelong  1       ABGR8888
+>0     lelong  2       RGB888
+>0     lelong  3       BGR888
+>0     lelong  4       RGB565
+>0     lelong  5       I8
+>0     lelong  6       IA88
+>0     lelong  7       P8
+>0     lelong  8       A8
+>0     lelong  9       RGB888 (bluescreen)
+>0     lelong  10      BGR888 (bluescreen)
+>0     lelong  11      ARGB8888
+>0     lelong  12      BGRA8888
+>0     lelong  13      DXT1
+>0     lelong  14      DXT3
+>0     lelong  15      DXT5
+>0     lelong  16      BGRx8888
+>0     lelong  17      BGR565
+>0     lelong  18      BGRx5551
+>0     lelong  19      BGRA4444
+>0     lelong  20      DXT1+A1
+>0     lelong  21      BGRA5551
+>0     lelong  22      UV88
+>0     lelong  23      UVWQ8888
+>0     lelong  24      RGBA16161616F
+>0     lelong  25      RGBA16161616
+>0     lelong  26      UVLX8888
+
+# Main VTF header.
+0      string  VTF\0                           Valve Texture Format
+>4     lelong  x                               v%u
+>8     lelong  x                               \b.%u
+>0x10  leshort x                               \b, %u
+>0x12  leshort >1                              x %u
+>4     lequad  0x0000000700000002
+>>0x3F leshort >1                              x %u
+>0x18  leshort >1                              \b, %u frames
+>0x38  byte    x                               \b, mipmaps: %u
+>0x34  lelong  >-1                             \b,
+>>0x34 use     vtf-image-format
+
+# Type: Valve VTF3 (PS3) texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+0      string          VTF3    Valve Texture Format (PS3)
+>0x14  beshort         x       \b, %u
+>0x16  beshort         x       \b x %u
+>0x10  belong&0x2000   0       \b, DXT1
+>0x10  belong&0x2000   0x2000  \b, DXT5
+
+# Type: ASTC texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://stackoverflow.com/questions/22600678/determine-internal-format-of-given-astc-compressed-image-through-its-header
+# - https://stackoverflow.com/a/22682244
+0      lelong  0x5ca1ab13                      ASTC
+>4     byte    x                               %u
+>5     byte    x                               \bx%u
+>6     byte    >1                              \bx%u
+# X, Y, and Z dimensions are stored as 24-bit LE.
+# Pretend it's 32-bit and mask off the high byte.
+>7     lelong&0x00FFFFFF       x               texture, %u
+>10    lelong&0x00FFFFFF       x               x %u
+>13    lelong&0x00FFFFFF       >1              x %u
+
+# Zebra Metafile graphic
+# http://www.fileformat.info/format/zbr/egff.htm
+0      beshort 0x9a02  Zebra Metafile graphic
+>2     leshort 1       (version 1.x)
+>2     leshort 2       (version 1.1x or 1.2x)
+>2     leshort 3       (version 1.49)
+>2     leshort 4       (version 1.50)
+>4     string  x       (comment = %s)
+
+# Microsoft Paint graphic
+# http://www.fileformat.info/format/mspaint/egff.htm
+0      string  DanM    icrosoft Paint image data (version 1.x)
+>4     leshort x       (%d
+>>6    leshort x       x %d)
+0      string  LinS    Microsoft Paint image data (version 2.0)
+>4     leshort x       (%d
+>>6    leshort x       x %d)
+
+# reMarkable tablet internal file format (https://www.remarkable.com/)
+# https://github.com/ax3l/lines-are-beautiful
+# https://plasma.ninja/blog/devices/remarkable/binary/format/2017/12/26/\
+#      reMarkable-lines-file-format.html#what-to-do-next
+# from Axel Huebl
+0              string  reMarkable
+>11            string  lines
+>>17           string  with
+>>>22          string  selections
+>>>>33         string  and
+>>>>>37                string  layers
+>>>>>>43       lelong  x       reMarkable tablet notebook lines, 1404 x 1872, %x page(s)
+
+# newer per-page files for the reMarkable
+0              string  reMarkable
+>11            string  .lines
+>>18           string  file,
+>>>24          string  version=
+>>>>32         byte    x       reMarkable tablet page (v%c), 1404 x 1872,
+>>>>>43                lelong  x       %d layer(s)
+
+# Type: PVR3 texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - http://cdn.imgtec.com/sdk-documentation/PVR+File+Format.Specification.pdf
+
+# PVR3 pixel formats.
+0      name            pvr3-pixel-format
+>4     ulelong 0
+>>0    ulelong 0       PVRTC 2bpp RGB
+>>0    ulelong 1       PVRTC 2bpp RGBA
+>>0    ulelong 2       PVRTC 4bpp RGB
+>>0    ulelong 3       PVRTC 4bpp RGBA
+>>0    ulelong 4       PVRTC-II 2bpp
+>>0    ulelong 5       PVRTC-II 4bpp
+>>0    ulelong 6       ETC1
+>>0    ulelong 7       DXT1
+>>0    ulelong 8       DXT2
+>>0    ulelong 9       DXT3
+>>0    ulelong 10      DXT4
+>>0    ulelong 11      DXT5
+>>0    ulelong 12      BC4
+>>0    ulelong 13      BC5
+>>0    ulelong 14      BC6
+>>0    ulelong 15      BC7
+>>0    ulelong 16      UYVY
+>>0    ulelong 17      YUY2
+>>0    ulelong 18      BW1bpp
+>>0    ulelong 19      R9G9B9E5 Shared Exponent
+>>0    ulelong 20      RGBG8888
+>>0    ulelong 21      GRGB8888
+>>0    ulelong 22      ETC2 RGB
+>>0    ulelong 23      ETC2 RGBA
+>>0    ulelong 24      ETC2 RGB A1
+>>0    ulelong 25      EAC R11
+>>0    ulelong 26      EAC RG11
+>>0    ulelong 27      ASTC_4x4
+>>0    ulelong 28      ASTC_5x4
+>>0    ulelong 29      ASTC_5x5
+>>0    ulelong 30      ASTC_6x5
+>>0    ulelong 31      ASTC_6x6
+>>0    ulelong 32      ASTC_8x5
+>>0    ulelong 33      ASTC_8x6
+>>0    ulelong 34      ASTC_8x8
+>>0    ulelong 35      ASTC_10x5
+>>0    ulelong 36      ASTC_10x6
+>>0    ulelong 37      ASTC_10x8
+>>0    ulelong 38      ASTC_10x10
+>>0    ulelong 39      ASTC_12x10
+>>0    ulelong 40      ASTC_12x12
+>>0    ulelong 41      ASTC_3x3x3
+>>0    ulelong 42      ASTC_4x3x3
+>>0    ulelong 43      ASTC_4x4x3
+>>0    ulelong 44      ASTC_4x4x4
+>>0    ulelong 45      ASTC_5x4x4
+>>0    ulelong 46      ASTC_5x5x4
+>>0    ulelong 47      ASTC_5x5x5
+>>0    ulelong 48      ASTC_6x5x5
+>>0    ulelong 49      ASTC_6x6x5
+>>0    ulelong 50      ASTC_6x6x6
+>4     ulelong !0
+>>0    byte    !0      %c
+>>1    byte    !0      \b%c
+>>2    byte    !0      \b%c
+>>3    byte    !0      \b%c
+
+0      string          PVR\x03                 PVR 3.0 texture:
+>0x18  ulelong         x       %u x
+>0x1C  ulelong         x       %u
+>0x20  ulelong         >1      x %u
+>0x08  byte            x       \b,
+>0x08  use     pvr3-pixel-format
+>0x10  ulelong         1       \b, sRGB
+>0x04  ulelong&0x02    0x02    \b, premultiplied alpha
+
+# Type: Microsoft Xbox XPR0 texture.
+# From: David Korth <gerbilsoft@gerbilsoft.com>
+# References:
+# - https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/blob/develop/src/core/hle/D3D8/XbD3D8Types.h
+
+# XPR pixel formats.
+0      name    xbox-xpr-pixel-format
+>0     byte    0x00    L8
+>0     byte    0x01    AL8
+>0     byte    0x02    ARGB1555
+>0     byte    0x03    RGB555
+>0     byte    0x04    ARGB4444
+>0     byte    0x05    RGB565
+>0     byte    0x06    ARGB8888
+>0     byte    0x07    xRGB8888
+>0     byte    0x0B    P8
+>0     byte    0x0C    DXT1
+>0     byte    0x0E    DXT2
+>0     byte    0x0F    DXT4
+>0     byte    0x10    Linear ARGB1555
+>0     byte    0x11    Linear RGB565
+>0     byte    0x12    Linear ARGB8888
+>0     byte    0x13    Linear L8
+>0     byte    0x16    Linear R8B8
+>0     byte    0x17    Linear G8B8
+>0     byte    0x19    A8
+>0     byte    0x1A    A8L8
+>0     byte    0x1B    Linear AL8
+>0     byte    0x1C    Linear RGB555
+>0     byte    0x1D    Linear ARGB4444
+>0     byte    0x1E    Linear xRGB8888
+>0     byte    0x1F    Linear A8
+>0     byte    0x20    Linear A8L8
+>0     byte    0x24    YUY2
+>0     byte    0x25    UYVY
+>0     byte    0x27    L6V5U5
+>0     byte    0x28    V8U8
+>0     byte    0x29    R8B8
+>0     byte    0x2A    D24S8
+>0     byte    0x2B    F24S8
+>0     byte    0x2C    D16
+>0     byte    0x2D    F16
+>0     byte    0x2E    Linear D24S8
+>0     byte    0x2F    Linear F24S8
+>0     byte    0x30    Linear D16
+>0     byte    0x31    Linear F16
+>0     byte    0x32    L16
+>0     byte    0x33    V16U16
+>0     byte    0x35    Linear L16
+>0     byte    0x36    Linear V16U16
+>0     byte    0x37    Linear L6V5U5
+>0     byte    0x38    RGBA5551
+>0     byte    0x39    RGBA4444
+>0     byte    0x3A    QWVU8888
+>0     byte    0x3B    BGRA8888
+>0     byte    0x3C    RGBA8888
+>0     byte    0x3D    Linear RGBA5551
+>0     byte    0x3E    Linear RGBA4444
+>0     byte    0x3F    Linear ABGR8888
+>0     byte    0x40    Linear BGRA8888
+>0     byte    0x41    Linear RGBA8888
+>0     byte    0x64    Vertex Data
+
+0      string          XPR0    Microsoft Xbox XPR0 texture
+>0x19  byte    x       \b, format:
+>>0x19 use     xbox-xpr-pixel-format
diff --git a/magic/Magdir/inform b/magic/Magdir/inform
new file mode 100644 (file)
index 0000000..a4be563
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# inform:  file(1) magic for Inform interactive fiction language
+
+# URL:  http://www.inform-fiction.org/
+# From: Reuben Thomas <rrt@sc3d.org>
+
+0      search/100/cW   constant\ story         Inform source text
diff --git a/magic/Magdir/intel b/magic/Magdir/intel
new file mode 100644 (file)
index 0000000..85e2abe
--- /dev/null
@@ -0,0 +1,69 @@
+
+#------------------------------------------------------------------------------
+# $File: intel,v 1.17 2018/08/01 10:34:03 christos Exp $
+# intel:  file(1) magic for x86 Unix
+#
+# Various flavors of x86 UNIX executable/object (other than Xenix, which
+# is in "microsoft").  DOS is in "msdos"; the ambitious soul can do
+# Windows as well.
+#
+# Windows NT belongs elsewhere, as you need x86 and MIPS and Alpha and
+# whatever comes next (HP-PA Hummingbird?).  OS/2 may also go elsewhere
+# as well, if, as, and when IBM makes it portable.
+#
+# The `versions' should be un-commented if they work for you.
+# (Was the problem just one of endianness?)
+#
+0      leshort         0502            basic-16 executable
+>12    lelong          >0              not stripped
+#>22   leshort         >0              - version %d
+0      leshort         0503            basic-16 executable (TV)
+>12    lelong          >0              not stripped
+#>22   leshort         >0              - version %d
+0      leshort         0510            x86 executable
+>12    lelong          >0              not stripped
+0      leshort         0511            x86 executable (TV)
+>12    lelong          >0              not stripped
+0      leshort         =0512           iAPX 286 executable small model (COFF)
+>12    lelong          >0              not stripped
+#>22   leshort         >0              - version %d
+0      leshort         =0522           iAPX 286 executable large model (COFF)
+>12    lelong          >0              not stripped
+#>22   leshort         >0              - version %d
+# updated by Joerg Jenderek at Oct 2015
+# https://de.wikipedia.org/wiki/Common_Object_File_Format
+# http://www.delorie.com/djgpp/doc/coff/filhdr.html
+# ./msdos (version 5.25) labeled the next entry as "MS Windows COFF Intel 80386 object file"
+# ./intel (version 5.25) label labeled the next entry as "80386 COFF executable"
+# SGI labeled the next entry as "iAPX 386 executable" --Dan Quinlan
+0      leshort         =0514
+# use subroutine to display name+flags+variables for common object formated files
+>0     use                             display-coff
+#>12   lelong          >0              not stripped
+# no hint found, that at offset 22 is version
+#>22   leshort         >0              - version %d
+0      leshort         0x0200
+>0     use                             display-coff
+0      leshort         0x8664
+>0     use                             display-coff
+
+# rom: file(1) magic for BIOS ROM Extensions found in intel machines
+#      mapped into memory between 0xC0000 and 0xFFFFF
+# From: Alex Myczko <alex@aiei.ch>
+# updated by Joerg Jenderek
+# https://en.wikipedia.org/wiki/Option_ROM
+0        beshort         0x55AA       BIOS (ia32) ROM Ext.
+!:mime application/octet-stream
+!:ext  rom/bin
+>5       string          USB          USB
+>7       string          LDR          UNDI image
+>30      string          IBM          IBM comp. Video
+>26      string          Adaptec      Adaptec
+>28      string          Adaptec      Adaptec
+>42      string          PROMISE      Promise
+>2       byte            x            (%d*512)
+
+# Flash descriptors for Intel SPI flash roms.
+# From Dr. Jesus <j@hug.gs>
+0      lelong          0x0ff0a55a      Intel serial flash for ICH/PCH ROM <= 5 or 3400 series A-step
+16     lelong          0x0ff0a55a      Intel serial flash for PCH ROM
diff --git a/magic/Magdir/interleaf b/magic/Magdir/interleaf
new file mode 100644 (file)
index 0000000..8d66864
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# interleaf:  file(1) magic for InterLeaf TPS:
+#
+0      string          =\210OPS        Interleaf saved data
+0      string          =<!OPS          Interleaf document text
+>5     string          ,\ Version\ =   \b, version
+>>17   string          >\0             %.3s
diff --git a/magic/Magdir/island b/magic/Magdir/island
new file mode 100644 (file)
index 0000000..9fd45fa
--- /dev/null
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# island:  file(1) magic for IslandWite/IslandDraw, from SunOS 5.5.1
+# "/etc/magic":
+# From: guy@netapp.com (Guy Harris)
+#
+4      string          pgscriptver     IslandWrite document
+13     string          DrawFile        IslandDraw document
+
diff --git a/magic/Magdir/ispell b/magic/Magdir/ispell
new file mode 100644 (file)
index 0000000..4185e28
--- /dev/null
@@ -0,0 +1,63 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# ispell:  file(1) magic for ispell
+#
+# Ispell 3.0 has a magic of 0x9601 and ispell 3.1 has 0x9602.  This magic
+# will match 0x9600 through 0x9603 in *both* little endian and big endian.
+# (No other current magic entries collide.)
+#
+# Updated by Daniel Quinlan (quinlan@yggdrasil.com)
+#
+0      leshort&0xFFFC  0x9600          little endian ispell
+>0     byte            0               hash file (?),
+>0     byte            1               3.0 hash file,
+>0     byte            2               3.1 hash file,
+>0     byte            3               hash file (?),
+>2     leshort         0x00            8-bit, no capitalization, 26 flags
+>2     leshort         0x01            7-bit, no capitalization, 26 flags
+>2     leshort         0x02            8-bit, capitalization, 26 flags
+>2     leshort         0x03            7-bit, capitalization, 26 flags
+>2     leshort         0x04            8-bit, no capitalization, 52 flags
+>2     leshort         0x05            7-bit, no capitalization, 52 flags
+>2     leshort         0x06            8-bit, capitalization, 52 flags
+>2     leshort         0x07            7-bit, capitalization, 52 flags
+>2     leshort         0x08            8-bit, no capitalization, 128 flags
+>2     leshort         0x09            7-bit, no capitalization, 128 flags
+>2     leshort         0x0A            8-bit, capitalization, 128 flags
+>2     leshort         0x0B            7-bit, capitalization, 128 flags
+>2     leshort         0x0C            8-bit, no capitalization, 256 flags
+>2     leshort         0x0D            7-bit, no capitalization, 256 flags
+>2     leshort         0x0E            8-bit, capitalization, 256 flags
+>2     leshort         0x0F            7-bit, capitalization, 256 flags
+>4     leshort         >0              and %d string characters
+0      beshort&0xFFFC  0x9600          big endian ispell
+>1     byte            0               hash file (?),
+>1     byte            1               3.0 hash file,
+>1     byte            2               3.1 hash file,
+>1     byte            3               hash file (?),
+>2     beshort         0x00            8-bit, no capitalization, 26 flags
+>2     beshort         0x01            7-bit, no capitalization, 26 flags
+>2     beshort         0x02            8-bit, capitalization, 26 flags
+>2     beshort         0x03            7-bit, capitalization, 26 flags
+>2     beshort         0x04            8-bit, no capitalization, 52 flags
+>2     beshort         0x05            7-bit, no capitalization, 52 flags
+>2     beshort         0x06            8-bit, capitalization, 52 flags
+>2     beshort         0x07            7-bit, capitalization, 52 flags
+>2     beshort         0x08            8-bit, no capitalization, 128 flags
+>2     beshort         0x09            7-bit, no capitalization, 128 flags
+>2     beshort         0x0A            8-bit, capitalization, 128 flags
+>2     beshort         0x0B            7-bit, capitalization, 128 flags
+>2     beshort         0x0C            8-bit, no capitalization, 256 flags
+>2     beshort         0x0D            7-bit, no capitalization, 256 flags
+>2     beshort         0x0E            8-bit, capitalization, 256 flags
+>2     beshort         0x0F            7-bit, capitalization, 256 flags
+>4     beshort         >0              and %d string characters
+# ispell 4.0 hash files  kromJx <kromJx@crosswinds.net>
+# Ispell 4.0
+0       string          ISPL            ispell
+>4      long            x               hash file version %d,
+>8      long            x               lexletters %d,
+>12     long            x               lexsize %d,
+>16     long            x               hashsize %d,
+>20     long            x               stblsize %d
diff --git a/magic/Magdir/isz b/magic/Magdir/isz
new file mode 100644 (file)
index 0000000..4d9c030
--- /dev/null
@@ -0,0 +1,15 @@
+
+#------------------------------------------------------------------------------
+# $File: isz,v 1.5 2019/04/19 00:42:27 christos Exp $
+# ISO Zipped file format
+# https://www.ezbsystems.com/isz/iszspec.txt
+0      string  IsZ!    ISO Zipped file
+>4     byte    x       \b, header size %u
+>5     byte    x       \b, version %u
+>8     lelong  x       \b, serial %u
+#12    leshort x       \b, sector size %u
+#>16   lelong  x       \b, total sectors %u
+>17    byte    >0      \b, password protected
+#>24   lequad  x       \b, segment size %llu
+#>32   lelong  x       \b, blocks %u
+#>36   lelong  x       \b, block size %u
diff --git a/magic/Magdir/java b/magic/Magdir/java
new file mode 100644 (file)
index 0000000..b9854e5
--- /dev/null
@@ -0,0 +1,45 @@
+
+#------------------------------------------------------------
+# $File: java,v 1.21 2019/02/18 17:58:50 christos Exp $
+# Java ByteCode and Mach-O binaries (e.g., Mac OS X) use the
+# same magic number, 0xcafebabe, so they are both handled
+# in the entry called "cafebabe".
+#------------------------------------------------------------
+# Java serialization
+# From Martin Pool (m.pool@pharos.com.au)
+0      beshort         0xaced          Java serialization data
+>2     beshort         >0x0004         \b, version %d
+
+0      belong          0xfeedfeed      Java KeyStore
+!:mime application/x-java-keystore
+0      belong          0xcececece      Java JCE KeyStore
+!:mime application/x-java-jce-keystore
+
+# Java source
+0      regex   \^import.*;$    Java source
+!:mime text/x-java
+
+# Java HPROF dumps
+# https://java.net/downloads/heap-snapshot/hprof-binary-format.html
+0      string          JAVA\x20PROFILE\x201.0.
+>0x12  byte            0
+>>0x11 ubyte-0x31      <2      Java HPROF dump,
+>>>0x17        beqdate/1000    x       created %s
+
+# Java jmod module
+# See https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java
+# Grr. 2 byte magic "JM", really? In 2019?
+0      belong          0x4a4d0100      Java jmod module version 1.0
+!:mime application/x-java-jmod
+
+# Java jlinked image
+# See https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/native/libjimage/imageFile.hpp
+0      belong  0xcafedada      Java module image (big endian)
+>4     beshort >0x00   \b, version %d
+>6     beshort x       \b.%d
+!:mime application/x-java-image
+
+0      lelong  0xcafedada      Java module image (little endian)
+>6     leshort >0x00   \b, version %d
+>4     leshort x       \b.%d
+!:mime application/x-java-image
diff --git a/magic/Magdir/javascript b/magic/Magdir/javascript
new file mode 100644 (file)
index 0000000..eb8205e
--- /dev/null
@@ -0,0 +1,17 @@
+
+#------------------------------------------------------------------------------
+# $File: $
+# javascript:  magic for javascript and node.js scripts.
+#
+0      search/1/w      #!/bin/node             Node.js script text executable
+!:mime application/javascript
+0      search/1/w      #!/usr/bin/node         Node.js script text executable
+!:mime application/javascript
+0      search/1/w      #!/bin/nodejs           Node.js script text executable
+!:mime application/javascript
+0      search/1/w      #!/usr/bin/nodejs       Node.js script text executable
+!:mime application/javascript
+0      search/1        #!/usr/bin/env\ node    Node.js script text executable
+!:mime application/javascript
+0      search/1        #!/usr/bin/env\ nodejs  Node.js script text executable
+!:mime application/javascript
diff --git a/magic/Magdir/jpeg b/magic/Magdir/jpeg
new file mode 100644 (file)
index 0000000..52c9ad3
--- /dev/null
@@ -0,0 +1,126 @@
+
+#------------------------------------------------------------------------------
+# $File: jpeg,v 1.32 2018/10/01 18:58:29 christos Exp $
+# JPEG images
+# SunOS 5.5.1 had
+#
+#      0       string          \377\330\377\340        JPEG file
+#      0       string          \377\330\377\356        JPG file
+#
+# both of which turn into "JPEG image data" here.
+#
+0      beshort         0xffd8          JPEG image data
+!:mime image/jpeg
+!:apple        8BIMJPEG
+!:strength *3
+!:ext jpeg/jpg/jpe/jfif
+>6     string          JFIF            \b, JFIF standard
+# The following added by Erik Rossen <rossen@freesurf.ch> 1999-09-06
+# in a vain attempt to add image size reporting for JFIF.  Note that these
+# tests are not fool-proof since some perfectly valid JPEGs are currently
+# impossible to specify in magic(4) format.
+# First, a little JFIF version info:
+>>11   byte            x               \b %d.
+>>12   byte            x               \b%02d
+# Next, the resolution or aspect ratio of the image:
+>>13   byte            0               \b, aspect ratio
+>>13   byte            1               \b, resolution (DPI)
+>>13   byte            2               \b, resolution (DPCM)
+>>14   beshort         x               \b, density %dx
+>>16   beshort         x               \b%d
+>>4    beshort         x               \b, segment length %d
+# Next, show thumbnail info, if it exists:
+>>18   byte            !0              \b, thumbnail %dx
+>>>19  byte            x               \b%d
+>6     string          Exif            \b, Exif standard: [
+>>12   indirect/r      x
+>>12   string          x               \b]
+
+# Jump to the first segment
+>(4.S+4)       use             jpeg_segment
+
+# This uses recursion...
+0              name            jpeg_segment
+>0     beshort         0xFFFE
+# Recursion handled by FFE0
+#>>(2.S+2)     use                     jpeg_segment
+>>2    pstring/HJ      x               \b, comment: "%s"
+
+>0     beshort         0xFFC0
+>>(2.S+2)      use                     jpeg_segment
+>>4    byte            x               \b, baseline, precision %d
+>>7    beshort         x               \b, %dx
+>>5    beshort         x               \b%d
+>>9    byte            x               \b, components %d
+
+>0     beshort         0xFFC1
+>>(2.S+2)      use                     jpeg_segment
+>>4    byte            x               \b, extended sequential, precision %d
+>>7    beshort         x               \b, %dx
+>>5    beshort         x               \b%d
+>>9    byte            x               \b, components %d
+
+>0     beshort         0xFFC2
+>>(2.S+2)      use                     jpeg_segment
+>>4    byte            x               \b, progressive, precision %d
+>>7    beshort         x               \b, %dx
+>>5    beshort         x               \b%d
+>>9    byte            x               \b, components %d
+
+# Define Huffman Tables
+>0     beshort         0xFFC4
+>>(2.S+2)      use                     jpeg_segment
+
+>0     beshort         0xFFE1
+# Recursion handled by FFE0
+#>>(2.S+2)     use                     jpeg_segment
+>>4    string          Exif            \b, Exif Standard: [
+>>>10  indirect/r      x
+>>>10  string          x               \b]
+
+# Application specific markers
+>0     beshort&0xFFE0  =0xFFE0
+>>(2.S+2)      use                     jpeg_segment
+
+# DB: Define Quantization tables
+# DD: Define Restart interval [XXX: wrong here, it is 4 bytes]
+# D8: Start of image
+# D9: End of image
+# Dn: Restart
+>0     beshort&0xFFD0  =0xFFD0
+>>0    beshort&0xFFE0  !0xFFE0
+>>>(2.S+2)     use                     jpeg_segment
+
+#>0    beshort         x               unknown 0x%x
+#>>(2.S+2)     use                     jpeg_segment
+
+# HSI is Handmade Software's proprietary JPEG encoding scheme
+0      string          hsi1            JPEG image data, HSI proprietary
+
+# From: David Santinoli <david@santinoli.com>
+0      string          \x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A        JPEG 2000
+# From: Johan van der Knijff <johan.vanderknijff@kb.nl>
+# Added sub-entries for JP2, JPX, JPM and MJ2 formats; added mimetypes
+# https://github.com/bitsgalore/jp2kMagic
+#
+# Now read value of 'Brand' field, which yields a few possibilities:
+>20    string          \x6a\x70\x32\x20        Part 1 (JP2)
+!:mime image/jp2
+>20    string          \x6a\x70\x78\x20        Part 2 (JPX)
+!:mime image/jpx
+>20    string          \x6a\x70\x6d\x20        Part 6 (JPM)
+!:mime image/jpm
+>20    string          \x6d\x6a\x70\x32        Part 3 (MJ2)
+!:mime video/mj2
+
+# Type: JPEG 2000 codesream
+# From: Mathieu Malaterre <mathieu.malaterre@gmail.com>
+0      belong          0xff4fff51                                              JPEG 2000 codestream
+45     beshort         0xff52
+
+# JPEG extended range
+0      string          \x49\x49\xbc
+>3     byte            1
+>>4    lelong%2        0       JPEG-XR
+!:mime image/jxr
+!:ext  jxr
diff --git a/magic/Magdir/karma b/magic/Magdir/karma
new file mode 100644 (file)
index 0000000..8961688
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File: karma,v 1.7 2014/04/30 21:41:02 christos Exp $
+# karma:  file(1) magic for Karma data files
+#
+# From <rgooch@atnf.csiro.au>
+
+0      string  KarmaRHD\040Version     Karma Data Structure Version
+>16    belong          x               %u
diff --git a/magic/Magdir/kde b/magic/Magdir/kde
new file mode 100644 (file)
index 0000000..06e5d9b
--- /dev/null
@@ -0,0 +1,11 @@
+
+#------------------------------------------------------------------------------
+# $File: kde,v 1.4 2009/09/19 16:28:10 christos Exp $
+# kde:  file(1) magic for KDE
+
+0              string/t        [KDE\ Desktop\ Entry]   KDE desktop entry
+!:mime application/x-kdelnk
+0              string/t        #\ KDE\ Config\ File    KDE config file
+!:mime application/x-kdelnk
+0              string/t        #\ xmcd xmcd database file for kscd
+!:mime text/x-xmcd
diff --git a/magic/Magdir/keepass b/magic/Magdir/keepass
new file mode 100644 (file)
index 0000000..3d26efa
--- /dev/null
@@ -0,0 +1,20 @@
+
+#------------------------------------------------------------------------------
+# $File: keepass,v 1.2 2019/04/19 00:42:27 christos Exp $
+# keepass: file(1) magic for KeePass file
+#
+# Keepass Password Safe:
+#  * original one: https://keepass.info/
+#  * *nix port:    https://www.keepassx.org/
+#  * android port: https://code.google.com/p/keepassdroid/
+
+0      lelong          0x9AA2D903      Keepass password database
+>4     lelong          0xB54BFB65      1.x KDB
+>>48   lelong          >0              \b, %d groups
+>>52   lelong          >0              \b, %d entries
+>>8    lelong&0x0f     1               \b, SHA-256
+>>8    lelong&0x0f     2               \b, AES
+>>8    lelong&0x0f     4               \b, RC4
+>>8    lelong&0x0f     8               \b, Twofish
+>>120  lelong          >0              \b, %d key transformation rounds
+>4     lelong          0xB54BFB67      2.x KDBX
diff --git a/magic/Magdir/kerberos b/magic/Magdir/kerberos
new file mode 100644 (file)
index 0000000..df6dc52
--- /dev/null
@@ -0,0 +1,45 @@
+
+#------------------------------------------------------------------------------
+# $File: kerberos,v 1.3 2019/04/19 00:42:27 christos Exp $
+# kerberos: MIT kerberos file binary formats
+#
+
+# This magic entry is for demonstration purposes and could be improved
+# if the following features were implemented in file:
+#
+# Strings inside [[ .. ]] in the descriptions have special meanings and
+# are not printed.
+#
+#      - Provide some form of iteration in number of components
+#              [[${counter}=%d]] in the description
+#              then append
+#              [${counter}--] in the offset of the entries
+#      - Provide a way to round the next offset
+#              Add [R:4] after the offset?
+#      - Provide a way to have optional entries
+#              XXX: Syntax:
+#      - Provide a way to "save" entries to print them later.
+#              if the description is [[${name}=%s]], then nothing is
+#              printed and a subsequent entry in the same magic file
+#              can refer to ${name}
+#      - Provide a way to format strings as hex values
+#
+# https://www.gnu.org/software/shishi/manual/html_node/\
+#      The-Keytab-Binary-File-Format.html
+#
+
+0              name            keytab_entry
+#>0            beshort         x               \b, size=%d
+#>2            beshort         x               \b, components=%d
+>4             pstring/H       x               \b, realm=%s
+>>&0           pstring/H       x               \b, principal=%s/
+>>>&0          pstring/H       x               \b%s
+>>>>&0         belong          x               \b, type=%d
+>>>>>&0                bedate          x               \b, date=%s
+>>>>>>&0       byte            x               \b, kvno=%u
+#>>>>>>>&0     pstring/H       x
+#>>>>>>>>&0    belong          x
+#>>>>>>>>>>&0  use             keytab_entry
+
+0              belong          0x05020000      Kerberos Keytab file
+>4             use             keytab_entry
diff --git a/magic/Magdir/kicad b/magic/Magdir/kicad
new file mode 100644 (file)
index 0000000..00c9ead
--- /dev/null
@@ -0,0 +1,69 @@
+
+#------------------------------------------------------------------------------
+# $File: kicad,v 1.1 2018/10/01 18:39:21 christos Exp $
+# kicad:  file(1) magic for KiCad files
+#
+# See
+#
+#      http://kicad-pcb.org
+#
+
+# KiCad Schematic Document
+0          string  EESchema
+>8         byte    0x20
+>>9        string  Schematic
+>>>18      byte    0x20                KiCad Schematic Document
+!:ext sch/bak
+>>>>24     string  Version
+>>>>>31            byte    0x20
+>>>>>>32    string  x                  (Version %s)
+
+# KiCad Symbol Library
+0          string  EESchema-LIBRARY
+>16        byte    0x20                KiCad Symbol Library
+!:ext lib
+>>17       string  Version
+>>>24      byte    0x20
+>>>>25     string  x                   (Version %s)
+
+# KiCad Symbol Library Documentation
+0          string  EESchema-DOCLIB
+>15        byte    0x20                KiCad Symbol Library Documentation
+!:ext dcm
+>>17       string  Version
+>>>24      byte    0x20
+>>>>25     string  x                   (Version %s)
+
+# KiCad Board Layout
+0          string  (kicad_pcb
+>10        byte    0x20                KiCad Board Layout
+!:ext kicad_pcb/kicad_pcb-bak
+>>11       string  (version
+>>>19      byte    0x20
+>>>>20     byte    x                   (Version %c)
+
+# KiCad Footprint
+0          string  (module
+>7         byte    0x20                KiCad Footprint
+!:ext kicad_mod
+
+# KiCad Footprint (Legacy)
+0          string  PCBNEW-LibModule-V1     KiCad Footprint (Legacy)
+!:ext mod
+
+# KiCad Netlist
+0          string  (export
+>7         byte    0x20                KiCad Netlist
+!:ext net
+
+# KiCad Symbol Library Table
+0          string  (sym_lib_table
+>14        byte    0xA                 KiCad Symbol Library Table
+>14        byte    0xD                 KiCad Symbol Library Table
+>14        byte    0x20                KiCad Symbol Library Table
+
+# KiCad Footprint Library Table
+0          string  (fp_lib_table
+>13        byte    0xA                 KiCad Footprint Library Table
+>13        byte    0xD                 KiCad Footprint Library Table
+>13        byte    0x20                KiCad Footprint Library Table
diff --git a/magic/Magdir/kml b/magic/Magdir/kml
new file mode 100644 (file)
index 0000000..dcdf64c
--- /dev/null
@@ -0,0 +1,34 @@
+
+#------------------------------------------------------------------------------
+# $File: kml,v 1.5 2019/04/19 00:42:27 christos Exp $
+# Type: Google KML, formerly Keyhole Markup Language
+# Future development of this format has been handed
+# over to the Open Geospatial Consortium.
+# https://www.opengeospatial.org/standards/kml/
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+0 string/t    \<?xml
+>20  search/400 \ xmlns=
+>>&0 regex ['"]https://earth.google.com/kml Google KML document
+!:mime application/vnd.google-earth.kml+xml
+>>>&1 string 2.0' \b, version 2.0
+>>>&1 string 2.1' \b, version 2.1
+>>>&1 string 2.2' \b, version 2.2
+
+#------------------------------------------------------------------------------
+# Type: OpenGIS KML, formerly Keyhole Markup Language
+# This standard is maintained by the
+# Open Geospatial Consortium.
+# https://www.opengeospatial.org/standards/kml/
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+>>&0 regex ['"]https://www.opengis.net/kml OpenGIS KML document
+!:mime application/vnd.google-earth.kml+xml
+>>>&1 string/t 2.2 \b, version 2.2
+
+#------------------------------------------------------------------------------
+# Type: Google KML Archive (ZIP based)
+# https://code.google.com/apis/kml/documentation/kml_tut.html
+# From: Asbjoern Sloth Toennesen <asbjorn@lila.io>
+0 string    PK\003\004
+>4  byte    0x14
+>>30  string doc.kml Compressed Google KML Document, including resources.
+!:mime application/vnd.google-earth.kmz
diff --git a/magic/Magdir/lecter b/magic/Magdir/lecter
new file mode 100644 (file)
index 0000000..65575b4
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# DEC SRC Virtual Paper: Lectern files
+# Karl M. Hegbloom <karlheg@inetarena.com>
+0      string  lect    DEC SRC Virtual Paper Lectern file
diff --git a/magic/Magdir/lex b/magic/Magdir/lex
new file mode 100644 (file)
index 0000000..1439076
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# lex:  file(1) magic for lex
+#
+#      derived empirically, your offsets may vary!
+0      search/100      yyprevious      C program text (from lex)
+>3     search/1        >\0              for %s
+# C program text from GNU flex, from Daniel Quinlan <quinlan@yggdrasil.com>
+0      search/100      generated\ by\ flex     C program text (from flex)
+# lex description file, from Daniel Quinlan <quinlan@yggdrasil.com>
+0      search/1        %{              lex description text
diff --git a/magic/Magdir/lif b/magic/Magdir/lif
new file mode 100644 (file)
index 0000000..4ae094e
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# lif:  file(1) magic for lif
+#
+# (Daniel Quinlan <quinlan@yggdrasil.com>)
+#
+0      beshort         0x8000          lif file
diff --git a/magic/Magdir/linux b/magic/Magdir/linux
new file mode 100644 (file)
index 0000000..ed7dcd1
--- /dev/null
@@ -0,0 +1,496 @@
+
+#------------------------------------------------------------------------------
+# $File: linux,v 1.67 2019/04/19 00:42:27 christos Exp $
+# linux:  file(1) magic for Linux files
+#
+# Values for Linux/i386 binaries, from Daniel Quinlan <quinlan@yggdrasil.com>
+# The following basic Linux magic is useful for reference, but using
+# "long" magic is a better practice in order to avoid collisions.
+#
+# 2    leshort         100             Linux/i386
+# >0   leshort         0407            impure executable (OMAGIC)
+# >0   leshort         0410            pure executable (NMAGIC)
+# >0   leshort         0413            demand-paged executable (ZMAGIC)
+# >0   leshort         0314            demand-paged executable (QMAGIC)
+#
+0      lelong          0x00640107      Linux/i386 impure executable (OMAGIC)
+>16    lelong          0               \b, stripped
+0      lelong          0x00640108      Linux/i386 pure executable (NMAGIC)
+>16    lelong          0               \b, stripped
+0      lelong          0x0064010b      Linux/i386 demand-paged executable (ZMAGIC)
+>16    lelong          0               \b, stripped
+0      lelong          0x006400cc      Linux/i386 demand-paged executable (QMAGIC)
+>16    lelong          0               \b, stripped
+#
+0      string          \007\001\000    Linux/i386 object file
+>20    lelong          >0x1020         \b, DLL library
+# Linux-8086 stuff:
+0      string          \01\03\020\04   Linux-8086 impure executable
+>28    long            !0              not stripped
+0      string          \01\03\040\04   Linux-8086 executable
+>28    long            !0              not stripped
+#
+0      string          \243\206\001\0  Linux-8086 object file
+#
+0      string          \01\03\020\20   Minix-386 impure executable
+>28    long            !0              not stripped
+0      string          \01\03\040\20   Minix-386 executable
+>28    long            !0              not stripped
+0      string          \01\03\04\20    Minix-386 NSYM/GNU executable
+>28    long            !0              not stripped
+# core dump file, from Bill Reynolds <bill@goshawk.lanl.gov>
+216    lelong          0421            Linux/i386 core file
+!:strength / 2
+>220   string          >\0             of '%s'
+>200   lelong          >0              (signal %d)
+#
+# LILO boot/chain loaders, from Daniel Quinlan <quinlan@yggdrasil.com>
+# this can be overridden by the DOS executable (COM) entry
+2      string          LILO            Linux/i386 LILO boot/chain loader
+#
+# Linux make config build file, from Ole Aamot <oka@oka.no>
+# Updated by Ken Sharp
+28     string          make\ config            Linux make config build file (old)
+49     search/70       Kernel\ Configuration   Linux make config build file
+
+#
+# PSF fonts, from H. Peter Anvin <hpa@yggdrasil.com>
+# Updated by Adam Buchbinder <adam.buchbinder@gmail.com>
+# See: https://www.win.tue.nl/~aeb/linux/kbd/font-formats-1.html
+0      leshort         0x0436          Linux/i386 PC Screen Font v1 data,
+>2     byte&0x01       0               256 characters,
+>2     byte&0x01       !0              512 characters,
+>2     byte&0x02       0               no directory,
+>2     byte&0x02       !0              Unicode directory,
+>3     byte            >0              8x%d
+0      string          \x72\xb5\x4a\x86\x00\x00 Linux/i386 PC Screen Font v2 data,
+>16    lelong          x               %d characters,
+>12    lelong&0x01     0               no directory,
+>12    lelong&0x01     !0              Unicode directory,
+>24    lelong          x               %d
+>28    lelong          x               \bx%d
+
+# Linux swap file, from Daniel Quinlan <quinlan@yggdrasil.com>
+4086   string          SWAP-SPACE      Linux/i386 swap file
+# From: Jeff Bailey <jbailey@ubuntu.com>
+# Linux swap file with swsusp1 image, from Jeff Bailey <jbailey@ubuntu.com>
+4076   string          SWAPSPACE2S1SUSPEND     Linux/i386 swap file (new style) with SWSUSP1 image
+# From: James Hunt <james.hunt@ubuntu.com>
+4076    string          SWAPSPACE2LINHIB0001    Linux/i386 swap file (new style) (compressed hibernate)
+# according to man page of mkswap (8) March 1999
+# volume label and UUID Russell Coker
+# https://etbe.coker.com.au/2008/07/08/label-vs-uuid-vs-device/
+4086   string          SWAPSPACE2      Linux/i386 swap file (new style),
+>0x400 long            x               version %d (4K pages),
+>0x404 long            x               size %d pages,
+>1052  string          \0              no label,
+>1052  string          >\0             LABEL=%s,
+>0x40c belong          x               UUID=%08x
+>0x410 beshort         x               \b-%04x
+>0x412 beshort         x               \b-%04x
+>0x414 beshort         x               \b-%04x
+>0x416 belong          x               \b-%08x
+>0x41a beshort         x               \b%04x
+# From Daniel Novotny <dnovotny@redhat.com>
+# swap file for PowerPC
+65526  string          SWAPSPACE2      Linux/ppc swap file
+>0x400 long            x               version %d,
+>0x404 long            x               size %d pages,
+>1052  string          \0              no label,
+>1052  string          >\0             LABEL=%s,
+>0x40c belong          x               UUID=%08x
+>0x410 beshort         x               \b-%04x
+>0x412 beshort         x               \b-%04x
+>0x414 beshort         x               \b-%04x
+>0x416 belong          x               \b-%08x
+>0x41a beshort         x               \b%04x
+16374  string          SWAPSPACE2      Linux/ia64 swap file
+#
+# Linux kernel boot images, from Albert Cahalan <acahalan@cs.uml.edu>
+# and others such as Axel Kohlmeyer <akohlmey@rincewind.chemie.uni-ulm.de>
+# and Nicolas Lichtmaier <nick@debian.org>
+# All known start with: b8 c0 07 8e d8 b8 00 90 8e c0 b9 00 01 29 f6 29
+# Linux kernel boot images (i386 arch) (Wolfram Kleff)
+# URL: https://www.kernel.org/doc/Documentation/x86/boot.txt
+514    string          HdrS            Linux kernel
+!:strength + 55
+# often no extension like in linux, vmlinuz, bzimage or memdisk but sometimes
+# Acronis Recovery kernel64.dat and Plop Boot Manager plpbtrom.bin
+# DamnSmallLinux 1.5 damnsmll.lnx 
+!:ext  /dat/bin/lnx
+>510   leshort         0xAA55          x86 boot executable
+>>518  leshort         >0x1ff
+>>>529 byte            0               zImage,
+>>>529 byte            1               bzImage,
+>>>526 lelong          >0
+>>>>(526.s+0x200) string       >\0     version %s,
+>>498  leshort         1               RO-rootFS,
+>>498  leshort         0               RW-rootFS,
+>>508  leshort         >0              root_dev 0x%X,
+>>502  leshort         >0              swap_dev 0x%X,
+>>504  leshort         >0              RAMdisksize %u KB,
+>>506  leshort         0xFFFF          Normal VGA
+>>506  leshort         0xFFFE          Extended VGA
+>>506  leshort         0xFFFD          Prompt for Videomode
+>>506  leshort         >0              Video mode %d
+# This also matches new kernels, which were caught above by "HdrS".
+0              belong  0xb8c0078e      Linux kernel
+>0x1e3         string  Loading         version 1.3.79 or older
+>0x1e9         string  Loading         from prehistoric times
+
+# System.map files - Nicolas Lichtmaier <nick@debian.org>
+8      search/1        \ A\ _text      Linux kernel symbol map text
+
+# LSM entries - Nicolas Lichtmaier <nick@debian.org>
+0      search/1        Begin3  Linux Software Map entry text
+0      search/1        Begin4  Linux Software Map entry text (new format)
+
+# From Matt Zimmerman, enhanced for v3 by Matthew Palmer
+0      belong  0x4f4f4f4d      User-mode Linux COW file
+>4     belong  <3              \b, version %d
+>>8    string  >\0             \b, backing file %s
+>4     belong  >2              \b, version %d
+>>32   string  >\0             \b, backing file %s
+
+############################################################################
+# Linux kernel versions
+
+0              string          \xb8\xc0\x07\x8e\xd8\xb8\x00\x90        Linux
+>497           leshort         0               x86 boot sector
+>>514          belong          0x8e    of a kernel from the dawn of time!
+>>514          belong          0x908ed8b4      version 0.99-1.1.42
+>>514          belong          0x908ed8b8      for memtest86
+
+>497           leshort         !0              x86 kernel
+>>504          leshort         >0              RAMdisksize=%u KB
+>>502          leshort         >0              swap=0x%X
+>>508          leshort         >0              root=0x%X
+>>>498         leshort         1               \b-ro
+>>>498         leshort         0               \b-rw
+>>506          leshort         0xFFFF          vga=normal
+>>506          leshort         0xFFFE          vga=extended
+>>506          leshort         0xFFFD          vga=ask
+>>506          leshort         >0              vga=%d
+>>514          belong          0x908ed881      version 1.1.43-1.1.45
+>>514          belong          0x15b281cd
+>>>0xa8e       belong          0x55AA5a5a      version 1.1.46-1.2.13,1.3.0
+>>>0xa99       belong          0x55AA5a5a      version 1.3.1,2
+>>>0xaa3       belong          0x55AA5a5a      version 1.3.3-1.3.30
+>>>0xaa6       belong          0x55AA5a5a      version 1.3.31-1.3.41
+>>>0xb2b       belong          0x55AA5a5a      version 1.3.42-1.3.45
+>>>0xaf7       belong          0x55AA5a5a      version 1.3.46-1.3.72
+>>514          string          HdrS
+>>>518         leshort         >0x1FF
+>>>>529                byte            0               \b, zImage
+>>>>529                byte            1               \b, bzImage
+>>>>(526.s+0x200) string       >\0             \b, version %s
+
+# Linux boot sector thefts.
+0              belong          0xb8c0078e      Linux
+>0x1e6         belong          0x454c4b53      ELKS Kernel
+>0x1e6         belong          !0x454c4b53     style boot sector
+
+############################################################################
+# Linux S390 kernel image
+# Created by: Jan Kaluza <jkaluza@redhat.com>
+8 string \x02\x00\x00\x18\x60\x00\x00\x50\x02\x00\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40\x40\x40\x40\x40 Linux S390
+>0x00010000 search/b/4096 \x00\x0a\x00\x00\x8b\xad\xcc\xcc
+# 64bit
+>>&0 string \xc1\x00\xef\xe3\xf0\x68\x00\x00 Z10 64bit kernel
+>>&0 string \xc1\x00\xef\xc3\x00\x00\x00\x00 Z9-109 64bit kernel
+>>&0 string \xc0\x00\x20\x00\x00\x00\x00\x00 Z990 64bit kernel
+>>&0 string \x00\x00\x00\x00\x00\x00\x00\x00 Z900 64bit kernel
+# 32bit
+>>&0 string \x81\x00\xc8\x80\x00\x00\x00\x00 Z10 32bit kernel
+>>&0 string \x81\x00\xc8\x80\x00\x00\x00\x00 Z9-109 32bit kernel
+>>&0 string \x80\x00\x20\x00\x00\x00\x00\x00 Z990 32bit kernel
+>>&0 string \x80\x00\x00\x00\x00\x00\x00\x00 Z900 32bit kernel
+
+# Linux ARM compressed kernel image
+# From: Kevin Cernekee <cernekee@gmail.com>
+# Update: Joerg Jenderek
+36     lelong  0x016f2818      Linux kernel ARM boot executable zImage (little-endian)
+# raspian "kernel7.img", Vu+ Ultimo4K "kernel_auto.bin"
+!:ext  img/bin
+36     belong  0x016f2818      Linux kernel ARM boot executable zImage (big-endian)
+
+############################################################################
+# Linux 8086 executable
+0      lelong&0xFF0000FF 0xC30000E9    Linux-Dev86 executable, headerless
+>5     string          .
+>>4    string          >\0             \b, libc version %s
+
+0      lelong&0xFF00FFFF 0x4000301     Linux-8086 executable
+>2     byte&0x01       !0              \b, unmapped zero page
+>2     byte&0x20       0               \b, impure
+>2     byte&0x20       !0
+>>2    byte&0x10       !0              \b, A_EXEC
+>2     byte&0x02       !0              \b, A_PAL
+>2     byte&0x04       !0              \b, A_NSYM
+>2     byte&0x08       !0              \b, A_STAND
+>2     byte&0x40       !0              \b, A_PURE
+>2     byte&0x80       !0              \b, A_TOVLY
+>28     long            !0              \b, not stripped
+>37    string          .
+>>36   string          >\0             \b, libc version %s
+
+# 0    lelong&0xFF00FFFF 0x10000301    ld86 I80386 executable
+# 0    lelong&0xFF00FFFF 0xB000301     ld86 M68K executable
+# 0    lelong&0xFF00FFFF 0xC000301     ld86 NS16K executable
+# 0    lelong&0xFF00FFFF 0x17000301    ld86 SPARC executable
+
+# SYSLINUX boot logo files (from 'ppmtolss16' sources)
+# https://www.syslinux.org/wiki/index.php/SYSLINUX#Display_graphic_from_filename:
+# file extension .lss .16
+0      lelong  =0x1413f33d             SYSLINUX' LSS16 image data
+# syslinux-4.05/mime/image/x-lss16.xml
+!:mime image/x-lss16
+>4     leshort x                       \b, width %d
+>6     leshort x                       \b, height %d
+
+0      string  OOOM                    User-Mode-Linux's Copy-On-Write disk image
+>4     belong  x                       version %d
+
+# SE Linux policy database
+# From: Mike Frysinger <vapier@gentoo.org>
+0      lelong  0xf97cff8c              SE Linux policy
+>16    lelong  x                       v%d
+>20    lelong  1                       MLS
+>24    lelong  x                       %d symbols
+>28    lelong  x                       %d ocons
+
+# Linux Logical Volume Manager (LVM)
+# Emmanuel VARAGNAT <emmanuel.varagnat@guzu.net>
+#
+# System ID, UUID and volume group name are 128 bytes long
+# but they should never be full and initialized with zeros...
+#
+# LVM1
+#
+0x0    string  HM\001          LVM1 (Linux Logical Volume Manager), version 1
+>0x12c string  >\0             , System ID: %s
+
+0x0    string  HM\002          LVM1 (Linux Logical Volume Manager), version 2
+>0x12c string  >\0             , System ID: %s
+
+#  LVM2
+#
+# It seems that the label header can be in one the four first sector
+# of the disk... (from _find_labeller in lib/label/label.c of LVM2)
+#
+# 0x200 seems to be the common case
+
+0x218           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+# read the offset to add to the start of the header, and the header
+# start in 0x200
+>&(&-12.l-0x21) byte    x
+# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
+>>&0x0          string  >\x2f          \b, UUID: %.6s
+>>&0x6          string  >\x2f          \b-%.4s
+>>&0xa          string  >\x2f          \b-%.4s
+>>&0xe          string  >\x2f          \b-%.4s
+>>&0x12         string  >\x2f          \b-%.4s
+>>&0x16         string  >\x2f          \b-%.4s
+>>&0x1a         string  >\x2f          \b-%.6s
+>>&0x20         lequad  x              \b, size: %lld
+
+0x018           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x21) byte    x
+# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
+>>&0x0          string  >\x2f          \b, UUID: %.6s
+>>&0x6          string  >\x2f          \b-%.4s
+>>&0xa          string  >\x2f          \b-%.4s
+>>&0xe          string  >\x2f          \b-%.4s
+>>&0x12         string  >\x2f          \b-%.4s
+>>&0x16         string  >\x2f          \b-%.4s
+>>&0x1a         string  >\x2f          \b-%.6s
+>>&0x20         lequad  x              \b, size: %lld
+
+0x418           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x21) byte    x
+# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
+>>&0x0          string  >\x2f          \b, UUID: %.6s
+>>&0x6          string  >\x2f          \b-%.4s
+>>&0xa          string  >\x2f          \b-%.4s
+>>&0xe          string  >\x2f          \b-%.4s
+>>&0x12         string  >\x2f          \b-%.4s
+>>&0x16         string  >\x2f          \b-%.4s
+>>&0x1a         string  >\x2f          \b-%.6s
+>>&0x20         lequad  x              \b, size: %lld
+
+0x618           string  LVM2\ 001      LVM2 PV (Linux Logical Volume Manager)
+>&(&-12.l-0x21) byte    x
+# display UUID in LVM format + display all 32 bytes (instead of max string length: 31)
+>>&0x0          string  >\x2f          \b, UUID: %.6s
+>>&0x6          string  >\x2f          \b-%.4s
+>>&0xa          string  >\x2f          \b-%.4s
+>>&0xe          string  >\x2f          \b-%.4s
+>>&0x12         string  >\x2f          \b-%.4s
+>>&0x16         string  >\x2f          \b-%.4s
+>>&0x1a         string  >\x2f          \b-%.6s
+>>&0x20         lequad  x              \b, size: %lld
+
+# LVM snapshot
+# from Jason Farrel
+0      string  SnAp    LVM Snapshot (CopyOnWrite store)
+>4     lelong  !0      - valid,
+>4     lelong  0       - invalid,
+>8     lelong  x       version %d,
+>12    lelong  x       chunk_size %d
+
+# SE Linux policy database
+0      lelong  0xf97cff8c              SE Linux policy
+>16    lelong  x                       v%d
+>20    lelong  1                       MLS
+>24    lelong  x                       %d symbols
+>28    lelong  x                       %d ocons
+
+# LUKS: Linux Unified Key Setup, On-Disk Format, http://luks.endorphin.org/spec
+# Anthon van der Neut (anthon@mnt.org)
+0      string  LUKS\xba\xbe    LUKS encrypted file,
+>6     beshort x               ver %d
+>8     string  x               [%s,
+>40    string  x               %s,
+>72    string  x               %s]
+>168   string  x               UUID: %s
+
+
+# Summary: Xen saved domain file
+# Created by: Radek Vokal <rvokal@redhat.com>
+0      string          LinuxGuestRecord        Xen saved domain
+>20    search/256      (name
+>>&1   string          x                       (name %s)
+
+# Type: Xen, the virtual machine monitor
+# From: Radek Vokal <rvokal@redhat.com>
+0      string          LinuxGuestRecord        Xen saved domain
+#>2    regex           \(name\ [^)]*\)         %s
+>20    search/256      (name                   (name
+>>&1   string          x                       %s...)
+
+# Systemd journald files
+# See https://www.freedesktop.org/wiki/Software/systemd/journal-files/.
+# From: Zbigniew Jedrzejewski-Szmek <zbyszek@in.waw.pl>
+
+# check magic
+0      string  LPKSHHRH
+# check that state is one of known values
+>16            ubyte&252       0
+# check that each half of three unique id128s is non-zero
+>>24           ubequad         >0
+>>>32          ubequad         >0
+>>>>40         ubequad         >0
+>>>>>48                ubequad         >0
+>>>>>>56       ubequad         >0
+>>>>>>>64      ubequad         >0      Journal file
+!:mime application/octet-stream
+# provide more info
+>>>>>>>>184    leqdate         0       empty
+>>>>>>>>16     ubyte           0       \b, offline
+>>>>>>>>16     ubyte           1       \b, online
+>>>>>>>>16     ubyte           2       \b, archived
+>>>>>>>>8      ulelong&1       1       \b, sealed
+>>>>>>>>12     ulelong&1       1       \b, compressed
+
+# BCache backing and cache devices
+# From: Gabriel de Perthuis <g2p.code@gmail.com>
+0x1008         lequad          8
+>0x1018                string          \xc6\x85\x73\xf6\x4e\x1a\x45\xca\x82\x65\xf5\x7f\x48\xba\x6d\x81        BCache
+>>0x1010       ulequad         0       cache device
+>>0x1010       ulequad         1       backing device
+>>0x1010       ulequad         3       cache device
+>>0x1010       ulequad         4       backing device
+>>0x1048       string          >0      \b, label "%.32s"
+>>0x1028       ubelong         x       \b, uuid %08x
+>>0x102c       ubeshort        x       \b-%04x
+>>0x102e       ubeshort        x       \b-%04x
+>>0x1030       ubeshort        x       \b-%04x
+>>0x1032       ubelong         x       \b-%08x
+>>0x1036       ubeshort        x       \b%04x
+>>0x1038       ubelong         x       \b, set uuid %08x
+>>0x103c       ubeshort        x       \b-%04x
+>>0x103e       ubeshort        x       \b-%04x
+>>0x1040       ubeshort        x       \b-%04x
+>>0x1042       ubelong         x       \b-%08x
+>>0x1046       ubeshort        x       \b%04x
+
+# Linux device tree:
+# File format description can be found in the Linux kernel sources at
+# Documentation/devicetree/booting-without-of.txt
+# From Christoph Biedl
+0              belong          0xd00dfeed
+# structure and strings must be within blob
+>&(8.L)                byte            x
+>>&(12.L)      byte            x
+>>>20          belong          >1      Device Tree Blob version %d
+>>>>4          belong          x       \b, size=%d
+>>>>20         belong          >1
+>>>>>28                belong          x       \b, boot CPU=%d
+>>>>20         belong          >2
+>>>>>32                belong          x       \b, string block size=%d
+>>>>20         belong          >16
+>>>>>36                belong          x       \b, DT structure block size=%d
+
+# glibc locale archive as defined in glibc locale/locarchive.h
+0              lelong          0xde020109      locale archive
+>24            lelong          x               %d strings
+
+# Linux Software RAID (mdadm)
+# Russell Coker <russell@coker.com.au>
+0      name    linuxraid
+>16    belong  x               UUID=%8x:
+>20    belong  x               \b%8x:
+>24    belong  x               \b%8x:
+>28    belong  x               \b%8x
+>32    string  x               name=%s
+>72    lelong  x               level=%d
+>92    lelong  x               disks=%d
+
+4096   lelong  0xa92b4efc      Linux Software RAID
+>4100  lelong  x               version 1.2 (%d)
+>4096  use     linuxraid
+
+0      lelong  0xa92b4efc      Linux Software RAID
+>4     lelong  x               version 1.1 (%d)
+>0     use     linuxraid
+
+# Summary:     Database file for mlocate
+# Description: A database file as used by mlocate, a fast implementation
+#              of locate/updatedb. It uses merging to reuse the existing
+#              database and avoid rereading most of the filesystem. It's
+#              the default version of locate on Arch Linux (and others).
+# File path:   /var/lib/mlocate/mlocate.db by default (but configurable)
+# Site:        https://fedorahosted.org/mlocate/
+# Format docs: https://linux.die.net/man/5/mlocate.db
+# Type: mlocate database file
+# URL:  https://fedorahosted.org/mlocate/
+# From: Wander Nauta <info@wandernauta.nl>
+0              string          \0mlocate       mlocate database
+>12            byte            x               \b, version %d
+>13            byte            1               \b, require visibility
+>16            string          x               \b, root %s
+
+# Dump files for iproute2 tool. Generated by the "ip r|a save" command. URL:
+# https://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
+# From: Pavel Emelyanov <xemul@parallels.com>
+0              lelong          0x45311224      iproute2 routes dump
+0              lelong          0x47361222      iproute2 addresses dump
+
+# Image and service files for CRIU tool.
+# URL: https://criu.org
+# From: Pavel Emelyanov <xemul@parallels.com>
+0              lelong          0x54564319      CRIU image file v1.1
+0              lelong          0x55105940      CRIU service file
+0              lelong          0x58313116      CRIU inventory
+
+# Kdump compressed dump files
+# https://sourceforge.net/p/makedumpfile/code/ci/master/tree/IMPLEMENTATION
+
+0              string          KDUMP           Kdump compressed dump
+>8             long            x               v%d
+>12            string          >\0             \b, system %s
+>77            string          >\0             \b, node %s
+>142           string          >\0             \b, release %s
+>207           string          >\0             \b, version %s
+>272           string          >\0             \b, machine %s
+>337           string          >\0             \b, domain %s
diff --git a/magic/Magdir/lisp b/magic/Magdir/lisp
new file mode 100644 (file)
index 0000000..d32cc10
--- /dev/null
@@ -0,0 +1,75 @@
+
+#------------------------------------------------------------------------------
+# $File: lisp,v 1.26 2019/04/19 00:42:27 christos Exp $
+# lisp:  file(1) magic for lisp programs
+#
+# various lisp types, from Daniel Quinlan (quinlan@yggdrasil.com)
+
+# updated by Joerg Jenderek
+# GRR: This lot is too weak
+#0     string  ;;
+# windows INF files often begin with semicolon and use CRLF as line end
+# lisp files are mainly created on unix system with LF as line end
+#>2    search/4096     !\r             Lisp/Scheme program text
+#>2    search/4096     \r              Windows INF file
+
+0      search/4096     (setq\                  Lisp/Scheme program text
+!:mime text/x-lisp
+0      search/4096     (defvar\                Lisp/Scheme program text
+!:mime text/x-lisp
+0      search/4096     (defparam\              Lisp/Scheme program text
+!:mime text/x-lisp
+0      search/4096     (defun\                 Lisp/Scheme program text
+!:mime text/x-lisp
+0      search/4096     (autoload\              Lisp/Scheme program text
+!:mime text/x-lisp
+0      search/4096     (custom-set-variables\  Lisp/Scheme program text
+!:mime text/x-lisp
+
+# URL: https://en.wikipedia.org/wiki/Emacs_Lisp
+# Reference: https://ftp.gnu.org/old-gnu/emacs/elisp-manual-18-1.03.tar.gz
+# Update: Joerg Jenderek
+# Emacs 18 - this is always correct, but not very magical.
+0      string  \012(
+# look for emacs lisp keywords
+# GRR: split regex because it is too long or get error like
+# lisp, 36: Warning: cannot get string from `^(defun|defvar|defconst|defmacro|setq|fset|put|provide|require|'
+>&0    regex   \^(defun|defvar|defconst|defmacro|setq|fset)    Emacs v18 byte-compiled Lisp data
+!:mime application/x-elc
+# https://searchcode.com/codesearch/view/2173420/
+# not really pure text
+!:apple        EMAxTEXT
+!:ext elc
+# remaining regex
+>&0    regex   \^(put|provide|require|random)  Emacs v18 byte-compiled Lisp data
+!:mime application/x-elc
+!:apple        EMAxTEXT
+!:ext elc
+# missed cl.elc dbx.elc simple.elc look like normal lisp starting with ;;;
+
+# Emacs 19+ - ver. recognition added by Ian Springer
+# Also applies to XEmacs 19+ .elc files; could tell them apart with regexs
+# - Chris Chittleborough <cchittleborough@yahoo.com.au>
+# Update: Joerg Jenderek
+0      string  ;ELC
+# version\0\0\0
+>4     byte    >18                     Emacs/XEmacs v%d byte-compiled Lisp data
+# why less than 32 ? does not make sense to me. GNU Emacs version is 24.5 at April 2015
+#>4    byte    <32                     Emacs/XEmacs v%d byte-compiled Lisp data
+!:mime application/x-elc
+!:apple        EMAxTEXT
+!:ext elc
+
+# Files produced by CLISP Common Lisp From: Bruno Haible <haible@ilog.fr>
+0      string  (SYSTEM::VERSION\040'   CLISP byte-compiled Lisp program (pre 2004-03-27)
+0      string  (|SYSTEM|::|VERSION|\040'       CLISP byte-compiled Lisp program text
+
+0      long    0x70768BD2              CLISP memory image data
+0      long    0xD28B7670              CLISP memory image data, other endian
+
+#.com and .bin for MIT scheme
+0      string  \372\372\372\372        MIT scheme (library?)
+
+# From: David Allouche <david@allouche.net>
+0      search/1        \<TeXmacs|      TeXmacs document text
+!:mime text/texmacs
diff --git a/magic/Magdir/llvm b/magic/Magdir/llvm
new file mode 100644 (file)
index 0000000..2691ef1
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File: llvm,v 1.9 2019/04/19 00:42:27 christos Exp $
+# llvm:  file(1) magic for LLVM byte-codes
+# URL:  https://llvm.org/docs/BitCodeFormat.html
+# From: Al Stone <ahs3@fc.hp.com>
+
+0      string  llvm    LLVM byte-codes, uncompressed
+0      string  llvc0   LLVM byte-codes, null compression
+0      string  llvc1   LLVM byte-codes, gzip compression
+0      string  llvc2   LLVM byte-codes, bzip2 compression
+
+0      lelong  0x0b17c0de      LLVM bitcode, wrapper
+# Are these Mach-O ABI values?  They appear to be.
+>16    lelong  0x01000007      x86_64
+>16    lelong  0x00000007      i386
+>16    lelong  0x00000012      ppc
+>16    lelong  0x01000012      ppc64
+>16    lelong  0x0000000c      arm
+
+0      string  BC\xc0\xde      LLVM IR bitcode
diff --git a/magic/Magdir/lua b/magic/Magdir/lua
new file mode 100644 (file)
index 0000000..0e47c2f
--- /dev/null
@@ -0,0 +1,22 @@
+
+#------------------------------------------------------------------------------
+# $File: lua,v 1.7 2019/04/19 00:42:27 christos Exp $
+# lua:  file(1) magic for Lua scripting language
+# URL:  https://www.lua.org/
+# From: Reuben Thomas <rrt@sc3d.org>, Seo Sanghyeon <tinuviel@sparcs.kaist.ac.kr>
+
+# Lua scripts
+0      search/1/w      #!\ /usr/bin/lua        Lua script text executable
+!:mime text/x-lua
+0      search/1/w      #!\ /usr/local/bin/lua  Lua script text executable
+!:mime text/x-lua
+0      search/1        #!/usr/bin/env\ lua     Lua script text executable
+!:mime text/x-lua
+0      search/1        #!\ /usr/bin/env\ lua   Lua script text executable
+!:mime text/x-lua
+
+# Lua bytecode
+0      string          \033Lua                 Lua bytecode,
+>4     byte            0x50                    version 5.0
+>4     byte            0x51                    version 5.1
+>4     byte            0x52                    version 5.2
diff --git a/magic/Magdir/luks b/magic/Magdir/luks
new file mode 100644 (file)
index 0000000..c84f84b
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# luks:  file(1) magic for Linux Unified Key Setup
+# URL: http://luks.endorphin.org/spec
+# From:        Anthon van der Neut <anthon@mnt.org>
+
+0      string          LUKS\xba\xbe    LUKS encrypted file,
+>6     beshort         x               ver %d
+>8     string          x               [%s,
+>40    string          x               %s,
+>72    string          x               %s]
+>168   string          x               UUID: %s
diff --git a/magic/Magdir/m4 b/magic/Magdir/m4
new file mode 100644 (file)
index 0000000..587ebe8
--- /dev/null
@@ -0,0 +1,11 @@
+#------------------------------------------------------------------------------
+# $File: m4,v 1.3 2019/02/27 16:46:23 christos Exp $
+# make:  file(1) magic for M4 scripts
+#
+0      search/8192     dnl
+>0     regex   \^dnl\          M4 macro processor script text
+!:mime text/x-m4
+0      search/8192     AC_DEFUN
+>0     regex   \^AC_DEFUN\\(\\[        M4 macro processor script text
+!:strength + 15
+!:mime text/x-m4
diff --git a/magic/Magdir/mach b/magic/Magdir/mach
new file mode 100644 (file)
index 0000000..86ca609
--- /dev/null
@@ -0,0 +1,251 @@
+
+#------------------------------------------------------------
+# $File: mach,v 1.22 2015/10/15 16:54:01 christos Exp $
+# Mach has two magic numbers, 0xcafebabe and 0xfeedface.
+# Unfortunately the first, cafebabe, is shared with
+# Java ByteCode, so they are both handled in the file "cafebabe".
+# The "feedface" ones are handled herein.
+#------------------------------------------------------------
+# if set, it's for the 64-bit version of the architecture
+# yes, this is separate from the low-order magic number bit
+# it's also separate from the "64-bit libraries" bit in the
+# upper 8 bits of the CPU subtype
+
+0      name    mach-o-cpu
+>0     belong&0x01000000       0
+#
+# 32-bit ABIs.
+#
+#                              1       vax
+>>0    belong&0x00ffffff       1
+>>>4           belong&0x00ffffff       0       vax
+>>>4           belong&0x00ffffff       1       vax11/780
+>>>4           belong&0x00ffffff       2       vax11/785
+>>>4           belong&0x00ffffff       3       vax11/750
+>>>4           belong&0x00ffffff       4       vax11/730
+>>>4           belong&0x00ffffff       5       uvaxI
+>>>4           belong&0x00ffffff       6       uvaxII
+>>>4           belong&0x00ffffff       7       vax8200
+>>>4           belong&0x00ffffff       8       vax8500
+>>>4           belong&0x00ffffff       9       vax8600
+>>>4           belong&0x00ffffff       10      vax8650
+>>>4           belong&0x00ffffff       11      vax8800
+>>>4           belong&0x00ffffff       12      uvaxIII
+>>>4           belong&0x00ffffff       >12     vax subarchitecture=%d
+>>0    belong&0x00ffffff       2       romp
+>>0    belong&0x00ffffff       3       architecture=3
+>>0    belong&0x00ffffff       4       ns32032
+>>0    belong&0x00ffffff       5       ns32332
+>>0    belong&0x00ffffff       6       m68k
+#                              7       x86
+>>0    belong&0x00ffffff       7
+>>>4   belong&0x0000000f       3               i386
+>>>4   belong&0x0000000f       4               i486
+>>>>4  belong&0x00fffff0       0
+>>>>4  belong&0x00fffff0       0x80            \bsx
+>>>4   belong&0x0000000f       5               i586
+>>>4   belong&0x0000000f       6
+>>>>4  belong&0x00fffff0       0               p6
+>>>>4  belong&0x00fffff0       0x10            pentium_pro
+>>>>4  belong&0x00fffff0       0x20            pentium_2_m0x20
+>>>>4  belong&0x00fffff0       0x30            pentium_2_m3
+>>>>4  belong&0x00fffff0       0x40            pentium_2_m0x40
+>>>>4  belong&0x00fffff0       0x50            pentium_2_m5
+>>>>4  belong&0x00fffff0       >0x50           pentium_2_m0x%x
+>>>4   belong&0x0000000f       7               celeron
+>>>>4  belong&0x00fffff0       0x00            \b_m0x%x
+>>>>4  belong&0x00fffff0       0x10            \b_m0x%x
+>>>>4  belong&0x00fffff0       0x20            \b_m0x%x
+>>>>4  belong&0x00fffff0       0x30            \b_m0x%x
+>>>>4  belong&0x00fffff0       0x40            \b_m0x%x
+>>>>4  belong&0x00fffff0       0x50            \b_m0x%x
+>>>>4  belong&0x00fffff0       0x60
+>>>>4  belong&0x00fffff0       0x70            \b_mobile
+>>>>4  belong&0x00fffff0       >0x70           \b_m0x%x
+>>>4   belong&0x0000000f       8               pentium_3
+>>>>4  belong&0x00fffff0       0x00
+>>>>4  belong&0x00fffff0       0x10            \b_m
+>>>>4  belong&0x00fffff0       0x20            \b_xeon
+>>>>4  belong&0x00fffff0       >0x20           \b_m0x%x
+>>>4   belong&0x0000000f       9               pentiumM
+>>>>4  belong&0x00fffff0       0x00
+>>>>4  belong&0x00fffff0       >0x00           \b_m0x%x
+>>>4   belong&0x0000000f       10              pentium_4
+>>>>4  belong&0x00fffff0       0x00
+>>>>4  belong&0x00fffff0       0x10            \b_m
+>>>>4  belong&0x00fffff0       >0x10           \b_m0x%x
+>>>4   belong&0x0000000f       11              itanium
+>>>>4  belong&0x00fffff0       0x00
+>>>>4  belong&0x00fffff0       0x10            \b_2
+>>>>4  belong&0x00fffff0       >0x10           \b_m0x%x
+>>>4   belong&0x0000000f       12              xeon
+>>>>4  belong&0x00fffff0       0x00
+>>>>4  belong&0x00fffff0       0x10            \b_mp
+>>>>4  belong&0x00fffff0       >0x10           \b_m0x%x
+>>>4   belong&0x0000000f       >12             ia32 family=%d
+>>>>4  belong&0x00fffff0       0x00
+>>>>4  belong&0x00fffff0       >0x00           model=%x
+>>0    belong&0x00ffffff       8       mips
+>>>4           belong&0x00ffffff       1       R2300
+>>>4           belong&0x00ffffff       2       R2600
+>>>4           belong&0x00ffffff       3       R2800
+>>>4           belong&0x00ffffff       4       R2000a
+>>>4           belong&0x00ffffff       5       R2000
+>>>4           belong&0x00ffffff       6       R3000a
+>>>4           belong&0x00ffffff       7       R3000
+>>>4           belong&0x00ffffff       >7      subarchitecture=%d
+>>0    belong&0x00ffffff       9       ns32532
+>>0    belong&0x00ffffff       10      mc98000
+>>0    belong&0x00ffffff       11      hppa
+>>>4           belong&0x00ffffff       0       7100
+>>>4           belong&0x00ffffff       1       7100LC
+>>>4           belong&0x00ffffff       >1      subarchitecture=%d
+>>0    belong&0x00ffffff       12      arm
+>>>4           belong&0x00ffffff       0
+>>>4           belong&0x00ffffff       1       subarchitecture=%d
+>>>4           belong&0x00ffffff       2       subarchitecture=%d
+>>>4           belong&0x00ffffff       3       subarchitecture=%d
+>>>4           belong&0x00ffffff       4       subarchitecture=%d
+>>>4           belong&0x00ffffff       5       \bv4t
+>>>4           belong&0x00ffffff       6       \bv6
+>>>4           belong&0x00ffffff       7       \bv5tej
+>>>4           belong&0x00ffffff       8       \bxscale
+>>>4           belong&0x00ffffff       9       \bv7
+>>>4           belong&0x00ffffff       10      \bv7f
+>>>4           belong&0x00ffffff       11      \bv7s
+>>>4           belong&0x00ffffff       12      \bv7k
+>>>4           belong&0x00ffffff       13      \bv8
+>>>4           belong&0x00ffffff       14      \bv6m
+>>>4           belong&0x00ffffff       15      \bv7m
+>>>4           belong&0x00ffffff       16      \bv7em
+>>>4           belong&0x00ffffff       >16     subarchitecture=%d
+#                              13      m88k
+>>0    belong&0x00ffffff       13
+>>>4           belong&0x00ffffff       0       mc88000
+>>>4           belong&0x00ffffff       1       mc88100
+>>>4           belong&0x00ffffff       2       mc88110
+>>>4           belong&0x00ffffff       >2      mc88000 subarchitecture=%d
+>>0    belong&0x00ffffff       14      SPARC
+>>0    belong&0x00ffffff       15      i860g
+>>0    belong&0x00ffffff       16      alpha
+>>0    belong&0x00ffffff       17      rs6000
+>>0    belong&0x00ffffff       18      ppc
+>>>4           belong&0x00ffffff       0
+>>>4           belong&0x00ffffff       1       \b_601
+>>>4           belong&0x00ffffff       2       \b_602
+>>>4           belong&0x00ffffff       3       \b_603
+>>>4           belong&0x00ffffff       4       \b_603e
+>>>4           belong&0x00ffffff       5       \b_603ev
+>>>4           belong&0x00ffffff       6       \b_604
+>>>4           belong&0x00ffffff       7       \b_604e
+>>>4           belong&0x00ffffff       8       \b_620
+>>>4           belong&0x00ffffff       9       \b_650
+>>>4           belong&0x00ffffff       10      \b_7400
+>>>4           belong&0x00ffffff       11      \b_7450
+>>>4           belong&0x00ffffff       100     \b_970
+>>>4           belong&0x00ffffff       >100    subarchitecture=%d
+>>0    belong&0x00ffffff       >18     architecture=%d
+>0     belong&0x01000000       0x01000000
+#
+# 64-bit ABIs.
+#
+>>0    belong&0x00ffffff       0       64-bit architecture=%d
+>>0    belong&0x00ffffff       1       64-bit architecture=%d
+>>0    belong&0x00ffffff       2       64-bit architecture=%d
+>>0    belong&0x00ffffff       3       64-bit architecture=%d
+>>0    belong&0x00ffffff       4       64-bit architecture=%d
+>>0    belong&0x00ffffff       5       64-bit architecture=%d
+>>0    belong&0x00ffffff       6       64-bit architecture=%d
+>>0    belong&0x00ffffff       7       x86_64
+>>>4           belong&0x00ffffff       0       subarchitecture=%d
+>>>4           belong&0x00ffffff       1       subarchitecture=%d
+>>>4           belong&0x00ffffff       2       subarchitecture=%d
+>>>4           belong&0x00ffffff       3
+>>>4           belong&0x00ffffff       4       \b_arch1
+>>>4           belong&0x00ffffff       8       \b_haswell
+>>>4           belong&0x00ffffff       >4      subarchitecture=%d
+>>0    belong&0x00ffffff       8       64-bit architecture=%d
+>>0    belong&0x00ffffff       9       64-bit architecture=%d
+>>0    belong&0x00ffffff       10      64-bit architecture=%d
+>>0    belong&0x00ffffff       11      64-bit architecture=%d
+>>0    belong&0x00ffffff       12      arm64
+>>>4           belong&0x00ffffff       0
+>>>4           belong&0x00ffffff       1       \bv8
+>>0    belong&0x00ffffff       13      64-bit architecture=%d
+>>0    belong&0x00ffffff       14      64-bit architecture=%d
+>>0    belong&0x00ffffff       15      64-bit architecture=%d
+>>0    belong&0x00ffffff       16      64-bit architecture=%d
+>>0    belong&0x00ffffff       17      64-bit architecture=%d
+>>0    belong&0x00ffffff       18      ppc64
+>>>4           belong&0x00ffffff       0
+>>>4           belong&0x00ffffff       1               \b_601
+>>>4           belong&0x00ffffff       2               \b_602
+>>>4           belong&0x00ffffff       3               \b_603
+>>>4           belong&0x00ffffff       4               \b_603e
+>>>4           belong&0x00ffffff       5               \b_603ev
+>>>4           belong&0x00ffffff       6               \b_604
+>>>4           belong&0x00ffffff       7               \b_604e
+>>>4           belong&0x00ffffff       8               \b_620
+>>>4           belong&0x00ffffff       9               \b_650
+>>>4           belong&0x00ffffff       10              \b_7400
+>>>4           belong&0x00ffffff       11              \b_7450
+>>>4           belong&0x00ffffff       100             \b_970
+>>>4           belong&0x00ffffff       >100            subarchitecture=%d
+>>0    belong&0x00ffffff       >18     64-bit architecture=%d
+
+
+0      name            mach-o-be
+>0     byte            0xcf            64-bit
+>4     use             mach-o-cpu
+>12    belong          1               object
+>12    belong          2               executable
+>12    belong          3               fixed virtual memory shared library
+>12    belong          4               core
+>12    belong          5               preload executable
+>12    belong          6               dynamically linked shared library
+>12    belong          7               dynamic linker
+>12    belong          8               bundle
+>12    belong          9               dynamically linked shared library stub
+>12    belong          10              dSYM companion file
+>12    belong          11              kext bundle
+>12    belong          >11
+>>12   belong          x               filetype=%d
+>24    belong          >0              \b, flags:<
+>>24   belong          &0x0000001      \bNOUNDEFS
+>>24   belong          &0x0000002      \b|INCRLINK
+>>24   belong          &0x0000004      \b|DYLDLINK
+>>24   belong          &0x0000008      \b|BINDATLOAD
+>>24   belong          &0x0000010      \b|PREBOUND
+>>24   belong          &0x0000020      \b|SPLIT_SEGS
+>>24   belong          &0x0000040      \b|LAZY_INIT
+>>24   belong          &0x0000080      \b|TWOLEVEL
+>>24   belong          &0x0000100      \b|FORCE_FLAT
+>>24   belong          &0x0000200      \b|NOMULTIDEFS
+>>24   belong          &0x0000400      \b|NOFIXPREBINDING
+>>24   belong          &0x0000800      \b|PREBINDABLE
+>>24   belong          &0x0001000      \b|ALLMODSBOUND
+>>24   belong          &0x0002000      \b|SUBSECTIONS_VIA_SYMBOLS
+>>24   belong          &0x0004000      \b|CANONICAL
+>>24   belong          &0x0008000      \b|WEAK_DEFINES
+>>24   belong          &0x0010000      \b|BINDS_TO_WEAK
+>>24   belong          &0x0020000      \b|ALLOW_STACK_EXECUTION
+>>24   belong          &0x0040000      \b|ROOT_SAFE
+>>24   belong          &0x0080000      \b|SETUID_SAFE
+>>24   belong          &0x0100000      \b|NO_REEXPORTED_DYLIBS
+>>24   belong          &0x0200000      \b|PIE
+>>24   belong          &0x0400000      \b|DEAD_STRIPPABLE_DYLIB
+>>24   belong          &0x0800000      \b|HAS_TLV_DESCRIPTORS
+>>24   belong          &0x1000000      \b|NO_HEAP_EXECUTION
+>>24   belong          &0x2000000      \b|APP_EXTENSION_SAFE
+>>24   belong          x               \b>
+
+#
+0      lelong&0xfffffffe       0xfeedface      Mach-O
+!:strength +1
+!:mime application/x-mach-binary
+>0     use     \^mach-o-be
+
+0      belong&0xfffffffe       0xfeedface      Mach-O
+!:strength +1
+!:mime application/x-mach-binary
+>0     use     mach-o-be
diff --git a/magic/Magdir/macintosh b/magic/Magdir/macintosh
new file mode 100644 (file)
index 0000000..2a9f7a7
--- /dev/null
@@ -0,0 +1,470 @@
+
+#------------------------------------------------------------------------------
+# $File: macintosh,v 1.29 2019/04/19 00:42:27 christos Exp $
+# macintosh description
+#
+# BinHex is the Macintosh ASCII-encoded file format (see also "apple")
+# Daniel Quinlan, quinlan@yggdrasil.com
+11     string  must\ be\ converted\ with\ BinHex       BinHex binary text
+!:mime application/mac-binhex40
+>41    string  x                                       \b, version %.3s
+
+# Stuffit archives are the de facto standard of compression for Macintosh
+# files obtained from most archives. (franklsm@tuns.ca)
+0      string          SIT!                    StuffIt Archive (data)
+!:mime application/x-stuffit
+!:apple        SIT!SIT!
+>2     string          x                       : %s
+0      string          SITD                    StuffIt Deluxe (data)
+>2     string          x                       : %s
+0      string          Seg                     StuffIt Deluxe Segment (data)
+>2     string          x                       : %s
+
+# Newer StuffIt archives (grant@netbsd.org)
+0      string          StuffIt                 StuffIt Archive
+!:mime application/x-stuffit
+!:apple        SIT!SIT!
+#>162  string          >0                      : %s
+
+# Macintosh Applications and Installation binaries (franklsm@tuns.ca)
+# GRR: Too weak
+#0     string          APPL                    Macintosh Application (data)
+#>2    string          x                       \b: %s
+
+# Macintosh System files (franklsm@tuns.ca)
+# GRR: Too weak
+#0     string          zsys                    Macintosh System File (data)
+#0     string          FNDR                    Macintosh Finder (data)
+#0     string          libr                    Macintosh Library (data)
+#>2    string          x                       : %s
+#0     string          shlb                    Macintosh Shared Library (data)
+#>2    string          x                       : %s
+#0     string          cdev                    Macintosh Control Panel (data)
+#>2    string          x                       : %s
+#0     string          INIT                    Macintosh Extension (data)
+#>2    string          x                       : %s
+#0     string          FFIL                    Macintosh Truetype Font (data)
+#>2    string          x                       : %s
+#0     string          LWFN                    Macintosh Postscript Font (data)
+#>2    string          x                       : %s
+
+# Additional Macintosh Files (franklsm@tuns.ca)
+# GRR: Too weak
+#0     string          PACT                    Macintosh Compact Pro Archive (data)
+#>2    string          x                       : %s
+#0     string          ttro                    Macintosh TeachText File (data)
+#>2    string          x                       : %s
+#0     string          TEXT                    Macintosh TeachText File (data)
+#>2    string          x                       : %s
+#0     string          PDF                     Macintosh PDF File (data)
+#>2    string          x                       : %s
+
+# MacBinary format (Eric Fischer, enf@pobox.com)
+# Update: Joerg Jenderek 
+# URL: https://en.wikipedia.org/wiki/MacBinary
+# Reference: https://files.stairways.com/other/macbinaryii-standard-info.txt
+#
+# Unfortunately MacBinary doesn't really have a magic number prior
+# to the MacBinary III format.
+#
+
+# old version number, must be kept at zero for compatibility
+0      byte    0
+# length of filename (must be in the range 1-63)
+>1     ubyte   >0
+# skip T.PIC.LZ INSTRUMENT.7T INVENTORY
+>>1    ubyte   <64
+# skip Docs.MWII ReadMe.MacWrite "Notes (MacWrite II)"
+# by looking for printable characters at beginning of file name
+>>>2   ubelong >0x1F000000
+# zero fill, must be zero for compatibility
+>>>>74 byte    0
+# zero fill, must be zero for compatibility
+>>>>>82        byte    0
+# MacBinary I          test for valid version numbers
+>>>>>>122      ubeshort        0
+# additional check for creation date after 1 Jan 1970 ~ 7C25B080h
+#>>>>>>>91     ubelong         >0x7c25b07F
+# additional check for undefined header fields in MacBinary I
+#>>>>>>>101    ulong           0
+>>>>>>>0       use     mac-bin
+# MacBinary II         the newer versions begins at 129
+>>>>>>122      ubeshort        0x8181
+>>>>>>>0       use     mac-bin
+# MacBinary III with MacBinary II to read
+>>>>>122       ubeshort        0x8281
+>>>>>>0        use     mac-bin
+
+#      display information of MacBinary file
+0      name            mac-bin
+>122   ubyte   x       MacBinary
+# versions for MacBinary II/III
+>122   ubyte   129             II
+>122   ubyte   130             III
+# only in MacBinary III
+>>102  string  !mBIN           with surprising version
+!:mime application/x-macbinary
+!:apple        PSPTBINA
+!:ext  bin/macbin
+# THIS SHOULD NEVER HAPPEN! Maybe another file type is misidetified as MacBinary
+#>1    ubyte   >63             \b, name length %u too BIG!
+#>122  ubeshort        x       \b, version 0x%x
+# Finder flags if not 0
+# >73  byte            !0              \b, flags 0x
+# >73  byte            =0              
+# >>101        byte            !0              \b, flags 0x
+# # original Finder flags (Bits 8-15)
+# >73  byte            !0              \b%x
+# # finder flags, bits 0-7
+# >101 byte            !0              \b%x
+>73    byte            &0x01           \b, inited
+>73    byte            &0x02           \b, changed
+>73    byte            &0x04           \b, busy
+>73    byte            &0x08           \b, bozo
+>73    byte            &0x10           \b, system
+>73    byte            &0x20           \b, bundle
+>73    byte            &0x40           \b, invisible
+>73    byte            &0x80           \b, locked
+
+# 75   beshort                         # vertical posn in window
+#>75   beshort         !0              \b, v.pos %u
+# 77   beshort                         # horiz posn in window
+#>77   beshort         !0              \b, h.pos %u
+# 79   beshort                         # window or folder ID
+>79    ubeshort        !0              \b, ID 0x%x
+# protected flag
+>81    byte            !0              \b, protected 0x%x
+# length of comment after resource
+>99    ubeshort        !0              \b, comment length %u
+# char. code of file name
+>106   ubyte           !0              \b, char. code 0x%x
+# still more Finder flags
+>107   ubyte           !0              \b, more flags 0x%x
+# length of total files when unpacked only used when pack and unpack on the fly
+>116   ubelong         !0              \b, total length %u
+# 120  beshort                         # length of add'l header
+>120   ubeshort        !0              \b, 2nd header length %u
+# 124  beshort                         # checksum
+#>124  ubeshort        !0              \b, CRC 0x%x
+# creation date in seconds since MacOS epoch start. So 1 Jan 1970 ~ 7C25B080
+>91    beldate-0x7C25B080      x       \b, %s
+# THIS SHOULD NEVER HAPPEN! Maybe another file type is misidetified or time overflow
+>91    ubelong         <0x7c25b080     INVALID date
+#>91   belong-0x7C25B080       x       \b, DEBUG DATE %d
+# last modified date
+>95    beldate-0x7C25B080      x       \b, modified %s
+# Apple creator+typ if not null
+# file creator (normally expressed as four characters)
+>69    ulong                   !0      \b, creator
+# instead 4 character code display full creator name
+>>69   use                     apple-creator
+# file type (normally expressed as four characters)
+>65    ulong                   !0      \b, type
+>>65   use                     apple-type
+# length of data segment
+>83    ubelong                 !0      \b, %u bytes
+# filename (in the range 1-63)
+>1     pstring                 x       "%s"
+# print 1 space and then at offset 128 inspect data fork content if it has one
+>83    ubelong                 !0      \b 
+>>128  indirect                x
+# Afterwards resource fork if length of resource segment not zero
+>87    ubelong                 !0
+# calculate resource fork offset
+>>83   ubelong+128             x       \b, at 0x%x
+# length of resource segment
+>>87   ubelong                 !0      %u bytes
+>>(83.S+128)   ubequad         x       resource 
+# further resource fork content inspection 
+>>>&-8 indirect                x
+
+# Apple Type/Creator Database
+# URL: https://en.wikipedia.org/wiki/Type_code
+# Reference:   https://www.lacikam.co.il/tcdb/
+#              https://www.macdisk.com/macsigen.php
+# Note:        classic Mac OS files have two 4 character codes for type and creator.
+#      Thereby the Finder attach documents types to applications.
+
+#>65   string          x               \b, type "%4.4s"
+
+#      display information about apple type
+0      name            apple-type
+>0     string          8BIM            PhotoShop
+>0     string          ALB3            PageMaker 3
+>0     string          ALB4            PageMaker 4
+>0     string          ALT3            PageMaker 3
+>0     string          APPL            application
+>0     string          AWWP            AppleWorks word processor
+>0     string          CIRC            simulated circuit
+>0     string          DRWG            MacDraw
+>0     string          EPSF            Encapsulated PostScript
+>0     string          FFIL            font suitcase
+>0     string          FKEY            function key
+>0     string          FNDR            Macintosh Finder
+>0     string          GIFf            GIF image
+>0     string          Gzip            GNU gzip
+>0     string          INIT            system extension
+>0     string          LIB\            library
+>0     string          LWFN            PostScript font
+>0     string          MSBC            Microsoft BASIC
+>0     string          PACT            Compact Pro archive
+>0     string          PDF\            Portable Document Format
+>0     string          PICT            picture
+>0     string          PNTG            MacPaint picture
+>0     string          PREF            preferences
+>0     string          PROJ            Think C project
+>0     string          QPRJ            Think Pascal project
+>0     string          SCFL            Defender scores
+>0     string          SCRN            startup screen
+>0     string          SITD            StuffIt Deluxe
+>0     string          SPn3            SuperPaint
+>0     string          STAK            HyperCard stack
+>0     string          Seg\            StuffIt segment
+>0     string          TARF            Unix tar archive
+>0     string          TEXT            ASCII
+>0     string          TIFF            TIFF image
+>0     string          TOVF            Eudora table of contents
+>0     string          WDBN            Microsoft Word word processor
+>0     string          WORD            MacWrite word processor
+>0     string          XLS\            Microsoft Excel
+>0     string          ZIVM            compress (.Z)
+>0     string          ZSYS            Pre-System 7 system file
+>0     string          acf3            Aldus FreeHand
+>0     string          cdev            control panel
+>0     string          dfil            Desk Accessory suitcase
+>0     string          libr            library
+>0     string          nX^d            WriteNow word processor
+>0     string          nX^w            WriteNow dictionary
+>0     string          rsrc            resource
+>0     string          scbk            Scrapbook
+>0     string          shlb            shared library
+>0     string          ttro            SimpleText read-only
+>0     string          zsys            system file
+
+#      additional types added in Dec 2017
+>0     string          BINA            binary file
+>0     string          BMPp            BMP image
+>0     string          JPEG            JPEG image
+#>0    string          W4BN            Microsoft Word x.y word processor?
+# if type name is not known display 4 character identifier
+>0     default         x               
+>>0    string          x               '%4.4s'
+
+#>69   string          x               \b, creator "%4.4s"
+
+# Now Apple has no repository of registered Creator IDs any more. These are
+# just the ones that I happened to have files from and was able to identify.
+
+#      display information about apple creator
+0      name            apple-creator
+>0     string          8BIM            Adobe Photoshop
+>0     string          ALD3            PageMaker 3
+>0     string          ALD4            PageMaker 4
+>0     string          ALFA            Alpha editor
+>0     string          APLS            Apple Scanner
+>0     string          APSC            Apple Scanner
+>0     string          BRKL            Brickles
+>0     string          BTFT            BitFont
+>0     string          CCL2            Common Lisp 2
+>0     string          CCL\            Common Lisp
+>0     string          CDmo            The Talking Moose
+>0     string          CPCT            Compact Pro
+>0     string          CSOm            Eudora
+>0     string          DMOV            Font/DA Mover
+>0     string          DSIM            DigSim
+>0     string          EDIT            Macintosh Edit
+>0     string          ERIK            Macintosh Finder
+>0     string          EXTR            self-extracting archive
+>0     string          Gzip            GNU gzip
+>0     string          KAHL            Think C
+>0     string          LWFU            LaserWriter Utility
+>0     string          LZIV            compress
+>0     string          MACA            MacWrite
+>0     string          MACS            Macintosh operating system
+>0     string          MAcK            MacKnowledge terminal emulator
+>0     string          MLND            Defender
+>0     string          MPNT            MacPaint
+>0     string          MSBB            Microsoft BASIC (binary)
+>0     string          MSWD            Microsoft Word
+>0     string          NCSA            NCSA Telnet
+>0     string          PJMM            Think Pascal
+>0     string          PSAL            Hunt the Wumpus
+#>0    string          PSI2            Apple File Exchange
+>0     string          R*ch            BBEdit
+>0     string          RMKR            Resource Maker
+>0     string          RSED            Resource Editor
+>0     string          Rich            BBEdit
+>0     string          SIT!            StuffIt
+>0     string          SPNT            SuperPaint
+>0     string          Unix            NeXT Mac filesystem
+>0     string          VIM!            Vim editor
+>0     string          WILD            HyperCard
+>0     string          XCEL            Microsoft Excel
+>0     string          aCa2            Fontographer
+>0     string          aca3            Aldus FreeHand
+>0     string          dosa            Macintosh MS-DOS file system
+>0     string          movr            Font/DA Mover
+>0     string          nX^n            WriteNow
+>0     string          pdos            Apple ProDOS file system
+>0     string          scbk            Scrapbook
+>0     string          ttxt            SimpleText
+>0     string          ufox            Foreign File Access
+#      additional creators added in Dec 2017
+# Claris/Apple Works
+>0     string          BOBO            Apple Works
+# CU-SeeMe_0.87b3_(68K).bin
+#>0    string          CUce            bar
+>0     string          PSPT            Apple File Exchange
+# Disk_Copy_4.2.sea.bin
+#>0    string          NCse            foo
+# probably StuffIt/Aladdin by Smith Micro Software, Inc.
+>0     string          STi0            stuffit
+# MacGzip-1.1.3.sea.bin
+#>0    string          aust            bar
+# D-Disk_Copy_6.3.3.smi.bin 
+>0     string          oneb            Disk Copy Self Mounting
+# if creator name is not known display 4 character identifier
+>0     default         x               
+>>0    string          x               '%4.4s'
+
+# sas magic from Bruce Foster (bef@nwu.edu)
+#
+#0     string          SAS             SAS
+#>8    string          x               %s
+0      string          SAS             SAS
+>24    string          DATA            data file
+>24    string          CATALOG         catalog
+>24    string          INDEX           data file index
+>24    string          VIEW            data view
+# sas 7+ magic from Reinhold Koch (reinhold.koch@roche.com)
+#
+0x54    string          SAS             SAS 7+
+>0x9C   string          DATA            data file
+>0x9C   string          CATALOG         catalog
+>0x9C   string          INDEX           data file index
+>0x9C   string          VIEW            data view
+
+# spss magic for SPSS system and portable files,
+#       from Bruce Foster (bef@nwu.edu).
+
+0      long            0xc1e2c3c9      SPSS Portable File
+>40    string          x               %s
+
+0      string          $FL2            SPSS System File
+>24    string          x               %s
+
+0      string          $FL3            SPSS System File
+>24    string          x               %s
+
+# Macintosh filesystem data
+# From "Tom N Harris" <telliamed@mac.com>
+# Fixed HFS+ and Partition map magic: Ethan Benson <erbenson@alaska.net>
+# The MacOS epoch begins on 1 Jan 1904 instead of 1 Jan 1970, so these
+# entries depend on the data arithmetic added after v.35
+# There's also some Pascal strings in here, ditto...
+
+# The boot block signature, according to IM:Files, is
+# "for HFS volumes, this field always contains the value 0x4C4B."
+# But if this is true for MFS or HFS+ volumes, I don't know.
+# Alternatively, the boot block is supposed to be zeroed if it's
+# unused, so a simply >0 should suffice.
+
+0x400  beshort                 0xD2D7          Macintosh MFS data
+>0     beshort                 0x4C4B          (bootable)
+>0x40a beshort                 &0x8000         (locked)
+>0x402 beldate-0x7C25B080      x               created: %s,
+>0x406 beldate-0x7C25B080      >0              last backup: %s,
+>0x414 belong                  x               block size: %d,
+>0x412 beshort                 x               number of blocks: %d,
+>0x424 pstring                 x               volume name: %s
+
+# *.hfs updated by Joerg Jenderek
+# https://en.wikipedia.org/wiki/Hierarchical_File_System
+# "BD" gives many false positives
+0x400  beshort                 0x4244
+# ftp://ftp.mars.org/pub/hfs/hfsutils-3.2.6.tar.gz/hfsutils-3.2.6/libhfs/apple.h
+# first block of volume bit map (always 3)
+>0x40e ubeshort                0x0003
+# maximal length of volume name is 27
+>>0x424                ubyte                   <28     Macintosh HFS data
+!:mime application/x-apple-diskimage
+#!:apple       hfsdINIT
+#!:apple       MACSdisk
+# https://www.macdisk.com/macsigen.php
+#!:apple       ddskdevi
+!:apple        ????devi
+# https://en.wikipedia.org/wiki/Apple_Disk_Image
+!:ext hfs/dmg
+>>>0           beshort                 0x4C4B  (bootable)
+#>>>0          beshort                 0x0000  (not bootable)
+>>>0x40a       beshort                 &0x8000 (locked)
+>>>0x40a       beshort                 ^0x0100 (mounted)
+>>>0x40a       beshort                 &0x0200 (spared blocks)
+>>>0x40a       beshort                 &0x0800 (unclean)
+>>>0x47C       beshort                 0x482B  (Embedded HFS+ Volume)
+# https://www.epochconverter.com/
+# 0x7C245F00 seconds   ~ 2082758400    ~ 01 Jan 2036 00:00:00  ~ 66 years to 1970
+# 0x7C25B080 seconds   ~ 2082844800    ~ 02 Jan 2036 00:00:00
+# construct not working
+#>>>0x402      beldate-0x7C25B080      x       created: %s,
+#>>>0x406      beldate-0x7C25B080      x       last modified: %s,
+#>>>0x440      beldate-0x7C25B080      >0      last backup: %s,
+# found block sizes 200h,1200h,2800h
+>>>0x414       belong                  x       block size: %d,
+>>>0x412       beshort                 x       number of blocks: %d,
+>>>0x424       pstring                 x       volume name: %s
+
+0x400  beshort                 0x482B          Macintosh HFS Extended
+>&0    beshort                 x               version %d data
+>0     beshort                 0x4C4B          (bootable)
+>0x404 belong                  ^0x00000100     (mounted)
+>&2    belong                  &0x00000200     (spared blocks)
+>&2    belong                  &0x00000800     (unclean)
+>&2    belong                  &0x00008000     (locked)
+>&6    string                  x               last mounted by: '%.4s',
+# really, that should be treated as a belong and we print a string
+# based on the value. TN1150 only mentions '8.10' for "MacOS 8.1"
+>&14   beldate-0x7C25B080      x               created: %s,
+# only the creation date is local time, all other timestamps in HFS+ are UTC.
+>&18   bedate-0x7C25B080       x               last modified: %s,
+>&22   bedate-0x7C25B080       >0              last backup: %s,
+>&26   bedate-0x7C25B080       >0              last checked: %s,
+>&38   belong                  x               block size: %d,
+>&42   belong                  x               number of blocks: %d,
+>&46   belong                  x               free blocks: %d
+
+## AFAIK, only the signature is different
+# same as Apple Partition Map
+# GRR: This magic is too weak, it is just "TS"
+#0x200         beshort         0x5453          Apple Old Partition data
+#>0x2          beshort         x               block size: %d,
+#>0x230                string          x               first type: %s,
+#>0x210                string          x               name: %s,
+#>0x254                belong          x               number of blocks: %d,
+#>0x400                beshort         0x504D
+#>>0x430               string          x               second type: %s,
+#>>0x410               string          x               name: %s,
+#>>0x454               belong          x               number of blocks: %d,
+#>>0x800               beshort         0x504D
+#>>>0x830      string          x               third type: %s,
+#>>>0x810      string          x               name: %s,
+#>>>0x854      belong          x               number of blocks: %d,
+#>>>0xa00      beshort         0x504D
+#>>>>0xa30     string          x               fourth type: %s,
+#>>>>0xa10     string          x               name: %s,
+#>>>>0xa54     belong          x               number of blocks: %d
+
+# From: Remi Mommsen <mommsen@slac.stanford.edu>
+0              string          BOMStore        Mac OS X bill of materials (BOM) file
+
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# URL: https://en.wikipedia.org/wiki/Datafork_TrueType
+# Derived from the 'fondu' and 'ufond' source code (fondu.sf.net). 'sfnt' is
+# TrueType; 'POST' is PostScript. 'FONT' and 'NFNT' sometimes appear, but I
+# don't know what they mean.
+0      belong  0x100
+>(0x4.L+24)    beshort x
+>>&4   belong  0x73666e74      Mac OSX datafork font, TrueType
+>>&4   belong  0x464f4e54      Mac OSX datafork font, 'FONT'
+>>&4   belong  0x4e464e54      Mac OSX datafork font, 'NFNT'
+>>&4   belong  0x504f5354      Mac OSX datafork font, PostScript
diff --git a/magic/Magdir/macos b/magic/Magdir/macos
new file mode 100644 (file)
index 0000000..2dd0e3f
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File: cups,v 1.2 2012/11/02 21:50:29 christos Exp $
+# MacOS files
+#
+
+0      string          book\0\0\0\0mark\0\0\0\0        MacOS Alias file
diff --git a/magic/Magdir/magic b/magic/Magdir/magic
new file mode 100644 (file)
index 0000000..2d39ed3
--- /dev/null
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# $File: magic,v 1.9 2009/09/19 16:28:10 christos Exp $
+# magic:  file(1) magic for magic files
+#
+0      string/t                #\ Magic        magic text file for file(1) cmd
+0      lelong          0xF11E041C      magic binary file for file(1) cmd
+>4     lelong          x               (version %d) (little endian)
+0      belong          0xF11E041C      magic binary file for file(1) cmd
+>4     belong          x               (version %d) (big endian)
diff --git a/magic/Magdir/mail.news b/magic/Magdir/mail.news
new file mode 100644 (file)
index 0000000..c58b371
--- /dev/null
@@ -0,0 +1,68 @@
+#------------------------------------------------------------------------------
+# $File: mail.news,v 1.24 2019/04/19 00:42:27 christos Exp $
+# mail.news:  file(1) magic for mail and news
+#
+# Unfortunately, saved netnews also has From line added in some news software.
+#0     string          From            mail text
+0      string/t                Relay-Version:  old news text
+!:mime message/rfc822
+0      string/t                #!\ rnews       batched news text
+!:mime message/rfc822
+0      string/t                N#!\ rnews      mailed, batched news text
+!:mime message/rfc822
+0      string/t                Forward\ to     mail forwarding text
+!:mime message/rfc822
+0      string/t                Pipe\ to        mail piping text
+!:mime message/rfc822
+0      string/tc               delivered-to:   SMTP mail text
+!:mime message/rfc822
+0      string/tc               return-path:    SMTP mail text
+!:mime message/rfc822
+0      string/t                Path:           news text
+!:mime message/news
+0      string/t                Xref:           news text
+!:mime message/news
+0      string/t                From:           news or mail text
+!:mime message/rfc822
+0      string/t                Article         saved news text
+!:mime message/news
+0      string/t                BABYL           Emacs RMAIL text
+0      string/t                Received:       RFC 822 mail text
+!:mime message/rfc822
+0      string/t                MIME-Version:   MIME entity text
+#0     string/t                Content-        MIME entity text
+
+# TNEF files...
+0      lelong          0x223E9F78      Transport Neutral Encapsulation Format
+!:mime application/vnd.ms-tnef
+
+# From: Kevin Sullivan <ksulliva@psc.edu>
+0      string          *mbx*           MBX mail folder
+
+# From: Simon Matter <simon.matter@invoca.ch>
+0      string          \241\002\213\015skiplist\ file\0\0\0    Cyrus skiplist DB
+0      string          \241\002\213\015twoskip\ file\0\0\0\0   Cyrus twoskip DB
+
+# JAM(mbp) Fidonet message area databases
+# JHR file
+0      string  JAM\0                   JAM message area header file
+>12    leshort >0                      (%d messages)
+
+# Squish Fidonet message area databases
+# SQD file (requires at least one message in the area)
+# XXX: Weak magic
+#256   leshort 0xAFAE4453              Squish message area data file
+#>4    leshort >0                      (%d messages)
+
+#0     string          \<!--\ MHonArc          text/html; x-type=mhonarc
+
+# Cyrus: file(1) magic for compiled Cyrus sieve scripts
+# URL: https://www.cyrusimap.org/docs/cyrus-imapd/2.4.6/internal/bytecode.php
+# URL: http://git.cyrusimap.org/cyrus-imapd/tree/sieve/bytecode.h?h=master
+# From: Philipp Hahn <hahn@univention.de>
+
+# Compiled Cyrus sieve script
+0       string CyrSBytecode     Cyrus sieve bytecode data,
+>12     belong =1       version 1, big-endian
+>12     lelong =1       version 1, little-endian
+>12     belong x        version %d, network-endian
diff --git a/magic/Magdir/make b/magic/Magdir/make
new file mode 100644 (file)
index 0000000..f522b4f
--- /dev/null
@@ -0,0 +1,36 @@
+#------------------------------------------------------------------------------
+# $File: make,v 1.4 2018/05/29 17:26:02 christos Exp $
+# make:  file(1) magic for makefiles
+#
+# URL: https://en.wikipedia.org/wiki/Make_(software)
+0      regex/100l      \^CFLAGS        makefile script text
+!:mime text/x-makefile
+0      regex/100l      \^VPATH         makefile script text
+!:mime text/x-makefile
+0      regex/100l      \^LDFLAGS       makefile script text
+!:mime text/x-makefile
+0      regex/100l      \^all:          makefile script text
+!:mime text/x-makefile
+0      regex/100l      \^\\.PRECIOUS   makefile script text
+!:mime text/x-makefile
+# Update: Joerg Jenderek
+# Reference: https://www.freebsd.org/cgi/man.cgi?make(1)
+# exclude grub-core\lib\libgcrypt\mpi\Makefile.am with "#BEGIN_ASM_LIST"
+# by additional escaping point character
+0      regex/100l      \^\\.BEGIN      BSD makefile script text
+!:mime text/x-makefile
+!:ext  /mk
+!:strength +10
+# exclude MS Windows help file CoNtenT with ":include FOOBAR.CNT"
+# and NSIS script with "!include" by additional escaping point character
+0      regex/100l      \^\\.include    BSD makefile script text
+!:mime text/x-makefile
+!:ext  /mk
+!:strength +10
+0      regex/100l      \^\\.endif      BSD makefile script text
+!:mime text/x-makefile
+!:ext  /mk
+!:strength +10
+0      regex/100l      \^SUBDIRS       automake makefile script text
+!:mime text/x-makefile
+!:strength +10
diff --git a/magic/Magdir/map b/magic/Magdir/map
new file mode 100644 (file)
index 0000000..af5f24e
--- /dev/null
@@ -0,0 +1,331 @@
+
+
+#------------------------------------------------------------------------------
+# $File: map,v 1.7 2019/04/30 04:02:04 christos Exp $
+# map:  file(1) magic for Map data
+#
+
+# Garmin .FIT files https://pub.ks-and-ks.ne.jp/cycling/edge500_fit.shtml
+8      string  .FIT            FIT Map data
+>15    byte    0
+>>35   belong  x               \b, unit id %d
+>>39   lelong  x               \b, serial %u
+# https://pub.ks-and-ks.ne.jp/cycling/edge500_fit.shtml
+# 20 years after unix epoch
+# TZ=GMT date -d '1989-12-31 0:00' +%s
+>>43   leldate+631065600       x       \b, %s
+
+>>47   leshort x               \b, manufacturer %d
+>>47   leshort 1               \b (garmin)
+>>49   leshort x               \b, product %d
+>>53   byte    x               \b, type %d
+>>53   byte    1               \b (Device)
+>>53   byte    2               \b (Settings)
+>>53   byte    3               \b (Sports/Cycling)
+>>53   byte    4               \b (Activity)
+>>53   byte    8               \b (Elevations)
+>>53   byte    10              \b (Totals)
+
+# Summary: Garmin map
+# From:        Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Garmin_.img
+# Reference: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/IMG_File_Format
+# sourceforge.net/projects/garmin-img/files/IMG%20File%20Format/1.0/imgformat-1.0.pdf
+# GRR: similar to MBR boot sector handled by ./filesystems
+0x1FE  leshort         =0xAA55
+# look for valid map signature
+>0x13  string          =IMG\0
+>>0    use             garmin-map
+0      name                            garmin-map
+>0     ubyte           x               Garmin
+!:mime application/x-garmin-map
+# If non-zero, every byte of the entire .img file is to be XORed with this value
+>0     ubyte           !0              \b, 0x%x XORed
+# goto block before FAT
+>(0x40.b*512)  ubyte   x
+# 1st fat name "DLLINFO TXT" only found for vpm
+>>&512                 string  =DLLINFO\ TXT   map (Voice Processing)
+# there exist 2 other Garmin VPM formats; see ./audio
+!:ext  vpm
+# Deutsch__Yannick_D4481-00_0210.vpm
+#>>>512        search/0x0116da60/s     RIFF    \b; with
+# determine type voice type by ./riff
+#>>>>&0        indirect        x       \b
+>>&512                 string  !DLLINFO\ TXT   map
+!:ext  img
+# 9 zeros
+>1     ubelong         !0              \b, zeroes 0x%x
+# Map's version major
+>8     ubyte           x               v%u
+# Map's version minor
+>9     ubyte           x               \b.%.2u
+# Map description[20], 0x20 padded
+>0x49  string          x               %.20s
+# Map name, continued (0x20 padded, \0 terminated)
+>0x65  string          >\              \b%.31s
+# Update year (+1900 for val >= 0x63, +2000 for val <= 0x62)
+>0xB   ubyte           x               \b, updated
+>>0xB  ubyte           >0x62
+>>>0xB ubyte-100       x               20%.2u
+>>0xB  ubyte           <0x63
+>>>0xB ubyte           x               20%.2u
+# Update month (0-11)
+>0xA   ubyte           x               \b-%.2u
+# All zeroes
+>0xc   uleshort        !0              \b, zeroes 0x%x
+# Mapsource flag, 1 - file created by Mapsource, 0 - Garmin map visible in Basecamp and Homeport 
+#>0xE  ubyte           !0              \b, Mapsource flag 0x%x
+>0xE   ubyte           1               \b, Mapsource
+# Checksum, sum of all bytes modulo 256 should be 0
+#>0xF  ubyte           x               \b, Checksum 0x%x
+# Signature: DSKIMG 0x00 or DSDIMG 0x00 for demo map 
+>0x10  string          !DSKIMG         \b, signature "%.7s"
+>0x39  use             garmin-date
+# Map file identifier like GARMIN\0
+>0x41  string          !GARMIN         \b, id "%.7s"
+# Block size exponent, E1; appears to always be 0x09; minimum block size 512 bytes
+>0x61  ubyte           !0x09           \b, E1=%u
+# Block size exponent, E2 ; file blocksize=2**(E1+E2)
+>>0x62 ubyte           x               \b, E2=%u
+>0x61  ubyte           =0x09           \b, blocksize
+>>0x62 ubyte           0               512
+>>0x62 ubyte           1               1024
+>>0x62 ubyte           2               2048
+>>0x62 ubyte           3               4096
+>>0x62 ubyte           4               8192
+>>0x62 ubyte           5               16384
+>>0x62 default         x
+>>>0x62        ubyte           x               E2=%u
+# MBR signature
+>0x1FE leshort         !0xAA55         \b, invalid MBR
+# 512 zeros
+>0x200         uquad           !0              \b, zeroes 0x%llx
+# First sub-file offset (absolute); sometimes NO/UNKNOWN sub file!
+>0x40C ulelong         >0              \b, at 0x%x
+# sub-file Header length
+#>>(0x40C.l)   uleshort        x       \b, header len 0x%x
+>>(0x40C.l)    uleshort        x       %u bytes
+# sub-file Type[10] like "GARMIN RGN" "GARMIN TRE", "GARMIN TYP", etc.
+>>(0x40C.l+2)  ubyte   >0x1F
+>>>(0x40C.l+2) ubyte   <0xFF
+>>>>(0x40C.l+2)        string  x               "%.10s"
+# 0x00 for most maps, 0x80 for locked maps (City Nav, City Select, etc.) 
+>>>>(0x40C.l+13)       ubyte   >0              \b, locked 0x%x
+# Block sequence numbers like 0000 0100 0200 ... FFFF
+# >0x420       ubequad         >0      \b, seq. 0x%16.16llx
+# >>0x428      ubequad         >0      \b%16.16llx
+# >>>0x430     ubequad >0      \b%16.16llx
+# >>>>0x438    ubequad >0      \b%16.16llx
+# >>>>>0x440   ubequad >0      \b%16.16llx
+# >>>>>>0x448  ubequad >0      \b%16.16llx
+# >>>>>>>0x450 ubequad >0      \b%16.16llx
+# >>>>>>>>0x458        ubequad >0      \b%16.16llx
+# >>>>>>>>>0x460       ubequad >0      \b%16.16llx
+# >>>>>>>>>>0x468      ubequad >0      \b%16.16llx
+# >>>>>>>>>>>0x470     ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>0x478    ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>0x480   ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>0x488  ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>0x490 ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>>0x498        ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>>>0x4A0       ubequad >0      \b%16.16llx
+# >>>>>>>>>>>>>>>>>>0x4A8      ubequad >0      \b%16.16llx
+# look for end of FAT
+#>>0x420       search/512/s    \xff\xff        FAT END
+# Physical block number of FAT header
+#>0x40 ubyte           x               \b, FAT at phy. block %u
+>0x40  ubyte           x
+>>(0x40.b*512) ubyte   x
+# 1st FAT block
+>>>&511        use     garmin-fat
+# 2nd FAT block
+>>>&1023       use     garmin-fat
+# 3th FAT block
+>>>&1535       use     garmin-fat
+# 4th FAT block
+>>>&2047       use     garmin-fat
+# ... xth FAT block
+#
+# 314 zeros but not in vpm and also gmaptz.img
+>0x84  uquad           !0              \b, at 0x84 0x%llx
+# display FileAllocationTable block entry in garmin map
+0      name                            garmin-fat
+>0     ubyte           x               \b;
+# sub file part; 0x0003 seems to be garbage
+>0x10  uleshort        !0              next 0x%4.4x
+>0x10  uleshort        =0
+# fat flag 0~dummy block 1~true sub file
+>>0    ubyte           !1              flag %u 
+>>0    ubyte           =1
+# sub-file name like MAKEGMAP 12345678
+>>>0x1 string          x               %.8s
+# sub-file typ like RGN TRE MDR LBL
+>>>0x9 string          x               \b.%.3s
+# size of sub file
+>>>0xC ulelong         x               \b, %u bytes
+# 32-bit block sequence numbers
+#>>>0x20       ubequad         x               \b, seq. 0x%16.16llx
+
+#      display date stored inside Garmin maps like yyyy-mm-dd h:mm:ss
+0      name                            garmin-date
+# year like 2018
+>0     uleshort        x               \b, created %u
+# month (0-11)
+>2     ubyte           x               \b-%.2u
+# day (1-31)
+>3     ubyte           x               \b-%.2u
+# hour (0-23)
+>4     ubyte           x               %u
+# minute (0-59)
+>5     ubyte           x               \b:%.2u
+# second (0-59)
+>6     ubyte           x               \b:%.2u
+
+# Summary: Garmin Map subfiles
+# From:        Joerg Jenderek
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/IMG_File_Format
+# Garmin Common Header
+2      string  GARMIN\ 
+# skip ASCII text by checking for low header length
+>0     uleshort <0x1000        Garmin map,
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/GMP_Subfile_Format
+>>9    string  GMP                             subtile
+!:mime                 application/x-garmin-gpm
+!:ext                  gmp
+# copyright message
+>>>(0.s)               string          x       %s
+>>>0x0E                use             garmin-date
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/MDR_Subfile_Format
+# This contains the searchable address table used for finding routing destinations
+>>9    string  MDR                             address table
+!:mime                 application/x-garmin-mdr
+!:ext                  mdr
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/NOD_Subfile_Format
+# http://svn.parabola.me.uk/display/trunk/doc/nod.txt
+# This contains the routing information
+>>9    string  NOD                             routing
+!:mime                 application/x-garmin-nod
+!:ext                  nod
+>>>0x0E                use             garmin-date
+#>>>0x15                       ulelong         x       \b, at 0x%x
+#>>>0x19                       ulelong         x       0x%x bytes NOD1
+#>>>0x25                       ulelong         x       \b, at 0x%x
+#>>>0x29                       ulelong         x       0x%x bytes NOD2
+#>>>0x31                       ulelong         x       \b, at 0x%x
+#>>>0x35                       ulelong         x       0x%x bytes NOD3
+# URL: http://www.pinns.co.uk/osm/net.html
+# routable highways (length, direction, allowed speed,house address information)
+>>9    string  NET                             highways
+!:mime                 application/x-garmin-net
+!:ext                  net
+#>>>0x15                       ulelong         x       \b, at 0x%x
+#>>>0x19                       ulelong         x       0x%x bytes NET1
+#>>>0x22                       ulelong         >0
+#>>>>0x1E              ulelong         x       \b, at 0x%x
+#>>>>0x22              ulelong         x       0x%x bytes NET2
+#>>>0x2B                       ulelong         >0
+#>>>>0x27              ulelong         x       \b, at 0x%x
+#>>>>0x2B              ulelong         x       0x%x bytes NET3
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/LBL_Subfile_Format
+>>9    string  LBL                             labels
+!:mime                 application/x-garmin-lbl
+!:ext                  lbl
+>>>(0.s)               string  x       %s
+# Label coding type 6h 9h and ah
+>>>0x1E                        ubyte           x       \b, coding type 0x%x
+#>>>0x15                       ulelong         x       \b, at 0x%x
+#>>>0x19                       ulelong         x       0x%x bytes LBL1
+#>>>0x1F                       ulelong         x       \b, at 0x%x
+#>>>0x23                       ulelong         x       0x%x bytes LBL2
+#>>>0x2D                       ulelong         x       \b, at 0x%x
+#>>>0x31                       ulelong         x       0x%x bytes LBL3
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/SRT_Subfile_Format
+# A lookup table of the chars in the map's codepage, and their collating sequence
+>>9    string  SRT                             sort table
+!:mime                 application/x-garmin-srt
+!:ext                  srt
+>>>0x0E                use             garmin-date
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/TRE_Subfile_Format
+>>9    string  TRE                             tree
+!:mime                 application/x-garmin-tre
+!:ext                  tre
+# title like City Nav Europe NTU 2019.2 Basemap
+# or OSM Street map
+>>>(0.s)               string          x       %s
+# 2nd title like Copyright 1995-2018 by GARMIN Corporation.
+# or http://www.openstreetmap.org/
+>>>>&1                 string          x       %s
+>>>0x0E                use             garmin-date
+#>>>0x21                       ulelong         x       \b, at 0x%x
+#>>>0x25                       ulelong         x       0x%x bytes TRE1
+#>>>0x29                       ulelong         x       \b, at 0x%x
+#>>>0x2D                       ulelong         x       0x%x bytes TRE2
+#>>>0x31                       ulelong         x       \b, at 0x%x
+#>>>0x35                       ulelong         x       0x%x bytes TRE3
+# Copyright record size
+#>>>0x39                       uleshort        x       \b, copyright record size %u
+# Map ID
+>>>0x74                        ulelong         x       \b, ID 0x%x
+# URL: https://www.gpspower.net/garmin-tutorials/353310-basecamp-installing-free-desktop-map.html
+# For road traffic information service (RDS/TMS/TMC). Commonly seen in City Navigator maps
+>>9    string  TRF                             traffic,
+!:mime                 application/x-garmin-trf
+!:ext                  trf
+# city/region like Preitenegg
+>>>(0.s+1)             string          x       1st %s
+# highway part like L606/L148
+>>>>&1                 string          x       %s
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/Format
+# Reference: http://www.pinns.co.uk/osm/typformat.html
+# customize the appearance of objects. For GPS and MapSource/Qlandkarte better looking maps
+>>9    string  TYP                             types
+!:mime                 application/x-garmin-typ
+!:ext                  typ
+>>>0x0E                use             garmin-date
+# character set 1252 65001~UTF8
+>>>0x15                        uleshort        x       \b, code page %u
+# POIs
+#>>>0x17                       ulelong         x       \b, at 0x%x
+#>>>0x1B                       ulelong         x       0x%x bytes TYP1
+# extra pois
+#>>>0x5B                       ulelong         x       \b, at 0x%x
+#>>>0x5F                       ulelong         x       0x%x bytes TYP8
+# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/RGN_Subfile_Format
+# http://www.pinns.co.uk/osm/RGN.html
+# region data used by the Garmin software
+>>9    string  RGN                             region
+!:mime                 application/x-garmin-rgn
+!:ext                  rgn
+# POIs,Indexed POIs,Polylines or Polygons or first map level
+#>>>0x15                       ulelong        x        \b, at 0x%x
+#>>>0x19                       ulelong        x        0x%x bytes RGN1
+# polygons with extended types
+#>>>0x21                       ulelong        >0
+#>>>>0x1D              ulelong        x        \b, at 0x%x
+#>>>>0x21              ulelong        x        0x%x bytes RGN2
+# polylines with extended types
+#>>>0x3D                       ulelong        >0
+#>>>>0x39              ulelong        x        \b, at 0x%x
+#>>>>0x3D              ulelong        x        0x%x bytes RGN3
+# extended POIs
+#>>>0x59                       ulelong        >0
+#>>>>0x55              ulelong        x        \b, at 0x%x
+#>>>>0x59              ulelong        x        0x%x bytes RGN3
+#>>9   default         x               unknown map type
+# Header length; GMP:31h 35h 3Dh,MDR:11Eh 238h 2C4h 310h,NOD:3Fh 7Fh,NET:64h,
+# LBL:2A9h,SRT:1Dh 25h 27h,TRE:CFh 135h,TRF:5Ah,TYP:5Bh 6Eh 7Ch AEh,RGN:7Dh
+>>0    uleshort        x               \b, header length 0x%x
+
+# TOM TOM GPS watches ttbin files:
+# https://github.com/ryanbinns/ttwatch/tree/master/ttbin
+# From: Daniel Lenski
+0      byte    0x20
+>1     leshort 0x0007
+>>0x76 byte    0x20
+>>>0x77        leshort 0x0075          TomTom activity file, v7
+>>>>8  leldate x               (%s,
+>>>>3  byte    x               device firmware %d.
+>>>>4  byte    x               \b%d.
+>>>>5  byte    x               \b%d,
+>>>>6  leshort x               product ID %04d)
+
diff --git a/magic/Magdir/maple b/magic/Magdir/maple
new file mode 100644 (file)
index 0000000..44ab284
--- /dev/null
@@ -0,0 +1,57 @@
+
+#------------------------------------------------------------------------------
+# $File: maple,v 1.8 2017/03/17 21:35:28 christos Exp $
+# maple:  file(1) magic for maple files
+# "H. Nanosecond" <aldomel@ix.netcom.com>
+# Maple V release 4, a multi-purpose math program
+#
+
+# maple library .lib
+0      string  \000MVR4\nI     MapleVr4 library
+
+# .ind
+# no magic for these :-(
+# they are compiled indexes for maple files
+
+# .hdb
+0      string  \000\004\000\000        Maple help database
+
+# .mhp
+# this has the form <PACKAGE=name>
+0      string  \<PACKAGE=      Maple help file
+0      string  \<HELP\ NAME=   Maple help file
+0      string  \n\<HELP\ NAME= Maple help file with extra carriage return at start (yuck)
+#0     string  #\ Newton       Maple help file, old style
+0      string  #\ daub Maple help file, old style
+#0     string  #===========    Maple help file, old style
+
+# .mws
+0      string  \000\000\001\044\000\221        Maple worksheet
+#this is anomalous
+0      string  WriteNow\000\002\000\001\000\000\000\000\100\000\000\000\000\000        Maple worksheet, but weird
+# this has the form {VERSION 2 3 "IBM INTEL NT" "2.3" }\n
+# that is {VERSION major_version miunor_version computer_type version_string}
+0      string  {VERSION\       Maple worksheet
+>9     string  >\0     version %.1s.
+>>11   string  >\0     %.1s
+
+# .mps
+0      string  \0\0\001$       Maple something
+# from byte 4 it is either 'nul E' or 'soh R'
+# I think 'nul E' means a file that was saved as  a different name
+# a sort of revision marking
+# 'soh R' means new
+>4     string  \000\105        An old revision
+>4     string  \001\122        The latest save
+
+# .mpl
+# some of these are the same as .mps above
+#0000000 000 000 001 044 000 105 same as .mps
+#0000000 000 000 001 044 001 122 same as .mps
+
+0      string  #\n##\ <SHAREFILE=      Maple something
+0      string  \n#\n##\ <SHAREFILE=    Maple something
+0      string  ##\ <SHAREFILE= Maple something
+0      string  #\r##\ <SHAREFILE=      Maple something
+0      string  \r#\r##\ <SHAREFILE=    Maple something
+0      string  #\ \r##\ <DESCRIBE>     Maple something anomalous.
diff --git a/magic/Magdir/marc21 b/magic/Magdir/marc21
new file mode 100644 (file)
index 0000000..bb4998e
--- /dev/null
@@ -0,0 +1,30 @@
+#--------------------------------------------
+# marc21: file(1) magic for MARC 21 Format
+#
+# Kevin Ford (kefo@loc.gov)
+#
+# MARC21 formats are for the representation and communication
+# of bibliographic and related information in machine-readable
+# form.  For more info, see https://www.loc.gov/marc/
+
+
+# leader position 20-21 must be 45
+# and 22-23 also 00 so far, but we check that later.
+20     string          45
+>0     search/2048     \x1e
+
+# leader starts with 5 digits, followed by codes specific to MARC format
+>>0    regex/1l        (^[0-9]{5})[acdnp][^bhlnqsu-z]  MARC21 Bibliographic
+!:mime application/marc
+>>0    regex/1l        (^[0-9]{5})[acdnosx][z] MARC21 Authority
+!:mime application/marc
+>>0    regex/1l        (^[0-9]{5})[cdn][uvxy]  MARC21 Holdings
+!:mime application/marc
+>>0    regex/1l        (^[0-9]{5})[acdn][w]    MARC21 Classification
+!:mime application/marc
+>>0    regex/1l        (^[0-9]{5})[cdn][q]     MARC21 Community
+!:mime application/marc
+
+# leader position 22-23, should be "00" but is it?
+>>0    regex/1l        (^.{21})([^0]{2})       (non-conforming)
+!:mime application/marc
diff --git a/magic/Magdir/mathcad b/magic/Magdir/mathcad
new file mode 100644 (file)
index 0000000..ccc8e69
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# mathcad:  file(1) magic for Mathcad documents
+# URL: http://www.mathsoft.com/
+# From:        Josh Triplett <josh@freedesktop.org>
+
+0      string  .MCAD\t         Mathcad document
diff --git a/magic/Magdir/mathematica b/magic/Magdir/mathematica
new file mode 100644 (file)
index 0000000..e76957e
--- /dev/null
@@ -0,0 +1,81 @@
+
+#------------------------------------------------------------------------------
+# $File: mathematica,v 1.9 2017/03/17 21:35:28 christos Exp $
+# mathematica:  file(1) magic for mathematica files
+# "H. Nanosecond" <aldomel@ix.netcom.com>
+# Mathematica a multi-purpose math program
+# versions 2.2 and 3.0
+
+#mathematica .mb
+0      string  \064\024\012\000\035\000\000\000        Mathematica version 2 notebook
+!:ext mb
+0      string  \064\024\011\000\035\000\000\000        Mathematica version 2 notebook
+!:ext mb
+
+# .ma
+# multiple possibilites:
+
+0      string  (*^\n\n::[\011frontEndVersion\ =\       Mathematica notebook
+#>41   string  >\0     %s
+!:ext mb
+
+#0     string  (*^\n\n::[\011palette   Mathematica notebook version 2.x
+
+#0     string  (*^\n\n::[\011Information       Mathematica notebook version 2.x
+#>675  string  >\0     %s #doesn't work well
+
+# there may be 'cr' instread of 'nl' in some does this matter?
+
+# generic:
+0      string  (*^\r\r::[\011  Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\r\n\r\n::[\011      Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\015                 Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\n\r\n\r::[\011      Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\r::[\011    Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\r\n::[\011  Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\n\n::[\011  Mathematica notebook version 2.x
+!:ext mb
+0      string  (*^\n::[\011    Mathematica notebook version 2.x
+!:ext mb
+
+
+# Mathematica .mx files
+
+#0     string  (*This\ is\ a\ Mathematica\ binary\ dump\ file.\ It\ can\ be\ loaded\ with\ Get.*)      Mathematica binary file
+0      string  (*This\ is\ a\ Mathematica\ binary\     Mathematica binary file
+#>71   string \000\010\010\010\010\000\000\000\000\000\000\010\100\010\000\000\000
+# >71... is optional
+>88    string  >\0     from %s
+
+
+# Mathematica files PBF:
+# 115 115 101 120 102 106 000 001 000 000 000 203 000 001 000
+0      string  MMAPBF\000\001\000\000\000\203\000\001\000      Mathematica PBF (fonts I think)
+
+# .ml files  These are menu resources I think
+# these start with "[0-9][0-9][0-9]\ A~[0-9][0-9][0-9]\
+# how to put that into a magic rule?
+4      string  \ A~    MAthematica .ml file
+
+# .nb files
+#too long 0    string  (***********************************************************************\n\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Mathematica-Compatible Notebook     Mathematica 3.0 notebook
+0      string  (***********************        Mathematica 3.0 notebook
+
+# other (* matches it is a comment start in these langs
+# GRR: Too weak; also matches other languages e.g. ML
+#0     string  (*      Mathematica, or Pascal, Modula-2 or 3 code text
+
+#########################
+# MatLab v5
+0       string  MATLAB  Matlab v5 mat-file
+>126    short   0x494d  (big endian)
+>>124   beshort x       version 0x%04x
+>126    short   0x4d49  (little endian)
+>>124   leshort x       version 0x%04x
+
diff --git a/magic/Magdir/matroska b/magic/Magdir/matroska
new file mode 100644 (file)
index 0000000..271af55
--- /dev/null
@@ -0,0 +1,17 @@
+
+#------------------------------------------------------------------------------
+# $File: matroska,v 1.9 2019/04/19 00:42:27 christos Exp $
+# matroska:  file(1) magic for Matroska files
+#
+# See https://www.matroska.org/
+#
+
+# EBML id:
+0              belong          0x1a45dfa3
+# DocType id:
+>4             search/4096     \x42\x82
+# DocType contents:
+>>&1           string          webm            WebM
+!:mime  video/webm
+>>&1           string          matroska        Matroska data
+!:mime  video/x-matroska
diff --git a/magic/Magdir/mcrypt b/magic/Magdir/mcrypt
new file mode 100644 (file)
index 0000000..1f9e610
--- /dev/null
@@ -0,0 +1,38 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# Mavroyanopoulos Nikos <nmav@hellug.gr>
+# mcrypt:   file(1) magic for mcrypt 2.2.x;
+0      string          \0m\3           mcrypt 2.5 encrypted data,
+>4     string          >\0             algorithm: %s,
+>>&1   leshort         >0              keysize: %d bytes,
+>>>&0  string          >\0             mode: %s,
+
+0      string          \0m\2           mcrypt 2.2 encrypted data,
+>3     byte            0               algorithm: blowfish-448,
+>3     byte            1               algorithm: DES,
+>3     byte            2               algorithm: 3DES,
+>3     byte            3               algorithm: 3-WAY,
+>3     byte            4               algorithm: GOST,
+>3     byte            6               algorithm: SAFER-SK64,
+>3     byte            7               algorithm: SAFER-SK128,
+>3     byte            8               algorithm: CAST-128,
+>3     byte            9               algorithm: xTEA,
+>3     byte            10              algorithm: TWOFISH-128,
+>3     byte            11              algorithm: RC2,
+>3     byte            12              algorithm: TWOFISH-192,
+>3     byte            13              algorithm: TWOFISH-256,
+>3     byte            14              algorithm: blowfish-128,
+>3     byte            15              algorithm: blowfish-192,
+>3     byte            16              algorithm: blowfish-256,
+>3     byte            100             algorithm: RC6,
+>3     byte            101             algorithm: IDEA,
+>4     byte            0               mode: CBC,
+>4     byte            1               mode: ECB,
+>4     byte            2               mode: CFB,
+>4     byte            3               mode: OFB,
+>4     byte            4               mode: nOFB,
+>5     byte            0               keymode: 8bit
+>5     byte            1               keymode: 4bit
+>5     byte            2               keymode: SHA-1 hash
+>5     byte            3               keymode: MD5 hash
diff --git a/magic/Magdir/measure b/magic/Magdir/measure
new file mode 100644 (file)
index 0000000..c99cac8
--- /dev/null
@@ -0,0 +1,39 @@
+
+#------------------------------------------------------------------------------
+# $File: measure,v 1.2 2018/06/23 16:13:15 christos Exp $
+# measure: file(1) magic for measurement data
+
+# DIY-Thermocam raw data
+0      name    diy-thermocam-parser
+>0     beshort x       scale %d-
+>2     beshort x       \b%d,
+>4     lefloat x       spot sensor temperature %f,
+>9     ubyte   0       unit celsius,
+>9     ubyte   1       unit fahrenheit,
+>8     ubyte   x       color scheme %d
+>10    ubyte   1       \b, show spot sensor
+>11    ubyte   1       \b, show scale bar
+>12    ubyte   &1      \b, minimum point enabled
+>12    ubyte   &2      \b, maximum point enabled
+>13    lefloat x       \b, calibration: offset %f,
+>17    lefloat x       slope %f
+
+0      name    diy-thermocam-checker
+>9     ubyte   <2
+>>10   ubyte   <2
+>>>11  ubyte   <2
+>>>>12 ubyte   <4
+>>>>>17        lefloat >0.0001 DIY-Thermocam raw data
+
+# V2 and Leption 3.x:
+38408  ubyte   <19
+>38400 use     diy-thermocam-checker
+>>38400        default x       (Lepton 3.x),
+>>>38400       use     diy-thermocam-parser
+
+# V1 or Lepton 2.x
+9608   ubyte   <19
+>9600  use     diy-thermocam-checker
+>>9600 default x       (Lepton 2.x),
+>>>9600        use     diy-thermocam-parser
+
diff --git a/magic/Magdir/mercurial b/magic/Magdir/mercurial
new file mode 100644 (file)
index 0000000..b8f3cdd
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File: mercurial,v 1.5 2019/04/19 00:42:27 christos Exp $
+# mercurial:  file(1) magic for Mercurial changeset bundles
+# https://www.selenic.com/mercurial/wiki/
+#
+# Jesse Glick (jesse.glick@sun.com)
+#
+
+0      string          HG10            Mercurial changeset bundle
+>4     string          UN              (uncompressed)
+>4     string          GZ              (gzip compressed)
+>4     string          BZ              (bzip2 compressed)
diff --git a/magic/Magdir/metastore b/magic/Magdir/metastore
new file mode 100644 (file)
index 0000000..e64e704
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File: metastore,v 1.3 2019/04/19 00:42:27 christos Exp $
+# metastore:  file(1) magic for metastore files
+# From: Thomas Wissen
+# see https://david.hardeman.nu/software.php#metastore
+0      string          MeTaSt00r3      Metastore data file,
+>10    bequad          x               version %0llx
diff --git a/magic/Magdir/meteorological b/magic/Magdir/meteorological
new file mode 100644 (file)
index 0000000..9e7a3f1
--- /dev/null
@@ -0,0 +1,49 @@
+
+#------------------------------------------------------------------------------
+# $File: meteorological,v 1.2 2017/03/17 21:35:28 christos Exp $
+# rinex:  file(1) magic for RINEX files
+# http://igscb.jpl.nasa.gov/igscb/data/format/rinex210.txt
+# ftp://cddis.gsfc.nasa.gov/pub/reports/formats/rinex300.pdf
+# data for testing: ftp://cddis.gsfc.nasa.gov/pub/gps/data
+60     string          RINEX
+>80    search/256      XXRINEXB        RINEX Data, GEO SBAS Broadcast
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/broadcast
+>80    search/256      XXRINEXD        RINEX Data, Observation (Hatanaka comp)
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/observation
+>80    search/256      XXRINEXC        RINEX Data, Clock
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/clock
+>80    search/256      XXRINEXH        RINEX Data, GEO SBAS Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXG        RINEX Data, GLONASS Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXL        RINEX Data, Galileo Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXM        RINEX Data, Meteorological
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/meteorological
+>80    search/256      XXRINEXN        RINEX Data, Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXO        RINEX Data, Observation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/observation
+
+# https://en.wikipedia.org/wiki/GRIB
+0      string  GRIB
+>7     byte    =1      Gridded binary (GRIB) version 1
+>7     byte    =2      Gridded binary (GRIB) version 2
diff --git a/magic/Magdir/microfocus b/magic/Magdir/microfocus
new file mode 100644 (file)
index 0000000..93e39aa
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File: microfocus,v 1.3 2019/04/19 00:42:27 christos Exp $
+# Micro Focus COBOL data files.
+
+# https://documentation.microfocus.com/help/index.jsp?topic=\
+# %2FGUID-0E0191D8-C39A-44D1-BA4C-D67107BAF784%2FHRFLRHFILE05.html
+# http://www.cobolproducts.com/datafile/data-viewer.html
+# https://github.com/miracle2k/mfcobol-export
+
+0 string \x30\x00\x00\x7C
+>36 string \x00\x3E Micro Focus File with Header (DAT)
+!:mime application/octet-stream
+
+0 string \x30\x7E\x00\x00
+>36 string \x00\x3E Micro Focus File with Header (DAT)
+!:mime application/octet-stream
+
+39 string \x02
+>136 string \x02\x02\x04\x04 Micro Focus Index File (IDX)
+!:mime application/octet-stream
diff --git a/magic/Magdir/mime b/magic/Magdir/mime
new file mode 100644 (file)
index 0000000..57b2dd5
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File: mime,v 1.8 2017/03/17 22:20:22 christos Exp $
+# mime:  file(1) magic for MIME encoded files
+#
+0      string/t                Content-Type:\040
+>14    string          >\0             %s
+0      string/t                Content-Type:
+>13    string          >\0             %s
diff --git a/magic/Magdir/mips b/magic/Magdir/mips
new file mode 100644 (file)
index 0000000..9681c98
--- /dev/null
@@ -0,0 +1,120 @@
+
+#------------------------------------------------------------------------------
+# $File: mips,v 1.9 2013/01/12 03:09:51 christos Exp $
+# mips:  file(1) magic for MIPS ECOFF and Ucode, as used in SGI IRIX
+# and DEC Ultrix
+#
+0      beshort 0x0160          MIPSEB ECOFF executable
+>20    beshort 0407            (impure)
+>20    beshort 0410            (swapped)
+>20    beshort 0413            (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>22    byte    x               - version %d
+>23    byte    x               \b.%d
+#
+0      beshort 0x0162          MIPSEL-BE ECOFF executable
+>20    beshort 0407            (impure)
+>20    beshort 0410            (swapped)
+>20    beshort 0413            (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+0      beshort 0x6001          MIPSEB-LE ECOFF executable
+>20    beshort 03401           (impure)
+>20    beshort 04001           (swapped)
+>20    beshort 05401           (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+0      beshort 0x6201          MIPSEL ECOFF executable
+>20    beshort 03401           (impure)
+>20    beshort 04001           (swapped)
+>20    beshort 05401           (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+# MIPS 2 additions
+#
+0      beshort 0x0163          MIPSEB MIPS-II ECOFF executable
+>20    beshort 0407            (impure)
+>20    beshort 0410            (swapped)
+>20    beshort 0413            (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>22    byte    x               - version %d
+>23    byte    x               \b.%d
+#
+0      beshort 0x0166          MIPSEL-BE MIPS-II ECOFF executable
+>20    beshort 0407            (impure)
+>20    beshort 0410            (swapped)
+>20    beshort 0413            (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>22    byte    x               - version %d
+>23    byte    x               \b.%d
+#
+0      beshort 0x6301          MIPSEB-LE MIPS-II ECOFF executable
+>20    beshort 03401           (impure)
+>20    beshort 04001           (swapped)
+>20    beshort 05401           (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+0      beshort 0x6601          MIPSEL MIPS-II ECOFF executable
+>20    beshort 03401           (impure)
+>20    beshort 04001           (swapped)
+>20    beshort 05401           (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+# MIPS 3 additions
+#
+0      beshort 0x0140          MIPSEB MIPS-III ECOFF executable
+>20    beshort 0407            (impure)
+>20    beshort 0410            (swapped)
+>20    beshort 0413            (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>22    byte    x               - version %d
+>23    byte    x               \b.%d
+#
+0      beshort 0x0142          MIPSEL-BE MIPS-III ECOFF executable
+>20    beshort 0407            (impure)
+>20    beshort 0410            (swapped)
+>20    beshort 0413            (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>22    byte    x               - version %d
+>23    byte    x               \b.%d
+#
+0      beshort 0x4001          MIPSEB-LE MIPS-III ECOFF executable
+>20    beshort 03401           (impure)
+>20    beshort 04001           (swapped)
+>20    beshort 05401           (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+0      beshort 0x4201          MIPSEL MIPS-III ECOFF executable
+>20    beshort 03401           (impure)
+>20    beshort 04001           (swapped)
+>20    beshort 05401           (paged)
+>8     belong  >0              not stripped
+>8     belong  0               stripped
+>23    byte    x               - version %d
+>22    byte    x               \b.%d
+#
+0      beshort 0x180           MIPSEB Ucode
+0      beshort 0x182           MIPSEL-BE Ucode
diff --git a/magic/Magdir/mirage b/magic/Magdir/mirage
new file mode 100644 (file)
index 0000000..31eb71f
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# mirage:  file(1) magic for Mirage executables
+#
+# XXX - byte order?
+#
+0      long    31415           Mirage Assembler m.out executable
diff --git a/magic/Magdir/misctools b/magic/Magdir/misctools
new file mode 100644 (file)
index 0000000..cef1da5
--- /dev/null
@@ -0,0 +1,65 @@
+
+#-----------------------------------------------------------------------------
+# $File: misctools,v 1.18 2019/04/19 00:42:27 christos Exp $
+# misctools:  file(1) magic for miscellaneous UNIX tools.
+#
+0      search/1        %%!!                    X-Post-It-Note text
+0      string/c        BEGIN:VCALENDAR         vCalendar calendar file
+!:mime text/calendar
+# updated by Joerg Jenderek at Apr 2015
+# Extension: .vcf
+# https://en.wikipedia.org/wiki/VCard
+0      string/c        BEGIN:VCARD             vCard visiting card
+# deprecated
+#!:mime        text/x-vcard
+!:mime text/vcard
+# VERSION must come right after BEGIN for 3.0 or 4.0 except in 2.1 , where it can be anywhere
+>12    search/14000/c  VERSION:
+# VERSION 2.1 , 3.0 or 4.0
+>>&0   string          x                       \b, version %-.3s
+
+# Summary: Libtool library file
+# Extension: .la
+# Submitted by: Tomasz Trojanowski <tomek@uninet.com.pl>
+0      search/80       .la\ -\ a\ libtool\ library\ file       libtool library file
+
+# Summary: Libtool object file
+# Extension: .lo
+# Submitted by: Abel Cheung <abelcheung@gmail.com>
+0      search/80       .lo\ -\ a\ libtool\ object\ file        libtool object file
+
+# From: Daniel Novotny <dnovotny@redhat.com>
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Core_dump#User-mode_memory_dumps
+# Reference: https://msdn.microsoft.com/en-us/library/ms680378%28VS.85%29.aspx
+#
+# "Windows Minidump" by TrID
+# ./misctools (version 5.25) labeled the entry as "MDMP crash report data"
+0      string          MDMP                                    Mini DuMP crash report
+# https://filext.com/file-extension/DMP
+!:mime application/x-dmp
+!:ext  dmp/mdmp
+# The high-order word is an internal value that is implementation specific.
+# The low-order word is MINIDUMP_VERSION 0xA793
+>4     ulelong&0x0000FFFF      !0xA793                         \b, version 0x%4.4x
+# NumberOfStreams 8,9,10,13
+>8     ulelong                 x                               \b, %d streams
+# StreamDirectoryRva 0x20
+>12    ulelong                 !0x20                           \b, 0x%8.8x RVA
+# CheckSum 0
+>16    ulelong                 !0                              \b, CheckSum 0x%8.8x
+# Reserved or TimeDateStamp
+>20    ledate                  x                               \b, %s
+# https://msdn.microsoft.com/en-us/library/windows/desktop/ms680519%28v=vs.85%29.aspx
+# Flags MINIDUMP_TYPE enumeration type 0 0x121 0x800
+>24    ulelong                 x                               \b, 0x%x type
+# >24  ulelong                 >0                              \b; include
+# >>24 ulelong                 &0x00000001                     \b data sections,
+# >>24 ulelong                 &0x00000020                     \b list of unloaded modules,
+# >>24 ulelong                 &0x00000100                     \b process and thread information,
+# >>24 ulelong                 &0x00000800                     \b memory information,
+
+# Summary: abook addressbook file
+# Submitted by: Mark Schreiber <mark7@alumni.cmu.edu>
+0      string  #\x20abook\x20addressbook\x20file abook address book
+!:mime application/x-abook-addressbook
diff --git a/magic/Magdir/mkid b/magic/Magdir/mkid
new file mode 100644 (file)
index 0000000..f6e464e
--- /dev/null
@@ -0,0 +1,11 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# mkid:  file(1) magic for mkid(1) databases
+#
+# ID is the binary tags database produced by mkid(1).
+#
+# XXX - byte order?
+#
+0      string          \311\304        ID tags data
+>2     short           >0              version %d
diff --git a/magic/Magdir/mlssa b/magic/Magdir/mlssa
new file mode 100644 (file)
index 0000000..449dc49
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# mlssa: file(1) magic for MLSSA datafiles
+#
+0              lelong          0xffffabcd      MLSSA datafile,
+>4             leshort         x               algorithm %d,
+>10            lelong          x               %d samples
diff --git a/magic/Magdir/mmdf b/magic/Magdir/mmdf
new file mode 100644 (file)
index 0000000..778ccf0
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# mmdf:  file(1) magic for MMDF mail files
+#
+0      string  \001\001\001\001        MMDF mailbox
diff --git a/magic/Magdir/modem b/magic/Magdir/modem
new file mode 100644 (file)
index 0000000..c7a53ee
--- /dev/null
@@ -0,0 +1,86 @@
+
+#------------------------------------------------------------------------------
+# $File: modem,v 1.9 2019/04/19 00:42:27 christos Exp $
+# modem:  file(1) magic for modem programs
+#
+# From: Florian La Roche <florian@knorke.saar.de>
+1      string          PC\ Research,\ Inc      Digifax-G3-File
+>29    byte            1                       \b, fine resolution
+>29    byte            0                       \b, normal resolution
+
+# Summary: CCITT Group 3 Facsimile in "raw" form (i.e. no header).
+# Modified by: Joerg Jenderek
+# URL: https://de.wikipedia.org/wiki/Fax
+# Reference: https://web.archive.org/web/20020628195336/http://www.netnam.vn/unescocourse/computervision/104.htm
+# GRR: EOL of G3 is too general as it catches also TrueType fonts, Postscript PrinterFontMetric, others
+0      short           0x0100
+# 16 0-bits near beginning like True Type fonts *.ttf, Postscript PrinterFontMetric *.pfm, FTYPE.HYPERCARD, XFER
+>2     search/9        \0\0
+# maximal 7 0-bits for pixel sequences or 11 0-bits for EOL in G3
+>2     default         x
+# skip IRCAM file (VAX big-endian)     ./audio
+>>0    belong          !0x0001a364
+# skip GEM Image data                  ./images
+>>>2   beshort         !0x0008
+# look for first keyword of Panorama database *.pan
+>>>>11 search/262      \x06DESIGN
+# skip Panorama database
+>>>>11 default         x
+# old Apple DreamWorld DreamGrafix *.3200 with keyword at end of g3 looking files
+>>>>>27118     search/1864     DreamWorld
+>>>>>27118     default         x
+# skip MouseTrap/Mt.Defaults with file size 16 found on Golden Orchard Apple II CD Rom
+>>>>>>8                ubequad         !0x2e01010454010203
+# skip PICTUREH.SML found on Golden Orchard Apple II CD Rom
+>>>>>>>8       ubequad         !0x5dee74ad1aa56394     raw G3 (Group 3) FAX, byte-padded
+# version 5.25 labeled the entry above "raw G3 data, byte-padded"
+!:mime image/g3fax
+#!:apple       ????TIFF
+!:ext  g3
+# unusual image starting with black pixel
+#0     short           0x1300          raw G3 (Group 3) FAX
+0      short           0x1400
+# 16 0-bits near beginning like PicturePuzzler found on Golden Orchard Apple CD Rom
+>2     search/9        \0\0
+# maximal 7 0-bits for pixel sequences or 11 0-bits for EOL in G3
+>2     default         x               raw G3 (Group 3) FAX
+# version 5.25 labeled the above entry as "raw G3 data"
+!:mime image/g3fax
+!:ext  g3
+# unusual image with black pixel near beginning
+#0     short           0x1900          raw G3 (Group 3) FAX
+
+#
+# Magic data for vgetty voice formats
+# (Martin Seine & Marc Eberhard)
+
+#
+# raw modem data version 1
+#
+0    string    RMD1      raw modem data
+>4   string    >\0       (%s /
+>20  short     >0        compression type 0x%04x)
+
+#
+# portable voice format 1
+#
+0    string    PVF1\n         portable voice format
+>5   string    >\0       (binary %s)
+
+#
+# portable voice format 2
+#
+0    string    PVF2\n         portable voice format
+>5   string >\0          (ascii %s)
+
+# From: Bernd Nuernberger <bernd.nuernberger@web.de>
+# Brooktrout G3 fax data incl. 128 byte header
+# Common suffixes: 3??, BRK, BRT, BTR
+0      leshort         0x01bb
+>2     leshort         0x0100          Brooktrout 301 fax image,
+>>9    leshort         x               %d x
+>>0x2d leshort         x               %d
+>>6    leshort         200             \b, fine resolution
+>>6    leshort         100             \b, normal resolution
+>>11   byte            1               \b, G3 compression
+>>11   byte            2               \b, G32D compression
diff --git a/magic/Magdir/motorola b/magic/Magdir/motorola
new file mode 100644 (file)
index 0000000..b6b2ce2
--- /dev/null
@@ -0,0 +1,71 @@
+
+#------------------------------------------------------------------------------
+# $File: motorola,v 1.10 2009/09/19 16:28:11 christos Exp $
+# motorola:  file(1) magic for Motorola 68K and 88K binaries
+#
+# 68K
+#
+0      beshort         0520            mc68k COFF
+>18    beshort         ^00000020       object
+>18    beshort         &00000020       executable
+>12    belong          >0              not stripped
+>168   string          .lowmem         Apple toolbox
+>20    beshort         0407            (impure)
+>20    beshort         0410            (pure)
+>20    beshort         0413            (demand paged)
+>20    beshort         0421            (standalone)
+0      beshort         0521            mc68k executable (shared)
+>12    belong          >0              not stripped
+0      beshort         0522            mc68k executable (shared demand paged)
+>12    belong          >0              not stripped
+#
+# Motorola/UniSoft 68K Binary Compatibility Standard (BCS)
+#
+0      beshort         0554            68K BCS executable
+#
+# 88K
+#
+# Motorola/88Open BCS
+#
+0      beshort         0555            88K BCS executable
+#
+# Motorola S-Records, from Gerd Truschinski <gt@freebsd.first.gmd.de>
+0   string      S0          Motorola S-Record; binary data in text format
+
+# ATARI ST relocatable PRG
+#
+# from Oskar Schirmer <schirmer@scara.com> Feb 3, 2001
+# (according to Roland Waldi, Oct 21, 1987)
+# besides the magic 0x601a, the text segment size is checked to be
+# not larger than 1 MB (which is a lot on ST).
+# The additional 0x601b distinction I took from Doug Lee's magic.
+0      belong&0xFFFFFFF0       0x601A0000      Atari ST M68K contiguous executable
+>2     belong                  x               (txt=%d,
+>6     belong                  x               dat=%d,
+>10    belong                  x               bss=%d,
+>14    belong                  x               sym=%d)
+0      belong&0xFFFFFFF0       0x601B0000      Atari ST M68K non-contig executable
+>2     belong                  x               (txt=%d,
+>6     belong                  x               dat=%d,
+>10    belong                  x               bss=%d,
+>14    belong                  x               sym=%d)
+
+# Atari ST/TT... program format (sent by Wolfram Kleff <kleff@cs.uni-bonn.de>)
+0       beshort         0x601A          Atari 68xxx executable,
+>2      belong          x               text len %u,
+>6      belong          x               data len %u,
+>10     belong          x               BSS len %u,
+>14     belong          x               symboltab len %u,
+>18     belong          0
+>22     belong          &0x01           fastload flag,
+>22     belong          &0x02           may be loaded to alternate RAM,
+>22     belong          &0x04           malloc may be from alternate RAM,
+>22     belong          x               flags: 0x%X,
+>26     beshort         0               no relocation tab
+>26     beshort         !0              + relocation tab
+>30     string          SFX             [Self-Extracting LZH SFX archive]
+>38     string          SFX             [Self-Extracting LZH SFX archive]
+>44     string          ZIP!            [Self-Extracting ZIP SFX archive]
+
+0       beshort         0x0064          Atari 68xxx CPX file
+>8      beshort         x               (version %04x)
diff --git a/magic/Magdir/mozilla b/magic/Magdir/mozilla
new file mode 100644 (file)
index 0000000..bc6b6a6
--- /dev/null
@@ -0,0 +1,37 @@
+
+#------------------------------------------------------------------------------
+# $File: mozilla,v 1.10 2019/04/19 00:42:27 christos Exp $
+# mozilla:  file(1) magic for Mozilla XUL fastload files
+# (XUL.mfasl and XPC.mfasl)
+# URL: https://www.mozilla.org/
+# From:        Josh Triplett <josh@freedesktop.org>
+
+0      string  XPCOM\nMozFASL\r\n\x1A          Mozilla XUL fastload data
+# Probably the next magic line contains misspelled "mozLz40\0"
+0      string  mozLz4a                         Mozilla lz4 compressed bookmark data
+# From: Joerg Jenderek
+# URL: https://lz4.github.io/lz4/
+# Reference: https://github.com/avih/dejsonlz4/archive/master.zip/
+# dejsonlz4-master\src\dejsonlz4.c 
+# Note: mostly JSON compressed with a non-standard LZ4 header
+# can be unpacked by dejsonlz4 but not lz4 programm.
+0      string  mozLz40\0                       Mozilla lz4 compressed data
+!:mime application/x-lz4+json
+# mozlz4 extension seems to be used for search/store, while jsonlz4 for bookmarks
+!:ext  jsonlz4/mozlz4
+# decomp_size
+>8     ulelong x                               \b, originally %u bytes
+# lz4 data
+#>12   ubequad x                               \b, lz4 data 0x%16.16llx
+
+# From: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Firefox_4
+# Reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
+# Note:        Most ZIP utilities are able to extract such archives
+#      maybe only partly or after some warnings. Example:
+#      zip -FF omni.ja --out omni.zip
+4      string  PK\001\002      Mozilla archive omni.ja
+!:mime application/x-zip
+!:ext  ja
+# TODO:
+#>4    use     zip-dir-entry
diff --git a/magic/Magdir/msdos b/magic/Magdir/msdos
new file mode 100644 (file)
index 0000000..eda0ddb
--- /dev/null
@@ -0,0 +1,1503 @@
+
+#------------------------------------------------------------------------------
+# $File: msdos,v 1.128 2019/04/19 00:42:27 christos Exp $
+# msdos:  file(1) magic for MS-DOS files
+#
+
+# .BAT files (Daniel Quinlan, quinlan@yggdrasil.com)
+# updated by Joerg Jenderek at Oct 2008,Apr 2011
+0      string/t        @
+>1     string/cW       \ echo\ off     DOS batch file text
+!:mime text/x-msdos-batch
+!:ext  bat
+>1     string/cW       echo\ off       DOS batch file text
+!:mime text/x-msdos-batch
+!:ext  bat
+>1     string/cW       rem             DOS batch file text
+!:mime text/x-msdos-batch
+!:ext  bat
+>1     string/cW       set\            DOS batch file text
+!:mime text/x-msdos-batch
+!:ext  bat
+
+
+# OS/2 batch files are REXX. the second regex is a bit generic, oh well
+# the matched commands seem to be common in REXX and uncommon elsewhere
+100    search/0xffff   rxfuncadd
+>100   regex/c =^[\ \t]{0,10}call[\ \t]{1,10}rxfunc    OS/2 REXX batch file text
+100    search/0xffff   say
+>100   regex/c =^[\ \t]{0,10}say\ ['"]                 OS/2 REXX batch file text
+
+# updated by Joerg Jenderek at Oct 2015
+# https://de.wikipedia.org/wiki/Common_Object_File_Format
+# http://www.delorie.com/djgpp/doc/coff/filhdr.html
+# ./intel already labeled COFF type 0x14c=0514 as "80386 COFF executable"
+#0     leshort         0x14c   MS Windows COFF Intel 80386 object file
+#>4    ledate          x       stamp %s
+0      leshort         0x166   MS Windows COFF MIPS R4000 object file
+#>4    ledate          x       stamp %s
+0      leshort         0x184   MS Windows COFF Alpha object file
+#>4    ledate          x       stamp %s
+0      leshort         0x268   MS Windows COFF Motorola 68000 object file
+#>4    ledate          x       stamp %s
+0      leshort         0x1f0   MS Windows COFF PowerPC object file
+#>4    ledate          x       stamp %s
+0      leshort         0x290   MS Windows COFF PA-RISC object file
+#>4    ledate          x       stamp %s
+
+# Tests for various EXE types.
+#
+# Many of the compressed formats were extraced from IDARC 1.23 source code.
+#
+0      string/b        MZ
+# All non-DOS EXE extensions have the relocation table more than 0x40 bytes into the file.
+>0x18  leshort <0x40 MS-DOS executable
+!:mime application/x-dosexec
+# Windows and later versions of DOS will allow .EXEs to be named with a .COM
+# extension, mostly for compatibility's sake.
+!:ext  exe/com
+# These traditional tests usually work but not always.  When test quality support is
+# implemented these can be turned on.
+#>>0x18        leshort 0x1c    (Borland compiler)
+#>>0x18        leshort 0x1e    (MS compiler)
+
+# If the relocation table is 0x40 or more bytes into the file, it's definitely
+# not a DOS EXE.
+>0x18  leshort >0x3f
+
+# Maybe it's a PE?
+>>(0x3c.l) string PE\0\0 PE
+!:mime application/x-dosexec
+>>>(0x3c.l+24) leshort         0x010b  \b32 executable
+>>>(0x3c.l+24) leshort         0x020b  \b32+ executable
+>>>(0x3c.l+24) leshort         0x0107  ROM image
+>>>(0x3c.l+24) default         x       Unknown PE signature
+>>>>&0                 leshort         x       0x%x
+>>>(0x3c.l+22) leshort&0x2000  >0      (DLL)
+>>>(0x3c.l+92) leshort         1
+# Native PEs include ntoskrnl.exe, hal.dll, smss.exe, autochk.exe, and all the
+# drivers in Windows/System32/drivers/*.sys.
+>>>>(0x3c.l+22)        leshort&0x2000  >0      (native)
+!:ext  dll/sys
+>>>>(0x3c.l+22)        leshort&0x2000  0       (native)
+!:ext  exe/sys
+>>>(0x3c.l+92) leshort         2
+>>>>(0x3c.l+22)        leshort&0x2000  >0      (GUI)
+# These could probably be at least partially distinguished from one another by
+# looking for specific exported functions.
+# CPL: Control Panel item
+# TLB: Type library
+# OCX: OLE/ActiveX control
+# ACM: Audio compression manager codec
+# AX: DirectShow source filter
+# IME: Input method editor
+!:ext  dll/cpl/tlb/ocx/acm/ax/ime
+>>>>(0x3c.l+22)        leshort&0x2000  0       (GUI)
+# Screen savers typically include code from the scrnsave.lib static library, but
+# that's not guaranteed.
+!:ext  exe/scr
+>>>(0x3c.l+92) leshort         3
+>>>>(0x3c.l+22)        leshort&0x2000  >0      (console)
+!:ext  dll/cpl/tlb/ocx/acm/ax/ime
+>>>>(0x3c.l+22)        leshort&0x2000  0       (console)
+!:ext  exe/com
+>>>(0x3c.l+92) leshort         7       (POSIX)
+>>>(0x3c.l+92) leshort         9       (Windows CE)
+>>>(0x3c.l+92) leshort         10      (EFI application)
+>>>(0x3c.l+92) leshort         11      (EFI boot service driver)
+>>>(0x3c.l+92) leshort         12      (EFI runtime driver)
+>>>(0x3c.l+92) leshort         13      (EFI ROM)
+>>>(0x3c.l+92) leshort         14      (XBOX)
+>>>(0x3c.l+92) leshort         15      (Windows boot application)
+>>>(0x3c.l+92) default         x       (Unknown subsystem
+>>>>&0         leshort         x       0x%x)
+>>>(0x3c.l+4)  leshort         0x14c   Intel 80386
+>>>(0x3c.l+4)  leshort         0x166   MIPS R4000
+>>>(0x3c.l+4)  leshort         0x168   MIPS R10000
+>>>(0x3c.l+4)  leshort         0x184   Alpha
+>>>(0x3c.l+4)  leshort         0x1a2   Hitachi SH3
+>>>(0x3c.l+4)  leshort         0x1a6   Hitachi SH4
+>>>(0x3c.l+4)  leshort         0x1c0   ARM
+>>>(0x3c.l+4)  leshort         0x1c2   ARM Thumb
+>>>(0x3c.l+4)  leshort         0x1c4   ARMv7 Thumb
+>>>(0x3c.l+4)  leshort         0x1f0   PowerPC
+>>>(0x3c.l+4)  leshort         0x200   Intel Itanium
+>>>(0x3c.l+4)  leshort         0x266   MIPS16
+>>>(0x3c.l+4)  leshort         0x268   Motorola 68000
+>>>(0x3c.l+4)  leshort         0x290   PA-RISC
+>>>(0x3c.l+4)  leshort         0x366   MIPSIV
+>>>(0x3c.l+4)  leshort         0x466   MIPS16 with FPU
+>>>(0x3c.l+4)  leshort         0xebc   EFI byte code
+>>>(0x3c.l+4)  leshort         0x8664  x86-64
+>>>(0x3c.l+4)  leshort         0xc0ee  MSIL
+>>>(0x3c.l+4)  default         x       Unknown processor type
+>>>>&0         leshort         x       0x%x
+>>>(0x3c.l+22) leshort&0x0200  >0      (stripped to external PDB)
+>>>(0x3c.l+22) leshort&0x1000  >0      system file
+>>>(0x3c.l+24) leshort         0x010b
+>>>>(0x3c.l+232) lelong        >0      Mono/.Net assembly
+>>>(0x3c.l+24) leshort         0x020b
+>>>>(0x3c.l+248) lelong        >0      Mono/.Net assembly
+
+# hooray, there's a DOS extender using the PE format, with a valid PE
+# executable inside (which just prints a message and exits if run in win)
+>>>(8.s*16)            string          32STUB  \b, 32rtm DOS extender
+>>>(8.s*16)            string          !32STUB \b, for MS Windows
+>>>(0x3c.l+0xf8)       string          UPX0 \b, UPX compressed
+>>>(0x3c.l+0xf8)       search/0x140    PEC2 \b, PECompact2 compressed
+>>>(0x3c.l+0xf8)       search/0x140    UPX2
+>>>>(&0x10.l+(-4))     string          PK\3\4 \b, ZIP self-extracting archive (Info-Zip)
+>>>(0x3c.l+0xf8)       search/0x140    .idata
+>>>>(&0xe.l+(-4))      string          PK\3\4 \b, ZIP self-extracting archive (Info-Zip)
+>>>>(&0xe.l+(-4))      string          ZZ0 \b, ZZip self-extracting archive
+>>>>(&0xe.l+(-4))      string          ZZ1 \b, ZZip self-extracting archive
+>>>(0x3c.l+0xf8)       search/0x140    .rsrc
+>>>>(&0x0f.l+(-4))     string          a\\\4\5 \b, WinHKI self-extracting archive
+>>>>(&0x0f.l+(-4))     string          Rar! \b, RAR self-extracting archive
+>>>>(&0x0f.l+(-4))     search/0x3000   MSCF \b, InstallShield self-extracting archive
+>>>>(&0x0f.l+(-4))     search/32       Nullsoft \b, Nullsoft Installer self-extracting archive
+>>>(0x3c.l+0xf8)       search/0x140    .data
+>>>>(&0x0f.l)          string          WEXTRACT \b, MS CAB-Installer self-extracting archive
+>>>(0x3c.l+0xf8)       search/0x140    .petite\0 \b, Petite compressed
+>>>>(0x3c.l+0xf7)      byte            x
+>>>>>(&0x104.l+(-4))   string          =!sfx! \b, ACE self-extracting archive
+>>>(0x3c.l+0xf8)       search/0x140    .WISE \b, WISE installer self-extracting archive
+>>>(0x3c.l+0xf8)       search/0x140    .dz\0\0\0 \b, Dzip self-extracting archive
+>>>&(0x3c.l+0xf8)      search/0x100    _winzip_ \b, ZIP self-extracting archive (WinZip)
+>>>&(0x3c.l+0xf8)      search/0x100    SharedD \b, Microsoft Installer self-extracting archive
+>>>0x30                        string          Inno \b, InnoSetup self-extracting archive
+
+# Hmm, not a PE but the relocation table is too high for a traditional DOS exe,
+# must be one of the unusual subformats.
+>>(0x3c.l) string !PE\0\0 MS-DOS executable
+!:mime application/x-dosexec
+
+>>(0x3c.l)             string          NE \b, NE
+!:mime application/x-dosexec
+>>>(0x3c.l+0x36)       byte            1 for OS/2 1.x
+>>>(0x3c.l+0x36)       byte            2 for MS Windows 3.x
+>>>(0x3c.l+0x36)       byte            3 for MS-DOS
+>>>(0x3c.l+0x36)       byte            4 for Windows 386
+>>>(0x3c.l+0x36)       byte            5 for Borland Operating System Services
+>>>(0x3c.l+0x36)       default         x
+>>>>(0x3c.l+0x36)      byte            x (unknown OS %x)
+>>>(0x3c.l+0x36)       byte            0x81 for MS-DOS, Phar Lap DOS extender
+>>>(0x3c.l+0x0c)       leshort&0x8000  0x8000 (DLL or font)
+# DRV: Driver
+# 3GR: Grabber device driver
+# CPL: Control Panel Item
+# VBX: Visual Basic Extension
+# FON: Bitmap font
+# FOT: Font resource file
+!:ext  dll/drv/3gr/cpl/vbx/fon/fot
+>>>(0x3c.l+0x0c)       leshort&0x8000  0 (EXE)
+!:ext  exe/scr
+>>>&(&0x24.s-1)                string          ARJSFX \b, ARJ self-extracting archive
+>>>(0x3c.l+0x70)       search/0x80     WinZip(R)\ Self-Extractor \b, ZIP self-extracting archive (WinZip)
+
+>>(0x3c.l)             string          LX\0\0 \b, LX
+!:mime application/x-dosexec
+>>>(0x3c.l+0x0a)       leshort         <1 (unknown OS)
+>>>(0x3c.l+0x0a)       leshort         1 for OS/2
+>>>(0x3c.l+0x0a)       leshort         2 for MS Windows
+>>>(0x3c.l+0x0a)       leshort         3 for DOS
+>>>(0x3c.l+0x0a)       leshort         >3 (unknown OS)
+>>>(0x3c.l+0x10)       lelong&0x28000  =0x8000 (DLL)
+>>>(0x3c.l+0x10)       lelong&0x20000  >0 (device driver)
+>>>(0x3c.l+0x10)       lelong&0x300    0x300 (GUI)
+>>>(0x3c.l+0x10)       lelong&0x28300  <0x300 (console)
+>>>(0x3c.l+0x08)       leshort         1 i80286
+>>>(0x3c.l+0x08)       leshort         2 i80386
+>>>(0x3c.l+0x08)       leshort         3 i80486
+>>>(8.s*16)            string          emx \b, emx
+>>>>&1                 string          x %s
+>>>&(&0x54.l-3)                string          arjsfx \b, ARJ self-extracting archive
+
+# MS Windows system file, supposedly a collection of LE executables
+>>(0x3c.l)             string          W3 \b, W3 for MS Windows
+!:mime application/x-dosexec
+
+>>(0x3c.l)             string          LE\0\0 \b, LE executable
+!:mime application/x-dosexec
+>>>(0x3c.l+0x0a)       leshort         1
+# some DOS extenders use LE files with OS/2 header
+>>>>0x240              search/0x100    DOS/4G for MS-DOS, DOS4GW DOS extender
+>>>>0x240              search/0x200    WATCOM\ C/C++ for MS-DOS, DOS4GW DOS extender
+>>>>0x440              search/0x100    CauseWay\ DOS\ Extender for MS-DOS, CauseWay DOS extender
+>>>>0x40               search/0x40     PMODE/W for MS-DOS, PMODE/W DOS extender
+>>>>0x40               search/0x40     STUB/32A for MS-DOS, DOS/32A DOS extender (stub)
+>>>>0x40               search/0x80     STUB/32C for MS-DOS, DOS/32A DOS extender (configurable stub)
+>>>>0x40               search/0x80     DOS/32A for MS-DOS, DOS/32A DOS extender (embedded)
+# this is a wild guess; hopefully it is a specific signature
+>>>>&0x24              lelong          <0x50
+>>>>>(&0x4c.l)         string          \xfc\xb8WATCOM
+>>>>>>&0               search/8        3\xdbf\xb9 \b, 32Lite compressed
+# another wild guess: if real OS/2 LE executables exist, they probably have higher start EIP
+#>>>>(0x3c.l+0x1c)     lelong          >0x10000 for OS/2
+# fails with DOS-Extenders.
+>>>(0x3c.l+0x0a)       leshort         2 for MS Windows
+>>>(0x3c.l+0x0a)       leshort         3 for DOS
+>>>(0x3c.l+0x0a)       leshort         4 for MS Windows (VxD)
+# VXD: VxD for Windows 95/98/Me
+# 386: VxD for Windows 2.10, 3.0, 3.1x
+# PDR: Port driver
+# MPD: Miniport driver (?)
+!:ext  vxd/386/pdr/mpd
+>>>(&0x7c.l+0x26)      string          UPX \b, UPX compressed
+>>>&(&0x54.l-3)                string          UNACE \b, ACE self-extracting archive
+
+# looks like ASCII, probably some embedded copyright message.
+# and definitely not NE/LE/LX/PE
+>>0x3c         lelong  >0x20000000
+>>>(4.s*512)   leshort !0x014c \b, MZ for MS-DOS
+!:mime application/x-dosexec
+!:ext  exe/com
+# header data too small for extended executable
+>2             long    !0
+>>0x18         leshort <0x40
+>>>(4.s*512)   leshort !0x014c
+
+>>>>&(2.s-514) string  !LE
+>>>>>&-2       string  !BW \b, MZ for MS-DOS
+!:mime application/x-dosexec
+>>>>&(2.s-514) string  LE \b, LE
+>>>>>0x240     search/0x100    DOS/4G for MS-DOS, DOS4GW DOS extender
+# educated guess since indirection is still not capable enough for complex offset
+# calculations (next embedded executable would be at &(&2*512+&0-2)
+# I suspect there are only LE executables in these multi-exe files
+>>>>&(2.s-514) string  BW
+>>>>>0x240     search/0x100    DOS/4G  \b, LE for MS-DOS, DOS4GW DOS extender (embedded)
+>>>>>0x240     search/0x100    !DOS/4G \b, BW collection for MS-DOS
+
+# This sequence skips to the first COFF segment, usually .text
+>(4.s*512)     leshort         0x014c \b, COFF
+!:mime application/x-dosexec
+>>(8.s*16)     string          go32stub for MS-DOS, DJGPP go32 DOS extender
+>>(8.s*16)     string          emx
+>>>&1          string          x for DOS, Win or OS/2, emx %s
+>>&(&0x42.l-3) byte            x
+>>>&0x26       string          UPX \b, UPX compressed
+# and yet another guess: small .text, and after large .data is unusal, could be 32lite
+>>&0x2c                search/0xa0     .text
+>>>&0x0b       lelong          <0x2000
+>>>>&0         lelong          >0x6000 \b, 32lite compressed
+
+>(8.s*16) string $WdX \b, WDos/X DOS extender
+
+# By now an executable type should have been printed out.  The executable
+# may be a self-uncompressing archive, so look for evidence of that and
+# print it out.
+#
+# Some signatures below from Greg Roelofs, newt@uchicago.edu.
+#
+>0x35  string  \x8e\xc0\xb9\x08\x00\xf3\xa5\x4a\x75\xeb\x8e\xc3\x8e\xd8\x33\xff\xbe\x30\x00\x05 \b, aPack compressed
+>0xe7  string  LH/2\   Self-Extract \b, %s
+>0x1c  string  UC2X    \b, UCEXE compressed
+>0x1c  string  WWP\    \b, WWPACK compressed
+>0x1c  string  RJSX    \b, ARJ self-extracting archive
+>0x1c  string  diet    \b, diet compressed
+>0x1c  string  LZ09    \b, LZEXE v0.90 compressed
+>0x1c  string  LZ91    \b, LZEXE v0.91 compressed
+>0x1c  string  tz      \b, TinyProg compressed
+>0x1e  string  Copyright\ 1989-1990\ PKWARE\ Inc.      Self-extracting PKZIP archive
+!:mime application/zip
+# Yes, this really is "Copr", not "Corp."
+>0x1e  string  PKLITE\ Copr.   Self-extracting PKZIP archive
+!:mime application/zip
+# winarj stores a message in the stub instead of the sig in the MZ header
+>0x20  search/0xe0     aRJsfX \b, ARJ self-extracting archive
+>0x20  string AIN
+>>0x23 string 2        \b, AIN 2.x compressed
+>>0x23 string <2       \b, AIN 1.x compressed
+>>0x23 string >2       \b, AIN 1.x compressed
+>0x24  string  LHa's\ SFX \b, LHa self-extracting archive
+!:mime application/x-lha
+>0x24  string  LHA's\ SFX \b, LHa self-extracting archive
+!:mime application/x-lha
+>0x24  string  \ $ARX \b, ARX self-extracting archive
+>0x24  string  \ $LHarc \b, LHarc self-extracting archive
+>0x20  string  SFX\ by\ LARC \b, LARC self-extracting archive
+>0x40  string aPKG \b, aPackage self-extracting archive
+>0x64  string  W\ Collis\0\0 \b, Compack compressed
+>0x7a  string          Windows\ self-extracting\ ZIP   \b, ZIP self-extracting archive
+>>&0xf4 search/0x140 \x0\x40\x1\x0
+>>>(&0.l+(4)) string MSCF \b, WinHKI CAB self-extracting archive
+>1638  string  -lh5- \b, LHa self-extracting archive v2.13S
+>0x17888 string Rar! \b, RAR self-extracting archive
+
+# Skip to the end of the EXE.  This will usually work fine in the PE case
+# because the MZ image is hardcoded into the toolchain and almost certainly
+# won't match any of these signatures.
+>(4.s*512)     long    x
+>>&(2.s-517)   byte    x
+>>>&0  string          PK\3\4 \b, ZIP self-extracting archive
+>>>&0  string          Rar! \b, RAR self-extracting archive
+>>>&0  string          =!\x11 \b, AIN 2.x self-extracting archive
+>>>&0  string          =!\x12 \b, AIN 2.x self-extracting archive
+>>>&0  string          =!\x17 \b, AIN 1.x self-extracting archive
+>>>&0  string          =!\x18 \b, AIN 1.x self-extracting archive
+>>>&7  search/400      **ACE** \b, ACE self-extracting archive
+>>>&0  search/0x480    UC2SFX\ Header \b, UC2 self-extracting archive
+
+# a few unknown ZIP sfxes, no idea if they are needed or if they are
+# already captured by the generic patterns above
+>(8.s*16)      search/0x20     PKSFX \b, ZIP self-extracting archive (PKZIP)
+# TODO: how to add this? >FileSize-34 string Windows\ Self-Installing\ Executable \b, ZIP self-extracting archive
+#
+
+# TELVOX Teleinformatica CODEC self-extractor for OS/2:
+>49801 string  \x79\xff\x80\xff\x76\xff        \b, CODEC archive v3.21
+>>49824 leshort                =1                      \b, 1 file
+>>49824 leshort                >1                      \b, %u files
+
+# added by Joerg Jenderek of https://www.freedos.org/software/?prog=kc
+# and https://www.freedos.org/software/?prog=kpdos
+# for FreeDOS files like KEYBOARD.SYS, KEYBRD2.SYS, KEYBRD3.SYS, *.KBD
+0      string/b        KCF             FreeDOS KEYBoard Layout collection
+# only version=0x100 found
+>3     uleshort        x               \b, version 0x%x
+# length of string containing author,info and special characters
+>6     ubyte           >0
+#>>6   pstring         x               \b, name=%s
+>>7    string          >\0             \b, author=%-.14s
+>>7    search/254      \xff            \b, info=
+#>>>&0 string          x               \b%-s
+>>>&0  string          x               \b%-.15s
+# for FreeDOS *.KL files
+0      string/b        KLF             FreeDOS KEYBoard Layout file
+# only version=0x100 or 0x101 found
+>3     uleshort        x               \b, version 0x%x
+# stringlength
+>5     ubyte           >0
+>>8    string          x               \b, name=%-.2s
+0      string  \xffKEYB\ \ \ \0\0\0\0
+>12    string  \0\0\0\0`\004\360       MS-DOS KEYBoard Layout file
+
+# DOS device driver updated by Joerg Jenderek at May 2011,Mar 2017
+# https://amaus.net/static/S100/IBM/software/DOS/DOS%20techref/CHAPTER.009
+0      ulequad&0x07a0ffffffff          0xffffffff
+>0     use                             msdos-driver
+0       name                           msdos-driver            DOS executable (
+#!:mime        application/octet-stream
+!:mime application/x-dosdriver
+# also found FreeDOS print driver SPOOL.DEV and disc compression driver STACLOAD.BIN
+!:ext  sys/dev/bin
+>40    search/7                        UPX!                    \bUPX compressed
+# DOS device driver attributes
+>4     uleshort&0x8000                 0x0000                  \bblock device driver
+# character device
+>4     uleshort&0x8000                 0x8000                  \b
+>>4    uleshort&0x0008                 0x0008                  \bclock
+# fast video output by int 29h
+>>4    uleshort&0x0010                 0x0010                  \bfast
+# standard input/output device
+>>4    uleshort&0x0003                 >0                      \bstandard
+>>>4   uleshort&0x0001                 0x0001                  \binput
+>>>4   uleshort&0x0003                 0x0003                  \b/
+>>>4   uleshort&0x0002                 0x0002                  \boutput
+>>4    uleshort&0x8000                 0x8000                  \bcharacter device driver
+>0     ubyte                           x
+# upx compressed device driver has garbage instead of real in name field of header
+>>40   search/7                        UPX!
+>>40   default                         x
+# leading/trailing nulls, zeros or non ASCII characters in 8-byte name field at offset 10 are skipped
+>>>12          ubyte                   >0x2E                   \b
+>>>>10         ubyte                   >0x20
+>>>>>10                ubyte                   !0x2E
+>>>>>>10       ubyte                   !0x2A                   \b%c
+>>>>11         ubyte                   >0x20
+>>>>>11                ubyte                   !0x2E                   \b%c
+>>>>12         ubyte                   >0x20
+>>>>>12                ubyte                   !0x39
+>>>>>>12       ubyte                   !0x2E                   \b%c
+>>>13          ubyte                   >0x20
+>>>>13         ubyte                   !0x2E                   \b%c
+>>>>14         ubyte                   >0x20
+>>>>>14                ubyte                   !0x2E                   \b%c
+>>>>15         ubyte                   >0x20
+>>>>>15                ubyte                   !0x2E                   \b%c
+>>>>16         ubyte                   >0x20
+>>>>>16                ubyte                   !0x2E
+>>>>>>16       ubyte                   <0xCB                   \b%c
+>>>>17         ubyte                   >0x20
+>>>>>17                ubyte                   !0x2E
+>>>>>>17       ubyte                   <0x90                   \b%c
+# some character device drivers like ASPICD.SYS, btcdrom.sys and Cr_atapi.sys contain only spaces or points in name field
+>>>12          ubyte                   <0x2F
+# they have their real name at offset 22
+# also block device drivers like DUMBDRV.SYS
+>>>>22         string                  >\056                   %-.6s
+>4     uleshort&0x8000                 0x0000
+# 32 bit sector addressing ( > 32 MB) for block devices
+>>4    uleshort&0x0002                 0x0002                  \b,32-bit sector-
+# support by driver functions 13h, 17h, 18h
+>4     uleshort&0x0040                 0x0040                  \b,IOCTL-
+# open, close, removable media support by driver functions 0Dh, 0Eh, 0Fh
+>4     uleshort&0x0800                 0x0800                  \b,close media-
+# output until busy support by int 10h for character device driver
+>4     uleshort&0x8000                 0x8000
+>>4    uleshort&0x2000                 0x2000                  \b,until busy-
+# direct read/write support by driver functions 03h,0Ch
+>4     uleshort&0x4000                 0x4000                  \b,control strings-
+>4     uleshort&0x8000                 0x8000
+>>4    uleshort&0x6840                 >0                      \bsupport
+>4     uleshort&0x8000                 0x0000
+>>4    uleshort&0x4842                 >0                      \bsupport
+>0     ubyte                           x                       \b)
+# DOS driver cmd640x.sys has 0x12 instead of 0xffffffff for pointer field to next device header
+0      ulequad                         0x0513c00000000012
+>0     use                             msdos-driver
+# DOS drivers DC2975.SYS, DUMBDRV.SYS, ECHO.SYS has also none 0xffffffff for pointer field
+0      ulequad                         0x32f28000ffff0016
+>0     use                             msdos-driver
+0      ulequad                         0x007f00000000ffff
+>0     use                             msdos-driver
+0      ulequad                         0x001600000000ffff
+>0     use                             msdos-driver
+# DOS drivers LS120.SYS, MKELS120.SYS use reserved bits of attribute field
+0      ulequad                         0x0bf708c2ffffffff
+>0     use                             msdos-driver
+0      ulequad                         0x07bd08c2ffffffff
+>0     use                             msdos-driver
+
+# updated by Joerg Jenderek
+# GRR: line below too general as it catches also
+# rt.lib DYADISKS.PIC and many more
+# start with assembler instruction MOV
+0      ubyte           0x8c
+# skip "AppleWorks word processor data" like ARTICLE.1 ./apple
+>4     string                  !O====
+# skip some unknown basic binaries like RocketRnger.SHR
+>>5    string                  !MAIN
+# skip "GPG symmetrically encrypted data" ./gnu
+# skip "PGP symmetric key encrypted data" ./pgp
+# openpgpdefs.h: fourth byte < 14 indicate cipher algorithm type
+>>>4   ubyte                   >13     DOS executable (COM, 0x8C-variant)
+# the remaining files should be DOS *.COM executables
+# dosshell.COM 8cc0 2ea35f07 e85211 e88a11 b80058 cd
+# hmload.COM   8cc8 8ec0 bbc02b 89dc 83c30f c1eb04 b4
+# UNDELETE.COM 8cca 2e8916 6503 b430 cd21 8b 2e0200 8b
+# BOOTFIX.COM  8cca 2e8916 9603 b430 cd21 8b 2e0200 8b
+# RAWRITE3.COM 8cca 2e8916 d602 b430 cd21 8b 2e0200 8b
+# SHARE.COM    8cca 2e8916 d602 b430 cd21 8b 2e0200 8b
+# validchr.COM 8cca 2e8916 9603 b430 cd21 8b 2e028b1e
+# devload.COM  8cca 8916ad01 b430 cd21 8b2e0200 892e
+!:mime application/x-dosexec
+!:ext com
+
+# updated by Joerg Jenderek at Oct 2008
+0      ulelong         0xffff10eb      DR-DOS executable (COM)
+# byte 0xeb conflicts with "sequent" magic leshort 0xn2eb
+0      ubeshort&0xeb8d >0xeb00
+# DR-DOS STACKER.COM SCREATE.SYS missed
+
+0       name    msdos-com
+>0  byte        x               DOS executable (COM)
+!:mime application/x-dosexec
+!:ext  com
+>6     string          SFX\ of\ LHarc  \b, %s
+>0x1FE leshort 0xAA55              \b, boot code
+>85    string          UPX                     \b, UPX compressed
+>4     string          \ $ARX              \b, ARX self-extracting archive
+>4     string          \ $LHarc            \b, LHarc self-extracting archive
+>0x20e string  SFX\ by\ LARC   \b, LARC self-extracting archive
+
+# JMP 8bit
+0              byte    0xeb
+# allow forward jumps only
+>1          byte    >-1
+# that offset must be accessible
+>>(1.b+2)   byte    x
+>>>0        use msdos-com
+
+# JMP 16bit
+0           byte    0xe9
+# forward jumps
+>1          short   >-1
+# that offset must be accessible
+>>(1.s+3)   byte    x
+>>>0        use msdos-com
+# negative offset, must not lead into PSP
+>1          short   <-259
+# that offset must be accessible
+>>(1,s+65539)   byte    x
+>>>0        use msdos-com
+
+# updated by Joerg Jenderek at Oct 2008,2015
+# following line is too general
+0      ubyte           0xb8
+# skip 2 linux kernels like memtest.bin with "\xb8\xc0\x07\x8e" in ./linux
+>0     string          !\xb8\xc0\x07\x8e
+# modified by Joerg Jenderek
+# syslinux COM32 or COM32R executable
+>>1    lelong&0xFFFFFFFe 0x21CD4CFe    COM executable (32-bit COMBOOT
+# https://www.syslinux.org/wiki/index.php/Comboot_API
+# Since version 5.00 c32 modules switched from the COM32 object format to ELF
+!:mime application/x-c32-comboot-syslinux-exec
+!:ext c32
+# https://syslinux.zytor.com/comboot.php
+# older syslinux version ( <4 )
+# (32-bit COMBOOT) programs *.C32 contain 32-bit code and run in flat-memory 32-bit protected mode
+# start with assembler instructions mov eax,21cd4cffh
+>>>1   lelong          0x21CD4CFf      \b)
+# syslinux:doc/comboot.txt
+# A COM32R program must start with the byte sequence B8 FE 4C CD 21 (mov
+# eax,21cd4cfeh) as a magic number.
+# syslinux version (4.x)
+# "COM executable (COM32R)" or "Syslinux COM32 module" by TrID
+>>>1   lelong          0x21CD4CFe      \b, relocatable)
+# remaining are DOS COM executables starting with assembler instruction MOV
+# like FreeDOS BANNER*.COM FINDDISK.COM GIF2RAW.COM WINCHK.COM
+# MS-DOS SYS.COM RESTART.COM
+# SYSLINUX.COM (version 1.40 - 2.13)
+# GFXBOOT.COM (version 3.75)
+# COPYBS.COM POWEROFF.COM INT18.COM
+>>1    default x                       COM executable for DOS
+!:mime application/x-dosexec
+#!:mime        application/x-ms-dos-executable
+#!:mime        application/x-msdos-program
+!:ext com
+
+0      string/b        \x81\xfc
+>4     string  \x77\x02\xcd\x20\xb9
+>>36   string  UPX!                    FREE-DOS executable (COM), UPX compressed
+!:mime application/x-dosexec
+!:ext  com
+252    string Must\ have\ DOS\ version DR-DOS executable (COM)
+!:mime application/x-dosexec
+!:ext  com
+# added by Joerg Jenderek at Oct 2008
+# GRR search is not working
+#34    search/2        UPX!            FREE-DOS executable (COM), UPX compressed
+34     string  UPX!                    FREE-DOS executable (COM), UPX compressed
+!:mime application/x-dosexec
+!:ext  com
+35     string  UPX!                    FREE-DOS executable (COM), UPX compressed
+!:mime application/x-dosexec
+!:ext  com
+# GRR search is not working
+#2     search/28       \xcd\x21        COM executable for MS-DOS
+#WHICHFAT.cOM
+2      string  \xcd\x21                COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+#DELTREE.cOM DELTREE2.cOM
+4      string  \xcd\x21                COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+#IFMEMDSK.cOM ASSIGN.cOM COMP.cOM
+5      string  \xcd\x21                COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+#DELTMP.COm HASFAT32.cOM
+7      string  \xcd\x21
+>0     byte    !0xb8                   COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+#COMP.cOM MORE.COm
+10     string  \xcd\x21
+>5     string  !\xcd\x21               COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+#comecho.com
+13     string  \xcd\x21                COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+#HELP.COm EDIT.coM
+18     string  \xcd\x21                COM executable for MS-DOS
+!:mime application/x-dosexec
+!:ext  com
+#NWRPLTRM.COm
+23     string  \xcd\x21                COM executable for MS-DOS
+!:mime application/x-dosexec
+!:ext  com
+#LOADFIX.cOm LOADFIX.cOm
+30     string  \xcd\x21                COM executable for MS-DOS
+!:mime application/x-dosexec
+!:ext  com
+#syslinux.com 3.11
+70     string  \xcd\x21                COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+# many compressed/converted COMs start with a copy loop instead of a jump
+0x6    search/0xa      \xfc\x57\xf3\xa5\xc3    COM executable for MS-DOS
+!:mime application/x-dosexec
+!:ext  com
+0x6    search/0xa      \xfc\x57\xf3\xa4\xc3    COM executable for DOS
+!:mime application/x-dosexec
+!:ext  com
+>0x18  search/0x10     \x50\xa4\xff\xd5\x73    \b, aPack compressed
+0x3c   string          W\ Collis\0\0           COM executable for MS-DOS, Compack compressed
+!:mime application/x-dosexec
+!:ext  com
+# FIXME: missing diet .com compression
+
+# miscellaneous formats
+0      string/b        LZ              MS-DOS executable (built-in)
+#0     byte            0xf0            MS-DOS program library data
+#
+
+# AAF files:
+# <stuartc@rd.bbc.co.uk> Stuart Cunningham
+0      string/b        \320\317\021\340\241\261\032\341AAFB\015\000OM\006\016\053\064\001\001\001\377                  AAF legacy file using MS Structured Storage
+>30    byte    9               (512B sectors)
+>30    byte    12              (4kB sectors)
+0      string/b        \320\317\021\340\241\261\032\341\001\002\001\015\000\002\000\000\006\016\053\064\003\002\001\001                        AAF file using MS Structured Storage
+>30    byte    9               (512B sectors)
+>30    byte    12              (4kB sectors)
+
+# Popular applications
+2080   string  Microsoft\ Word\ 6.0\ Document  %s
+!:mime application/msword
+2080   string  Documento\ Microsoft\ Word\ 6 Spanish Microsoft Word 6 document data
+!:mime application/msword
+# Pawel Wiecek <coven@i17linuxb.ists.pwr.wroc.pl> (for polish Word)
+2112   string  MSWordDoc                       Microsoft Word document data
+!:mime application/msword
+#
+0      belong  0x31be0000                      Microsoft Word Document
+!:mime application/msword
+#
+0      string/b        PO^Q`                           Microsoft Word 6.0 Document
+!:mime application/msword
+#
+4   long        0
+>0  belong      0xfe320000      Microsoft Word for Macintosh 1.0
+!:mime application/msword
+!:ext   mcw
+>0  belong      0xfe340000      Microsoft Word for Macintosh 3.0
+!:mime application/msword
+!:ext   mcw
+>0  belong      0xfe37001c      Microsoft Word for Macintosh 4.0
+!:mime application/msword
+!:ext   mcw
+>0  belong      0xfe370023      Microsoft Word for Macintosh 5.0
+!:mime application/msword
+!:ext   mcw
+
+0      string/b        \333\245-\0\0\0                 Microsoft Word 2.0 Document
+!:mime application/msword
+!:ext   doc
+# Note: seems already recognized as "OLE 2 Compound Document" in ./ole2compounddocs
+#512   string/b        \354\245\301                    Microsoft Word Document
+#!:mime        application/msword
+
+#
+0      string/b        \xDB\xA5\x2D\x00                Microsoft WinWord 2.0 Document
+!:mime application/msword
+#
+2080   string  Microsoft\ Excel\ 5.0\ Worksheet        %s
+!:mime application/vnd.ms-excel
+#
+0      string/b        \xDB\xA5\x2D\x00                Microsoft WinWord 2.0 Document
+!:mime application/msword
+
+2080   string  Foglio\ di\ lavoro\ Microsoft\ Exce     %s
+!:mime application/vnd.ms-excel
+#
+# Pawel Wiecek <coven@i17linuxb.ists.pwr.wroc.pl> (for polish Excel)
+2114   string  Biff5           Microsoft Excel 5.0 Worksheet
+!:mime application/vnd.ms-excel
+# Italian MS-Excel
+2121   string  Biff5           Microsoft Excel 5.0 Worksheet
+!:mime application/vnd.ms-excel
+0      string/b        \x09\x04\x06\x00\x00\x00\x10\x00        Microsoft Excel Worksheet
+!:mime application/vnd.ms-excel
+#
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Lotus_1-2-3
+# Reference: http://www.aboutvb.de/bas/formate/pdf/wk3.pdf
+# Note: newer Lotus versions >2 use longer BOF record
+# record type (BeginningOfFile=0000h) + length (001Ah)
+0      belong  0x00001a00
+# reserved should be 0h but 8c0dh for TUTMAC.WK3, 5h for SAMPADNS.WK3, 1h for a_readme.wk3, 1eh for K&G86.WK3
+#>18   uleshort&0x73E0 0
+# Lotus Multi Byte Character Set (LMBCS=1-31)
+>20    ubyte           >0
+>>20   ubyte           <32     Lotus 1-2-3
+#!:mime        application/x-123
+!:mime application/vnd.lotus-1-2-3
+!:apple        ????L123
+# (version 5.26) labeled the entry as "Lotus 1-2-3 wk3 document data"
+>>>4   uleshort        0x1000  WorKsheet, version 3
+!:ext  wk3
+# (version 5.26) labeled the entry as "Lotus 1-2-3 wk4 document data"
+>>>4   uleshort        0x1002  WorKsheet, version 4
+# also worksheet template 4 (.wt4)
+!:ext  wk4/wt4
+# no example or documentation for wk5
+#>>4   uleshort        0x????  WorKsheet, version 4
+#!:ext wk5
+# only MacrotoScript.123 example
+>>>4   uleshort        0x1003  WorKsheet, version 97
+# also worksheet template Smartmaster (.12M)?
+!:ext  123
+# only Set_Y2K.123 example
+>>>4   uleshort        0x1005  WorKsheet, version 9.8 Millennium
+!:ext  123
+# no example for this version
+>>>4   uleshort        0x8001  FoRMatting data
+!:ext  frm
+# (version 5.26) labeled the entry as "Lotus 1-2-3 fm3 or fmb document data"
+# TrID labeles the entry as "Formatting Data for Lotus 1-2-3 worksheet"
+>>>4   uleshort        0x8007  ForMatting data, version 3
+!:ext  fm3
+>>>4   default         x       unknown
+# file revision sub code 0004h for worksheets
+>>>>6  uleshort        =0x0004 worksheet
+!:ext  wXX
+>>>>6  uleshort        !0x0004 formatting data
+!:ext  fXX
+# main revision number
+>>>>4  uleshort        x       \b, revision 0x%x
+>>>6   uleshort        =0x0004 \b, cell range
+# active cellcoord range (start row, page,column ; end row, page, column)
+# start values normally 0~1st sheet A1
+>>>>8  ulelong         !0
+>>>>>10        ubyte           >0      \b%d*
+>>>>>8 uleshort        x       \b%d,
+>>>>>11        ubyte           x       \b%d-
+# end page mostly 0
+>>>>14 ubyte           >0      \b%d*
+# end raw, column normally not 0
+>>>>12 uleshort        x       \b%d,
+>>>>15 ubyte           x       \b%d
+# Lotus Multi Byte Character Set (1~cp850,2~cp851,...,16~japan,...,31~??)
+>>>>20 ubyte           >1      \b, character set 0x%x
+# flags
+>>>>21 ubyte           x       \b, flags 0x%x
+>>>6   uleshort        !0x0004
+# record type (FONTNAME=00AEh)
+>>>>30 search/29       \0\xAE
+# variable length m (2) + entries (1) + ?? (1) + LCMBS string (n)
+>>>>>&4        string          >\0     \b, 1st font "%s"
+#
+# Update: Joerg Jenderek
+# URL: http://fileformats.archiveteam.org/wiki/Lotus_1-2-3
+# Reference: http://www.schnarff.com/file-formats/lotus-1-2-3/WSFF2.TXT
+# Note: Used by both old Lotus 1-2-3 and Lotus Symphony (DOS) til version 2.x
+# record type (BeginningOfFile=0000h) + length (0002h)
+0      belong  0x00000200
+# GRR: line above is too general as it catches also MS Windows CURsor
+# to display MS Windows cursor (strength=70) before Lotus 1-2-3 (strength=70-1)
+!:strength -1
+# skip Windows cursors with image height <256 and keep Lotus with low opcode 0001-0083h
+>7     ubyte           0
+# skip Windows cursors with image width 256 and keep Lotus with positiv opcode
+>>6    ubyte           >0      Lotus
+# !:mime       application/x-123
+!:mime application/vnd.lotus-1-2-3
+!:apple        ????L123
+# revision number (0404h = 123 1A, 0405h = Lotus Symphony , 0406h = 123 2.x wk1 , 8006h = fmt , ...)
+# undocumented; (version 5.26) labeled the configurations as "Lotus 1-2-3"
+>>>4   uleshort        0x0007  1-2-3 CoNFiguration, version 2.x (PGRAPH.CNF)
+!:ext  cnf
+>>>4   uleshort        0x0C05  1-2-3 CoNFiguration, version 2.4J
+!:ext  cnf
+>>>4   uleshort        0x0801  1-2-3 CoNFiguration, version 1-2.1
+!:ext  cnf
+>>>4   uleshort        0x0802  Symphony CoNFiguration
+!:ext  cnf
+>>>4   uleshort        0x0804  1-2-3 CoNFiguration, version 2.2
+!:ext  cnf
+>>>4   uleshort        0x080A  1-2-3 CoNFiguration, version 2.3-2.4
+!:ext  cnf
+>>>4   uleshort        0x1402  1-2-3 CoNFiguration, version 3.x
+!:ext  cnf
+>>>4   uleshort        0x1450  1-2-3 CoNFiguration, version 4.x
+!:ext  cnf
+# (version 5.26) labeled the entry as "Lotus 123"
+# TrID labeles the entry as "Lotus 123 Worksheet (generic)"
+>>>4   uleshort        0x0404  1-2-3 WorKSheet, version 1
+# extension "wks" also for Microsoft Works document
+!:ext  wks
+# (version 5.26) labeled the entry as "Lotus 123"
+# TrID labeles the entry as "Lotus 123 Worksheet (generic)"
+>>>4   uleshort        0x0405  Symphony WoRksheet, version 1.0
+!:ext  wrk/wr1
+# (version 5.26) labeled the entry as "Lotus 1-2-3 wk1 document data"
+# TrID labeles the entry as "Lotus 123 Worksheet (V2)"
+>>>4   uleshort        0x0406  1-2-3/Symphony worksheet, version 2
+# Symphony (.wr1)
+!:ext  wk1/wr1
+# no example for this japan version
+>>>4   uleshort        0x0600  1-2-3 WorKsheet, version 1.xJ
+!:ext  wj1
+# no example or documentation for wk2
+#>>>4  uleshort        0x????  1-2-3 WorKsheet, version 2
+#!:ext wk2
+# undocumented japan version
+>>>4   uleshort        0x0602  1-2-3 worksheet, version 2.4J
+!:ext  wj3
+# (version 5.26) labeled the entry as "Lotus 1-2-3 fmt document data"
+>>>4   uleshort        0x8006  1-2-3 ForMaTting data, version 2.x
+# japan version 2.4J (fj3)
+!:ext  fmt/fj3
+# no example for this version
+>>>4   uleshort        0x8007  1-2-3 FoRMatting data, version 2.0
+!:ext  frm
+# (version 5.26) labeled the entry as "Lotus 1-2-3"
+>>>4   default         x       unknown worksheet or configuration
+!:ext  cnf
+>>>>4  uleshort        x       \b, revision 0x%x
+# 2nd record for most worksheets describes cells range
+>>>6           use     lotus-cells
+# 3nd record for most japan worksheets describes cells range
+>>>(8.s+10)    use     lotus-cells
+#      check and then display Lotus worksheet cells range
+0      name            lotus-cells
+# look for type (RANGE=0006h) + length (0008h) at record begin
+>0     ubelong 0x06000800      \b, cell range
+# cell range (start column, row, end column, row) start values normally 0,0~A1 cell
+>>4    ulong           !0
+>>>4   uleshort        x       \b%d,
+>>>6   uleshort        x       \b%d-
+# end of cell range
+>>8    uleshort        x       \b%d,
+>>10   uleshort        x       \b%d
+# EndOfLotus123
+0      string/b                WordPro\0       Lotus WordPro
+!:mime application/vnd.lotus-wordpro
+0      string/b                WordPro\r\373   Lotus WordPro
+!:mime application/vnd.lotus-wordpro
+
+
+# Summary: Script used by InstallScield to uninstall applications
+# Extension: .isu
+# Submitted by: unknown
+# Modified by (1): Abel Cheung <abelcheung@gmail.com> (replace useless entry)
+0              string          \x71\xa8\x00\x00\x01\x02
+>12            string          Stirling\ Technologies,         InstallShield Uninstall Script
+
+# Winamp .avs
+#0     string  Nullsoft\ AVS\ Preset\ \060\056\061\032 A plug in for Winamp ms-windows Freeware media player
+0      string/b        Nullsoft\ AVS\ Preset\  Winamp plug in
+
+# Windows Metafile .WMF
+0      string/b        \327\315\306\232        Windows metafile
+!:mime image/wmf
+!:ext  wmf
+0      string/b        \002\000\011\000        Windows metafile
+!:mime image/wmf
+!:ext  wmf
+0      string/b        \001\000\011\000        Windows metafile
+!:mime image/wmf
+!:ext  wmf
+
+#tz3 files whatever that is (MS Works files)
+0      string/b        \003\001\001\004\070\001\000\000        tz3 ms-works file
+0      string/b        \003\002\001\004\070\001\000\000        tz3 ms-works file
+0      string/b        \003\003\001\004\070\001\000\000        tz3 ms-works file
+
+# PGP sig files .sig
+#0 string \211\000\077\003\005\000\063\237\127 065 to  \027\266\151\064\005\045\101\233\021\002 PGP sig
+0 string \211\000\077\003\005\000\063\237\127\065\027\266\151\064\005\045\101\233\021\002 PGP sig
+0 string \211\000\077\003\005\000\063\237\127\066\027\266\151\064\005\045\101\233\021\002 PGP sig
+0 string \211\000\077\003\005\000\063\237\127\067\027\266\151\064\005\045\101\233\021\002 PGP sig
+0 string \211\000\077\003\005\000\063\237\127\070\027\266\151\064\005\045\101\233\021\002 PGP sig
+0 string \211\000\077\003\005\000\063\237\127\071\027\266\151\064\005\045\101\233\021\002 PGP sig
+0 string \211\000\225\003\005\000\062\122\207\304\100\345\042 PGP sig
+
+# windows zips files .dmf
+0      string/b        MDIF\032\000\010\000\000\000\372\046\100\175\001\000\001\036\001\000 MS Windows special zipped file
+
+
+#ico files
+0      string/b        \102\101\050\000\000\000\056\000\000\000\000\000\000\000        Icon for MS Windows
+
+# Windows icons
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/CUR_(file_format)
+# Note: similar to Windows CURsor. container for BMP (only DIB part) or PNG
+0   belong  0x00000100
+>9  byte    0
+>>0 byte    x
+>>0 use     cur-ico-dir
+>9  ubyte   0xff
+>>0 byte    x
+>>0 use     cur-ico-dir
+#      displays number of icons and information for icon or cursor
+0      name            cur-ico-dir
+# skip some Lotus 1-2-3 worksheets, CYCLE.PIC and keep Windows cursors with
+# 1st data offset = dir header size + n * dir entry size = 6 + n * 10h = ?6h
+>18            ulelong         &0x00000006
+# skip remaining worksheets, because valid only for DIB image (40) or PNG image (\x89PNG)
+>>(18.l)       ulelong         x               MS Windows
+>>>0           ubelong         0x00000100      icon resource
+# https://www.iana.org/assignments/media-types/image/vnd.microsoft.icon
+!:mime         image/vnd.microsoft.icon
+#!:mime                image/x-icon
+!:ext          ico
+>>>>4          uleshort        x               - %d icon
+# plural s
+>>>>4          uleshort        >1              \bs
+# 1st icon
+>>>>0x06       use             ico-entry
+# 2nd icon
+>>>>4          uleshort        >1
+>>>>>0x16      use             ico-entry
+>>>0           ubelong         0x00000200      cursor resource
+#!:mime                image/x-cur
+!:mime         image/x-win-bitmap
+!:ext          cur
+>>>>4          uleshort        x               - %d icon
+>>>>4          uleshort        >1              \bs
+# 1st cursor
+>>>>0x06       use             cur-entry
+#>>>>0x16      use             cur-entry
+#      display information of one cursor entry
+0      name            cur-entry
+>0     use             cur-ico-entry
+>4     uleshort        x       \b, hotspot @%dx
+>6     uleshort        x       \b%d
+#      display information of one icon entry
+0      name            ico-entry
+>0                     use     cur-ico-entry
+# normally 0 1 but also found 14
+>4     uleshort        >1      \b, %d planes
+# normally 0 1 but also found some 3, 4, some 6, 8, 24, many 32, two 256
+>6     uleshort        >1      \b, %d bits/pixel
+#      display shared information of cursor or icon entry
+0              name            cur-ico-entry
+>0             byte            =0              \b, 256x
+>0             byte            !0              \b, %dx
+>1             byte            =0              \b256
+>1             byte            !0              \b%d
+# number of colors in palette
+>2             ubyte           !0              \b, %d colors
+# reserved 0 FFh
+#>3            ubyte           x               \b, reserved %x
+#>8            ulelong         x               \b, image size %d
+# offset of PNG or DIB image
+#>12           ulelong         x               \b, offset 0x%x
+# PNG header (\x89PNG)
+>(12.l)                ubelong         =0x89504e47
+# 1 space char after "with" to get phrase "with PNG image" by magic in ./images
+>>&-4          indirect        x       \b with 
+# DIB image
+>(12.l)                ubelong         !0x89504e47
+#>>&-4         use             dib-image
+
+# Windows non-animated cursors
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/CUR_(file_format)
+# Note: similar to Windows ICOn. container for BMP ( only DIB part)
+# GRR: line below is too general as it catches also Lotus 1-2-3 files
+0   belong  0x00000200
+>9  byte    0
+>>0 use     cur-ico-dir
+>9  ubyte   0xff
+>>0 use     cur-ico-dir
+
+# .chr files
+0      string/b        PK\010\010BGI   Borland font
+>4     string  >\0     %s
+# then there is a copyright notice
+
+
+# .bgi files
+0      string/b        pk\010\010BGI   Borland device
+>4     string  >\0     %s
+# then there is a copyright notice
+
+
+# Windows Recycle Bin record file (named INFO2)
+# By Abel Cheung (abelcheung AT gmail dot com)
+# Version 4 always has 280 bytes (0x118) per record, version 5 has 800 bytes
+# Since Vista uses another structure, INFO2 structure probably won't change
+# anymore. Detailed analysis in:
+# http://www.cybersecurityinstitute.biz/downloads/INFO2.pdf
+0      lelong          0x00000004
+>12    lelong          0x00000118      Windows Recycle Bin INFO2 file (Win98 or below)
+
+0      lelong          0x00000005
+>12    lelong          0x00000320      Windows Recycle Bin INFO2 file (Win2k - WinXP)
+
+# From Doug Lee via a FreeBSD pr
+9      string          GERBILDOC       First Choice document
+9      string          GERBILDB        First Choice database
+9      string          GERBILCLIP      First Choice database
+0      string          GERBIL          First Choice device file
+9      string          RABBITGRAPH     RabbitGraph file
+0      string          DCU1            Borland Delphi .DCU file
+0      string          =!<spell>       MKS Spell hash list (old format)
+0      string          =!<spell2>      MKS Spell hash list
+# Too simple - MPi
+#0     string          AH              Halo(TM) bitmapped font file
+0      lelong          0x08086b70      TurboC BGI file
+0      lelong          0x08084b50      TurboC Font file
+
+# Debian#712046: The magic below identifies "Delphi compiled form data".
+# An additional source of information is available at:
+# http://www.woodmann.com/fravia/dafix_t1.htm
+0      string          TPF0
+>4     pstring         >\0             Delphi compiled form '%s'
+
+# tests for DBase files moved, updated and merged to database
+
+0      string          PMCC            Windows 3.x .GRP file
+1      string          RDC-meg         MegaDots
+>8     byte            >0x2F           version %c
+>9     byte            >0x2F           \b.%c file
+0      lelong          0x4C
+>4     lelong          0x00021401      Windows shortcut file
+
+# .PIF files added by Joerg Jenderek from https://smsoft.ru/en/pifdoc.htm
+# only for windows versions equal or greater 3.0
+0x171  string  MICROSOFT\ PIFEX\0      Windows Program Information File
+!:mime application/x-dosexec
+!:ext  pif
+#>2    string          >\0             \b, Title:%.30s
+>0x24  string          >\0             \b for %.63s
+>0x65  string          >\0             \b, directory=%.64s
+>0xA5  string          >\0             \b, parameters=%.64s
+#>0x181        leshort x       \b, offset %x
+#>0x183        leshort x       \b, offsetdata %x
+#>0x185        leshort x       \b, section length %x
+>0x187 search/0xB55    WINDOWS\ VMM\ 4.0\0
+>>&0x5e                ubyte   >0
+>>>&-1         string  <PIFMGR.DLL             \b, icon=%s
+#>>>&-1                string  PIFMGR.DLL              \b, icon=%s
+>>>&-1         string  >PIFMGR.DLL             \b, icon=%s
+>>&0xF0                ubyte   >0
+>>>&-1         string  <Terminal               \b, font=%.32s
+#>>>&-1                string  =Terminal               \b, font=%.32s
+>>>&-1         string  >Terminal               \b, font=%.32s
+>>&0x110       ubyte   >0
+>>>&-1         string  <Lucida\ Console        \b, TrueTypeFont=%.32s
+#>>>&-1                string  =Lucida\ Console        \b, TrueTypeFont=%.32s
+>>>&-1         string  >Lucida\ Console        \b, TrueTypeFont=%.32s
+#>0x187        search/0xB55    WINDOWS\ 286\ 3.0\0     \b, Windows 3.X standard mode-style
+#>0x187        search/0xB55    WINDOWS\ 386\ 3.0\0     \b, Windows 3.X enhanced mode-style
+>0x187 search/0xB55    WINDOWS\ NT\ \ 3.1\0    \b, Windows NT-style
+#>0x187        search/0xB55    WINDOWS\ NT\ \ 4.0\0    \b, Windows NT-style
+>0x187 search/0xB55    CONFIG\ \ SYS\ 4.0\0    \b +CONFIG.SYS
+#>>&06         string  x                       \b:%s
+>0x187 search/0xB55    AUTOEXECBAT\ 4.0\0      \b +AUTOEXEC.BAT
+#>>&06         string  x                       \b:%s
+
+# DOS EPS Binary File Header
+# From: Ed Sznyter <ews@Black.Market.NET>
+0      belong          0xC5D0D3C6      DOS EPS Binary File
+!:mime image/x-eps
+>4     long            >0              Postscript starts at byte %d
+>>8    long            >0              length %d
+>>>12  long            >0              Metafile starts at byte %d
+>>>>16 long            >0              length %d
+>>>20  long            >0              TIFF starts at byte %d
+>>>>24 long            >0              length %d
+
+# TNEF magic From "Joomy" <joomy@se-ed.net>
+# Microsoft Outlook's Transport Neutral Encapsulation Format (TNEF)
+0      lelong          0x223e9f78      TNEF
+!:mime application/vnd.ms-tnef
+
+# Norton Guide (.NG , .HLP) files added by Joerg Jenderek from source NG2HTML.C
+# of http://www.davep.org/norton-guides/ng2h-105.tgz
+# https://en.wikipedia.org/wiki/Norton_Guides
+0      string          NG\0\001
+# only value 0x100 found at offset 2
+>2     ulelong         0x00000100      Norton Guide
+# Title[40]
+>>8    string          >\0             "%-.40s"
+#>>6   uleshort        x               \b, MenuCount=%u
+# szCredits[5][66]
+>>48   string          >\0             \b, %-.66s
+>>114  string          >\0             %-.66s
+
+# 4DOS help (.HLP) files added by Joerg Jenderek from source TPHELP.PAS
+# of https://www.4dos.info/
+# pointer,HelpID[8]=4DHnnnmm
+0      ulelong 0x48443408              4DOS help file
+>4     string  x                       \b, version %-4.4s
+
+# old binary Microsoft (.HLP) files added by Joerg Jenderek from http://file-extension.net/seeker/file_extension_hlp
+0      ulequad 0x3a000000024e4c        MS Advisor help file
+
+# HtmlHelp files (.chm)
+0      string/b        ITSF\003\000\000\000\x60\000\000\000    MS Windows HtmlHelp Data
+
+# GFA-BASIC (Wolfram Kleff)
+2      string/b        GFA-BASIC3      GFA-BASIC 3 data
+
+#------------------------------------------------------------------------------
+# From Stuart Caie <kyzer@4u.net> (developer of cabextract)
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Cabinet_(file_format)
+# Reference: https://msdn.microsoft.com/en-us/library/bb267310.aspx
+# Note: verified by `7z l *.cab`
+# Microsoft Cabinet files
+0      string/b        MSCF\0\0\0\0    Microsoft Cabinet archive data
+#
+# https://support.microsoft.com/en-us/help/973559/frequently-asked-questions-about-the-microsoft-support-diagnostic-tool
+# CAB with *.{diagcfg,diagpkg} is used by Microsoft Support Diagnostic Tool MSDT.EXE
+# because some archive does not have *.diag* as 1st or 2nd archive member like
+# O15CTRRemove.diagcab or AzureStorageAnalyticsLogs_global.DiagCab
+# brute looking after header for filenames with diagcfg or diagpkg extension in CFFILE section
+>0x2c  search/980/c    .diag           \b, Diagnostic
+!:mime application/vnd.ms-cab-compressed
+!:ext  diagcab
+# http://fileformats.archiveteam.org/wiki/PUZ
+# Microsoft Publisher version about 2003 has a "Pack and Go" feature that
+# bundles a Publisher document *PNG.pub with all links into a CAB
+>0x2c  search/300/c    png.pub\0               \b, Publisher Packed and Go
+!:mime application/vnd.ms-cab-compressed
+!:ext  puz
+# ppz variant with Microsoft PowerPoint Viewer ppview32.exe to play PowerPoint presentation
+>0x2c  search/17/c     ppview32.exe\0          \b, PowerPoint Viewer Packed and Go
+!:mime application/vnd.ms-powerpoint
+#!:mime        application/mspowerpoint
+!:ext  ppz
+# http://www.incredimail.com/
+# IncrediMail CAB contains an initialisation file "content.ini" like in im2.ims
+>0x2c  search/3369/c   content.ini\0   \b, IncrediMail
+!:mime application/x-incredimail
+# member Flavor.htm implies IncrediMail ecard like in tell_a_friend.imf
+>>0x2c search/83/c     Flavor.htm\0    ecard
+!:ext  imf
+# member Macromedia Flash data *.swf implies IncrediMail skin like in im2.ims
+>>0x2c search/211/c    .swf\0          skin
+!:ext  ims
+# member anim.im3 implies IncrediMail animation like in letter_fold.ima 
+>>0x2c search/92/c     anim.im3\0      animation
+!:ext  ima
+# other IncrediMail cab archive
+>>0x2c default         x
+>>>0x2c        search/116/c    thumb           ecard, image, notifier or skin
+!:ext  imf/imi/imn/ims
+# http://file-extension.net/seeker/file_extension_ime
+>>>0x2c        default         x               emoticons or sound
+!:ext  ime/imw
+# no Diagnostic and IncrediMail
+>0x2c  default         x
+# look for 1st member name
+>>(16.l+16)    ubyte   x
+# https://en.wikipedia.org/wiki/SNP_file_format
+>>>&-1 string/c        _accrpt_.snp    \b, Access report snapshot
+!:mime application/msaccess
+!:ext  snp
+# https://www.cabextract.org.uk/wince_cab_format/
+# extension of DOS 8+3 name with ".000" of 1st archive member name implies Windows CE installer
+>>>&7  string          =.000           \b, WinCE install
+!:mime application/vnd.ms-cab-compressed
+!:ext  cab
+
+# https://support.microsoft.com/kb/934307/en-US
+# All inspected MSU contain a file with name WSUSSCAN.cab
+# that is called "Windows Update meta data" by Microsoft
+>>>&-1 string/c        wsusscan.cab    \b, Microsoft Standalone Update
+!:mime application/vnd.ms-cab-compressed
+!:ext  msu
+>>>&-1 default         x
+# look at point charcter of 1st archive member name for file name extension
+>>>>&-1        search/255      .
+# http://www.pptfaq.com/FAQ00164_What_is_a_PPZ_file-.htm
+# PPZ were created using Pack & Go feature of PowerPoint versions 97 - 2002
+# packs optional files, a PowerPoint presentation *.ppt with optional PLAYLIST.LST to CAB
+>>>>>&0        string/c        ppt\0           \b, PowerPoint Packed and Go
+!:mime application/vnd.ms-powerpoint
+#!:mime        application/mspowerpoint
+!:ext  ppz
+# https://msdn.microsoft.com/en-us/library/windows/desktop/bb773190(v=vs.85).aspx
+# first member *.theme implies Windows 7 Theme Pack like in CommunityShowcaseAqua3.themepack
+# or Windows 8 Desktop Theme Pack like in PanoramicGlaciers.deskthemepack
+>>>>>&0        string/c        theme           \b, Windows
+!:mime application/x-windows-themepack
+# https://www.drewkeller.com/content/using-theme-both-windows-7-and-windows-8
+# 1st member Panoramic.theme or Panoramas.theme implies Windows 8-10 Theme Pack
+# with MTSM=RJSPBS in [MasterThemeSelector] inside *.theme
+>>>>>>(16.l+16)        string  =Panoram        8
+!:ext  deskthemepack
+>>>>>>(16.l+16)        string  !Panoram        7 or 8
+!:ext  themepack/deskthemepack
+>>>>>>(16.l+16)        ubyte   x               Theme Pack
+>>>>>&0        default         x
+# look for null terminator of 1st member name
+>>>>>>&0       search/255      \0
+# 2nd member name WSUSSCAN.cab like in Microsoft-Windows-MediaFeaturePack-OOB-Package.msu
+>>>>>>>&16     string/c        wsusscan.cab    \b, Microsoft Standalone Update
+!:mime application/vnd.ms-cab-compressed
+!:ext  msu
+>>>>>>>&16     default x
+# archive with more then one file need some output in version 5.32 to avoid error message like
+# Magdir/msdos, 1138: Warning: Current entry does not yet have a description for adding a MIME type
+# Magdir/msdos, 1139: Warning: Current entry does not yet have a description for adding a EXTENSION type
+# file: could not find any valid magic files!
+>>>>>>>>28     uleshort        >1      \b, many
+!:mime application/vnd.ms-cab-compressed
+!:ext  cab
+# remaining archives with just one file
+>>>>>>>>28     uleshort        =1
+# neither extra bytes nor cab chain implies Windows 2000,XP setup files in directory i386
+>>>>>>>>>30    uleshort        =0x0000 \b, Windows 2000/XP setup
+# cut of last char of source extension and add underscore to generate extension
+# TERMCAP._ ... FXSCOUNT.H_ ... L3CODECA.AC_ ... NPDRMV2.ZI_
+!:mime application/vnd.ms-cab-compressed
+!:ext  _/?_/??_
+# archive need some output like "single" in version 5.32 to avoid error messages
+>>>>>>>>>30    uleshort        !0x0000 \b, single
+!:mime application/vnd.ms-cab-compressed
+!:ext  cab
+# TODO: additional extensions like
+# .xsn InfoPath Dynamic Form
+# .xtp InfoPath Template Part
+# .lvf Logitech Video Effects Face Accessory
+>8     ulelong         x               \b, %u bytes
+>28    uleshort                1               \b, 1 file
+>28    uleshort                >1              \b, %u files
+# Reserved fields, set to zero
+#>4    belong          !0              \b, reserved1 %x
+#>12   belong          !0              \b, reserved2 %x
+# offset of the first CFFILE entry coffFiles: minimal 2Ch
+>16    ulelong         x               \b, at 0x%x
+>(16.l)        use             cab-file
+# at least also 2nd member
+>28    uleshort                >1
+>>(16.l+16)    ubyte   x
+>>>&0  search/255      \0
+# second member info
+>>>>&0 use             cab-file
+#>20   belong          !0              \b, reserved %x
+# Cabinet file format version. Currently, versionMajor = 1 and versionMinor = 3
+>24    ubeshort        !0x0301         \b version 0x%x
+# number of CFFOLDER entries
+>26    uleshort        >1              \b, %u cffolders
+# cabinet file option indicators 1~PREVIOUS, 2~NEXT, 4~reserved fields
+# only found for flags 0 1 2 3 4 not 7
+>30    uleshort        >0              \b, flags 0x%x
+# Cabinet files have a 16-bit cabinet setID field that is designed for application use.
+# default is zero, however, the -i option of cabarc can be used to set this field
+>32    uleshort        >0              \b, ID %u
+# iCabinet is number of this cabinet file in a set, where 0 for the first cabinet
+#>34   uleshort        x               \b, iCabinet %u
+# add one for display because humans start numbering by 1 and also fit to name of disk szDisk*
+>34    uleshort+1      x               \b, number %u
+>30    uleshort        &0x0004         \b, extra bytes
+# cbCFHeader optional size of per-cabinet reserved area 14h 1800h
+>>36   uleshort        >0              %u in head
+# cbCFFolder is optional size of per-folder reserved area
+>>38   ubyte           >0              %u in folder
+# cbCFData is optional size of per-datablock reserved area
+>>39   ubyte           >0              %u in data block
+# optional per-cabinet reserved area abReserve[cbCFHeader]
+>>36   uleshort        >0
+# 1st CFFOLDER after reserved area in header
+>>>(36.s+40)   use                     cab-folder
+# no reserved area in header
+>30    uleshort        ^0x0004
+# no previous and next cab archive
+>>30   uleshort                =0x0000
+>>>36  use                             cab-folder
+# only previous cab archive
+>>30   uleshort                =0x0001 \b, previous
+>>>36  use                             cab-anchor
+# only next cab archive
+>>30   uleshort                =0x0002 \b, next
+>>>36  use                             cab-anchor
+# previous+next cab archive
+# can not use sub routine cab-anchor to display previous and next cabinet together
+#>>>36 use                             cab-anchor
+#>>>>&0        use                             cab-anchor
+>>30   uleshort                =0x0003 \b, previous
+>>>36  string          x               %s
+# optional name of previous disk szDisk*
+>>>>&1 string          x               disk %s
+>>>>>&1        string          x               \b, next %s
+# optional name of previous disk szDisk*
+>>>>>>&1       string          x       disk %s
+>>>>>>>&1      use                     cab-folder
+#      display filename and disk name of previous or next cabinet
+0       name                           cab-anchor
+# optional name of previous/next cabinet file szCabinet*[255]
+>&0    string          x               %s
+# optional name of previous/next disk szDisk*[255]
+>>&1   string          x               disk %s
+#      display folder structure CFFOLDER information like compression of cabinet
+0       name                           cab-folder
+# offset of the CFDATA block in this folder
+#>0    ulelong         x               \b, coffCabStart 0x%x
+# number of CFDATA blocks in folder
+>4     uleshort        x               \b, %u datablock
+# plural s
+>4     uleshort        >1              \bs
+# compression typeCompress: 0~None 1~MSZIP 0x1503~LZX:21 0x1003~LZX:16 0x0f03~LZX:15
+>6     uleshort        x               \b, 0x%x compression
+# optional per-folder reserved area
+#>8    ubequad         x               \b, abReserve 0x%llx
+#      display member structure CFFILE information like member name of cabinet
+0       name                           cab-file
+# cbFile is uncompressed size of file in bytes 
+#>0    ulelong         x               \b, cbFile %u
+# uoffFolderStart is uncompressed offset of file in folder
+#>4    ulelong         >0              \b, uoffFolderStart 0x%x
+# iFolder is index into the CFFOLDER area. 0 indicates first folder in cabinet
+# define ifoldCONTINUED_FROM_PREV      (0xFFFD)
+# define ifoldCONTINUED_TO_NEXT        (0xFFFE)
+# define ifoldCONTINUED_PREV_AND_NEXT  (0xFFFF)
+>8     uleshort        >0              \b, iFolder 0x%x
+# date stamp for file
+#>10   uleshort        x               \b, date 0x%x
+# time stamp for file
+#>12   uleshort        x               \b, time 0x%x
+# attribs is attribute flags for file
+# define  _A_RDONLY       (0x01)  file is read-only
+# define  _A_HIDDEN       (0x02)  file is hidden
+# define  _A_SYSTEM       (0x04)  file is a system file
+# define  _A_ARCH         (0x20)  file modified since last backup
+# example http://sebastien.kirche.free.fr/pebuilder_plugins/depends.cab
+# define  _A_EXEC         (0x40)  run after extraction
+# define  _A_NAME_IS_UTF  (0x80)  szName[] contains UTF
+# define  UNKNOWN       (0x0100)  undocumented or accident
+#>14   uleshort        x               \b, attribs 0x%x
+>14    uleshort        >0              +
+>>14   uleshort        &0x0001         \bR
+>>14   uleshort        &0x0002         \bH
+>>14   uleshort        &0x0004         \bS
+>>14   uleshort        &0x0020         \bA
+>>14   uleshort        &0x0040         \bX
+>>14   uleshort        &0x0080         \bUtf
+# unknown 0x0100 flag found on one XP_CD:\I386\DRIVER.CAB
+>>14   uleshort        &0x0100         \b?
+# szName is name of archive member
+>16    string          x               "%s"
+# next archive member name if more files
+#>>&17 string          >\0             \b, NEXT NAME %-.50s
+
+# InstallShield Cabinet files
+0      string/b        ISc(            InstallShield Cabinet archive data
+>5     byte&0xf0       =0x60           version 6,
+>5     byte&0xf0       !0x60           version 4/5,
+>(12.l+40)     lelong  x               %u files
+
+# Windows CE package files
+0      string/b        MSCE\0\0\0\0    Microsoft WinCE install header
+>20    lelong          0               \b, architecture-independent
+>20    lelong          103             \b, Hitachi SH3
+>20    lelong          104             \b, Hitachi SH4
+>20    lelong          0xA11           \b, StrongARM
+>20    lelong          4000            \b, MIPS R4000
+>20    lelong          10003           \b, Hitachi SH3
+>20    lelong          10004           \b, Hitachi SH3E
+>20    lelong          10005           \b, Hitachi SH4
+>20    lelong          70001           \b, ARM 7TDMI
+>52    leshort         1               \b, 1 file
+>52    leshort         >1              \b, %u files
+>56    leshort         1               \b, 1 registry entry
+>56    leshort         >1              \b, %u registry entries
+
+
+# Windows Enhanced Metafile (EMF)
+# See msdn.microsoft.com/archive/en-us/dnargdi/html/msdn_enhmeta.asp
+# for further information.
+0      ulelong 1
+>40    string  \ EMF           Windows Enhanced Metafile (EMF) image data
+>>44   ulelong x               version 0x%x
+
+
+0      string/b        \224\246\056            Microsoft Word Document
+!:mime application/msword
+
+512    string  R\0o\0o\0t\0\ \0E\0n\0t\0r\0y   Microsoft Word Document
+!:mime application/msword
+
+# From: "Nelson A. de Oliveira" <naoliv@gmail.com>
+# Magic type for Dell's BIOS .hdr files
+# Dell's .hdr
+0      string/b $RBU
+>23    string Dell                     %s system BIOS
+>5     byte   2
+>>48   byte   x                        version %d.
+>>49   byte   x                        \b%d.
+>>50   byte   x                        \b%d
+>5     byte   <2
+>>48   string x                        version %.3s
+
+# Type: Microsoft Document Imaging Format (.mdi)
+# URL: https://en.wikipedia.org/wiki/Microsoft_Document_Imaging_Format
+# From: Daniele Sempione <scrows@oziosi.org>
+# Too weak (EP)
+#0     short   0x5045                  Microsoft Document Imaging Format
+
+# MS eBook format (.lit)
+0      string/b        ITOLITLS                Microsoft Reader eBook Data
+>8     lelong  x                       \b, version %u
+!:mime                                 application/x-ms-reader
+
+# Windows CE Binary Image Data Format
+# From: Dr. Jesus <j@hug.gs>
+0      string/b        B000FF\n        Windows Embedded CE binary image
+
+# The second byte of these signatures is a file version; I don't know what,
+# if anything, produced files with version numbers 0-2.
+# From: John Elliott <johne@seasip.demon.co.uk>
+0      string  \xfc\x03\x00    Mallard BASIC program data (v1.11)
+0      string  \xfc\x04\x00    Mallard BASIC program data (v1.29+)
+0      string  \xfc\x03\x01    Mallard BASIC protected program data (v1.11)
+0      string  \xfc\x04\x01    Mallard BASIC protected program data (v1.29+)
+
+0      string  MIOPEN          Mallard BASIC Jetsam data
+0      string  Jetsam0         Mallard BASIC Jetsam index data
+
+# DOS backup 2.0 to 3.2
+
+# backupid.@@@
+
+# plausibility check for date
+0x3    ushort  >1979
+>0x5   ubyte-1 <31
+>>0x6  ubyte-1 <12
+# actually 121 nul bytes
+>>>0x7 string  \0\0\0\0\0\0\0\0
+>>>>0x1 ubyte  x       DOS 2.0 backup id file, sequence %d
+!:ext @@@
+>>>>0x0 ubyte  0xff    \b, last disk
+
+# backed up file
+
+# skip some AppleWorks word like Tomahawk.Awp, WIN98SE-DE.vhd
+# by looking for trailing nul of maximal file name string
+0x52   ubyte   0       
+# test for flag byte: FFh~complete file, 00h~split file
+# FFh -127 =   -1 -127 =       -128
+# 00h -127 =    0 -127 =       -127
+>0     byte-127        <-126
+# plausibility check for file name length
+>>0x53 ubyte-1 <78     
+# looking for terminating nul of file name string
+>>>(0x53.b+4)  ubyte   0       
+# looking if last char of string is valid DOS file name
+>>>>(0x53.b+3) ubyte   >0x1F   
+# actually 44 nul bytes
+# but sometimes garbage according to Ralf Quint. So can not be used as test
+#>0x54 string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+# first char of full file name is DOS (5Ch) or UNIX (2Fh) path separator
+# only DOS variant found. UNIX variant according to V32SLASH.TXT in archive PD0315.EXE 
+>>>>>5 ubyte&0x8C      0x0C    
+# ./msdos (version 5.30) labeled the entry as
+# "DOS 2.0 backed up file %s, split file, sequence %d" or
+# "DOS 2.0 backed up file %s, complete file"
+>>>>>>0        ubyte   x       DOS 2.0-3.2 backed up
+#>>>>>>0       ubyte   0xff    complete
+>>>>>>0        ubyte   0
+>>>>>>>1 uleshort      x       sequence %d of
+# full file name with path but without drive letter and colon stored from 0x05 til 0x52
+>>>>>>0x5      string  x       file %s
+# backup name is original filename
+#!:ext *
+# magic/Magdir/msdos, 1169: Warning: EXTENSION type `     *' has bad char '*'
+# file: line 1169: Bad magic entry '  *'
+# after header original file content
+>>>>>>128      indirect x      \b; 
+
+
+# DOS backup 3.3 to 5.x
+
+# CONTROL.nnn files
+0      string  \x8bBACKUP\x20
+# actually 128 nul bytes
+>0xa   string  \0\0\0\0\0\0\0\0
+>>0x9  ubyte   x       DOS 3.3 backup control file, sequence %d
+>>0x8a ubyte   0xff    \b, last disk
+
+# NB: The BACKUP.nnn files consist of the files backed up,
+# concatenated.
diff --git a/magic/Magdir/msooxml b/magic/Magdir/msooxml
new file mode 100644 (file)
index 0000000..194cf53
--- /dev/null
@@ -0,0 +1,45 @@
+
+#------------------------------------------------------------------------------
+# $File: msooxml,v 1.12 2019/04/19 00:42:27 christos Exp $
+# msooxml:  file(1) magic for Microsoft Office XML
+# From: Ralf Brown <ralf.brown@gmail.com>
+
+# .docx, .pptx, and .xlsx are XML plus other files inside a ZIP
+#   archive.  The first member file is normally "[Content_Types].xml".
+#   but some libreoffice generated files put this later. Perhaps skip
+#   the "[Content_Types].xml" test?
+# Since MSOOXML doesn't have anything like the uncompressed "mimetype"
+#   file of ePub or OpenDocument, we'll have to scan for a filename
+#   which can distinguish between the three types
+
+0              name            msooxml
+>0             string          word/           Microsoft Word 2007+
+!:mime application/vnd.openxmlformats-officedocument.wordprocessingml.document
+>0             string          ppt/            Microsoft PowerPoint 2007+
+!:mime application/vnd.openxmlformats-officedocument.presentationml.presentation
+>0             string          xl/             Microsoft Excel 2007+
+!:mime application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+
+# start by checking for ZIP local file header signature
+0              string          PK\003\004
+!:strength +10
+# make sure the first file is correct
+>0x1E          use             msooxml
+>0x1E          regex           \\[Content_Types\\]\\.xml|_rels/\\.rels|docProps
+# skip to the second local file header
+# since some documents include a 520-byte extra field following the file
+# header, we need to scan for the next header
+>>(18.l+49)    search/6000     PK\003\004
+# now skip to the *third* local file header; again, we need to scan due to a
+# 520-byte extra field following the file header
+>>>&26         search/6000     PK\003\004
+# and check the subdirectory name to determine which type of OOXML
+# file we have.  Correct the mimetype with the registered ones:
+# https://technet.microsoft.com/en-us/library/cc179224.aspx
+>>>>&26                use             msooxml 
+>>>>&26                default         x
+# OpenOffice/Libreoffice orders ZIP entry differently, so check the 4th file
+>>>>>&26       search/6000     PK\003\004
+>>>>>>&26      use             msooxml 
+>>>>>>&26      default         x               Microsoft OOXML
+>>>>>&26       default         x               Microsoft OOXML
diff --git a/magic/Magdir/msvc b/magic/Magdir/msvc
new file mode 100644 (file)
index 0000000..8cf5c16
--- /dev/null
@@ -0,0 +1,69 @@
+
+#------------------------------------------------------------------------------
+# $File: msvc,v 1.10 2018/10/01 19:14:03 christos Exp $
+# msvc:  file(1) magic for msvc
+# "H. Nanosecond" <aldomel@ix.netcom.com>
+# Microsoft visual C
+#
+# I have version 1.0
+
+# .aps
+0      string  HWB\000\377\001\000\000\000     Microsoft Visual C .APS file
+
+# .ide
+#too long 0    string  \102\157\162\154\141\156\144\040\103\053\053\040\120\162\157\152\145\143\164\040\106\151\154\145\012\000\032\000\002\000\262\000\272\276\372\316        MSVC .ide
+0      string  \102\157\162\154\141\156\144\040\103\053\053\040\120\162\157    MSVC .ide
+
+# .res
+0      string  \000\000\000\000\040\000\000\000\377    MSVC .res
+0      string  \377\003\000\377\001\000\020\020\350    MSVC .res
+0      string  \377\003\000\377\001\000\060\020\350    MSVC .res
+
+#.lib
+0      string  \360\015\000\000        Microsoft Visual C library
+0      string  \360\075\000\000        Microsoft Visual C library
+0      string  \360\175\000\000        Microsoft Visual C library
+
+#.pch
+0      string  DTJPCH0\000\022\103\006\200     Microsoft Visual C .pch
+
+# Summary: Symbol Table / Debug info used by Microsoft compilers
+# URL: https://en.wikipedia.org/wiki/Program_database
+# Reference: https://code.google.com/p/pdbparser/wiki/MSF_Format
+# Update: Joerg Jenderek
+# Note:        test only for Windows XP+SP3 x86 , 8.1 x64 arm and 10.1 x86
+#      info does only applies partly for older files like msvbvm50.pdb about year 2001
+0      string  Microsoft\ C/C++\040
+# "Microsoft Program DataBase" by TrID
+>24    search/14       \r\n\x1A        MSVC program database
+!:mime application/x-ms-pdb
+!:ext  pdb
+# "MSF 7.00" "program database 2.00" for msvbvm50.pdb
+>>16   regex   \([0-9.]+\)     ver %s
+#>>>0x38       search/128123456        /LinkInfo       \b with linkinfo
+# "MSF 7.00" variant
+>>0x1e leshort 0
+# PageSize 400h 1000h
+>>>0x20        lelong  x       \b, %d
+# Page Count
+>>>0x28        lelong  x       \b*%d bytes
+# "program database 2.00"  variant
+>>0x1e leshort !0
+# PageSize 400h
+>>>0x2c        lelong  x       \b, %d
+# Page Count for msoo-dll.pdb 4379h
+>>>0x32        leshort x       \b*%d bytes
+
+# Reference: https://github.com/Microsoft/vstest/pull/856/commits/fdc7a9f074ca5a8dfeec83b1be9162bf0cf4000d
+0       string/c bsjb\001\000\001\000\000\000\000\000\f\000\000\000pdb\ v1.0     Microsoft Roslyn C# debugging symbols version 1.0
+
+#.sbr
+0      string  \000\002\000\007\000    MSVC .sbr
+>5     string  >\0     %s
+
+#.bsc
+0      string  \002\000\002\001        MSVC .bsc
+
+#.wsp
+0      string  1.00\ .0000.0000\000\003        MSVC .wsp version 1.0000.0000
+# these seem to start with the version and contain menus
diff --git a/magic/Magdir/msx b/magic/Magdir/msx
new file mode 100644 (file)
index 0000000..69df641
--- /dev/null
@@ -0,0 +1,309 @@
+
+#------------------------------------------------------------------------------
+# msx:  file(1) magic for the MSX Home Computer
+# v1.3
+# Fabio R. Schmidlin <sd-snatcher@users.sourceforge.net>
+
+############## MSX Music file formats ##############
+
+# Gigamix MGSDRV music file
+0      string/b                MGS     MSX Gigamix MGSDRV3 music file,
+>6     ubeshort        0x0D0A
+>>3    byte            x       \bv%c
+>>4    byte            x       \b.%c
+>>5    byte            x       \b%c
+>>8    string          >\0     \b, title: %s
+
+1      string/b                mgs2\   MSX Gigamix MGSDRV2 music file
+>6     uleshort        0x80
+>>0x2E uleshort        0
+>>>0x30        string          >\0     \b, title: %s
+
+# KSS music file
+0      string/b                KSCC    KSS music file v1.03
+>0xE   byte            0
+>>0xF  byte&0x02       0       \b, soundchips: AY-3-8910, SCC(+)
+>>0xF  byte&0x02       2       \b, soundchip(s): SN76489
+>>>0xF byte&0x04       4       stereo
+>>0xF  byte&0x01       1       \b, YM2413
+>>0xF  byte&0x08       8       \b, Y8950
+
+0      string/b                KSSX    KSS music file v1.20
+>0xE   byte&0xEF       0
+>>0xF  byte&0x40       0x00    \b, 60Hz
+>>0xF  byte&0x40       0x40    \b, 50Hz
+>>0xF  byte&0x02       0       \b, soundchips: AY-3-8910, SCC(+)
+>>0xF  byte&0x02       0x02    \b, soundchips: SN76489
+>>>0xF byte&0x04       0x04    stereo
+>>0xF  byte&0x01       0x01    \b,
+>>>0xF byte&0x18       0x00    \bYM2413
+>>>0xF byte&0x18       0x08    \bYM2413, Y8950
+>>>0xF byte&0x18       0x18    \bYM2413+Y8950 pseudostereo
+>>0xF  byte&0x18       0x10    \b, Majyutsushi DAC
+
+# Moonblaster for Moonsound
+0      string/b                MBMS
+>4     byte            0x10    MSX Moonblaster for MoonSound music
+
+# Music Player K-kaz
+0      string/b                MPK     MSX Music Player K-kaz song
+>6     ubeshort        0x0D0A
+>>3    byte            x       v%c
+>>4    byte            x       \b.%c
+>>5    byte            x       \b%c
+
+# I don't know why these don't work
+#0     search/0xFFFF   \r\n.FM9
+#>0    search/0xFFFF   \r\n#FORMAT     MSX Music Player K-kaz source MML file
+#0     search/0xFFFF   \r\nFM1\ \=
+#>0    search/0xFFFF   \r\nPSG1\=
+#>>0   search/0xFFFF   \r\nSCC1\=              MSX MuSiCa MML source file
+
+# OPX Music file
+0x35   beshort         0x0d0a
+>0x7B  beshort         0x0d0a
+>>0x7D byte            0x1a
+>>>0x87        uleshort        0               MSX OPX Music file
+>>>>0x86       byte            0               v1.5
+>>>>>0 string          >\32            \b, title: %s
+>>>>0x86       byte            1               v2.4
+>>>>>0 string          >\32            \b, title: %s
+
+# SCMD music file
+0x8B   string/b                SCMD
+>0xCE  uleshort        0       MSX SCMD Music file
+#>>-2  uleshort        0x6a71  ; The file must end with this value. How to code this here?
+>>0x8F string          >\0             \b, title: %s
+
+0      search/0xFFFF   \r\n@title
+>&0    search/0xFFFF   \r\n@m=[        MSX SCMD source MML file
+
+
+############## MSX image file formats ##############
+
+# MSX raw VRAM dump
+0      ubyte           0xFE
+>1     uleshort        0
+>>5    uleshort        0
+>>>3   uleshort        0x37FF          MSX SC2/GRP raw image
+>>>3   uleshort        0x6A00          MSX Graph Saurus SR5 raw image
+>>>3   uleshort        >0x769E
+>>>>3  uleshort        <0x8000         MSX GE5/GE6 raw image
+>>>>>3 uleshort        0x7FFF          \b, with sprite patterns
+>>>3   uleshort        0xD3FF          MSX screen 7-12 raw image
+>>>3   uleshort        0xD400          MSX Graph Saurus SR7/SR8/SRS raw image
+
+# Graph Saurus compressed images
+0      ubyte           0xFD
+>1     uleshort        0
+>>5    uleshort        0
+>>>3   uleshort        >0x013D         MSX Graph Saurus compressed image
+
+# MSX G9B image file
+0      string/b                G9B
+>1     uleshort        11
+>>3    uleshort        >10
+>>>5   ubyte           >0              MSX G9B image, depth=%d
+>>>>8  uleshort        x               \b, %dx
+>>>>10 uleshort        x               \b%d
+>>>>5  ubyte           <9
+>>>>>6 ubyte           0
+>>>>>>7        ubyte           x               \b, codec=%d RGB color palettes
+>>>>>6 ubyte           64              \b, codec=RGB fixed color
+>>>>>6 ubyte           128             \b, codec=YJK
+>>>>>6 ubyte           192             \b, codec=YUV
+>>>>5  ubyte           >8              codec=RGB fixed color
+>>>>12 ubyte           0               \b, raw
+>>>>12 ubyte           1               \b, bitbuster compression
+
+############## Other MSX file formats ##############
+
+# MSX internal ROMs
+0              ubeshort        0xF3C3
+>2             uleshort        <0x4000
+>>8            ubyte           0xC3
+>>>9           uleshort        <0x4000
+>>>>0x0B       ubeshort        0x00C3
+>>>>>0x0D      uleshort        <0x4000
+>>>>>>0x0F     ubeshort        0x00C3
+>>>>>>>0x11    uleshort        <0x4000
+>>>>>>>>0x13   ubeshort        0x00C3
+>>>>>>>>>0x15  uleshort        <0x4000
+>>>>>>>>>>0x50 ubyte           0xC3
+>>>>>>>>>>>0x51        uleshort        <0x4000
+>>>>>>>>>>>>(9.s)      ubyte   0xC3
+>>>>>>>>>>>>>&0        uleshort        >0x4000
+>>>>>>>>>>>>>>&0       ubyte   0xC3            MSX BIOS+BASIC
+>>>>>>>>>>>>>>>0x002D  ubyte+1 <3              \b. version=MSX%d
+>>>>>>>>>>>>>>>0x002D  ubyte   2               \b, version=MSX2+
+>>>>>>>>>>>>>>>0x002D  ubyte   3               \b, version=MSX Turbo-R
+>>>>>>>>>>>>>>>0x002D  ubyte   >3              \b, version=Unknown MSX %d version
+>>>>>>>>>>>>>>>0x0006  ubyte   x               \b, VDP.DR=0x%2x
+>>>>>>>>>>>>>>>0x0007  ubyte   x               \b, VDP.DW=0x%2x
+>>>>>>>>>>>>>>>0x002B  ubyte&0xF       0               \b, charset=Japanese
+>>>>>>>>>>>>>>>0x002B  ubyte&0xF       1               \b, charset=International
+>>>>>>>>>>>>>>>0x002B  ubyte&0xF       2               \b, charset=Korean
+>>>>>>>>>>>>>>>0x002B  ubyte&0xF       >2              \b, charset=Unknown id:%d
+>>>>>>>>>>>>>>>0x002B  ubyte&0x70      0x00            \b, date format=Y-M-D
+>>>>>>>>>>>>>>>0x002B  ubyte&0x70      0x10            \b, date format=M-D-Y
+>>>>>>>>>>>>>>>0x002B  ubyte&0x70      0x20            \b, date format=D-M-Y
+>>>>>>>>>>>>>>>0x002B  ubyte&0x80      0x00            \b, vfreq=60Hz
+>>>>>>>>>>>>>>>0x002B  ubyte&0x80      0x80            \b, vfreq=50Hz
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      0               \b, keyboard=Japanese
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      1               \b, keyboard=International
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      2               \b, keyboard=French
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      3               \b, keyboard=UK
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      4               \b, keyboard=German
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      5               \b, keyboard=Unknown id:%d
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      6               \b, keyboard=Spanish
+>>>>>>>>>>>>>>>0x002C  ubyte&0x0F      >6              \b, keyboard=Unknown id:%d
+>>>>>>>>>>>>>>>0x002C  ubyte&0xF0      0x00            \b, basic=Japanese
+>>>>>>>>>>>>>>>0x002C  ubyte&0xF0      0x10            \b, basic=International
+>>>>>>>>>>>>>>>0x002C  ubyte&0xF0      >0x10           \b, basic=Unknown id:%d
+>>>>>>>>>>>>>>>0x002E  ubyte&1         1               \b, built-in MIDI
+
+
+0              string/b                CD
+>2             uleshort        >0x10
+>>2            uleshort        <0x4000
+>>>4           uleshort        <0x4000
+>>>>6          uleshort        <0x4000
+>>>>>8         ubyte           0xC3
+>>>>>>9                uleshort        <0x4000
+>>>>>>>0x10    ubyte           0xC3
+>>>>>>>>0x11   uleshort        <0x4000
+>>>>>>>>>0x14  ubyte           0xC3
+>>>>>>>>>>0x15 uleshort        <0x4000         MSX2/2+/TR SubROM
+
+0              string          \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>0x5F0         ubequad         0x8282828244380000
+>>0x150                ubyte           0x38
+>>>0x170       string          \20\20\20
+>>>>0x1E32     string          ())
+>>>>>0x2130    ubequad         0xA5A5594924231807
+>>>>>0x2138    ubequad         0x4A4A3424488830C0      MSX Kanji Font
+
+
+
+# MSX extension ROMs
+0      string/b                AB
+>2     uleshort        0x0010                  MSX ROM
+>>2    uleshort        x                       \b, init=0x%4x
+>>4    uleshort        >0                      \b, stahdl=0x%4x
+>>6    uleshort        >0                      \b, devhdl=0x%4x
+>>8    uleshort        >0                      \b, bas=0x%4x
+>2     uleshort        0x4010                  MSX ROM
+>>2    uleshort        x                       \b, init=0x%04x
+>>4    uleshort        >0                      \b, stahdl=0x%04x
+>>6    uleshort        >0                      \b, devhdl=0x%04x
+>>8    uleshort        >0                      \b, bas=0x%04x
+>2     uleshort        0x8010                  MSX ROM
+>>2    uleshort        x                       \b, init=0x%04x
+>>4    uleshort        >0                      \b, stahdl=0x%04x
+>>6    uleshort        >0                      \b, devhdl=0x%04x
+>>8    uleshort        >0                      \b, bas=0x%04x
+0      string/b                AB\0\0
+>6     uleshort        0
+>>4    uleshort        >0x400F                 MSX-BASIC extension ROM
+>>>4   uleshort        >0                      \b, stahdl=0x%04x
+>>>6   uleshort        >0                      \b, devhdl=0x%04x
+>>>0x1C                string          OPLL                    \b, MSX-Music
+>>>>0x18       string          PAC2                    \b (external)
+>>>>0x18       string          APRL                    \b (internal)
+
+0      string/b                AB\0\0\0\0
+>6     uleshort        >0x400F                 MSX device BIOS
+>>6    uleshort        >0                      \b, devhdl=0x%04x
+
+
+0      string/b                AB
+#>2    string          5JSuperLAYDOCK          MSX Super Laydock ROM
+#>3    string          @HYDLIDE3MSX            MSX Hydlide-3 ROM
+#>3    string          @3\x80IA862             Golvellius MSX1 ROM
+>2     uleshort        >15
+>>2    uleshort        <0xC000
+>>>8   string          \0\0\0\0\0\0\0\0
+>>>>(2.s&0x3FFF)       uleshort        >0              MSX ROM
+>>>>>0x10      string          YZ\0\0\0\0              Konami Game Master 2 MSX ROM
+>>>>>0x10      string          CD                      \b, Konami RC-
+>>>>>>0x12     ubyte           x                       \b%d
+>>>>>>0x13     ubyte/16        x                       \b%d
+>>>>>>0x13     ubyte&0xF       x                       \b%d
+>>>>>0x10      string          EF                      \b, Konami RC-
+>>>>>>0x12     ubyte           x                       \b%d
+>>>>>>0x13     ubyte/16        x                       \b%d
+>>>>>>0x13     ubyte&0xF       x                       \b%d
+>>>>>2 uleshort        x                       \b, init=0x%04x
+>>>>>4 uleshort        >0                      \b, stahdl=0x%04x
+>>>>>6 uleshort        >0                      \b, devhdl=0x%04x
+>>>>>8 uleshort        >0                      \b, bas=0x%04x
+>>>2   uleshort        0
+>>>>4  uleshort        0
+>>>>>6 uleshort        0
+>>>>>>8        uleshort        >0                      MSX BASIC program in ROM, bas=0x%04x
+
+0x4000 string/b                AB
+>0x4002        uleshort        >0x400F
+>>0x400A       string          \0\0\0\0\0\0    MSX ROM with nonstandard page order
+>>>0x4002      uleshort        x                       \b, init=0x%04x
+>>>0x4004      uleshort        >0                      \b, stahdl=0x%04x
+>>>0x4006      uleshort        >0                      \b, devhdl=0x%04x
+>>>0x4008      uleshort        >0                      \b, bas=0x%04x
+
+0x8000 string/b                AB
+>0x8002        uleshort        >0x400F
+>>0x800A       string          \0\0\0\0\0\0    MSX ROM with nonstandard page order
+>>>0x8002      uleshort        x                       \b, init=0x%04x
+>>>0x8004      uleshort        >0                      \b, stahdl=0x%04x
+>>>0x8006      uleshort        >0                      \b, devhdl=0x%04x
+>>>0x8008      uleshort        >0                      \b, bas=0x%04x
+
+
+0x3C000        string/b                AB
+>0x3C008       string          \0\0\0\0\0\0\0\0        MSX MegaROM with nonstandard page order
+>>0x3C002      uleshort        x                       \b, init=0x%04x
+>>0x3C004      uleshort        >0                      \b, stahdl=0x%04x
+>>0x3C006      uleshort        >0                      \b, devhdl=0x%04x
+>>0x3C008      uleshort        >0                      \b, bas=0x%04x
+
+# MSX BIN file
+#0     byte            0xFE
+#>1    uleshort        >0x8000
+#>>3   uleshort        >0x8004
+#>>>5  uleshort        >0x8000                 MSX BIN file
+
+# MSX-BASIC file
+0      byte            0xFF
+>3     uleshort        0x000A
+>>1    uleshort        >0x8000                 MSX-BASIC program
+
+# MSX .CAS file
+0      string/b        \x1F\xA6\xDE\xBA\xCC\x13\x7D\x74        MSX cassette archive
+
+# Mega-Assembler file
+0      byte            0xFE
+>1     uleshort        0x0001
+>>5    uleshort        0xffff
+>>>6   byte            0x0A            MSX Mega-Assembler source
+
+# Execrom Patchfile
+0      string          ExecROM\ patchfile\x1A  MSX ExecROM patchfile
+>0x12  ubyte/16        x               v%d
+>0x12  ubyte&0xF       x               \b.%d
+>0x13  ubyte           x               \b, contains %d patches
+
+# Konami's King's Valley-2 custom stage (ELG file)
+4      uleshort        0x0900
+>0xF   byte            1
+>>0x14 byte            0
+>>>0x1E        string          \040\040\040
+>>>>0x23       byte    1
+>>>>>0x25      byte    0
+>>>>>>0x15     string  >\x30
+>>>>>>>0x15    string  <\x5A           Konami King's Valley-2 custom stage, title: "%-8.8s"
+>>>>>>>>0x1D   byte    <32     \b, theme: %d
+
+# Metal Gear 1 savegame
+#0x4F  string  \x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF
+#>>0x60        string  \xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF
+#>>>0x7B       string  \0x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00       Metal Gear 1 savegame
diff --git a/magic/Magdir/mup b/magic/Magdir/mup
new file mode 100644 (file)
index 0000000..05b9471
--- /dev/null
@@ -0,0 +1,24 @@
+
+# ------------------------------------------------------------------------
+# $File: mup,v 1.5 2017/03/17 21:35:28 christos Exp $
+# mup: file(1) magic for Mup (Music Publisher) input file.
+#
+# From: Abel Cheung <abel (@) oaka.org>
+#
+# NOTE: This header is mainly proposed in the Arkkra mailing list,
+# and is not a mandatory header because of old mup input file
+# compatibility. Noteedit also use mup format, but is not forcing
+# user to use any header as well.
+#
+0              search/1        //!Mup          Mup music publication program input text
+>6             string          -Arkkra         (Arkkra)
+>>13           string          -
+>>>16          string          .
+>>>>14         string          x               \b, need V%.4s
+>>>15          string          .
+>>>>14         string          x               \b, need V%.3s
+>6             string          -
+>>9            string          .
+>>>7           string          x               \b, need V%.4s
+>>8            string          .
+>>>7           string          x               \b, need V%.3s
diff --git a/magic/Magdir/music b/magic/Magdir/music
new file mode 100644 (file)
index 0000000..a066a48
--- /dev/null
@@ -0,0 +1,17 @@
+#------------------------------------------------------------------------------
+# $File: cracklib,v 1.7 2009/09/19 16:28:08 christos Exp $
+# music:  file (1) magic for music formats
+
+# BWW format used by Bagpipe Music Writer Gold by Robert MacNeil Musicworks
+# and Bagpipe Writer by Doug Wickstrom
+#
+0      string          Bagpipe         Bagpipe
+>8     string          Reader          Reader
+>>15   string          >\0             (version %.3s)
+>8     string          Music\ Writer   Music Writer
+>>20   string          :
+>>>21  string          >\0             (version %.3s)
+>>21   string          Gold            Gold
+>>>25  string          :
+>>>>26 string          >\0             (version %.3s)
+
diff --git a/magic/Magdir/nasa b/magic/Magdir/nasa
new file mode 100644 (file)
index 0000000..de3545f
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# nasa:        file(1) magic
+
+# From: Barry Carter <carter.barry@gmail.com>
+0      string  DAF/SPK                         NASA SPICE file (binary format)
+0      string  DAFETF\ NAIF\ DAF\ ENCODED      NASA SPICE file (transfer format)
diff --git a/magic/Magdir/natinst b/magic/Magdir/natinst
new file mode 100644 (file)
index 0000000..b3ccf15
--- /dev/null
@@ -0,0 +1,24 @@
+
+#-----------------------------------------------------------------------------
+# $File: natinst,v 1.5 2013/02/06 14:18:52 christos Exp $
+# natinst:  file(1) magic for National Instruments Code Files
+
+#
+# From <egamez@fcfm.buap.mx> Enrique Gamez-Flores
+# version 1
+# Many formats still missing, we use, for the moment LabVIEW
+# We guess VXI format file. VISA, LabWindowsCVI, BridgeVIEW, etc, are missing
+#
+0       string          RSRC            National Instruments,
+# Check if it's a LabVIEW File
+>8      string          LV              LabVIEW File,
+# Check which kind of file it is
+>>10    string          SB              Code Resource File, data
+>>10    string          IN              Virtual Instrument Program, data
+>>10    string          AR              VI Library, data
+# This is for Menu Libraries
+>8      string          LMNULBVW        Portable File Names, data
+# This is for General Resources
+>8      string          rsc             Resources File, data
+# This is for VXI Package
+0       string          VMAP            National Instruments, VXI File, data
diff --git a/magic/Magdir/ncr b/magic/Magdir/ncr
new file mode 100644 (file)
index 0000000..f6c978e
--- /dev/null
@@ -0,0 +1,49 @@
+
+#------------------------------------------------------------------------------
+# $File: ncr,v 1.7 2009/09/19 16:28:11 christos Exp $
+# ncr:  file(1) magic for NCR Tower objects
+#
+# contributed by
+# Michael R. Wayne  ***  TMC & Associates  ***  INTERNET: wayne@ford-vax.arpa
+# uucp: {philabs | pyramid} !fmsrl7!wayne   OR   wayne@fmsrl7.UUCP
+#
+0      beshort         000610  Tower/XP rel 2 object
+>12       belong               >0      not stripped
+>20       beshort              0407    executable
+>20       beshort              0410    pure executable
+>22       beshort              >0      - version %d
+0      beshort         000615  Tower/XP rel 2 object
+>12       belong               >0      not stripped
+>20       beshort              0407    executable
+>20       beshort              0410    pure executable
+>22       beshort              >0      - version %d
+0      beshort         000620  Tower/XP rel 3 object
+>12       belong               >0      not stripped
+>20       beshort              0407    executable
+>20       beshort              0410    pure executable
+>22       beshort              >0      - version %d
+0      beshort         000625  Tower/XP rel 3 object
+>12       belong               >0      not stripped
+>20       beshort              0407    executable
+>20       beshort              0410    pure executable
+>22       beshort              >0      - version %d
+0      beshort         000630  Tower32/600/400 68020 object
+>12       belong               >0      not stripped
+>20       beshort              0407    executable
+>20       beshort              0410    pure executable
+>22       beshort              >0      - version %d
+0      beshort         000640  Tower32/800 68020
+>18       beshort              &020000 w/68881 object
+>18       beshort              &040000 compatible object
+>18       beshort              &060000 object
+>20       beshort              0407    executable
+>20       beshort              0413    pure executable
+>12       belong               >0      not stripped
+>22       beshort              >0      - version %d
+0      beshort         000645  Tower32/800 68010
+>18       beshort              &040000 compatible object
+>18       beshort              &060000 object
+>20       beshort              0407    executable
+>20       beshort              0413    pure executable
+>12       belong               >0      not stripped
+>22       beshort              >0      - version %d
diff --git a/magic/Magdir/neko b/magic/Magdir/neko
new file mode 100644 (file)
index 0000000..6bedc22
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------
+# $File: neko,v 1.2 2019/04/19 00:42:27 christos Exp $
+
+# From: Mikhail Gusarov <dottedmag@dottedmag.net>
+# NekoVM (https://nekovm.org/) bytecode
+0      string          NEKO    NekoVM bytecode
+>4     lelong          x       (%d global symbols,
+>8     lelong          x       %d global fields,
+>12    lelong          x       %d bytecode ops)
+!:mime application/x-nekovm-bytecode
+
diff --git a/magic/Magdir/netbsd b/magic/Magdir/netbsd
new file mode 100644 (file)
index 0000000..77e64f0
--- /dev/null
@@ -0,0 +1,251 @@
+
+#------------------------------------------------------------------------------
+# $File: netbsd,v 1.26 2019/01/01 03:11:23 christos Exp $
+# netbsd:  file(1) magic for NetBSD objects
+#
+# All new-style magic numbers are in network byte order.
+# The old-style magic numbers are indistinguishable from the same magic
+# numbers used in other systems, and are handled, for all those systems,
+# in aout.
+#
+
+0      name    netbsd-detail
+>20    lelong  x               @%#x
+>4     lelong  >0              \b+T=%d
+>8     lelong  >0              \b+D=%d
+>12    lelong  >0              \b+B=%d
+>16    lelong  >0              \b+S=%d
+>24    lelong  >0              \b+TR=%d
+>28    lelong  >0              \b+TD=%d
+
+0      name                    netbsd-4096
+>0     byte                    &0x80
+>>20   lelong                  <4096           shared library
+>>20   lelong                  =4096           dynamically linked executable
+>>20   lelong                  >4096           dynamically linked executable
+>0     byte                    ^0x80           executable
+>16    lelong                  >0              not stripped
+
+0      name                    netbsd-8192
+>0     byte                    &0x80
+>>20   lelong                  <8192           shared library
+>>20   lelong                  =8192           dynamically linked executable
+>>20   lelong                  >8192           dynamically linked executable
+>0     byte                    ^0x80           executable
+>16    lelong                  >0              not stripped
+>0     use                     netbsd-detail
+
+0      name                    netbsd-normal
+>0     byte                    &0x80           dynamically linked executable
+>0     byte                    ^0x80
+>>0    byte                    &0x40           position independent
+>>20   lelong                  !0              executable
+>>20   lelong                  =0              object file
+>16    lelong                  >0              not stripped
+>0     use                     netbsd-detail
+
+0      name                    netbsd-pure
+>0     byte                    &0x80           dynamically linked executable
+>0     byte                    ^0x80           executable
+>16    lelong                  >0              not stripped
+>0     use                     netbsd-detail
+
+0      name                    netbsd-core
+>12    string                  >\0             from '%s'
+>32    lelong                  !0              (signal %d)
+
+0      belong&0377777777       041400413       a.out NetBSD/i386 demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       041400410       a.out NetBSD/i386 pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       041400407       a.out NetBSD/i386
+>0     use                     netbsd-normal
+
+0      belong&0377777777       041400507       a.out NetBSD/i386 core
+>0     use                     netbsd-core
+
+0      belong&0377777777       041600413       a.out NetBSD/m68k demand paged
+>0     use                     \^netbsd-8192
+
+0      belong&0377777777       041600410       a.out NetBSD/m68k pure
+>0     use                     \^netbsd-pure
+
+0      belong&0377777777       041600407       a.out NetBSD/m68k
+>0     use                     \^netbsd-normal
+
+0      belong&0377777777       041600507       a.out NetBSD/m68k core
+>0     use                     \^netbsd-core
+
+0      belong&0377777777       042000413       a.out NetBSD/m68k4k demand paged
+>0     use                     \^netbsd-4096
+
+0      belong&0377777777       042000410       a.out NetBSD/m68k4k pure
+>0     use                     \^netbsd-pure
+
+0      belong&0377777777       042000407       a.out NetBSD/m68k4k
+>0     use                     \^netbsd-normal
+
+0      belong&0377777777       042000507       a.out NetBSD/m68k4k core
+>0     use                     \^netbsd-core
+
+0      belong&0377777777       042200413       a.out NetBSD/ns32532 demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       042200410       a.out NetBSD/ns32532 pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       042200407       a.out NetBSD/ns32532
+>0     use                     netbsd-normal
+
+0      belong&0377777777       042200507       a.out NetBSD/ns32532 core
+>0     use                     netbsd-core
+
+0      belong&0377777777       045200507       a.out NetBSD/powerpc core
+>0     use                     netbsd-core
+
+0      belong&0377777777       042400413       a.out NetBSD/SPARC demand paged
+>0     use                     \^netbsd-8192
+
+0      belong&0377777777       042400410       a.out NetBSD/SPARC pure
+>0     use                     \^netbsd-pure
+
+0      belong&0377777777       042400407       a.out NetBSD/SPARC
+>0     use                     \^netbsd-normal
+
+0      belong&0377777777       042400507       a.out NetBSD/SPARC core
+>0     use                     \^netbsd-core
+
+0      belong&0377777777       042600413       a.out NetBSD/pmax demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       042600410       a.out NetBSD/pmax pure
+>0     use                     \^netbsd-pure
+
+0      belong&0377777777       042600407       a.out NetBSD/pmax
+>0     use                     netbsd-normal
+
+0      belong&0377777777       042600507       a.out NetBSD/pmax core
+>0     use                     netbsd-core
+
+0      belong&0377777777       043000413       a.out NetBSD/vax 1k demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       043000410       a.out NetBSD/vax 1k pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       043000407       a.out NetBSD/vax 1k
+>0     use                     netbsd-normal
+
+0      belong&0377777777       043000507       a.out NetBSD/vax 1k core
+>0     use                     netbsd-core
+
+0      belong&0377777777       045400413       a.out NetBSD/vax 4k demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       045400410       a.out NetBSD/vax 4k pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       045400407       a.out NetBSD/vax 4k
+>0     use                     netbsd-normal
+
+0      belong&0377777777       045400507       a.out NetBSD/vax 4k core
+>0     use                     netbsd-core
+
+# NetBSD/alpha does not support (and has never supported) a.out objects,
+# so no rules are provided for them.  NetBSD/alpha ELF objects are
+# dealt with in "elf".
+0      lelong          0x00070185              ECOFF NetBSD/alpha binary
+>10    leshort         0x0001                  not stripped
+>10    leshort         0x0000                  stripped
+0      belong&0377777777       043200507       a.out NetBSD/alpha core
+>12    string                  >\0             from '%s'
+>32    lelong                  !0              (signal %d)
+
+0      belong&0377777777       043400413       a.out NetBSD/mips demand paged
+>0     use                     \^netbsd-8192
+
+>16    belong                  >0              not stripped
+0      belong&0377777777       043400410       a.out NetBSD/mips pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       043400407       a.out NetBSD/mips
+>0     use                     netbsd-normal
+
+0      belong&0377777777       043400507       a.out NetBSD/mips core
+>0     use                     netbsd-core
+
+0      belong&0377777777       043600413       a.out NetBSD/arm32 demand paged
+>0     use                     netbsd-4096
+
+0      belong&0377777777       043600410       a.out NetBSD/arm32 pure
+>0     use                     netbsd-pure
+
+0      belong&0377777777       043600407       a.out NetBSD/arm32
+>0     use                     netbsd-normal
+
+# NetBSD/arm26 has always used ELF objects, but it shares a core file
+# format with NetBSD/arm32.
+0      belong&0377777777       043600507       a.out NetBSD/arm core
+>0     use                     netbsd-core
+
+# Kernel core dump format
+0      belong&0x0000ffff 0x00008fca    NetBSD kernel core file
+>0     belong&0x03ff0000 0x00000000    \b, Unknown
+>0     belong&0x03ff0000 0x00010000    \b, sun 68010/68020
+>0     belong&0x03ff0000 0x00020000    \b, sun 68020
+>0     belong&0x03ff0000 0x00640000    \b, 386 PC
+>0     belong&0x03ff0000 0x00860000    \b, i386 BSD
+>0     belong&0x03ff0000 0x00870000    \b, m68k BSD (8K pages)
+>0     belong&0x03ff0000 0x00880000    \b, m68k BSD (4K pages)
+>0     belong&0x03ff0000 0x00890000    \b, ns32532 BSD
+>0     belong&0x03ff0000 0x008a0000    \b, SPARC/32 BSD
+>0     belong&0x03ff0000 0x008b0000    \b, pmax BSD
+>0     belong&0x03ff0000 0x008c0000    \b, vax BSD (1K pages)
+>0     belong&0x03ff0000 0x008d0000    \b, alpha BSD
+>0     belong&0x03ff0000 0x008e0000    \b, mips BSD (Big Endian)
+>0     belong&0x03ff0000 0x008f0000    \b, arm6 BSD
+>0     belong&0x03ff0000 0x00900000    \b, m68k BSD (2K pages)
+>0     belong&0x03ff0000 0x00910000    \b, sh3 BSD
+>0     belong&0x03ff0000 0x00950000    \b, ppc BSD (Big Endian)
+>0     belong&0x03ff0000 0x00960000    \b, vax BSD (4K pages)
+>0     belong&0x03ff0000 0x00970000    \b, mips1 BSD
+>0     belong&0x03ff0000 0x00980000    \b, mips2 BSD
+>0     belong&0x03ff0000 0x00990000    \b, m88k BSD
+>0     belong&0x03ff0000 0x00920000    \b, parisc BSD
+>0     belong&0x03ff0000 0x009b0000    \b, sh5/64 BSD
+>0     belong&0x03ff0000 0x009c0000    \b, SPARC/64 BSD
+>0     belong&0x03ff0000 0x009d0000    \b, amd64 BSD
+>0     belong&0x03ff0000 0x009e0000    \b, sh5/32 BSD
+>0     belong&0x03ff0000 0x009f0000    \b, ia64 BSD
+>0     belong&0x03ff0000 0x00b70000    \b, aarch64 BSD
+>0     belong&0x03ff0000 0x00b80000    \b, or1k BSD
+>0     belong&0x03ff0000 0x00b90000    \b, Risk-V BSD
+>0     belong&0x03ff0000 0x00c80000    \b, hp200 BSD
+>0     belong&0x03ff0000 0x012c0000    \b, hp300 BSD
+>0     belong&0x03ff0000 0x020b0000    \b, hp800 HP-UX
+>0     belong&0x03ff0000 0x020c0000    \b, hp200/hp300 HP-UX
+>0     belong&0xfc000000 0x04000000    \b, CPU
+>0     belong&0xfc000000 0x08000000    \b, DATA
+>0     belong&0xfc000000 0x10000000    \b, STACK
+>4     leshort x                       \b, (headersize = %d
+>6     leshort x                       \b, segmentsize = %d
+>8     lelong  x                       \b, segments = %d)
+
+# little endian only for now.
+0      name            ktrace
+>4     leshort         7
+>>6    leshort         <3              NetBSD ktrace file version %d
+>>>12  string          x               from %s
+>>>56  string          x               \b, emulation %s
+>>>8   lelong          <65536          \b, pid=%d
+
+56     string          netbsd
+>0     use             ktrace
+56     string          linux
+>0     use             ktrace
+56     string          sunos
+>0     use             ktrace
+56     string          hpux
+>0     use             ktrace
diff --git a/magic/Magdir/netscape b/magic/Magdir/netscape
new file mode 100644 (file)
index 0000000..0e1ca61
--- /dev/null
@@ -0,0 +1,26 @@
+
+#------------------------------------------------------------------------------
+# $File: netscape,v 1.8 2017/03/17 21:35:28 christos Exp $
+# netscape:  file(1) magic for Netscape files
+# "H. Nanosecond" <aldomel@ix.netcom.com>
+# version 3 and 4 I think
+#
+
+# Netscape Address book  .nab
+0      string \000\017\102\104\000\000\000\000\000\000\001\000\000\000\000\002\000\000\000\002\000\000\004\000 Netscape Address book
+
+# Netscape Communicator address book
+0   string   \000\017\102\111 Netscape Communicator address book
+
+# .snm Caches
+0      string          #\ Netscape\ folder\ cache      Netscape folder cache
+0      string  \000\036\204\220\000    Netscape folder cache
+# .n2p
+# Net 2 Phone
+#0     string  123\130\071\066\061\071\071\071\060\070\061\060\061\063\060
+0      string  SX961999        Net2phone
+
+#
+#This is files ending in .art, FIXME add more rules
+0      string  JG\004\016\0\0\0\0      AOL ART image
+0      string  JG\003\016\0\0\0\0      AOL ART image
diff --git a/magic/Magdir/netware b/magic/Magdir/netware
new file mode 100644 (file)
index 0000000..13d4164
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# netware:  file(1) magic for NetWare Loadable Modules (NLMs)
+# From: Mads Martin Joergensen <mmj@suse.de>
+
+0      string  NetWare\ Loadable\ Module       NetWare Loadable Module
diff --git a/magic/Magdir/news b/magic/Magdir/news
new file mode 100644 (file)
index 0000000..af9921b
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# news:  file(1) magic for SunOS NeWS fonts (not "news" as in "netnews")
+#
+0      string          StartFontMetrics        ASCII font metrics
+0      string          StartFont       ASCII font bits
+0      belong          0x137A2944      NeWS bitmap font
+0      belong          0x137A2947      NeWS font family
+0      belong          0x137A2950      scalable OpenFont binary
+0      belong          0x137A2951      encrypted scalable OpenFont binary
+8      belong          0x137A2B45      X11/NeWS bitmap font
+8      belong          0x137A2B48      X11/NeWS font family
diff --git a/magic/Magdir/nitpicker b/magic/Magdir/nitpicker
new file mode 100644 (file)
index 0000000..bea96c3
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File: nitpicker,v 1.8 2019/04/19 00:42:27 christos Exp $
+# nitpicker:  file(1) magic for Flowfiles.
+# From: Christian Jachmann <C.Jachmann@gmx.net> https://www.nitpicker.de
+0      string  NPFF    NItpicker Flow File
+>4     byte    x       V%d.
+>5     byte    x       %d
+>6     bedate  x       started: %s
+>10    bedate  x       stopped: %s
+>14    belong  x       Bytes: %u
+>18    belong  x       Bytes1: %u
+>22    belong  x       Flows: %u
+>26    belong  x       Pkts: %u
diff --git a/magic/Magdir/numpy b/magic/Magdir/numpy
new file mode 100644 (file)
index 0000000..c1520dd
--- /dev/null
@@ -0,0 +1,9 @@
+
+#------------------------------------------------------------------------------
+# $File: numpy,v 1.1 2019/05/09 16:24:36 christos Exp $
+# numpy: file(1) magic for NumPy array binary serialization format
+# Reference: https://docs.scipy.org/doc/numpy/reference/generated/numpy.lib.format.html
+0      string          \x93NUMPY       NumPy array,
+>6     ubyte           x               version %d
+>7     ubyte           x               \b.%d,
+>8     uleshort        x               header length %d
diff --git a/magic/Magdir/oasis b/magic/Magdir/oasis
new file mode 100644 (file)
index 0000000..e20a857
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File: oasis,v 1.1 2011/03/15 02:09:38 christos Exp $
+# OASIS
+# Summary: OASIS stream file
+# Long description: Open Artwork System Interchange Standard
+# File extension: .oas
+# Full name:   Ben Cowley (bcowley@broadcom.com)
+#              Philip Dixon (pdixon@broadcom.com)
+# Reference: http://www.wrcad.com/oasis/oasis-3626-042303-draft.pdf
+#              (see page 3)
+0      string  %SEMI-OASIS\r\n         OASIS Stream file
diff --git a/magic/Magdir/ocaml b/magic/Magdir/ocaml
new file mode 100644 (file)
index 0000000..80de36c
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File: ocaml,v 1.4 2009/09/19 16:28:11 christos Exp $
+# ocaml: file(1) magic for Objective Caml files.
+0      string  Caml1999        OCaml
+>8     string  X               exec file
+>8     string  I               interface file (.cmi)
+>8     string  O               object file (.cmo)
+>8     string  A               library file (.cma)
+>8     string  Y               native object file (.cmx)
+>8     string  Z               native library file (.cmxa)
+>8     string  M               abstract syntax tree implementation file
+>8     string  N               abstract syntax tree interface file
+>9     string  >\0             (Version %3.3s)
diff --git a/magic/Magdir/octave b/magic/Magdir/octave
new file mode 100644 (file)
index 0000000..8154e59
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# octave binary data file(1) magic, from Dirk Eddelbuettel <edd@debian.org>
+0      string          Octave-1-L      Octave binary data (little endian)
+0      string          Octave-1-B      Octave binary data (big endian)
diff --git a/magic/Magdir/ole2compounddocs b/magic/Magdir/ole2compounddocs
new file mode 100644 (file)
index 0000000..f4046cc
--- /dev/null
@@ -0,0 +1,33 @@
+
+#------------------------------------------------------------------------------
+# $File: ole2compounddocs,v 1.6 2019/04/19 00:42:27 christos Exp $
+# Microsoft OLE 2 Compound Documents : file(1) magic for Microsoft Structured
+# storage (https://en.wikipedia.org/wiki/Compound_File_Binary_Format)
+# Additional tests for OLE 2 Compound Documents should be under this recipe.
+
+0   string  \320\317\021\340\241\261\032\341      OLE 2 Compound Document
+# - Microstation V8 DGN files (www.bentley.com)
+#   Last update on 10/23/2006 by Lester Hightower
+> 0x480  string  D\000g\000n\000~\000H                : Microstation V8 DGN
+# - Visio documents
+#   Last update on 10/23/2006 by Lester Hightower
+> 0x480  string  V\000i\000s\000i\000o\000D\000o\000c : Visio Document
+
+# Note: moved & merged Microsoft Office parts from ./msdos Oct 2017
+# Update: Joerg Jenderek
+# from https://filext.com by Derek M Jones <derek@knosof.co.uk>
+# False positive with PPT (also currently this string is too long)
+#0     string/b        \xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x03\x00\xFE\xFF\x09\x00\x06    Microsoft Installer
+#0     string/b        \320\317\021\340\241\261\032\341        Microsoft Office Document
+#>48   byte    0x1B                                    Excel Document
+#!:mime application/vnd.ms-excel
+>546   string  bjbj                    : Microsoft Word Document
+!:mime application/msword
+# https://www.macdisk.com/macsigen.php
+!:apple        MSWDWDBN
+!:ext  doc/dot
+>546   string  jbjb                    : Microsoft Word Document
+!:mime application/msword
+!:apple        MSWDWDBN
+!:ext  doc
+
diff --git a/magic/Magdir/olf b/magic/Magdir/olf
new file mode 100644 (file)
index 0000000..990975c
--- /dev/null
@@ -0,0 +1,98 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# olf:  file(1) magic for OLF executables
+#
+# We have to check the byte order flag to see what byte order all the
+# other stuff in the header is in.
+#
+# MIPS R3000 may also be for MIPS R2000.
+# What're the correct byte orders for the nCUBE and the Fujitsu VPP500?
+#
+# Created by Erik Theisen <etheisen@openbsd.org>
+# Based on elf from Daniel Quinlan <quinlan@yggdrasil.com>
+0      string          \177OLF         OLF
+>4     byte            0               invalid class
+>4     byte            1               32-bit
+>4     byte            2               64-bit
+>7     byte            0               invalid os
+>7     byte            1               OpenBSD
+>7     byte            2               NetBSD
+>7     byte            3               FreeBSD
+>7     byte            4               4.4BSD
+>7     byte            5               Linux
+>7     byte            6               SVR4
+>7     byte            7               esix
+>7     byte            8               Solaris
+>7     byte            9               Irix
+>7     byte            10              SCO
+>7     byte            11              Dell
+>7     byte            12              NCR
+>5     byte            0               invalid byte order
+>5     byte            1               LSB
+>>16   leshort         0               no file type,
+>>16   leshort         1               relocatable,
+>>16   leshort         2               executable,
+>>16   leshort         3               shared object,
+# Core handling from Peter Tobias <tobias@server.et-inf.fho-emden.de>
+# corrections by Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de>
+>>16   leshort         4               core file
+>>>(0x38+0xcc) string  >\0             of '%s'
+>>>(0x38+0x10) lelong  >0              (signal %d),
+>>16   leshort         &0xff00         processor-specific,
+>>18   leshort         0               no machine,
+>>18   leshort         1               AT&T WE32100 - invalid byte order,
+>>18   leshort         2               SPARC - invalid byte order,
+>>18   leshort         3               Intel 80386,
+>>18   leshort         4               Motorola 68000 - invalid byte order,
+>>18   leshort         5               Motorola 88000 - invalid byte order,
+>>18   leshort         6               Intel 80486,
+>>18   leshort         7               Intel 80860,
+>>18   leshort         8               MIPS R3000_BE - invalid byte order,
+>>18   leshort         9               Amdahl - invalid byte order,
+>>18   leshort         10              MIPS R3000_LE,
+>>18   leshort         11              RS6000 - invalid byte order,
+>>18   leshort         15              PA-RISC - invalid byte order,
+>>18   leshort         16              nCUBE,
+>>18   leshort         17              VPP500,
+>>18   leshort         18              SPARC32PLUS,
+>>18   leshort         20              PowerPC,
+>>18   leshort         0x9026          Alpha,
+>>20   lelong          0               invalid version
+>>20   lelong          1               version 1
+>>36   lelong          1               MathCoPro/FPU/MAU Required
+>8     string          >\0             (%s)
+>5     byte            2               MSB
+>>16   beshort         0               no file type,
+>>16   beshort         1               relocatable,
+>>16   beshort         2               executable,
+>>16   beshort         3               shared object,
+>>16   beshort         4               core file,
+>>>(0x38+0xcc) string  >\0             of '%s'
+>>>(0x38+0x10) belong  >0              (signal %d),
+>>16   beshort         &0xff00         processor-specific,
+>>18   beshort         0               no machine,
+>>18   beshort         1               AT&T WE32100,
+>>18   beshort         2               SPARC,
+>>18   beshort         3               Intel 80386 - invalid byte order,
+>>18   beshort         4               Motorola 68000,
+>>18   beshort         5               Motorola 88000,
+>>18   beshort         6               Intel 80486 - invalid byte order,
+>>18   beshort         7               Intel 80860,
+>>18   beshort         8               MIPS R3000_BE,
+>>18   beshort         9               Amdahl,
+>>18   beshort         10              MIPS R3000_LE - invalid byte order,
+>>18   beshort         11              RS6000,
+>>18   beshort         15              PA-RISC,
+>>18   beshort         16              nCUBE,
+>>18   beshort         17              VPP500,
+>>18   beshort         18              SPARC32PLUS,
+>>18   beshort         20              PowerPC or cisco 4500,
+>>18   beshort         21              cisco 7500,
+>>18   beshort         24              cisco SVIP,
+>>18   beshort         25              cisco 7200,
+>>18   beshort         36              cisco 12000,
+>>18   beshort         0x9026          Alpha,
+>>20   belong          0               invalid version
+>>20   belong          1               version 1
+>>36   belong          1               MathCoPro/FPU/MAU Required
diff --git a/magic/Magdir/os2 b/magic/Magdir/os2
new file mode 100644 (file)
index 0000000..ace69cb
--- /dev/null
@@ -0,0 +1,49 @@
+
+#------------------------------------------------------------------------------
+# $File: os2,v 1.10 2017/03/17 21:35:28 christos Exp $
+# os2:  file(1) magic for OS/2 files
+#
+
+# Provided 1998/08/22 by
+# David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
+1      search/100      InternetShortcut        MS Windows 95 Internet shortcut text
+>17    search/100      URL=                    (URL=<
+>>&0   string          x                       \b%s>)
+
+# OS/2 URL objects
+# Provided 1998/08/22 by
+# David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
+#0     string  http:                   OS/2 URL object text
+#>5    string  >\                      (WWW) <http:%s>
+#0     string  mailto:                 OS/2 URL object text
+#>7    string  >\                      (email) <%s>
+#0     string  news:                   OS/2 URL object text
+#>5    string  >\                      (Usenet) <%s>
+#0     string  ftp:                    OS/2 URL object text
+#>4    string  >\                      (FTP) <ftp:%s>
+#0     string  file:                   OS/2 URL object text
+#>5    string  >\                      (Local file) <%s>
+
+# >>>>> OS/2 INF/HLP <<<<<  (source: Daniel Dissett ddissett@netcom.com)
+# Carl Hauser (chauser.parc@xerox.com) and
+# Marcus Groeber (marcusg@ph-cip.uni-koeln.de)
+# list the following header format in inf02a.doc:
+#
+#  int16 ID;           // ID magic word (5348h = "HS")
+#  int8  unknown1;     // unknown purpose, could be third letter of ID
+#  int8  flags;        // probably a flag word...
+#                      //  bit 0: set if INF style file
+#                      //  bit 4: set if HLP style file
+#                      // patching this byte allows reading HLP files
+#                      // using the VIEW command, while help files
+#                      // seem to work with INF settings here as well.
+#  int16 hdrsize;      // total size of header
+#  int16 unknown2;     // unknown purpose
+#
+0   string  HSP\x01\x9b\x00 OS/2 INF
+>107 string >0                      (%s)
+0   string  HSP\x10\x9b\x00     OS/2 HLP
+>107 string >0                      (%s)
+
+# OS/2 INI (this is a guess)
+0  string   \xff\xff\xff\xff\x14\0\0\0  OS/2 INI
diff --git a/magic/Magdir/os400 b/magic/Magdir/os400
new file mode 100644 (file)
index 0000000..ef8af36
--- /dev/null
@@ -0,0 +1,39 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# os400:  file(1) magic for IBM OS/400 files
+#
+# IBM OS/400 (i5/OS) Save file (SAVF) - gerardo.cacciari@gmail.com
+# In spite of its quite variable format (due to internal memory page
+# length differences between CISC and RISC versions of the OS) the
+# SAVF structure hasn't suitable offsets to identify the catalog
+# header in the first descriptor where there are some useful infos,
+# so we must search in a somewhat large area for a particular string
+# that represents the EBCDIC encoding of 'QSRDSSPC' (save/restore
+# descriptor space) preceded by a two byte constant.
+#
+1090    search/7393    \x19\xDB\xD8\xE2\xD9\xC4\xE2\xE2\xD7\xC3 IBM OS/400 save file data
+>&212   byte           0x01                     \b, created with SAVOBJ
+>&212   byte           0x02                     \b, created with SAVLIB
+>&212   byte           0x07                     \b, created with SAVCFG
+>&212   byte           0x08                     \b, created with SAVSECDTA
+>&212   byte           0x0A                     \b, created with SAVSECDTA
+>&212   byte           0x0B                     \b, created with SAVDLO
+>&212   byte           0x0D                     \b, created with SAVLICPGM
+>&212   byte           0x11                     \b, created with SAVCHGOBJ
+>&213   byte           0x44                     \b, at least V5R4 to open
+>&213   byte           0x43                     \b, at least V5R3 to open
+>&213   byte           0x42                     \b, at least V5R2 to open
+>&213   byte           0x41                     \b, at least V5R1 to open
+>&213   byte           0x40                     \b, at least V4R5 to open
+>&213   byte           0x3F                     \b, at least V4R4 to open
+>&213   byte           0x3E                     \b, at least V4R3 to open
+>&213   byte           0x3C                     \b, at least V4R2 to open
+>&213   byte           0x3D                     \b, at least V4R1M4 to open
+>&213   byte           0x3B                     \b, at least V4R1 to open
+>&213   byte           0x3A                     \b, at least V3R7 to open
+>&213   byte           0x35                     \b, at least V3R6 to open
+>&213   byte           0x36                     \b, at least V3R2 to open
+>&213   byte           0x34                     \b, at least V3R1 to open
+>&213   byte           0x31                     \b, at least V3R0M5 to open
+>&213   byte           0x30                     \b, at least V2R3 to open
diff --git a/magic/Magdir/os9 b/magic/Magdir/os9
new file mode 100644 (file)
index 0000000..74b47f3
--- /dev/null
@@ -0,0 +1,80 @@
+
+#------------------------------------------------------------------------------
+# $File: os9,v 1.8 2017/03/17 21:35:28 christos Exp $
+#
+# Copyright (c) 1996 Ignatios Souvatzis. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#
+#
+# OS9/6809 module descriptions:
+#
+0      beshort         0x87CD  OS9/6809 module:
+#
+>6     byte&0x0f       0x00    non-executable
+>6     byte&0x0f       0x01    machine language
+>6     byte&0x0f       0x02    BASIC I-code
+>6     byte&0x0f       0x03    Pascal P-code
+>6     byte&0x0f       0x04    C I-code
+>6     byte&0x0f       0x05    COBOL I-code
+>6     byte&0x0f       0x06    Fortran I-code
+#
+>6     byte&0xf0       0x10    program executable
+>6     byte&0xf0       0x20    subroutine
+>6     byte&0xf0       0x30    multi-module
+>6     byte&0xf0       0x40    data module
+#
+>6     byte&0xf0       0xC0    system module
+>6     byte&0xf0       0xD0    file manager
+>6     byte&0xf0       0xE0    device driver
+>6     byte&0xf0       0xF0    device descriptor
+#
+# OS9/m68k stuff (to be continued)
+#
+0      beshort         0x4AFC  OS9/68K module:
+#
+# attr
+>0x14  byte&0x80       0x80    re-entrant
+>0x14  byte&0x40       0x40    ghost
+>0x14  byte&0x20       0x20    system-state
+#
+# lang:
+#
+>0x13  byte            1       machine language
+>0x13  byte            2       BASIC I-code
+>0x13  byte            3       Pascal P-code
+>0x13  byte            4       C I-code
+>0x13  byte            5       COBOL I-code
+>0x13  byte            6       Fortran I-code
+#
+#
+# type:
+#
+>0x12  byte            1       program executable
+>0x12  byte            2       subroutine
+>0x12  byte            3       multi-module
+>0x12  byte            4       data module
+>0x12  byte            11      trap library
+>0x12  byte            12      system module
+>0x12  byte            13      file manager
+>0x12  byte            14      device driver
+>0x12  byte            15      device descriptor
diff --git a/magic/Magdir/osf1 b/magic/Magdir/osf1
new file mode 100644 (file)
index 0000000..3139993
--- /dev/null
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# $File$
+#
+# Mach magic number info
+#
+0      long            0xefbe  OSF/Rose object
+# I386 magic number info
+#
+0      short           0565    i386 COFF object
diff --git a/magic/Magdir/palm b/magic/Magdir/palm
new file mode 100644 (file)
index 0000000..8cec9df
--- /dev/null
@@ -0,0 +1,155 @@
+
+#------------------------------------------------------------------------------
+# $File: palm,v 1.14 2019/04/19 00:42:27 christos Exp $
+# palm:         file(1) magic for PalmOS {.prc,.pdb}: applications, docfiles, and hacks
+#
+# Brian Lalor <blalor@hcirisc.cs.binghamton.edu>
+
+# These are weak, byte 59 is not guaranteed to be 0 and there are
+# 8 character identifiers at byte 60, one I found for appl is BIGb.
+# What are the possibilities and where is this documented?
+
+# The common header format for PalmOS .pdb/.prc files is
+# {
+#         char            name[ 32 ];
+#         Word            attributes;
+#         Word            version;
+#         DWord           creationDate;
+#         DWord           modificationDate;
+#         DWord           lastBackupDate;
+#         DWord           modificationNumber;
+#         DWord           appInfoID;
+#         DWord           sortInfoID;
+#         char            type[4];
+#         char            creator[4];
+#         DWord           uniqueIDSeed;
+#         RecordListType  recordList;
+# };
+#
+# Datestamps are unsigned seconds since the MacOS epoch (Jan 1, 1904),
+# or Unix/POSIX time + 2082844800.
+
+0              name            aportisdoc
+# date is supposed to be big-endian seconds since 1 Jan 1904, but many
+# files contain the timestamp in little-endian or a completely
+# nonsensical value...
+#>36           bedate-2082844800       >0      \b, created %s
+# compression: 1=uncomp, 2=orig, 0x4448=HuffDic
+>(78.L)                beshort         =1              \b, uncompressed
+# compressed
+>(78.L)                beshort         >1
+>>(78.L+4)     belong          x               \b, %d bytes uncompressed
+
+# appl
+#60            string          appl            PalmOS application
+#>0            string          >\0             "%s"
+
+# HACK
+#60            string          HACK            HackMaster hack
+#>0            string          >\0             "%s"
+
+# iSiloX e-book
+60             string          SDocSilX        iSiloX E-book
+>0             string          >\0             "%s"
+
+# Mobipocket (www.mobipocket.com), donated by Carl Witty
+# expanded by Ralf Brown
+60             string          BOOKMOBI        Mobipocket E-book
+# MobiPocket stores a full title, pointed at by the belong at offset
+# 0x54 in its header at (78.L), with length given by the belong at
+# offset 0x58.
+# there's no guarantee that the title string is null-terminated, but
+# we currently can't specify a variable-length string where the length
+# field is not at the start of the string; in practice, the data
+# following the string always seems to start with a zero byte
+>(78.L)                belong          x
+>>&(&0x50.L-4) string          >\0             "%s"
+>0             use             aportisdoc
+>>(78.L+0x68)  belong          >0              \b, version %d
+>>(78.L+0x1C)  belong          !0              \b, codepage %d
+>>(78.L+0x0C)  beshort         >0              \b, encrypted (type %d)
+
+# AportisDoc/PalmDOC
+60             string          TEXtREAd        AportisDoc/PalmDOC E-book
+>0             string          >\0             "%s"
+>0             use             aportisdoc
+
+# Variety of PalmOS document types
+# Michael-John Turner <mj@debian.org>
+# Thanks to Hasan Umit Ezerce <humit@tr-net.net.tr> for his DocType
+60     string                  BVokBDIC        BDicty PalmOS document
+>0     string                  >\0             "%s"
+60     string                  DB99DBOS        DB PalmOS document
+>0     string                  >\0             "%s"
+60     string                  vIMGView        FireViewer/ImageViewer PalmOS document
+>0     string                  >\0             "%s"
+60     string                  PmDBPmDB        HanDBase PalmOS document
+>0     string                  >\0             "%s"
+60     string                  InfoINDB        InfoView PalmOS document
+>0     string                  >\0             "%s"
+60     string                  ToGoToGo        iSilo PalmOS document
+>0     string                  >\0             "%s"
+60     string                  JfDbJBas        JFile PalmOS document
+>0     string                  >\0             "%s"
+60     string                  JfDbJFil        JFile Pro PalmOS document
+>0     string                  >\0             "%s"
+60     string                  DATALSdb        List PalmOS document
+>0     string                  >\0             "%s"
+60     string                  Mdb1Mdb1        MobileDB PalmOS document
+>0     string                  >\0             "%s"
+60     string                  PNRdPPrs        PeanutPress PalmOS document
+>0     string                  >\0             "%s"
+60     string                  DataPlkr        Plucker PalmOS document
+>0     string                  >\0             "%s"
+60     string                  DataSprd        QuickSheet PalmOS document
+>0     string                  >\0             "%s"
+60     string                  SM01SMem        SuperMemo PalmOS document
+>0     string                  >\0             "%s"
+60     string                  TEXtTlDc        TealDoc PalmOS document
+>0     string                  >\0             "%s"
+60     string                  InfoTlIf        TealInfo PalmOS document
+>0     string                  >\0             "%s"
+60     string                  DataTlMl        TealMeal PalmOS document
+>0     string                  >\0             "%s"
+60     string                  DataTlPt        TealPaint PalmOS document
+>0     string                  >\0             "%s"
+60     string                  dataTDBP        ThinkDB PalmOS document
+>0     string                  >\0             "%s"
+60     string                  TdatTide        Tides PalmOS document
+>0     string                  >\0             "%s"
+60     string                  ToRaTRPW        TomeRaider PalmOS document
+>0     string                  >\0             "%s"
+
+# A GutenPalm zTXT etext for use on Palm Pilots (http://gutenpalm.sf.net)
+# For version 1.xx zTXTs, outputs version and numbers of bookmarks and
+#   annotations.
+# For other versions, just outputs version.
+#
+60             string          zTXT            A GutenPalm zTXT e-book
+>0             string          >\0             "%s"
+>(0x4E.L)      byte            0
+>>(0x4E.L+1)   byte            x               (v0.%02d)
+>(0x4E.L)      byte            1
+>>(0x4E.L+1)   byte            x               (v1.%02d)
+>>>(0x4E.L+10) beshort         >0
+>>>>(0x4E.L+10) beshort                <2              - 1 bookmark
+>>>>(0x4E.L+10) beshort                >1              - %d bookmarks
+>>>(0x4E.L+14) beshort         >0
+>>>>(0x4E.L+14) beshort                <2              - 1 annotation
+>>>>(0x4E.L+14) beshort                >1              - %d annotations
+>(0x4E.L)      byte            >1              (v%d.
+>>(0x4E.L+1)   byte            x               %02d)
+
+# Palm OS .prc file types
+60             string          libr
+# flags, only bit 0 or bit 6
+# https://en.wikipedia.org/wiki/PRC_%28Palm_OS%29
+# https://web.mit.edu/tytso/www/pilot/prc-format.html
+>0x20          beshort&0xffbe  0
+>>0            string          >\0             Palm OS dynamic library data "%s"
+60             string          ptch            Palm OS operating system patch data
+>0             string          >\0             "%s"
+
+# Mobipocket (www.mobipocket.com), donated by Carl Witty
+60     string                  BOOKMOBI        Mobipocket E-book
+>0     string                  >\0             "%s"
diff --git a/magic/Magdir/parix b/magic/Magdir/parix
new file mode 100644 (file)
index 0000000..23147ab
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+#
+# Parix COFF executables
+# From: Ignatios Souvatzis <ignatios@cs.uni-bonn.de>
+#
+0      beshort&0xfff   0xACE   PARIX
+>0     byte&0xf0       0x80    T800
+>0     byte&0xf0       0x90    T9000
+>19    byte&0x02       0x02    executable
+>19    byte&0x02       0x00    object
+>19    byte&0x0c       0x00    not stripped
diff --git a/magic/Magdir/parrot b/magic/Magdir/parrot
new file mode 100644 (file)
index 0000000..b2a56c8
--- /dev/null
@@ -0,0 +1,22 @@
+#------------------------------------------------------------------------------
+# $File: parrot,v 1.2 2019/04/19 00:42:27 christos Exp $
+# parrot: file(1) magic for Parrot Virtual Machine
+# URL: https://www.lua.org/
+# From: Lubomir Rintel <lkundrak@v3.sk>
+
+# Compiled Parrot byte code
+0      string  \376PBC\r\n\032\n       Parrot bytecode
+>64    byte    x                       %d.
+>72    byte    x                       \b%d,
+>8     byte    >0                      %d byte words,
+>16    byte    0                       little-endian,
+>16    byte    1                       big-endian,
+>32    byte    0                       IEEE-754 8 byte double floats,
+>32    byte    1                       x86 12 byte long double floats,
+>32    byte    2                       IEEE-754 16 byte long double floats,
+>32    byte    3                       MIPS 16 byte long double floats,
+>32    byte    4                       AIX 16 byte long double floats,
+>32    byte    5                       4-byte floats,
+>40    byte    x                       Parrot %d.
+>48    byte    x                       \b%d.
+>56    byte    x                       \b%d
diff --git a/magic/Magdir/pascal b/magic/Magdir/pascal
new file mode 100644 (file)
index 0000000..d8e61c6
--- /dev/null
@@ -0,0 +1,10 @@
+#------------------------------------------------------------------------------
+# $File: pascal,v 1.1 2011/12/08 12:12:46 rrt Exp $
+# pascal:  file(1) magic for Pascal source
+#
+0      search/8192     (input,         Pascal source text
+!:mime text/x-pascal
+#0     regex           \^program       Pascal source text
+#!:mime        text/x-pascal
+#0     regex                   \^record                Pascal source text
+#!:mime        text/x-pascal
diff --git a/magic/Magdir/pbf b/magic/Magdir/pbf
new file mode 100644 (file)
index 0000000..0ab7a88
--- /dev/null
@@ -0,0 +1,11 @@
+
+#------------------------------------------------------------------------------
+# $File: pbf,v 1.3 2019/04/19 00:42:27 christos Exp $
+# file(1) magic(5) data for OpenStreetMap
+
+# OpenStreetMap Protocolbuffer Binary Format (.osm.pbf)
+# https://wiki.openstreetmap.org/wiki/PBF_Format
+# From: Markus Heidelberg <markus.heidelberg@web.de>
+0      belong&0xfffffff0       0
+>4     beshort                 0x0A09
+>>6    string                  OSMHeader       OpenStreetMap Protocolbuffer Binary Format
diff --git a/magic/Magdir/pbm b/magic/Magdir/pbm
new file mode 100644 (file)
index 0000000..5d2c6b2
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# pbm:  file(1) magic for Portable Bitmap files
+#
+# XXX - byte order?
+#
+0      short   0x2a17  "compact bitmap" format (Poskanzer)
diff --git a/magic/Magdir/pc88 b/magic/Magdir/pc88
new file mode 100644 (file)
index 0000000..03822f5
--- /dev/null
@@ -0,0 +1,24 @@
+#------------------------------------------------------------------------------
+# pc88:  file(1) magic for the NEC Home Computer
+# v1.0
+# Fabio R. Schmidlin <sd-snatcher@users.sourceforge.net>
+
+# PC88 2D disk image
+0x20           ulelong&0xFFFFFEFF      0x2A0
+>0x10          string          \0\0\0\0\0\0\0\0\0\0
+>>0x280                string          \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
+>>>0x1A                ubyte&0xEF      0
+>>>>0x1B       ubyte&0x8F      0
+>>>>>0x1B      ubyte&70        <0x40
+>>>>>>0x1C     ulelong >0x21
+>>>>>>>0               regex   [[:print:]]*    NEC PC-88 disk image, name=%s
+>>>>>>>>0x1B   ubyte   0       \b, media=2D
+>>>>>>>>0x1B   ubyte   0x10    \b, media=2DD
+>>>>>>>>0x1B   ubyte   0x20    \b, media=2HD
+>>>>>>>>0x1B   ubyte   0x30    \b, media=1D
+>>>>>>>>0x1B   ubyte   0x40    \b, media=1DD
+>>>>>>>>0x1A   ubyte   0x10    \b, write-protected
+
+
+
+
diff --git a/magic/Magdir/pc98 b/magic/Magdir/pc98
new file mode 100644 (file)
index 0000000..e8f6b8a
--- /dev/null
@@ -0,0 +1,77 @@
+#------------------------------------------------------------------------------
+# pc98:  file(1) magic for the MSX Home Computer
+# v1.0
+# Fabio R. Schmidlin <sd-snatcher@users.sourceforge.net>
+
+# Maki-chan v1 Graphic format
+# The image resolution should be X=(44.L - 40.L) and Y=(46.L - 42.L), but I couldn't find a way to do so
+# http://www.jisyo.com/viewer/faq/maki_tech.htm
+0      string/b                MAKI01  Maki-chan v1.
+>6     ubyte|0x20      x               \b%c image
+>8     ubelong         >0x40404040     \b, system ID:
+>>8    byte            x               %c
+>>9    byte            x               \b%c
+>>10   byte            x               \b%c
+>>11   byte            x               \b%c
+>44    ubeshort        x               \b, %dx
+>46    ubeshort        x               \b%d
+>38    ubeshort&2      0               \b, 16 paletted RGB colors
+>38    ubeshort&2      2               \b, 8 fixed RGB colors
+>38    ubeshort&1      1               \b, 2:1 dot aspect ratio
+
+# Maki-chan v2 Graphic format
+# http://www.jisyo.com/viewer/faq/mag_tech.htm
+# https://mooncore.eu/bunny/txt/makichan.htm
+# http://metanest.jp/mag/mag.xhtml
+0      string/b                MAKI02\ \       Maki-chan v2 image,
+>8     byte            x               system ID: %c
+>9     byte            x               \b%c
+>10    byte            x               \b%c
+>11    byte            x               \b%c,
+>13    search/0x200    \x1A
+#Maki-chan video modes are a bit messy and seems to have been expanded over the years without too much planing:
+#1) When offset1(ubeshort) !=0x0344:
+# 1.1) And  offset3(ubyte).b7=0:
+# - b0=pixel aspect ratio: 1=2:1   (note: this ignores that the machine's 1:1 pixel aspect ratio isn't really 1:1)
+# - b1=number of colors: 0=16 colors, 1=8 colors
+# - b2=Palette or fixed colors flag (called "analog" and "digital" in the doc): 0=Paletted, 1=Fixed colors encoded directly in the pixel data
+# 1.2) And  offset3(ubyte).B7=1:
+# - b0=256 paletted colors
+# - b1=256 fixed colors using the MSX SCR8 palette
+#2) When offset1(ubeshort) =0x0344:
+# - 256x212 image with 19268 YJK colors. The usual resolution and color information fields from the file must be ignored
+>>&1   ubeshort        0x0344          256x212, 19268 fixed YJK colors
+>>&1   ubeshort        !0x0344
+>>>&5  uleshort+1      x               %dx
+>>>&7  uleshort+1      x               \b%d,
+>>>&0  ubyte&0x86      0x00            16 paletted RGB colors
+>>>&0  ubyte&0x86      0x02            8 paletted RGB colors
+>>>&0  ubyte&0x86      0x04            16 fixed RGB colors
+>>>&0  ubyte&0x86      0x06            8 fixed RGB colors
+>>>&0  ubyte&0x81      0x80            256 paletted RGB colors
+>>>&0  ubyte&0x81      0x81            256 fixed MSX-SCR8 colors
+>>>&0  ubyte&0x01      1               \b, 2:1 dot aspect ratio
+
+# XLD4 (Q4) picture
+11     string/b        MAJYO           XLD4(Q4) picture
+
+# Yanagisawa Pi picture
+#0     string          Pi\x1A\0        Yanagisawa Pi picture
+#>3    search/0x200    \x04
+0      string          Pi
+>2     search/0x200    \x1A
+>>&0   ubyte           0
+>>>&3  ubyte           4               Yanagisawa Pi 16 color picture,
+>>>&4  byte            x               system ID: %c
+>>>&5  byte            x               \b%c
+>>>&6  byte            x               \b%c
+>>>&7  byte            x               \b%c,
+>>>&10 ubeshort        x               %dx
+>>>&12 ubeshort        x               \b%d
+>>>&3  ubyte           8               Yanagisawa Pi 256 color picture
+>>>&4  byte            x               system ID: %c
+>>>&5  byte            x               \b%c
+>>>&6  byte            x               \b%c
+>>>&7  byte            x               \b%c,
+>>>&10 ubeshort        x               %dx
+>>>&12 ubeshort        x               \b%d
diff --git a/magic/Magdir/pdf b/magic/Magdir/pdf
new file mode 100644 (file)
index 0000000..0a06dc9
--- /dev/null
@@ -0,0 +1,31 @@
+
+#------------------------------------------------------------------------------
+# $File: pdf,v 1.10 2018/05/23 22:21:01 christos Exp $
+# pdf:  file(1) magic for Portable Document Format
+#
+
+0      string          %PDF-           PDF document
+!:mime application/pdf
+!:strength +60
+>5     byte            x               \b, version %c
+>7     byte            x               \b.%c
+
+0      string          \012%PDF-       PDF document
+!:mime application/pdf
+!:strength +60
+>6     byte            x               \b, version %c
+>8     byte            x               \b.%c
+
+# From: Nick Schmalenberger <nick@schmalenberger.us>
+# Forms Data Format
+0       string          %FDF-           FDF document
+!:mime application/vnd.fdf
+!:strength +60
+>5      byte            x               \b, version %c
+>7      byte            x               \b.%c
+
+0      search/256      %PDF-           PDF document
+!:mime application/pdf
+!:strength +60
+>&0    byte            x               \b, version %c
+>&2    byte            x               \b.%c
diff --git a/magic/Magdir/pdp b/magic/Magdir/pdp
new file mode 100644 (file)
index 0000000..2d18b62
--- /dev/null
@@ -0,0 +1,42 @@
+
+#------------------------------------------------------------------------------
+# $File: pdp,v 1.11 2017/03/17 21:35:28 christos Exp $
+# pdp:  file(1) magic for PDP-11 executable/object and APL workspace
+#
+0      lelong          0101555         PDP-11 single precision APL workspace
+0      lelong          0101554         PDP-11 double precision APL workspace
+#
+# PDP-11 a.out
+#
+0      leshort         0407            PDP-11 executable
+>8     leshort         >0              not stripped
+>15    byte            >0              - version %d
+
+# updated by Joerg Jenderek at Mar 2013
+# GRR: line below too general as it catches also Windows precompiled setup information *.PNF
+0      leshort         0401
+# skip *.PNF with WinDirPathOffset 58h
+>68    ulelong         !0x00000058     PDP-11 UNIX/RT ldp
+# skip *.PNF with high byte of InfVersionDatumCount zero
+#>>15  byte            !0              PDP-11 UNIX/RT ldp
+0      leshort         0405            PDP-11 old overlay
+
+0      leshort         0410            PDP-11 pure executable
+>8     leshort         >0              not stripped
+>15    byte            >0              - version %d
+
+0      leshort         0411            PDP-11 separate I&D executable
+>8     leshort         >0              not stripped
+>15    byte            >0              - version %d
+
+0      leshort         0437            PDP-11 kernel overlay
+
+# These last three are derived from 2.11BSD file(1)
+0      leshort         0413            PDP-11 demand-paged pure executable
+>8     leshort         >0              not stripped
+
+0      leshort         0430            PDP-11 overlaid pure executable
+>8     leshort         >0              not stripped
+
+0      leshort         0431            PDP-11 overlaid separate executable
+>8     leshort         >0              not stripped
diff --git a/magic/Magdir/perl b/magic/Magdir/perl
new file mode 100644 (file)
index 0000000..3423b5c
--- /dev/null
@@ -0,0 +1,100 @@
+#------------------------------------------------------------------------------
+# $File: perl,v 1.25 2016/06/07 23:28:37 rrt Exp $
+# perl:  file(1) magic for Larry Wall's perl language.
+#
+# The `eval' lines recognizes an outrageously clever hack.
+# Keith Waclena <keith@cerberus.uchicago.edu>
+# Send additions to <perl5-porters@perl.org>
+0      search/1024     eval\ "exec\ perl               Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ "exec\ /bin/perl          Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ "exec\ /usr/bin/perl      Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ "exec\ /usr/local/bin/perl        Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ 'exec\ perl               Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ 'exec\ /bin/perl          Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ 'exec\ /usr/bin/perl      Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ 'exec\ /usr/local/bin/perl        Perl script text
+!:mime text/x-perl
+0      search/1024     eval\ '(exit\ $?0)'\ &&\ eval\ 'exec    Perl script text
+!:mime text/x-perl
+0      string  #!/usr/bin/env\ perl    Perl script text executable
+!:mime text/x-perl
+0      string  #!\ /usr/bin/env\ perl  Perl script text executable
+!:mime text/x-perl
+0      string  #!
+>0     regex   \^#!.*/bin/perl([[:space:]].*)*$        Perl script text executable
+!:mime text/x-perl
+
+# by Dmitry V. Levin and Alexey Tourbin
+# check the first line
+0      search/8192     package
+>0     regex           \^package[\ \t]+[0-9A-Za-z_:]+\ *;      Perl5 module source text
+!:strength + 40
+# not 'p', check other lines
+0      search/8192     !p
+>0     regex           \^package[\ \t]+[0-9A-Za-z_:]+\ *;
+>>0    regex           \^1\ *;|\^(use|sub|my)\ .*[(;{=]        Perl5 module source text
+!:strength + 75
+
+# Perl POD documents
+# From: Tom Hukins <tom@eborcom.com>
+0      search/1024/W   \=pod\n         Perl POD document text
+0      search/1024/W   \n\=pod\n       Perl POD document text
+0      search/1024/W   \=head1\        Perl POD document text
+0      search/1024/W   \n\=head1\      Perl POD document text
+0      search/1024/W   \=head2\        Perl POD document text
+0      search/1024/W   \n\=head2\      Perl POD document text
+0      search/1024/W   \=encoding\     Perl POD document text
+0      search/1024/W   \n\=encoding\   Perl POD document text
+
+
+# Perl Storable data files.
+0      string  perl-store      perl Storable (v0.6) data
+>4     byte    >0      (net-order %d)
+>>4    byte    &01     (network-ordered)
+>>4    byte    =3      (major 1)
+>>4    byte    =2      (major 1)
+
+0      string  pst0    perl Storable (v0.7) data
+>4     byte    >0
+>>4    byte    &01     (network-ordered)
+>>4    byte    =5      (major 2)
+>>4    byte    =4      (major 2)
+>>5    byte    >0      (minor %d)
+
+# This is Debian #742949 by Zefram <zefram@fysh.org>:
+# -----------------------------------------------------------
+# The Perl module Hash::SharedMem
+# <https://metacpan.org/release/Hash-SharedMem> defines a file format
+# for a key/value store.  Details of the file format are in the "DESIGN"
+# file in the module distribution.  Magic:
+0      bequad  =0xa58afd185cbf5af7     Hash::SharedMem master file, big-endian
+>8     bequad  <0x1000000
+>>15   byte    >2      \b, line size 2^%d byte
+>>14   byte    >2      \b, page size 2^%d byte
+>>13   byte    &1
+>>>13  byte    >1      \b, max fanout %d
+0      lequad  =0xa58afd185cbf5af7     Hash::SharedMem master file, little-endian
+>8     lequad  <0x1000000
+>>8    byte    >2      \b, line size 2^%d byte
+>>9    byte    >2      \b, page size 2^%d byte
+>>10   byte    &1
+>>>10  byte    >1      \b, max fanout %d
+0      bequad  =0xc693dac5ed5e47c2     Hash::SharedMem data file, big-endian
+>8     bequad  <0x1000000
+>>15   byte    >2      \b, line size 2^%d byte
+>>14   byte    >2      \b, page size 2^%d byte
+>>13   byte    &1
+>>>13  byte    >1      \b, max fanout %d
+0      lequad  =0xc693dac5ed5e47c2     Hash::SharedMem data file, little-endian
+>8     lequad  <0x1000000
+>>8    byte    >2      \b, line size 2^%d byte
+>>9    byte    >2      \b, page size 2^%d byte
+>>10   byte    &1
+>>>10  byte    >1      \b, max fanout %d
diff --git a/magic/Magdir/pgf b/magic/Magdir/pgf
new file mode 100644 (file)
index 0000000..b5a251e
--- /dev/null
@@ -0,0 +1,52 @@
+
+#------------------------------------------------------------------------------
+# $File: pgf,v 1.2 2017/03/17 21:35:28 christos Exp $
+# pgf: file(1) magic for Progressive Graphics File (PGF)
+#
+# <http://www.libpgf.org/uploads/media/PGF_Details_01.pdf>
+# 2013 by Philipp Hahn <pmhahn debian org>
+0 string PGF Progressive Graphics image data,
+!:mime image/x-pgf
+>3     string  2       version %s,
+>3     string  4       version %s,
+>3     string  5       version %s,
+>3     string  6       version %s,
+#      PGFPreHeader
+#>>4   lelong  x       header size %d,
+#      PGFHeader
+>>8    lelong  x       %d x
+>>12   lelong  x       %d,
+>>16   byte    x       %d levels,
+>>17   byte    x       compression level %d,
+>>18   byte    x       %d bpp,
+>>19   byte    x       %d channels,
+>>20   clear   x
+>>20   byte    0       bitmap,
+>>20   byte    1       gray scale,
+>>20   byte    2       indexed color,
+>>20   byte    3       RGB color,
+>>20   byte    4       CYMK color,
+>>20   byte    5       HSL color,
+>>20   byte    6       HSB color,
+>>20   byte    7       multi-channel,
+>>20   byte    8       duo tone,
+>>20   byte    9       LAB color,
+>>20   byte    10      gray scale 16,
+>>20   byte    11      RGB color 48,
+>>20   byte    12      LAB color 48,
+>>20   byte    13      CYMK color 64,
+>>20   byte    14      deep multi-channel,
+>>20   byte    15      duo tone 16,
+>>20   byte    17      RGBA color,
+>>20   byte    18      gray scale 32,
+>>20   byte    19      RGB color 12,
+>>20   byte    20      RGB color 16,
+>>20   byte    255     unknown format,
+>>20   default x       format
+>>>20  byte    x       \b %d,
+>>21   byte    x       %d bpc
+#      PGFPostHeader
+#      Level-Sizes
+#>>(4.l+4)     lelong x level 0 size: %d
+#>>(4.l+8)     lelong x level 1 size: %d
+#>>(4.l+12)    lelong x level 2 size: %d
diff --git a/magic/Magdir/pgp b/magic/Magdir/pgp
new file mode 100644 (file)
index 0000000..acb5395
--- /dev/null
@@ -0,0 +1,561 @@
+
+#------------------------------------------------------------------------------
+# $File: pgp,v 1.17 2019/04/19 00:42:27 christos Exp $
+# pgp:  file(1) magic for Pretty Good Privacy
+# see https://lists.gnupg.org/pipermail/gnupg-devel/1999-September/016052.html
+#
+# Update: Joerg Jenderek
+# Note: verified by `gpg -v --debug 0x02 --list-packets < PUBRING263_10.PGP`
+#0             byte    0x99            MAYBE PGP 0x99
+0              byte    0x99
+# 99h~10;0110;01~2=old packet type;tag 6=Public-Key Packet;1=two-octet length
+# A two-octet body header encodes packet lengths of 192~00C0h - 8383~20BFh
+#>1            ubeshort        x               \b, body length 0x%.4x
+# skip Basic.Image Beauty.320 Pic.Icons by looking for low version number
+#>3            ubyte           x               \b, V=%u
+#>3            ubyte           <5              VERSION OK
+>3             ubyte           <5
+# next packet type often b4h~(tag 13)~User ID Packet, b0h~(tag 12)~Trust packet
+#>>(1.S+3)     ubyte   x               \b, next packet type 0x%x
+# skip 9900-v4.bin 9902-v4.bin by looking for valid second packet type (bit 7=1)
+#>>(1.S+3)     ubyte   >0x7F           TYPE OK,
+>>(1.S+3)      ubyte   >0x7F
+# old versions 2,3 implies Pretty Good Privacy
+>>>3           ubyte           <4              PGP key public ring (v%u)
+!:mime         application/pgp-keys
+!:ext          pgp/ASD
+>>>>4          beldate         x               created %s
+# days that this key is valid. If this number is zero, then it does not expire
+>>>>8          ubeshort        >0              \b, %u days valid
+>>>>8          ubeshort        =0              \b, not expire
+# display key algorithm 1~RSA (Encrypt or Sign)
+>>>>10         use             key_algo
+# Multiprecision Integers (MPI) size
+>>>>11         ubeshort        x               %u bits
+# MPI
+>>>>13         ubequad         x               MPI=0x%16.16llx...
+# new version implies Pretty Good Privacy (PGP) >= 5.0 or Gnu Privacy Guard (GPG)
+>>>3           ubyte           >3              PGP/GPG key public ring (v%u)
+!:mime         application/pgp-keys
+!:ext          pgp/gpg/pkr/asd
+>>>>4          beldate         x               created %s
+# display key algorithm 17~DSA
+>>>>8          use             key_algo
+# Multiprecision Integers (MPI) size
+>>>>9          ubeshort        x               %u bits
+>>>>11         ubequad         x               MPI=0x%16.16llx...
+
+0       beshort         0x9501                  PGP key security ring
+!:mime application/x-pgp-keyring
+0       beshort         0x9500                  PGP key security ring
+!:mime application/x-pgp-keyring
+0      beshort         0xa600                  PGP encrypted data
+#!:mime        application/pgp-encrypted
+#0     string          -----BEGIN\040PGP       text/PGP armored data
+!:mime text/PGP # encoding: armored data
+#>15   string  PUBLIC\040KEY\040BLOCK- public key block
+#>15   string  MESSAGE-                message
+#>15   string  SIGNED\040MESSAGE-      signed message
+#>15   string  PGP\040SIGNATURE-       signature
+
+2      string  ---BEGIN\040PGP\040PUBLIC\040KEY\040BLOCK-      PGP public key block
+!:mime application/pgp-keys
+>10    search/100      \n\n
+>>&0   use             pgp
+0      string  -----BEGIN\040PGP\040MESSAGE-           PGP message
+!:mime application/pgp
+>10    search/100      \n\n
+>>&0   use             pgp
+0      string  -----BEGIN\040PGP\040SIGNATURE-         PGP signature
+!:mime application/pgp-signature
+>10    search/100      \n\n
+>>&0   use             pgp
+
+# Decode the type of the packet based on it's base64 encoding.
+# Idea from Mark Martinec
+# The specification is in RFC 4880, section 4.2 and 4.3:
+# https://tools.ietf.org/html/rfc4880#section-4.2
+
+0      name            pgp
+>0     byte            0x67            Reserved (old)
+>0     byte            0x68            Public-Key Encrypted Session Key (old)
+>0     byte            0x69            Signature (old)
+>0     byte            0x6a            Symmetric-Key Encrypted Session Key (old)
+>0     byte            0x6b            One-Pass Signature (old)
+>0     byte            0x6c            Secret-Key (old)
+>0     byte            0x6d            Public-Key (old)
+>0     byte            0x6e            Secret-Subkey (old)
+>0     byte            0x6f            Compressed Data (old)
+>0     byte            0x70            Symmetrically Encrypted Data (old)
+>0     byte            0x71            Marker (old)
+>0     byte            0x72            Literal Data (old)
+>0     byte            0x73            Trust (old)
+>0     byte            0x74            User ID (old)
+>0     byte            0x75            Public-Subkey (old)
+>0     byte            0x76            Unused (old)
+>0     byte            0x77
+>>1    byte&0xc0       0x00            Reserved
+>>1    byte&0xc0       0x40            Public-Key Encrypted Session Key
+>>1    byte&0xc0       0x80            Signature
+>>1    byte&0xc0       0xc0            Symmetric-Key Encrypted Session Key
+>0     byte            0x78
+>>1    byte&0xc0       0x00            One-Pass Signature
+>>1    byte&0xc0       0x40            Secret-Key
+>>1    byte&0xc0       0x80            Public-Key
+>>1    byte&0xc0       0xc0            Secret-Subkey
+>0     byte            0x79
+>>1    byte&0xc0       0x00            Compressed Data
+>>1    byte&0xc0       0x40            Symmetrically Encrypted Data
+>>1    byte&0xc0       0x80            Marker
+>>1    byte&0xc0       0xc0            Literal Data
+>0     byte            0x7a
+>>1    byte&0xc0       0x00            Trust
+>>1    byte&0xc0       0x40            User ID
+>>1    byte&0xc0       0x80            Public-Subkey
+>>1    byte&0xc0       0xc0            Unused [z%x]
+>0     byte            0x30
+>>1    byte&0xc0       0x00            Unused [0%x]
+>>1    byte&0xc0       0x40            User Attribute
+>>1    byte&0xc0       0x80            Sym. Encrypted and Integrity Protected Data
+>>1    byte&0xc0       0xc0            Modification Detection Code
+
+# magic signatures to detect PGP crypto material (from stef)
+# detects and extracts metadata from:
+#  - symmetric encrypted packet header
+#  - RSA (e=65537) secret (sub-)keys
+
+# 1024b RSA encrypted data
+
+0      string  \x84\x8c\x03            PGP RSA encrypted session key -
+>3     lelong  x                       keyid: %X
+>7     lelong  x                       %X
+>11    byte    0x01                    RSA (Encrypt or Sign) 1024b
+>11    byte    0x02                    RSA Encrypt-Only 1024b
+>12    string  \x04\x00
+>12    string  \x03\xff
+>12    string  \x03\xfe
+>12    string  \x03\xfd
+>12    string  \x03\xfc
+>12    string  \x03\xfb
+>12    string  \x03\xfa
+>12    string  \x03\xf9
+>142   byte    0xd2                    .
+
+# 2048b RSA encrypted data
+
+0      string  \x85\x01\x0c\x03        PGP RSA encrypted session key -
+>4     lelong  x                       keyid: %X
+>8     lelong  x                       %X
+>12    byte    0x01                    RSA (Encrypt or Sign) 2048b
+>12    byte    0x02                    RSA Encrypt-Only 2048b
+>13    string  \x08\x00
+>13    string  \x07\xff
+>13    string  \x07\xfe
+>13    string  \x07\xfd
+>13    string  \x07\xfc
+>13    string  \x07\xfb
+>13    string  \x07\xfa
+>13    string  \x07\xf9
+>271   byte    0xd2                    .
+
+# 3072b RSA encrypted data
+
+0      string  \x85\x01\x8c\x03        PGP RSA encrypted session key -
+>4     lelong  x                       keyid: %X
+>8     lelong  x                       %X
+>12    byte    0x01                    RSA (Encrypt or Sign) 3072b
+>12    byte    0x02                    RSA Encrypt-Only 3072b
+>13    string  \x0c\x00
+>13    string  \x0b\xff
+>13    string  \x0b\xfe
+>13    string  \x0b\xfd
+>13    string  \x0b\xfc
+>13    string  \x0b\xfb
+>13    string  \x0b\xfa
+>13    string  \x0b\xf9
+>399   byte    0xd2                    .
+
+# 3072b RSA encrypted data
+
+0      string  \x85\x02\x0c\x03        PGP RSA encrypted session key -
+>4     lelong  x                       keyid: %X
+>8     lelong  x                       %X
+>12    byte    0x01                    RSA (Encrypt or Sign) 4096b
+>12    byte    0x02                    RSA Encrypt-Only 4096b
+>13    string  \x10\x00
+>13    string  \x0f\xff
+>13    string  \x0f\xfe
+>13    string  \x0f\xfd
+>13    string  \x0f\xfc
+>13    string  \x0f\xfb
+>13    string  \x0f\xfa
+>13    string  \x0f\xf9
+>527   byte    0xd2                    .
+
+# 4096b RSA encrypted data
+
+0      string  \x85\x04\x0c\x03        PGP RSA encrypted session key -
+>4     lelong  x                       keyid: %X
+>8     lelong  x                       %X
+>12    byte    0x01                    RSA (Encrypt or Sign) 8129b
+>12    byte    0x02                    RSA Encrypt-Only 8129b
+>13    string  \x20\x00
+>13    string  \x1f\xff
+>13    string  \x1f\xfe
+>13    string  \x1f\xfd
+>13    string  \x1f\xfc
+>13    string  \x1f\xfb
+>13    string  \x1f\xfa
+>13    string  \x1f\xf9
+>1039  byte    0xd2                    .
+
+# crypto algo mapper
+
+0      name    crypto
+>0     byte    0x00                    Plaintext or unencrypted data
+>0     byte    0x01                    IDEA
+>0     byte    0x02                    TripleDES
+>0     byte    0x03                    CAST5 (128 bit key)
+>0     byte    0x04                    Blowfish (128 bit key, 16 rounds)
+>0     byte    0x07                    AES with 128-bit key
+>0     byte    0x08                    AES with 192-bit key
+>0     byte    0x09                    AES with 256-bit key
+>0     byte    0x0a                    Twofish with 256-bit key
+
+# hash algo mapper
+
+0      name    hash
+>0     byte    0x01                    MD5
+>0     byte    0x02                    SHA-1
+>0     byte    0x03                    RIPE-MD/160
+>0     byte    0x08                    SHA256
+>0     byte    0x09                    SHA384
+>0     byte    0x0a                    SHA512
+>0     byte    0x0b                    SHA224
+
+# display public key algorithms as human readable text
+0      name    key_algo
+>0     byte    0x01                    RSA (Encrypt or Sign)
+# keep old look of version 5.28 without parentheses
+>0     byte    0x02                    RSA Encrypt-Only
+>0     byte    0x03                    RSA (Sign-Only)
+>0     byte    16                      ElGamal (Encrypt-Only)
+>0     byte    17                      DSA
+>0     byte    18                      Elliptic Curve
+>0     byte    19                      ECDSA
+>0     byte    20                      ElGamal (Encrypt or Sign)
+>0     byte    21                      Diffie-Hellman
+>0     default x
+>>0    ubyte   <22                     unknown (pub %d)
+# this should never happen
+>>0    ubyte   >21                     invalid (%d)
+
+# pgp symmetric encrypted data
+
+0      byte    0x8c                    PGP symmetric key encrypted data -
+>1     byte    0x0d
+>1     byte    0x0c
+>2     byte    0x04
+>3     use     crypto
+>4     byte    0x01                    salted -
+>>5    use     hash
+>>14   byte    0xd2                    .
+>>14   byte    0xc9                    .
+>4     byte    0x03                    salted & iterated -
+>>5    use     hash
+>>15   byte    0xd2                    .
+>>15   byte    0xc9                    .
+
+# encrypted keymaterial needs s2k & can be checksummed/hashed
+
+0      name    chkcrypto
+>0     use     crypto
+>1     byte    0x00                    Simple S2K
+>1     byte    0x01                    Salted S2K
+>1     byte    0x03                    Salted&Iterated S2K
+>2     use     hash
+
+# all PGP keys start with this prolog
+# containing version, creation date, and purpose
+
+0      name    keyprolog
+>0     byte    0x04
+>1     beldate x                       created on %s -
+>5     byte    0x01                    RSA (Encrypt or Sign)
+>5     byte    0x02                    RSA Encrypt-Only
+
+# end of secret keys known signature
+# contains e=65537 and the prolog to
+# the encrypted parameters
+
+0      name    keyend
+>0     string  \x00\x11\x01\x00\x01    e=65537
+>5     use     crypto
+>5     byte    0xff                    checksummed
+>>6    use     chkcrypto
+>5     byte    0xfe                    hashed
+>>6    use     chkcrypto
+
+# PGP secret keys contain also the public parts
+# these vary by bitsize of the key
+
+0      name    x1024
+>0     use     keyprolog
+>6     string  \x03\xfe
+>6     string  \x03\xff
+>6     string  \x04\x00
+>136   use     keyend
+
+0      name    x2048
+>0     use     keyprolog
+>6     string  \x80\x00
+>6     string  \x07\xfe
+>6     string  \x07\xff
+>264   use     keyend
+
+0      name    x3072
+>0     use     keyprolog
+>6     string  \x0b\xfe
+>6     string  \x0b\xff
+>6     string  \x0c\x00
+>392   use     keyend
+
+0      name    x4096
+>0     use     keyprolog
+>6     string  \x10\x00
+>6     string  \x0f\xfe
+>6     string  \x0f\xff
+>520   use     keyend
+
+# \x00|\x1f[\xfe\xff]).{1024})'
+0      name    x8192
+>0     use     keyprolog
+>6     string  \x20\x00
+>6     string  \x1f\xfe
+>6     string  \x1f\xff
+>1032  use     keyend
+
+# depending on the size of the pkt
+# we branch into the proper key size
+# signatures defined as x{keysize}
+
+>0     name    pgpkey
+>0     string  \x01\xd8        1024b
+>>2    use     x1024
+>0     string  \x01\xeb        1024b
+>>2    use     x1024
+>0     string  \x01\xfb        1024b
+>>2    use     x1024
+>0     string  \x01\xfd        1024b
+>>2    use     x1024
+>0     string  \x01\xf3        1024b
+>>2    use     x1024
+>0     string  \x01\xee        1024b
+>>2    use     x1024
+>0     string  \x01\xfe        1024b
+>>2    use     x1024
+>0     string  \x01\xf4        1024b
+>>2    use     x1024
+>0     string  \x02\x0d        1024b
+>>2    use     x1024
+>0     string  \x02\x03        1024b
+>>2    use     x1024
+>0     string  \x02\x05        1024b
+>>2    use     x1024
+>0     string  \x02\x15        1024b
+>>2    use     x1024
+>0     string  \x02\x00        1024b
+>>2    use     x1024
+>0     string  \x02\x10        1024b
+>>2    use     x1024
+>0     string  \x02\x04        1024b
+>>2    use     x1024
+>0     string  \x02\x06        1024b
+>>2    use     x1024
+>0     string  \x02\x16        1024b
+>>2    use     x1024
+>0     string  \x03\x98        2048b
+>>2    use     x2048
+>0     string  \x03\xab        2048b
+>>2    use     x2048
+>0     string  \x03\xbb        2048b
+>>2    use     x2048
+>0     string  \x03\xbd        2048b
+>>2    use     x2048
+>0     string  \x03\xcd        2048b
+>>2    use     x2048
+>0     string  \x03\xb3        2048b
+>>2    use     x2048
+>0     string  \x03\xc3        2048b
+>>2    use     x2048
+>0     string  \x03\xc5        2048b
+>>2    use     x2048
+>0     string  \x03\xd5        2048b
+>>2    use     x2048
+>0     string  \x03\xae        2048b
+>>2    use     x2048
+>0     string  \x03\xbe        2048b
+>>2    use     x2048
+>0     string  \x03\xc0        2048b
+>>2    use     x2048
+>0     string  \x03\xd0        2048b
+>>2    use     x2048
+>0     string  \x03\xb4        2048b
+>>2    use     x2048
+>0     string  \x03\xc4        2048b
+>>2    use     x2048
+>0     string  \x03\xc6        2048b
+>>2    use     x2048
+>0     string  \x03\xd6        2048b
+>>2    use     x2048
+>0     string  \x05X           3072b
+>>2    use     x3072
+>0     string  \x05k           3072b
+>>2    use     x3072
+>0     string  \x05{           3072b
+>>2    use     x3072
+>0     string  \x05}           3072b
+>>2    use     x3072
+>0     string  \x05\x8d        3072b
+>>2    use     x3072
+>0     string  \x05s           3072b
+>>2    use     x3072
+>0     string  \x05\x83        3072b
+>>2    use     x3072
+>0     string  \x05\x85        3072b
+>>2    use     x3072
+>0     string  \x05\x95        3072b
+>>2    use     x3072
+>0     string  \x05n           3072b
+>>2    use     x3072
+>0     string  \x05\x7e        3072b
+>>2    use     x3072
+>0     string  \x05\x80        3072b
+>>2    use     x3072
+>0     string  \x05\x90        3072b
+>>2    use     x3072
+>0     string  \x05t           3072b
+>>2    use     x3072
+>0     string  \x05\x84        3072b
+>>2    use     x3072
+>0     string  \x05\x86        3072b
+>>2    use     x3072
+>0     string  \x05\x96        3072b
+>>2    use     x3072
+>0     string  \x07[           4096b
+>>2    use     x4096
+>0     string  \x07\x18        4096b
+>>2    use     x4096
+>0     string  \x07+           4096b
+>>2    use     x4096
+>0     string  \x07;           4096b
+>>2    use     x4096
+>0     string  \x07=           4096b
+>>2    use     x4096
+>0     string  \x07M           4096b
+>>2    use     x4096
+>0     string  \x073           4096b
+>>2    use     x4096
+>0     string  \x07C           4096b
+>>2    use     x4096
+>0     string  \x07E           4096b
+>>2    use     x4096
+>0     string  \x07U           4096b
+>>2    use     x4096
+>0     string  \x07.           4096b
+>>2    use     x4096
+>0     string  \x07>           4096b
+>>2    use     x4096
+>0     string  \x07@           4096b
+>>2    use     x4096
+>0     string  \x07P           4096b
+>>2    use     x4096
+>0     string  \x074           4096b
+>>2    use     x4096
+>0     string  \x07D           4096b
+>>2    use     x4096
+>0     string  \x07F           4096b
+>>2    use     x4096
+>0     string  \x07V           4096b
+>>2    use     x4096
+>0     string  \x0e[           8192b
+>>2    use     x8192
+>0     string  \x0e\x18        8192b
+>>2    use     x8192
+>0     string  \x0e+           8192b
+>>2    use     x8192
+>0     string  \x0e;           8192b
+>>2    use     x8192
+>0     string  \x0e=           8192b
+>>2    use     x8192
+>0     string  \x0eM           8192b
+>>2    use     x8192
+>0     string  \x0e3           8192b
+>>2    use     x8192
+>0     string  \x0eC           8192b
+>>2    use     x8192
+>0     string  \x0eE           8192b
+>>2    use     x8192
+>0     string  \x0eU           8192b
+>>2    use     x8192
+>0     string  \x0e.           8192b
+>>2    use     x8192
+>0     string  \x0e>           8192b
+>>2    use     x8192
+>0     string  \x0e@           8192b
+>>2    use     x8192
+>0     string  \x0eP           8192b
+>>2    use     x8192
+>0     string  \x0e4           8192b
+>>2    use     x8192
+>0     string  \x0eD           8192b
+>>2    use     x8192
+>0     string  \x0eF           8192b
+>>2    use     x8192
+>0     string  \x0eV           8192b
+>>2    use     x8192
+
+# PGP RSA (e=65537) secret (sub-)key header
+
+0      byte    0x95                    PGP Secret Key -
+>1     use     pgpkey
+0      byte    0x97                    PGP Secret Sub-key -
+>1     use     pgpkey
+0      byte    0x9d
+# Update: Joerg Jenderek
+# secret subkey packet (tag 7) with same structure as secret key packet (tag 5)
+# skip Fetus.Sys16 CALIBUS.MAIN OrbFix.Sys16.Ex by looking for positive len
+>1     ubeshort        >0
+#>1    ubeshort        x               \b, body length 0x%x
+# next packet type often 88h,89h~(tag 2)~Signature Packet
+#>>(1.S+3)     ubyte   x               \b, next packet type 0x%x
+# skip Dragon.SHR DEMO.INIT by looking for positive version
+>>3    ubyte           >0
+# skip BUISSON.13 GUITAR1 by looking for low version number
+>>>3   ubyte           <5              PGP Secret Sub-key
+# sub-key are normally part of secret key. So it does not occur as standalone file
+#!:ext bin
+# version 2,3~old 4~new . Comment following line for version 5.28 look
+>>>>3  ubyte           x               (v%d)
+>>>>3  ubyte           x               -
+# old versions 2 or 3 but no real example found
+>>>>3  ubyte           <4
+# 2 byte for key bits in version 5.28 look
+>>>>>11                ubeshort        x       %db
+>>>>>4         beldate         x       created on %s -
+# old versions use 2 additional bytes after time stamp
+#>>>>>8                ubeshort        x       0x%x
+# display key algorithm 1~RSA Encrypt|Sign - 21~Diffie-Hellman
+>>>>>10                use             key_algo
+>>>>>(11.S/8)  ubequad         x
+# look after first key
+>>>>>>&5       use             keyend
+# new version
+>>>>3  ubyte           >3
+>>>>>9         ubeshort        x       %db
+>>>>>4         beldate         x       created on %s -
+# display key algorithm
+>>>>>8         use             key_algo
+>>>>>(9.S/8)   ubequad         x
+# look after first key for something like s2k
+>>>>>>&3       use             keyend
diff --git a/magic/Magdir/pkgadd b/magic/Magdir/pkgadd
new file mode 100644 (file)
index 0000000..8d921dc
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# pkgadd:  file(1) magic for SysV R4 PKG Datastreams
+#
+0       string          #\ PaCkAgE\ DaTaStReAm  pkg Datastream (SVR4)
+!:mime application/x-svr4-package
diff --git a/magic/Magdir/plan9 b/magic/Magdir/plan9
new file mode 100644 (file)
index 0000000..9bf7135
--- /dev/null
@@ -0,0 +1,18 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# plan9:  file(1) magic for AT&T Bell Labs' Plan 9 executables
+# From: "Stefan A. Haubenthal" <polluks@web.de>
+#
+0      belong          0x00000107      Plan 9 executable, Motorola 68k
+0      belong          0x000001EB      Plan 9 executable, Intel 386
+0      belong          0x00000247      Plan 9 executable, Intel 960
+0      belong          0x000002AB      Plan 9 executable, SPARC
+0      belong          0x00000407      Plan 9 executable, MIPS R3000
+0      belong          0x0000048B      Plan 9 executable, AT&T DSP 3210
+0      belong          0x00000517      Plan 9 executable, MIPS R4000 BE
+0      belong          0x000005AB      Plan 9 executable, AMD 29000
+0      belong          0x00000647      Plan 9 executable, ARM 7-something
+0      belong          0x000006EB      Plan 9 executable, PowerPC
+0      belong          0x00000797      Plan 9 executable, MIPS R4000 LE
+0      belong          0x0000084B      Plan 9 executable, DEC Alpha
diff --git a/magic/Magdir/plus5 b/magic/Magdir/plus5
new file mode 100644 (file)
index 0000000..2875f87
--- /dev/null
@@ -0,0 +1,18 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# plus5:  file(1) magic for Plus Five's UNIX MUMPS
+#
+# XXX - byte order?  Paging Hokey....
+#
+0      short           0x259           mumps avl global
+>2     byte            >0              (V%d)
+>6     byte            >0              with %d byte name
+>7     byte            >0              and %d byte data cells
+0      short           0x25a           mumps blt global
+>2     byte            >0              (V%d)
+>8     short           >0              - %d byte blocks
+>15    byte            0x00            - P/D format
+>15    byte            0x01            - P/K/D format
+>15    byte            0x02            - K/D format
+>15    byte            >0x02           - Bad Flags
diff --git a/magic/Magdir/polyml b/magic/Magdir/polyml
new file mode 100644 (file)
index 0000000..1cc0109
--- /dev/null
@@ -0,0 +1,23 @@
+
+#------------------------------------------------------------------------------
+# $File: polyml,v 1.2 2019/04/19 00:42:27 christos Exp $
+# polyml:  file(1) magic for PolyML
+#
+# PolyML
+# MPEG, FLI, DL originally from vax@ccwf.cc.utexas.edu (VaX#n8)
+# FLC, SGI, Apple originally from Daniel Quinlan (quinlan@yggdrasil.com)
+
+# [0]: https://www.polyml.org/
+# [1]: https://github.com/polyml/polyml/blob/master/\
+#      libpolyml/savestate.cpp#L146-L147
+# [2]: https://github.com/polyml/polyml/blob/master/\
+#      libpolyml/savestate.cpp#L1262-L1263
+
+# Type: Poly/ML saved data
+# From: Matthew Fernandez <matthew.fernandez@gmail.com>
+
+0      string  POLYSAVE        Poly/ML saved state
+>8     long    x               version %u
+
+0      string  POLYMODU        Poly/ML saved module
+>8     long    x               version %u
diff --git a/magic/Magdir/printer b/magic/Magdir/printer
new file mode 100644 (file)
index 0000000..e8fccd2
--- /dev/null
@@ -0,0 +1,150 @@
+
+#------------------------------------------------------------------------------
+# $File: printer,v 1.29 2019/04/19 00:42:27 christos Exp $
+# printer:  file(1) magic for printer-formatted files
+#
+
+# PostScript, updated by Daniel Quinlan (quinlan@yggdrasil.com)
+0      string          %!              PostScript document text
+!:mime application/postscript
+!:apple        ASPSTEXT
+>2     string          PS-Adobe-       conforming
+>>11   string          >\0             DSC level %.3s
+>>>15  string          EPS             \b, type %s
+>>>15  string          Query           \b, type %s
+>>>15  string          ExitServer      \b, type %s
+>>>15   search/1000            %%LanguageLevel:\040
+>>>>&0 string          >\0             \b, Level %s
+# Some PCs have the annoying habit of adding a ^D as a document separator
+0      string          \004%!          PostScript document text
+!:mime application/postscript
+!:apple        ASPSTEXT
+>3     string          PS-Adobe-       conforming
+>>12   string          >\0             DSC level %.3s
+>>>16  string          EPS             \b, type %s
+>>>16  string          Query           \b, type %s
+>>>16  string          ExitServer      \b, type %s
+>>>16   search/1000            %%LanguageLevel:\040
+>>>>&0 string          >\0             \b, Level %s
+0      string          \033%-12345X%!PS        PostScript document
+
+# DOS EPS Binary File Header
+# From: Ed Sznyter <ews@Black.Market.NET>
+0       belong          0xC5D0D3C6      DOS EPS Binary File
+>4      long            >0              Postscript starts at byte %d
+>>8     long            >0              length %d
+>>>12   long            >0              Metafile starts at byte %d
+>>>>16  long            >0              length %d
+>>>20   long            >0              TIFF starts at byte %d
+>>>>24  long            >0              length %d
+
+# Summary: Adobe's PostScript Printer Description File
+# Extension: .ppd
+# Reference: https://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf, Section 3.8
+# Submitted by: Yves Arrouye <arrouye@marin.fdn.fr>
+#
+0      string          *PPD-Adobe:\x20 PPD file
+>&0    string          x               \b, version %s
+
+# HP Printer Job Language
+0      string          \033%-12345X@PJL        HP Printer Job Language data
+# HP Printer Job Language
+# The header found on Win95 HP plot files is the "Silliest Thing possible"
+# (TM)
+# Every driver puts the language at some random position, with random case
+# (LANGUAGE and Language)
+# For example the LaserJet 5L driver puts the "PJL ENTER LANGUAGE" in line 10
+# From: Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
+#
+0      string          \033%-12345X@PJL        HP Printer Job Language data
+>&0    string          >\0                     %s
+>>&0   string          >\0                     %s
+>>>&0  string          >\0                     %s
+>>>>&0 string          >\0                     %s
+#>15   string          \ ENTER\ LANGUAGE\ =
+#>31   string          PostScript              PostScript
+
+# From: Stefan Thurner <thurners@nicsys.de>
+0      string          \033%-12345X@PJL
+>&0    search/10000    %!                      PJL encapsulated PostScript document text
+
+# Rick Richardson <rickrich@gmail.com>
+
+# For Fuji-Xerox Printers - HBPL stands for Host Based Printer Language
+# For Oki Data Printers - HIPERC
+# For Konica Minolta Printers - LAVAFLOW
+# For Samsung Printers - QPDL
+# For HP Printers - ZJS stands for Zenographics ZJStream
+0      string          \033%-12345X@PJL        HP Printer Job Language data
+>0     search/10000    @PJL\ ENTER\ LANGUAGE=HBPL      - HBPL
+>0     search/10000    @PJL\ ENTER\ LANGUAGE=HIPERC    - Oki Data HIPERC
+>0     search/10000    @PJL\ ENTER\ LANGUAGE=LAVAFLOW  - Konica Minolta LAVAFLOW
+>0     search/10000    @PJL\ ENTER\ LANGUAGE=QPDL      - Samsung QPDL
+>0     search/10000    @PJL\ ENTER\ LANGUAGE\ =\ QPDL  - Samsung QPDL
+>0     search/10000    @PJL\ ENTER\ LANGUAGE=ZJS       - HP ZJS
+
+
+# HP Printer Control Language, Daniel Quinlan (quinlan@yggdrasil.com)
+0      string          \033E\033       HP PCL printer data
+>3     string          \&l0A           - default page size
+>3     string          \&l1A           - US executive page size
+>3     string          \&l2A           - US letter page size
+>3     string          \&l3A           - US legal page size
+>3     string          \&l26A          - A4 page size
+>3     string          \&l80A          - Monarch envelope size
+>3     string          \&l81A          - No. 10 envelope size
+>3     string          \&l90A          - Intl. DL envelope size
+>3     string          \&l91A          - Intl. C5 envelope size
+>3     string          \&l100A         - Intl. B5 envelope size
+>3     string          \&l-81A         - No. 10 envelope size (landscape)
+>3     string          \&l-90A         - Intl. DL envelope size (landscape)
+
+# IMAGEN printer-ready files:
+0      string  @document(              Imagen printer
+# this only works if "language xxx" is first item in Imagen header.
+>10    string  language\ impress       (imPRESS data)
+>10    string  language\ daisy         (daisywheel text)
+>10    string  language\ diablo        (daisywheel text)
+>10    string  language\ printer       (line printer emulation)
+>10    string  language\ tektronix     (Tektronix 4014 emulation)
+# Add any other languages that your Imagen uses - remember
+# to keep the word `text' if the file is human-readable.
+# [GRR 950115:  missing "postscript" or "ultrascript" (whatever it was called)]
+#
+# Now magic for IMAGEN font files...
+0      string          Rast            RST-format raster font data
+>45    string          >0              face %s
+# From Jukka Ukkonen
+0      string          \033[K\002\0\0\017\033(a\001\0\001\033(g        Canon Bubble Jet BJC formatted data
+
+# From <mike@flyn.org>
+# These are the /etc/magic entries to decode data sent to an Epson printer.
+0       string          \x1B\x40\x1B\x28\x52\x08\x00\x00REMOTE1P        Epson Stylus Color 460 data
+
+
+#------------------------------------------------------------------------------
+# zenographics:  file(1) magic for Zenographics ZjStream printer data
+# Rick Richardson <rickrich@gmail.com>
+0      string          JZJZ
+>0x12  string          ZZ              Zenographics ZjStream printer data (big-endian)
+0      string          ZJZJ
+>0x12  string          ZZ              Zenographics ZjStream printer data (little-endian)
+
+
+#------------------------------------------------------------------------------
+# Oak Technologies printer stream
+# Rick Richardson <rickrich@gmail.com>
+0       string          OAK
+>0x07  byte            0
+>0x0b  byte            0       Oak Technologies printer stream
+
+# This would otherwise be recognized as PostScript - nick@debian.org
+0      string          %!VMF           SunClock's Vector Map Format data
+
+#------------------------------------------------------------------------------
+# HP LaserJet 1000 series downloadable firmware file
+0      string  \xbe\xefABCDEFGH        HP LaserJet 1000 series downloadable firmware
+
+# From: Paolo <oopla@users.sf.net>
+# Epson ESC/Page, ESC/PageColor
+0      string  \x1b\x01@EJL    Epson ESC/Page language printer data
diff --git a/magic/Magdir/project b/magic/Magdir/project
new file mode 100644 (file)
index 0000000..9180b57
--- /dev/null
@@ -0,0 +1,10 @@
+
+#------------------------------------------------------------------------------
+# $File: project,v 1.5 2017/03/17 21:35:28 christos Exp $
+# project:  file(1) magic for Project management
+#
+# Magic strings for ftnchek project files. Alexander Mai
+0      string  FTNCHEK_\ P     project file for ftnchek
+>10    string  1               version 2.7
+>10    string  2               version 2.8 to 2.10
+>10    string  3               version 2.11 or later
diff --git a/magic/Magdir/psdbms b/magic/Magdir/psdbms
new file mode 100644 (file)
index 0000000..3eec965
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File: psdbms,v 1.8 2017/03/17 21:35:28 christos Exp $
+# psdbms:  file(1) magic for psdatabase
+#
+# Update: Joerg Jenderek
+# GRR: line below too general as it catches also some Panorama database *.pan ,
+# AppleWorks word processor
+0      belong&0xff00ffff       0x56000000
+# assume version starts with digit
+>1     regex/s                 =^[0-9]         ps database
+>>1    string  >\0     version %s
+# kernel name
+>>4    string  >\0     from kernel %s
diff --git a/magic/Magdir/psl b/magic/Magdir/psl
new file mode 100644 (file)
index 0000000..0296540
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File: psl,v 1.3 2019/04/19 00:42:27 christos Exp $
+# psl:  file(1) magic for Public Suffix List representations
+# From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+# URL: https://publicsuffix.org
+# see also: https://thread.gmane.org/gmane.network.dns.libpsl.bugs/162/focus=166
+
+0      search/512      \n\n//\ ===BEGIN\ ICANN\ DOMAINS===\n\n Public Suffix List data
+
+0      string  .DAFSA@PSL_
+>15    string  \n      Public Suffix List data (optimized)
+>>11   byte    >0x2f
+>>>11  byte    <0x3a   (Version %c)
diff --git a/magic/Magdir/pulsar b/magic/Magdir/pulsar
new file mode 100644 (file)
index 0000000..747b9c4
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# pulsar:  file(1) magic for Pulsar POP3 daemon binary files
+#
+# http://pulsar.sourceforge.net
+# mailto:rok.papez@lugos.si
+#
+
+0      belong  0x1ee7f11e      Pulsar POP3 daemon mailbox cache file.
+>4     ubelong x               Version: %d.
+>8     ubelong x               \b%d
+
diff --git a/magic/Magdir/pwsafe b/magic/Magdir/pwsafe
new file mode 100644 (file)
index 0000000..549093f
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File: pwsafe,v 1.2 2019/04/19 00:42:27 christos Exp $
+# pwsafe: file(1) magic for passwordsafe file
+#
+# Password Safe
+# http://passwordsafe.sourceforge.net/
+# file format specs
+# https://passwordsafe.svn.sourceforge.net/viewvc/passwordsafe/trunk/pwsafe/pwsafe/docs/formatV3.txt
+# V2 https://passwordsafe.svn.sourceforge.net/viewvc/passwordsafe/trunk/pwsafe/pwsafe/docs/formatV2.txt
+# V1 https://passwordsafe.svn.sourceforge.net/viewvc/passwordsafe/trunk/pwsafe/pwsafe/docs/notes.txt
+# V2 and V1 have no easy identifier that I can find
+# .psafe3
+0      string  PWS3    Password Safe V3 database
diff --git a/magic/Magdir/pyramid b/magic/Magdir/pyramid
new file mode 100644 (file)
index 0000000..ac6c017
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# pyramid:  file(1) magic for Pyramids
+#
+# XXX - byte order?
+#
+0      long            0x50900107      Pyramid 90x family executable
+0      long            0x50900108      Pyramid 90x family pure executable
+>16    long            >0              not stripped
+0      long            0x5090010b      Pyramid 90x family demand paged pure executable
+>16    long            >0              not stripped
diff --git a/magic/Magdir/python b/magic/Magdir/python
new file mode 100644 (file)
index 0000000..acf05dd
--- /dev/null
@@ -0,0 +1,101 @@
+
+#------------------------------------------------------------------------------
+# $File: python,v 1.36 2019/04/09 18:28:25 christos Exp $
+# python:  file(1) magic for python
+#
+# Outlook puts """ too for urgent messages
+# From: David Necas <yeti@physics.muni.cz>
+# often the module starts with a multiline string
+0      string/t        """     Python script text executable
+# MAGIC as specified in Python/import.c (1.5 to 2.7a0 and 3.1a0, assuming
+# that Py_UnicodeFlag is off for Python 2)
+# two bytes of magic followed by "\r\n" in little endian order
+0      belong          0x994e0d0a      python 1.5/1.6 byte-compiled
+0      belong          0x87c60d0a      python 2.0 byte-compiled
+0      belong          0x2aeb0d0a      python 2.1 byte-compiled
+0      belong          0x2ded0d0a      python 2.2 byte-compiled
+0      belong          0x3bf20d0a      python 2.3 byte-compiled
+0      belong          0x6df20d0a      python 2.4 byte-compiled
+0      belong          0xb3f20d0a      python 2.5 byte-compiled
+0      belong          0xd1f20d0a      python 2.6 byte-compiled
+0      belong          0x03f30d0a      python 2.7 byte-compiled
+0      belong          0x3b0c0d0a      python 3.0 byte-compiled
+0      belong          0x4f0c0d0a      python 3.1 byte-compiled
+0      belong          0x6c0c0d0a      python 3.2 byte-compiled
+0      belong          0x9e0c0d0a      python 3.3 byte-compiled
+0      belong          0xee0c0d0a      python 3.4 byte-compiled
+0      belong          0x160d0d0a      python 3.5.1- byte-compiled
+0      belong          0x170d0d0a      python 3.5.2+ byte-compiled
+0      belong          0x330d0d0a      python 3.6 byte-compiled
+0      belong          0x420d0d0a      python 3.7 byte-compiled
+
+
+0      search/1/w      #!\ /usr/bin/python     Python script text executable
+!:strength + 15
+!:mime text/x-python
+0      search/1/w      #!\ /usr/local/bin/python       Python script text executable
+!:strength + 15
+!:mime text/x-python
+0      search/1        #!/usr/bin/env\ python  Python script text executable
+!:strength + 15
+!:mime text/x-python
+0      search/10       #!\ /usr/bin/env\ python        Python script text executable
+!:strength + 15
+!:mime text/x-python
+
+
+# from module.submodule import func1, func2
+0      search/8192     import
+>0     regex           \^from[\040\t\f\r\n]+([A-Za-z0-9_]|\\.)+[\040\t\f\r\n]+import.*$        Python script text executable
+!:strength + 15
+!:mime text/x-python
+
+# def __init__ (self, ...):
+0      search/4096     def\ __init__
+>&0    search/64 self  Python script text executable
+!:strength + 15
+!:mime text/x-python
+
+# if __name__ == "__main__":
+0 search/4096 if\ __name__
+>&0 search/64 '__main__'       Python script text executable
+>&0 search/64 "__main__"       Python script text executable
+!:strength + 15
+!:mime text/x-python
+
+# import module [as abrev]
+0      search/8192     import
+>0     regex   \^import\ [_[:alpha:]]+\ as\ [[:alpha:]][[:space:]]*$ Python script text executable
+!:mime text/x-python
+
+# comments
+#0     search/4096     '''
+#>&0   regex   .*'''$  Python script text executable
+#!:mime text/x-python
+
+#0     search/4096     """
+#>&0   regex   .*"""$  Python script text executable
+#!:mime text/x-python
+
+# try:
+# except: or finally:
+# block
+0      search/4096     try:
+>&0    regex   \^[[:space:]]*except.*:$        Python script text executable
+!:strength + 15
+!:mime text/x-python
+>&0    search/4096     finally:        Python script text executable
+!:mime text/x-python
+
+# class name[(base classes,)]: [pass]
+0      search/8192     class
+>0     regex   \^class\ [_[:alpha:]]+(\\(.*\\))?(\ )*:([\ \t]+pass)?$          Python script text executable
+!:strength + 15
+!:mime text/x-python
+
+# def name(*args, **kwargs):
+0      search/8192     def\ 
+>0     regex    \^[[:space:]]{0,50}def\ {1,50}[_a-zA-Z]{1,100}
+>>&0   regex    \\(([[:alpha:]*_,\ ]){0,255}\\):$ Python script text executable
+!:strength + 15
+!:mime text/x-python
diff --git a/magic/Magdir/qt b/magic/Magdir/qt
new file mode 100644 (file)
index 0000000..83aa124
--- /dev/null
@@ -0,0 +1,19 @@
+
+#------------------------------------------------------------------------------
+# $File: qt,v 1.3 2019/04/19 00:42:27 christos Exp $
+# qt:  file(1) magic for Qt
+
+# https://doc.qt.io/qt-5/resources.html
+0      string          \<!DOCTYPE\040RCC\>     Qt Resource Collection file
+
+# https://qt.gitorious.org/qt/qtbase/source/\
+# 5367fa356233da4c0f28172a8f817791525f5457:\
+# src/tools/rcc/rcc.cpp#L840
+0      string          qres\0\0                Qt Binary Resource file
+0      search/1024     The\040Resource\040Compiler\040for\040Qt        Qt C-code resource file
+
+# https://qt.gitorious.org/qt/qtbase/source/\
+# 5367fa356233da4c0f28172a8f817791525f5457:\
+# src/corelib/kernel/qtranslator.cpp#L62
+0      string          \x3c\xb8\x64\x18\xca\xef\x9c\x95
+>8     string          \xcd\x21\x1c\xbf\x60\xa1\xbd\xdd        Qt Translation file
diff --git a/magic/Magdir/revision b/magic/Magdir/revision
new file mode 100644 (file)
index 0000000..824220a
--- /dev/null
@@ -0,0 +1,66 @@
+
+#------------------------------------------------------------------------------
+# $File: revision,v 1.11 2019/04/19 00:42:27 christos Exp $
+# file(1) magic for revision control files
+# From Hendrik Scholz <hendrik@scholz.net>
+0      string/t        /1\ :pserver:   cvs password text file
+
+# Conary changesets
+# From: Jonathan Smith <smithj@rpath.com>
+0      belong  0xea3f81bb      Conary changeset data
+
+# Type: Git bundles (git-bundle)
+# From: Josh Triplett <josh@freedesktop.org>
+0      string  #\ v2\ git\ bundle\n    Git bundle
+
+# Type: Git pack
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+# Update: Joerg Jenderek
+# URL: http://fileformats.archiveteam.org/wiki/Git
+# reference: https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt
+# The actual magic is 'PACK', but that clashes with Doom/Quake packs. However,
+# those have a little-endian offset immediately following the magic 'PACK',
+# the first byte of which is never 0, while the first byte of the Git pack
+# version, since it's a tiny number stored in big-endian format, is always 0.
+0      string  PACK
+# GRR: line above is too general as it matches also PackDir archive ./acorn
+# test for major version. Git 2017 accepts version number 2 or 3
+>4     ubelong <9
+# Acorn PackDir with method 0 compression has root like ADFS::HardDisc4.$.AsylumSrc
+# or SystemDevice::foobar
+>>9    search/13 ::
+# but in git binary
+>>9    default x       Git pack
+!:mime application/x-git
+!:ext  pack
+# 4 GB limit implies unsigned integer
+>>>4   ubelong x               \b, version %u
+>>>8   ubelong x               \b, %u objects
+
+# Type: Git pack index
+# From: Adam Buchbinder <adam.buchbinder@gmail.com>
+0      string  \377tOc         Git pack index
+>4     belong  =2              \b, version 2
+
+# Type: Git index file
+# From: Frederic Briare <fbriere@fbriere.net>
+0      string  DIRC            Git index
+>4     belong  >0              \b, version %d
+>>8    belong  >0              \b, %d entries
+
+# Type:        Mercurial bundles
+# From:        Seo Sanghyeon <tinuviel@sparcs.kaist.ac.kr>
+0      string  HG10            Mercurial bundle,
+>4     string  UN              uncompressed
+>4     string  BZ              bzip2 compressed
+
+# Type:        Subversion (SVN) dumps
+# From:        Uwe Zeisberger <zeisberg@informatik.uni-freiburg.de>
+0      string  SVN-fs-dump-format-version:     Subversion dumpfile
+>28    string  >\0                             (version: %s)
+
+# Type:        Bazaar revision bundles and merge requests
+# URL: https://www.bazaar-vcs.org/
+# From:        Jelmer Vernooij <jelmer@samba.org>
+0      string  #\ Bazaar\ revision\ bundle\ v Bazaar Bundle
+0      string  #\ Bazaar\ merge\ directive\ format Bazaar merge directive
diff --git a/magic/Magdir/riff b/magic/Magdir/riff
new file mode 100644 (file)
index 0000000..33d439a
--- /dev/null
@@ -0,0 +1,332 @@
+
+#------------------------------------------------------------------------------
+# $File: riff,v 1.34 2019/04/19 00:42:27 christos Exp $
+# riff:  file(1) magic for RIFF format
+# See
+#
+#      https://www.seanet.com/users/matts/riffmci/riffmci.htm
+#      http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf
+#
+
+# audio format tag. Assume limits: max 1024 bit, 128 channels, 1 MHz
+0   name    riff-wave
+>0     leshort         1               \b, Microsoft PCM
+>>14   leshort         >0
+>>>14  leshort         <1024   \b, %d bit
+>0     leshort         2               \b, Microsoft ADPCM
+>0     leshort         6               \b, ITU G.711 A-law
+>0     leshort         7               \b, ITU G.711 mu-law
+>0     leshort         8               \b, Microsoft DTS
+>0     leshort         17              \b, IMA ADPCM
+>0     leshort         20              \b, ITU G.723 ADPCM (Yamaha)
+>0     leshort         49              \b, GSM 6.10
+>0     leshort         64              \b, ITU G.721 ADPCM
+>0     leshort         80              \b, MPEG
+>0     leshort         85              \b, MPEG Layer 3
+>0     leshort         0x2001          \b, DTS
+>2     leshort         =1              \b, mono
+>2     leshort         =2              \b, stereo
+>2     leshort         >2
+>>2    leshort         <128    \b, %d channels
+>4     lelong          >0
+>>4    lelong          <1000000        %d Hz
+
+# try to find "fmt "
+0   name    riff-walk
+>0  string  fmt\x20
+>>4 lelong  <0x80
+>>>8 use    riff-wave
+>0  string  LIST
+>>&(4.l+4)  use riff-walk
+>0  string  DISP
+>>&(4.l+4)  use riff-walk
+>0  string  bext
+>>&(4.l+4)  use riff-walk
+>0  string  Fake
+>>&(4.l+4)  use riff-walk
+>0  string  fact
+>>&(4.l+4)  use riff-walk
+>0  string  VP8
+>>11           byte            0x9d
+>>>12          byte            0x01
+>>>>13         byte            0x2a    \b, VP8 encoding
+>>>>>14                leshort&0x3fff  x       \b, %d
+>>>>>16                leshort&0x3fff  x       \bx%d, Scaling:
+>>>>>14                leshort&0xc000  0x0000  \b [none]
+>>>>>14                leshort&0xc000  0x1000  \b [5/4]
+>>>>>14                leshort&0xc000  0x2000  \b [5/3]
+>>>>>14                leshort&0xc000  0x3000  \b [2]
+>>>>>14                leshort&0xc000  0x0000  \bx[none]
+>>>>>14                leshort&0xc000  0x1000  \bx[5/4]
+>>>>>14                leshort&0xc000  0x2000  \bx[5/3]
+>>>>>14                leshort&0xc000  0x3000  \bx[2]
+>>>>>15                byte&0x80       =0x00   \b, YUV color
+>>>>>15                byte&0x80       =0x80   \b, bad color specification
+>>>>>15                byte&0x40       =0x40   \b, no clamping required
+>>>>>15                byte&0x40       =0x00   \b, decoders should clamp
+#>0  string  x         we got %s
+#>>&(4.l+4)  use riff-walk
+
+# AVI section extended by Patrik Radman <patrik+file-magic@iki.fi>
+#
+0      string          RIFF            RIFF (little-endian) data
+# RIFF Palette format
+# Update: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/Resource_Interchange_File_Format
+# Reference: https://worms2d.info/Palette_file
+>8     string          PAL\            \b, palette
+!:mime application/x-riff
+# color palette by Microsoft Corporation
+!:ext  pal
+# file size =  chunk size + 8 in most cases
+>>4    ulelong+8       x               \b, %u bytes
+# Extended PAL Format
+>>12   string          plth            \b, extended
+# Simple PAL Format
+>>12   string          data            
+# data chunk size = color entries * 4 + 4 + sometimes extra (4) appended bytes
+>>>16  ulelong         x               \b, data size %u
+# palVersion is always 0x0300
+#>>>20 leshort         x               \b, version 0x%4.4x
+# palNumEntries specifies the number of palette color entries
+>>>22  uleshort        x               \b, %u entries
+# after palPalEntry sized (number of color entries * 4 ) vector
+>>>(22.s*4)    ubequad x               
+# jump relative 22 ( 8 + 16) bytes forward points after end of file or to
+# appended extra bytes like in http://safecolours.rigdenage.com/set(ms).zip/Protan(MS).pal
+>>>>&16                ubelong x               \b, extra bytes
+>>>>>&-4       ubelong >0              0x%8.8x
+# RIFF Device Independent Bitmap format
+>8     string          RDIB            \b, device-independent bitmap
+>>16   string          BM
+>>>30  leshort         12              \b, OS/2 1.x format
+>>>>34 leshort         x               \b, %d x
+>>>>36 leshort         x               %d
+>>>30  leshort         64              \b, OS/2 2.x format
+>>>>34 leshort         x               \b, %d x
+>>>>36 leshort         x               %d
+>>>30  leshort         40              \b, Windows 3.x format
+>>>>34 lelong          x               \b, %d x
+>>>>38 lelong          x               %d x
+>>>>44 leshort         x               %d
+# RIFF MIDI format
+>8     string          RMID            \b, MIDI
+# RIFF Multimedia Movie File format
+>8     string          RMMP            \b, multimedia movie
+# RIFF wrapper for MP3
+>8     string          RMP3            \b, MPEG Layer 3 audio
+# Microsoft WAVE format (*.wav)
+>8     string          WAVE            \b, WAVE audio
+!:mime audio/x-wav
+>>12    string  >\0
+>>>12   use     riff-walk
+# Corel Draw Picture
+>8     string          CDRA            \b, Corel Draw Picture
+!:mime image/x-coreldraw
+>8     string          CDR6            \b, Corel Draw Picture, version 6
+!:mime image/x-coreldraw
+>8     string          NUNDROOT        \b, Steinberg CuBase
+# AVI == Audio Video Interleave
+>8     string          AVI\040         \b, AVI
+!:mime video/x-msvideo
+>>12    string          LIST
+>>>20   string          hdrlavih
+>>>>&36 lelong          x               \b, %u x
+>>>>&40 lelong          x               %u,
+>>>>&4  lelong          >1000000        <1 fps,
+>>>>&4  lelong          1000000         1.00 fps,
+>>>>&4  lelong          500000          2.00 fps,
+>>>>&4  lelong          333333          3.00 fps,
+>>>>&4  lelong          250000          4.00 fps,
+>>>>&4  lelong          200000          5.00 fps,
+>>>>&4  lelong          166667          6.00 fps,
+>>>>&4  lelong          142857          7.00 fps,
+>>>>&4  lelong          125000          8.00 fps,
+>>>>&4  lelong          111111          9.00 fps,
+>>>>&4  lelong          100000          10.00 fps,
+# ]9.9,10.1[
+>>>>&4  lelong          <101010
+>>>>>&-4        lelong  >99010
+>>>>>>&-4       lelong  !100000         ~10 fps,
+>>>>&4  lelong          83333           12.00 fps,
+# ]11.9,12.1[
+>>>>&4  lelong          <84034
+>>>>>&-4        lelong  >82645
+>>>>>>&-4       lelong  !83333          ~12 fps,
+>>>>&4  lelong          66667           15.00 fps,
+# ]14.9,15.1[
+>>>>&4  lelong          <67114
+>>>>>&-4        lelong  >66225
+>>>>>>&-4       lelong  !66667          ~15 fps,
+>>>>&4  lelong          50000           20.00 fps,
+>>>>&4  lelong          41708           23.98 fps,
+>>>>&4  lelong          41667           24.00 fps,
+# ]23.9,24.1[
+>>>>&4  lelong          <41841
+>>>>>&-4        lelong  >41494
+>>>>>>&-4       lelong  !41708
+>>>>>>>&-4      lelong  !41667          ~24 fps,
+>>>>&4  lelong          40000           25.00 fps,
+# ]24.9,25.1[
+>>>>&4  lelong          <40161
+>>>>>&-4        lelong  >39841
+>>>>>>&-4       lelong  !40000          ~25 fps,
+>>>>&4  lelong          33367           29.97 fps,
+>>>>&4  lelong          33333           30.00 fps,
+# ]29.9,30.1[
+>>>>&4  lelong          <33445
+>>>>>&-4        lelong  >33223
+>>>>>>&-4       lelong  !33367
+>>>>>>>&-4      lelong  !33333          ~30 fps,
+>>>>&4  lelong          <32224          >30 fps,
+##>>>>&4  lelong          x               (%lu)
+##>>>>&20 lelong          x               %lu frames,
+# Note: The tests below assume that the AVI has 1 or 2 streams,
+#       "vids" optionally followed by "auds".
+#       (Should cover 99.9% of all AVIs.)
+# assuming avih length = 56
+>>>88   string  LIST
+>>>>96  string  strlstrh
+>>>>>108        string  vids    video:
+>>>>>>&0        lelong  0               uncompressed
+# skip past vids strh
+>>>>>>(104.l+108)       string  strf
+>>>>>>>(104.l+132)      lelong          1       RLE 8bpp
+>>>>>>>(104.l+132)      string/c        cvid    Cinepak
+>>>>>>>(104.l+132)      string/c        i263    Intel I.263
+>>>>>>>(104.l+132)      string/c        iv32    Indeo 3.2
+>>>>>>>(104.l+132)      string/c        iv41    Indeo 4.1
+>>>>>>>(104.l+132)      string/c        iv50    Indeo 5.0
+>>>>>>>(104.l+132)      string/c        mp42    Microsoft MPEG-4 v2
+>>>>>>>(104.l+132)      string/c        mp43    Microsoft MPEG-4 v3
+>>>>>>>(104.l+132)      string/c        fmp4    FFMpeg MPEG-4
+>>>>>>>(104.l+132)      string/c        mjpg    Motion JPEG
+>>>>>>>(104.l+132)      string/c        div3    DivX 3
+>>>>>>>>112             string/c        div3    Low-Motion
+>>>>>>>>112             string/c        div4    Fast-Motion
+>>>>>>>(104.l+132)      string/c        divx    DivX 4
+>>>>>>>(104.l+132)      string/c        dx50    DivX 5
+>>>>>>>(104.l+132)      string/c        xvid    XviD
+>>>>>>>(104.l+132)     string/c        h264    H.264
+>>>>>>>(104.l+132)      string/c        wmv3    Windows Media Video 9
+>>>>>>>(104.l+132)      string/c        h264    X.264 or H.264
+>>>>>>>(104.l+132)      lelong  0
+##>>>>>>>(104.l+132)      string  x       (%.4s)
+# skip past first (video) LIST
+>>>>(92.l+96)   string  LIST
+>>>>>(92.l+104) string  strlstrh
+>>>>>>(92.l+116)        string          auds    \b, audio:
+# auds strh length = 56:
+>>>>>>>(92.l+172)       string          strf
+>>>>>>>>(92.l+180)      leshort 0x0001  uncompressed PCM
+>>>>>>>>(92.l+180)      leshort 0x0002  ADPCM
+>>>>>>>>(92.l+180)      leshort 0x0006  aLaw
+>>>>>>>>(92.l+180)      leshort 0x0007  uLaw
+>>>>>>>>(92.l+180)      leshort 0x0050  MPEG-1 Layer 1 or 2
+>>>>>>>>(92.l+180)      leshort 0x0055  MPEG-1 Layer 3
+>>>>>>>>(92.l+180)      leshort 0x2000  Dolby AC3
+>>>>>>>>(92.l+180)      leshort 0x0161  DivX
+##>>>>>>>>(92.l+180)      leshort x       (0x%.4x)
+>>>>>>>>(92.l+182)      leshort 1       (mono,
+>>>>>>>>(92.l+182)      leshort 2       (stereo,
+>>>>>>>>(92.l+182)      leshort >2      (%d channels,
+>>>>>>>>(92.l+184)      lelong  x       %d Hz)
+# auds strh length = 64:
+>>>>>>>(92.l+180)       string          strf
+>>>>>>>>(92.l+188)      leshort 0x0001  uncompressed PCM
+>>>>>>>>(92.l+188)      leshort 0x0002  ADPCM
+>>>>>>>>(92.l+188)      leshort 0x0055  MPEG-1 Layer 3
+>>>>>>>>(92.l+188)      leshort 0x2000  Dolby AC3
+>>>>>>>>(92.l+188)      leshort 0x0161  DivX
+##>>>>>>>>(92.l+188)      leshort x       (0x%.4x)
+>>>>>>>>(92.l+190)      leshort 1       (mono,
+>>>>>>>>(92.l+190)      leshort 2       (stereo,
+>>>>>>>>(92.l+190)      leshort >2      (%d channels,
+>>>>>>>>(92.l+192)      lelong  x       %d Hz)
+# Animated Cursor format
+>8     string          ACON            \b, animated cursor
+# SoundFont 2 <mpruett@sgi.com>
+>8     string          sfbk            SoundFont/Bank
+# MPEG-1 wrapped in a RIFF, apparently
+>8      string          CDXA            \b, wrapped MPEG-1 (CDXA)
+>8     string          4XMV            \b, 4X Movie file
+# AMV-type AVI file: https://wiki.multimedia.cx/index.php?title=AMV
+>8     string          AMV\040         \b, AMV
+>8      string          WEBP            \b, Web/P image
+!:mime image/webp
+>>12   use             riff-walk
+
+#
+# XXX - some of the below may only appear in little-endian form.
+#
+# Also "MV93" appears to be for one form of Macromedia Director
+# files, and "GDMF" appears to be another multimedia format.
+#
+0      string          RIFX            RIFF (big-endian) data
+# RIFF Palette format
+>8     string          PAL             \b, palette
+>>16   beshort         x               \b, version %d
+>>18   beshort         x               \b, %d entries
+# RIFF Device Independent Bitmap format
+>8     string          RDIB            \b, device-independent bitmap
+>>16   string          BM
+>>>30  beshort         12              \b, OS/2 1.x format
+>>>>34 beshort         x               \b, %d x
+>>>>36 beshort         x               %d
+>>>30  beshort         64              \b, OS/2 2.x format
+>>>>34 beshort         x               \b, %d x
+>>>>36 beshort         x               %d
+>>>30  beshort         40              \b, Windows 3.x format
+>>>>34 belong          x               \b, %d x
+>>>>38 belong          x               %d x
+>>>>44 beshort         x               %d
+# RIFF MIDI format
+>8     string          RMID            \b, MIDI
+# RIFF Multimedia Movie File format
+>8     string          RMMP            \b, multimedia movie
+# Microsoft WAVE format (*.wav)
+>8     string          WAVE            \b, WAVE audio
+>>20   leshort         1               \b, Microsoft PCM
+>>>34  leshort         >0              \b, %d bit
+>>22   beshort         =1              \b, mono
+>>22   beshort         =2              \b, stereo
+>>22   beshort         >2              \b, %d channels
+>>24   belong          >0              %d Hz
+# Corel Draw Picture
+>8     string          CDRA            \b, Corel Draw Picture
+>8     string          CDR6            \b, Corel Draw Picture, version 6
+# AVI == Audio Video Interleave
+>8     string          AVI\040         \b, AVI
+# Animated Cursor format
+>8     string          ACON            \b, animated cursor
+# Notation Interchange File Format (big-endian only)
+>8     string          NIFF            \b, Notation Interchange File Format
+# SoundFont 2 <mpruett@sgi.com>
+>8     string          sfbk            SoundFont/Bank
+
+#------------------------------------------------------------------------------
+# Sony Wave64
+# see http://www.vcs.de/fileadmin/user_upload/MBS/PDF/Whitepaper/Informations_about_Sony_Wave64.pdf
+# 128 bit RIFF-GUID { 66666972-912E-11CF-A5D6-28DB04C10000 } in little-endian
+0      string  riff\x2E\x91\xCF\x11\xA5\xD6\x28\xDB\x04\xC1\x00\x00            Sony Wave64 RIFF data
+# 128 bit + total file size (64 bits) so 24 bytes
+# then WAVE-GUID { 65766177-ACF3-11D3-8CD1-00C04F8EDB8A }
+>24    string          wave\xF3\xAC\xD3\x11\x8C\xD1\x00\xC0\x4F\x8E\xDB\x8A            \b, WAVE 64 audio
+!:mime audio/x-w64
+# FMT-GUID { 20746D66-ACF3-11D3-8CD1-00C04F8EDB8A }
+>>40   search/256      fmt\x20\xF3\xAC\xD3\x11\x8C\xD1\x00\xC0\x4F\x8E\xDB\x8A         \b
+>>>&10 leshort         =1              \b, mono
+>>>&10 leshort         =2              \b, stereo
+>>>&10 leshort         >2              \b, %d channels
+>>>&12 lelong          >0              %d Hz
+
+#------------------------------------------------------------------------------
+# MBWF/RF64
+# see EBU TECH 3306 https://tech.ebu.ch/docs/tech/tech3306-2009.pdf
+0      string  RF64\xff\xff\xff\xffWAVEds64            MBWF/RF64 audio
+!:mime audio/x-wav
+>40    search/256      fmt\x20         \b
+>>&6   leshort         =1              \b, mono
+>>&6   leshort         =2              \b, stereo
+>>&6   leshort         >2              \b, %d channels
+>>&8   lelong          >0              %d Hz
diff --git a/magic/Magdir/rinex b/magic/Magdir/rinex
new file mode 100644 (file)
index 0000000..22fb060
--- /dev/null
@@ -0,0 +1,44 @@
+
+#------------------------------------------------------------------------------
+# $File: rinex,v 1.3 2011/04/04 21:12:03 christos Exp $
+# rinex:  file(1) magic for RINEX files
+# http://igscb.jpl.nasa.gov/igscb/data/format/rinex210.txt
+# ftp://cddis.gsfc.nasa.gov/pub/reports/formats/rinex300.pdf
+# data for testing: ftp://cddis.gsfc.nasa.gov/pub/gps/data
+60     string          RINEX
+>80    search/256      XXRINEXB        RINEX Data, GEO SBAS Broadcast
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/broadcast
+>80    search/256      XXRINEXD        RINEX Data, Observation (Hatanaka comp)
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/observation
+>80    search/256      XXRINEXC        RINEX Data, Clock
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/clock
+>80    search/256      XXRINEXH        RINEX Data, GEO SBAS Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXG        RINEX Data, GLONASS Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXL        RINEX Data, Galileo Navigation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXM        RINEX Data, Meteorological
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/meteorological
+>80    search/256      XXRINEXN        RINEX Data, Navigation  
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/navigation
+>80    search/256      XXRINEXO        RINEX Data, Observation
+>>&32  string          x               \b, date %15.15s
+>>5    string          x               \b, version %6.6s
+!:mime rinex/observation
diff --git a/magic/Magdir/rpi b/magic/Magdir/rpi
new file mode 100644 (file)
index 0000000..ac1be94
--- /dev/null
@@ -0,0 +1,15 @@
+
+#------------------------------------------------------------------------------
+# $File: rpi,v 1.1 2018/01/01 05:25:17 christos Exp $
+# rpi:  file(1) magic for Raspberry Pi images
+-44            lelong  0
+>4             lelong  0
+>>8            lelong  1
+>>12           lelong  4
+>>>16          string  283x
+>>>>20         lelong  1
+>>>>>24                lelong  4
+>>>>>>28       string  DTOK
+>>>>>>>32      lelong  44
+>>>>>>>>36     lelong  4
+>>>>>>>>>40    string  RPTL            Raspberry PI kernel image
diff --git a/magic/Magdir/rpm b/magic/Magdir/rpm
new file mode 100644 (file)
index 0000000..fa336c0
--- /dev/null
@@ -0,0 +1,45 @@
+
+#------------------------------------------------------------------------------
+# $File: rpm,v 1.11 2011/06/14 12:47:41 christos Exp $
+#
+# RPM: file(1) magic for Red Hat Packages   Erik Troan (ewt@redhat.com)
+#
+0      belong          0xedabeedb      RPM
+!:mime application/x-rpm
+>4     byte            x               v%d
+>5     byte            x               \b.%d
+>6     beshort         1               src
+>6     beshort         0               bin
+>>8    beshort         1               i386/x86_64
+>>8    beshort         2               Alpha/Sparc64
+>>8    beshort         3               Sparc
+>>8    beshort         4               MIPS
+>>8    beshort         5               PowerPC
+>>8    beshort         6               68000
+>>8    beshort         7               SGI
+>>8    beshort         8               RS6000
+>>8    beshort         9               IA64
+>>8    beshort         10              Sparc64
+>>8    beshort         11              MIPSel
+>>8    beshort         12              ARM
+>>8    beshort         13              MiNT
+>>8    beshort         14              S/390
+>>8    beshort         15              S/390x
+>>8    beshort         16              PowerPC64
+>>8    beshort         17              SuperH
+>>8    beshort         18              Xtensa
+>>8    beshort         255             noarch
+
+#delta RPM    Daniel Novotny (dnovotny@redhat.com)
+0      string          drpm            Delta RPM
+!:mime  application/x-rpm
+>12    string  x       %s
+>>8    beshort         11              MIPSel
+>>8    beshort         12              ARM
+>>8    beshort         13              MiNT
+>>8    beshort         14              S/390
+>>8    beshort         15              S/390x
+>>8    beshort         16              PowerPC64
+>>8    beshort         17              SuperH
+>>8    beshort         18              Xtensa
+>>10   string          x               %s
diff --git a/magic/Magdir/rpmsg b/magic/Magdir/rpmsg
new file mode 100644 (file)
index 0000000..cbbbb2b
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File: rpmsg,v 1.1 2019/04/19 00:40:47 christos Exp $
+# rpmsg: file(1) magic for restricted-permission messages (or "rights-protected" messages)
+# see https://en.wikipedia.org/wiki/Rpmsg
+
+0      string  \x76\xe8\x04\x60\xc4\x11\xe3\x86        rpmsg Restricted Permission Message
diff --git a/magic/Magdir/rtf b/magic/Magdir/rtf
new file mode 100644 (file)
index 0000000..144078c
--- /dev/null
@@ -0,0 +1,16 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# rtf: file(1) magic for Rich Text Format (RTF)
+#
+# Duncan P. Simpson, D.P.Simpson@dcs.warwick.ac.uk
+#
+0      string          {\\rtf          Rich Text Format data,
+!:mime text/rtf
+>5     string          1               version 1,
+>>6    string          \\ansi          ANSI
+>>6    string          \\mac           Apple Macintosh
+>>6    string          \\pc            IBM PC, code page 437
+>>6    string          \\pca           IBM PS/2, code page 850
+>>6    default         x               unknown character set
+>5     default         x               unknown version
diff --git a/magic/Magdir/ruby b/magic/Magdir/ruby
new file mode 100644 (file)
index 0000000..87af47d
--- /dev/null
@@ -0,0 +1,55 @@
+
+#------------------------------------------------------------------------------
+# $File: ruby,v 1.9 2019/04/19 00:42:27 christos Exp $
+# ruby:  file(1) magic for Ruby scripting language
+# URL:  https://www.ruby-lang.org/
+# From: Reuben Thomas <rrt@sc3d.org>
+
+# Ruby scripts
+0      search/1/w      #!\ /usr/bin/ruby                               Ruby script text executable
+!:strength + 15
+!:mime text/x-ruby
+0      search/1/w      #!\ /usr/local/bin/ruby Ruby script text executable
+!:strength + 15
+!:mime text/x-ruby
+0      search/1        #!/usr/bin/env\ ruby                            Ruby script text executable
+!:strength + 15
+!:mime text/x-ruby
+0      search/1        #!\ /usr/bin/env\ ruby                  Ruby script text executable
+!:strength + 15
+!:mime text/x-ruby
+
+# What looks like ruby, but does not have a shebang
+# (modules and such)
+# From: Lubomir Rintel <lkundrak@v3.sk>
+0      search/8192     require
+>0     regex           \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+'
+>>0    regex           def\ [a-z]|\ do$
+>>>&0  regex           \^[[:space:]]*end([[:space:]]+[;#].*)?$         Ruby script text
+!:strength + 30
+!:mime text/x-ruby
+0      regex           \^[[:space:]]*(class|module)[[:space:]][A-Z]
+>0     regex           (modul|includ)e\ [A-Z]|def\ [a-z]
+>>&0   regex           \^[[:space:]]*end([[:space:]]+[;#].*)?$         Ruby script text
+!:strength + 30
+!:mime text/x-ruby
+# Classes with no modules or defs, beats simple ASCII
+0      regex           \^[[:space:]]*(class|module)[[:space:]][A-Z]
+>&0    regex   \^[[:space:]]*end([[:space:]]+[;#if].*)?$               Ruby script text
+!:strength + 10
+!:mime text/x-ruby
+# Looks for function definition to balance python magic
+# def name (args)
+# end
+0      search/8192     def\ 
+>0     regex           \^[[:space:]]*def\ [a-z]|def\ [[:alpha:]]+::[a-z]
+>>&0   regex           \^[[:space:]]*end([[:space:]]+[;#].*)?$         Ruby script text
+!:strength + 10
+!:mime text/x-ruby
+
+0      search/8192     require
+>0     regex           \^[[:space:]]*require[[:space:]]'[A-Za-z_/]+'   Ruby script text
+!:mime text/x-ruby
+0      search/8192     include
+>0 regex       \^[[:space:]]*include\ ([A-Z]+[a-z]*(::))+      Ruby script text
+!:mime text/x-ruby
diff --git a/magic/Magdir/sc b/magic/Magdir/sc
new file mode 100644 (file)
index 0000000..8b2232f
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# sc:  file(1) magic for "sc" spreadsheet
+#
+38     string          Spreadsheet     sc spreadsheet file
+!:mime application/x-sc
diff --git a/magic/Magdir/sccs b/magic/Magdir/sccs
new file mode 100644 (file)
index 0000000..4717948
--- /dev/null
@@ -0,0 +1,22 @@
+
+#------------------------------------------------------------------------------
+# $File: sccs,v 1.7 2017/03/17 21:35:28 christos Exp $
+# sccs:  file(1) magic for SCCS archives
+#
+# SCCS archive structure:
+# \001h01207
+# \001s 00276/00000/00000
+# \001d D 1.1 87/09/23 08:09:20 ian 1 0
+# \001c date and time created 87/09/23 08:09:20 by ian
+# \001e
+# \001u
+# \001U
+# ... etc.
+# Now '\001h' happens to be the same as the 3B20's a.out magic number (0550).
+# *Sigh*. And these both came from various parts of the USG.
+# Maybe we should just switch everybody from SCCS to RCS!
+# Further, you can't just say '\001h0', because the five-digit number
+# is a checksum that could (presumably) have any leading digit,
+# and we don't have regular expression matching yet.
+# Hence the following official kludge:
+8      string          \001s\                  SCCS archive data
diff --git a/magic/Magdir/scientific b/magic/Magdir/scientific
new file mode 100644 (file)
index 0000000..0e78712
--- /dev/null
@@ -0,0 +1,111 @@
+
+#------------------------------------------------------------------------------
+# $File: scientific,v 1.13 2019/04/19 00:42:27 christos Exp $
+# scientific:  file(1) magic for scientific formats
+#
+# From: Joe Krahn <krahn@niehs.nih.gov>
+
+########################################################
+# CCP4 data and plot files:
+0      string          MTZ\040         MTZ reflection file
+
+92     string          PLOT%%84        Plot84 plotting file
+>52    byte            1               , Little-endian
+>55    byte            1               , Big-endian
+
+########################################################
+# Electron density MAP/MASK formats
+
+0      string          EZD_MAP NEWEZD Electron Density Map
+109    string          MAP\040(  Old EZD Electron Density Map
+
+0      string/c        :-)\040Origin   BRIX Electron Density Map
+>170   string          >0      , Sigma:%.12s
+#>4    string          >0      %.178s
+#>4    addr            x       %.178s
+
+7      string          18\040!NTITLE   XPLOR ASCII Electron Density Map
+9      string          \040!NTITLE\012\040REMARK       CNS ASCII electron density map
+
+208    string          MAP\040 CCP4 Electron Density Map
+# Assumes same stamp for float and double (normal case)
+>212   byte            17      \b, Big-endian
+>212   byte            34      \b, VAX format
+>212   byte            68      \b, Little-endian
+>212   byte            85      \b, Convex native
+
+############################################################
+# X-Ray Area Detector images
+0      string  R-AXIS4\ \ \    R-Axis Area Detector Image:
+>796   lelong  <20             Little-endian, IP #%d,
+>>768  lelong  >0              Size=%dx
+>>772  lelong  >0              \b%d
+>796   belong  <20             Big-endian, IP #%d,
+>>768  belong  >0              Size=%dx
+>>772  belong  >0              \b%d
+
+0      string  RAXIS\ \ \ \ \  R-Axis Area Detector Image, Win32:
+>796   lelong  <20             Little-endian, IP #%d,
+>>768  lelong  >0              Size=%dx
+>>772  lelong  >0              \b%d
+>796   belong  <20             Big-endian, IP #%d,
+>>768  belong  >0              Size=%dx
+>>772  belong  >0              \b%d
+
+
+1028   string  MMX\000\000\000\000\000\000\000\000\000\000\000\000\000 MAR Area Detector Image,
+>1072  ulong   >1              Compressed(%d),
+>1100  ulong   >1              %d headers,
+>1104  ulong   >0              %d x
+>1108  ulong   >0              %d,
+>1120  ulong   >0              %d bits/pixel
+
+# Type: GEDCOM genealogical (family history) data
+# From: Giuseppe Bilotta
+0       search/1/c     0\ HEAD         GEDCOM genealogy text
+>&0     search         1\ GEDC
+>>&0    search         2\ VERS         version
+>>>&1   string         >\0             %s
+# From: Phil Endecott <phil05@chezphil.org>
+0      string  \000\060\000\040\000\110\000\105\000\101\000\104                GEDCOM data
+0      string  \060\000\040\000\110\000\105\000\101\000\104\000                GEDCOM data
+0      string  \376\377\000\060\000\040\000\110\000\105\000\101\000\104        GEDCOM data
+0      string  \377\376\060\000\040\000\110\000\105\000\101\000\104\000        GEDCOM data
+
+# PDB: Protein Data Bank files
+# Adam Buchbinder <adam.buchbinder@gmail.com>
+#
+# https://www.wwpdb.org/documentation/format32/sect2.html
+# https://www.ch.ic.ac.uk/chemime/
+#
+# The PDB file format is fixed-field, 80 columns. From the spec:
+#
+# COLS        DATA
+#  1 -  6      "HEADER"
+#  11 - 50     String(40)
+#  51 - 59     Date
+#  63 - 66     IDcode
+#
+# Thus, positions 7-10, 60-62 and 67-80 are spaces. The Date must be in the
+# format DD-MMM-YY, e.g., 01-JAN-70, and the IDcode consists of numbers and
+# uppercase letters. However, examples have been seen without the date string,
+# e.g., the example on the chemime site.
+0      string  HEADER\ \ \ \040
+>&0    regex/1l        \^.{40}
+>>&0   regex/1l        [0-9]{2}-[A-Z]{3}-[0-9]{2}\ {3}
+>>>&0  regex/1ls       [A-Z0-9]{4}.{14}$
+>>>>&0 regex/1l        [A-Z0-9]{4}     Protein Data Bank data, ID Code %s
+!:mime chemical/x-pdb
+>>>>0  regex/1l        [0-9]{2}-[A-Z]{3}-[0-9]{2}      \b, %s
+
+# Type:        GDSII Stream file
+0      belong  0x00060002      GDSII Stream file
+>4     byte    0x00
+>>5    byte    x               version %d.0
+>4     byte    >0x00           version %d
+>>5    byte    x               \b.%d
+
+# Type: LXT (interLaced eXtensible Trace)
+# chrysn <chrysn@fsfe.org>
+0      beshort 0x0138  interLaced eXtensible Trace (LXT) file
+>2     beshort >0      (Version %u)
diff --git a/magic/Magdir/securitycerts b/magic/Magdir/securitycerts
new file mode 100644 (file)
index 0000000..d315a15
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File$
+0      search/1                -----BEGIN\ CERTIFICATE------   RFC1421 Security Certificate text
+0      search/1                -----BEGIN\ NEW\ CERTIFICATE    RFC1421 Security Certificate Signing Request text
+0      belong  0xedfeedfe      Sun 'jks' Java Keystore File data
diff --git a/magic/Magdir/selinux b/magic/Magdir/selinux
new file mode 100644 (file)
index 0000000..89d5f53
--- /dev/null
@@ -0,0 +1,24 @@
+# Type:        SE Linux policy modules *.pp reference policy
+#      for Fedora 5 to 9, RHEL5, and Debian Etch and Lenny.
+# URL: https://doc.coker.com.au/computers/selinux-magic
+# From:        Russell Coker <russell@coker.com.au>
+
+0              lelong  0xf97cff8f      SE Linux modular policy
+>4             lelong  x               version %d,
+>8             lelong  x               %d sections,
+>>(12.l)       lelong  0xf97cff8d
+>>>(12.l+27)   lelong  x               mod version %d,
+>>>(12.l+31)   lelong  0               Not MLS,
+>>>(12.l+31)   lelong  1               MLS,
+>>>(12.l+23)   lelong  2
+>>>>(12.l+47)  string  >\0             module name %s
+>>>(12.l+23)   lelong  1               base
+
+1      string  policy_module(  SE Linux policy module source
+2      string  policy_module(  SE Linux policy module source
+
+0      string  ##\ <summary>   SE Linux policy interface source
+
+#0     search  gen_context(    SE Linux policy file contexts
+
+#0     search  gen_sens(       SE Linux policy MLS constraints source
diff --git a/magic/Magdir/sendmail b/magic/Magdir/sendmail
new file mode 100644 (file)
index 0000000..54028fd
--- /dev/null
@@ -0,0 +1,37 @@
+
+#------------------------------------------------------------------------------
+# $File: sendmail,v 1.11 2019/04/19 00:42:27 christos Exp $
+# sendmail:  file(1) magic for sendmail config files
+#
+# XXX - byte order?
+#
+# Update: Joerg Jenderek
+# GRR: this test is too general as it catches also
+# READ.ME.FIRST.AWP Sendmail frozen configuration
+# - version ====|====|====|====|====|====|====|====|====|====|====|====|===
+# Email_23_f217153422.ts Sendmail frozen configuration
+# - version \330jK\354
+0      byte    046
+# https://www.sendmail.com/sm/open_source/docs/older_release_notes/
+# freezed configuration file (dbm format?) created from sendmal.cf with -bz
+# by older sendmail. til version 8.6 support for frozen configuration files is removed
+# valid version numbers look like "7.14.4" and should be similar to output of commands
+# "sendmail -d0 -bt < /dev/null |grep -i Version" or "egrep '^DZ' /etc/sendmail.cf"
+>16    regex/s =^[0-78][0-9.]{4}       Sendmail frozen configuration
+# normally only /etc/sendmail.fc or /var/adm/sendmail/sendmail.fc
+!:ext fc
+>>16   string  >\0                     - version %s
+0      short   0x271c
+# look for valid version number
+>16    regex/s =^[0-78][0-9.]{4}       Sendmail frozen configuration
+!:ext fc
+>>16   string  >\0                     - version %s
+
+#------------------------------------------------------------------------------
+# sendmail:  file(1) magic for sendmail m4(1) files
+#
+# From Hendrik Scholz <hendrik@scholz.net>
+# i.e. files in /usr/share/sendmail/cf/
+#
+0   string  divert(-1)\n    sendmail m4 text file
+
diff --git a/magic/Magdir/sequent b/magic/Magdir/sequent
new file mode 100644 (file)
index 0000000..da38de6
--- /dev/null
@@ -0,0 +1,42 @@
+
+#------------------------------------------------------------------------------
+# $File: sequent,v 1.14 2019/04/19 00:42:27 christos Exp $
+# sequent:  file(1) magic for Sequent machines
+#
+# Sequent information updated by Don Dwiggins <atsun!dwiggins>.
+# For Sequent's multiprocessor systems (incomplete).
+0      lelong  0x00ea          BALANCE NS32000 .o
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+0      lelong  0x10ea          BALANCE NS32000 executable (0 @ 0)
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+0      lelong  0x20ea          BALANCE NS32000 executable (invalid @ 0)
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+0      lelong  0x30ea          BALANCE NS32000 standalone executable
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+#
+# Symmetry information added by Jason Merrill <jason@jarthur.claremont.edu>.
+# Symmetry magic nums will not be reached if DOS COM comes before them;
+# byte 0xeb is matched before these get a chance.
+0      leshort 0x12eb          SYMMETRY i386 .o
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+0      leshort 0x22eb          SYMMETRY i386 executable (0 @ 0)
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+0      leshort 0x32eb          SYMMETRY i386 executable (invalid @ 0)
+>16    lelong  >0              not stripped
+>124   lelong  >0              version %d
+# https://en.wikipedia.org/wiki/Sequent_Computer_Systems
+# below test line conflicts with MS-DOS 2.11 floppies and Acronis loader
+#0     leshort 0x42eb          SYMMETRY i386 standalone executable
+0      leshort 0x42eb
+# skip unlike negative version
+>124   lelong  >-1
+# assuming version 28867614 is very low probable
+>>124  lelong  !28867614       SYMMETRY i386 standalone executable
+>>>16  lelong  >0              not stripped
+>>>124 lelong  >0              version %d
diff --git a/magic/Magdir/sereal b/magic/Magdir/sereal
new file mode 100644 (file)
index 0000000..b7c2e26
--- /dev/null
@@ -0,0 +1,35 @@
+
+#------------------------------------------------------------------------------
+# $File: sereal,v 1.2 2014/11/11 20:10:49 christos Exp $
+# sereal: file(1) magic the Sereal binary serialization format
+#
+# From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+#
+# See the specification of the format at
+# https://github.com/Sereal/Sereal/blob/master/sereal_spec.pod#document-header-format
+#
+# I'd have liked to do the byte&0xF0 matching against 0, 1, 2 ... by
+# doing (byte&0xF0)>>4 here, but unfortunately that's not
+# supported. So when we print out a message about an unknown format
+# we'll print out e.g. 0x30 instead of the more human-readable
+# 0x30>>4.
+#
+# See https://github.com/Sereal/Sereal/commit/35372ae01d in the
+# Sereal.git repository for test Sereal data.
+0      name            sereal
+>4     byte&0x0F       x               (version %d,
+>4     byte&0xF0       0x00            uncompressed)
+>4     byte&0xF0       0x10            compressed with non-incremental Snappy)
+>4     byte&0xF0       0x20            compressed with incremental Snappy)
+>4     byte&0xF0       >0x20           unknown subformat, flag: %d>>4)
+
+0      string/b        \=srl           Sereal data packet
+!:mime application/sereal
+>&0    use             sereal
+0      string/b        \=\xF3rl        Sereal data packet
+!:mime application/sereal
+>&0    use             sereal
+0      string/b        \=\xC3\xB3rl    Sereal data packet, UTF-8 encoded
+!:mime application/sereal
+>&0    use             sereal
+
diff --git a/magic/Magdir/sgi b/magic/Magdir/sgi
new file mode 100644 (file)
index 0000000..9519204
--- /dev/null
@@ -0,0 +1,138 @@
+
+#------------------------------------------------------------------------------
+# $File: sgi,v 1.23 2018/05/29 02:26:56 christos Exp $
+# sgi:  file(1) magic for Silicon Graphics operating systems and applications
+#
+# Executable images are handled either in aout (for old-style a.out
+# files for 68K; they are indistinguishable from other big-endian 32-bit
+# a.out files) or in mips (for MIPS ECOFF and Ucode files)
+#
+
+# kbd file definitions
+0      string  kbd!map         kbd map file
+>8     byte    >0              Ver %d:
+>10    short   >0              with %d table(s)
+
+0      beshort 0x8765          disk quotas file
+
+0      beshort 0x0506          IRIS Showcase file
+>2     byte    0x49            -
+>3     byte    x               - version %d
+0      beshort 0x0226          IRIS Showcase template
+>2     byte    0x63            -
+>3     byte    x               - version %d
+0      belong  0x5343464d      IRIS Showcase file
+>4     byte    x               - version %d
+0      belong  0x5443464d      IRIS Showcase template
+>4     byte    x               - version %d
+0      belong  0xdeadbabe      IRIX Parallel Arena
+>8     belong  >0              - version %d
+
+# core files
+#
+# 32bit core file
+0      belong  0xdeadadb0      IRIX core dump
+>4     belong  1               of
+>16    string  >\0             '%s'
+# 64bit core file
+0      belong  0xdeadad40      IRIX 64-bit core dump
+>4     belong  1               of
+>16    string  >\0             '%s'
+# N32bit core file
+0       belong 0xbabec0bb      IRIX N32 core dump
+>4      belong 1               of
+>16     string >\0             '%s'
+# New style crash dump file
+0      string  \x43\x72\x73\x68\x44\x75\x6d\x70        IRIX vmcore dump of
+>36    string  >\0                                     '%s'
+
+# Trusted IRIX info
+0      string  SGIAUDIT        SGI Audit file
+>8     byte    x               - version %d
+>9     byte    x               \b.%d
+#
+0      string  WNGZWZSC        Wingz compiled script
+0      string  WNGZWZSS        Wingz spreadsheet
+0      string  WNGZWZHP        Wingz help file
+#
+0      string  #Inventor\040V  IRIS Inventor 1.0 file
+0      string  #Inventor\040V2 Open Inventor 2.0 file
+# GLF is OpenGL stream encoding
+0      string  glfHeadMagic();         GLF_TEXT
+4      belong  0x7d000000              GLF_BINARY_LSB_FIRST
+!:strength -30
+4      belong  0x0000007d              GLF_BINARY_MSB_FIRST
+!:strength -30
+# GLS is OpenGL stream encoding; GLS is the successor of GLF
+0      string  glsBeginGLS(            GLS_TEXT
+4      belong  0x10000000              GLS_BINARY_LSB_FIRST
+!:strength -30
+4      belong  0x00000010              GLS_BINARY_MSB_FIRST
+!:strength -30
+
+# Performance Co-Pilot file types
+0      string  PmNs                            PCP compiled namespace (V.0)
+0      string  PmN                             PCP compiled namespace
+>3     string  >\0                             (V.%1.1s)
+#3     lelong  0x84500526                      PCP archive
+3      belong  0x84500526                      PCP archive
+>7     byte    x                               (V.%d)
+#>20   lelong  -2                              temporal index
+#>20   lelong  -1                              metadata
+#>20   lelong  0                               log volume #0
+#>20   lelong  >0                              log volume #%d
+>20    belong  -2                              temporal index
+>20    belong  -1                              metadata
+>20    belong  0                               log volume #0
+>20    belong  >0                              log volume #%d
+>24    string  >\0                             host: %s
+0      string  PCPFolio                        PCP
+>9     string  Version:                        Archive Folio
+>18    string  >\0                             (V.%s)
+0      string  #pmchart                        PCP pmchart view
+>9     string  Version
+>17    string  >\0                             (V%-3.3s)
+0      string  #kmchart                        PCP kmchart view
+>9     string  Version
+>17    string  >\0                             (V.%s)
+0      string  pmview                          PCP pmview config
+>7     string  Version
+>15    string  >\0                             (V%-3.3s)
+0      string  #pmlogger                       PCP pmlogger config
+>10    string  Version
+>18    string  >\0                             (V%1.1s)
+0      string  #pmdahotproc                    PCP pmdahotproc config
+>13    string  Version
+>21    string  >\0                             (V%-3.3s)
+0      string  PcPh                            PCP Help
+>4     string  1                               Index
+>4     string  2                               Text
+>5     string  >\0                             (V.%1.1s)
+0      string  #pmieconf-rules                 PCP pmieconf rules
+>16    string  >\0                             (V.%1.1s)
+3      string  pmieconf-pmie                   PCP pmie config
+>17    string  >\0                             (V.%1.1s)
+0      string  MMV                             PCP memory mapped values
+>4     long    x                               (V.%d)
+
+# SpeedShop data files
+0      lelong  0x13130303                      SpeedShop data file
+
+# mdbm files
+0      lelong  0x01023962                      mdbm file, version 0 (obsolete)
+0      string  mdbm                            mdbm file,
+>5     byte    x                               version %d,
+>6     byte    x                               2^%d pages,
+>7     byte    x                               pagesize 2^%d,
+>17    byte    x                               hash %d,
+>11    byte    x                               dataformat %d
+
+# Alias Maya files
+0      string/t        //Maya\040ASCII Alias Maya Ascii File,
+>13    string  >\0     version %s
+8      string  MAYAFOR4        Alias Maya Binary File,
+>32    string  >\0     version %s scene
+8      string  MayaFOR4        Alias Maya Binary File,
+>32    string  >\0     version %s scene
+8      string  CIMG            Alias Maya Image File
+8      string  DEEP            Alias Maya Image File
diff --git a/magic/Magdir/sgml b/magic/Magdir/sgml
new file mode 100644 (file)
index 0000000..987fe10
--- /dev/null
@@ -0,0 +1,145 @@
+
+#------------------------------------------------------------------------------
+# $File: sgml,v 1.39 2019/04/19 00:42:27 christos Exp $
+# Type:        SVG Vectorial Graphics
+# From:        Noel Torres <tecnico@ejerciciosresueltos.com>
+0      string          \<?xml\ version=
+>14    regex           ['"\ \t]*[0-9.]+['"\ \t]*
+>>19   search/4096     \<svg                   SVG Scalable Vector Graphics image
+!:mime image/svg+xml
+>>19   search/4096     \<gnc-v2                GnuCash file
+!:mime application/x-gnucash
+0      string          \<svg                   SVG Scalable Vector Graphics image
+!:mime image/svg
+
+# Sitemap file
+0      string/t                \<?xml\ version=
+>14    regex           ['"\ \t]*[0-9.]+['"\ \t]*
+>>19   search/4096     \<urlset                XML Sitemap document text
+!:mime application/xml-sitemap
+
+# OpenStreetMap XML (.osm)
+# https://wiki.openstreetmap.org/wiki/OSM_XML
+# From: Markus Heidelberg <markus.heidelberg@web.de>
+0      string          \<?xml\ version=
+>14    regex           ['"\ \t]*[0-9.]+['"\ \t]*
+>>19   search/4096     \<osm                   OpenStreetMap XML data
+
+# xhtml
+0      string/t                \<?xml\ version="
+>19    search/4096/cWbt        \<!doctype\ html        XHTML document text
+>>15   string          >\0     (version %.3s)
+!:mime text/html
+0      string/t                \<?xml\ version='
+>19    search/4096/cWbt        \<!doctype\ html        XHTML document text
+>>15   string          >\0     (version %.3s)
+!:mime text/html
+0      string/t                \<?xml\ version="
+>19    search/4096/cWbt        \<html  broken XHTML document text
+>>15   string          >\0     (version %.3s)
+!:mime text/html
+
+#------------------------------------------------------------------------------
+# sgml:  file(1) magic for Standard Generalized Markup Language
+# HyperText Markup Language (HTML) is an SGML document type,
+# from Daniel Quinlan (quinlan@yggdrasil.com)
+# adapted to string extenstions by Anthon van der Neut <anthon@mnt.org)
+0      search/4096/cWt \<!doctype\ html        HTML document text
+!:mime text/html
+!:strength + 5
+
+# SVG document
+# https://www.w3.org/TR/SVG/single-page.html
+0      search/4096/cWbt        \<!doctype\ svg SVG XML document
+!:mime  image/svg+xml
+!:strength + 5
+
+0      search/4096/cwt \<head\>                HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cWt \<head\                 HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cwt \<title\>               HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cWt \<title\                HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cwt \<html\>                HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cWt \<html\                 HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cwt \<script\>              HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cWt \<script\               HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cwt \<style\>               HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cWt \<style\                HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cwt \<table\>               HTML document text
+!:mime text/html
+!:strength + 5
+0      search/4096/cWt \<table\                HTML document text
+!:mime text/html
+!:strength + 5
+
+0      search/4096/cwt \<a\ href=              HTML document text
+!:mime text/html
+!:strength + 5
+
+# Extensible markup language (XML), a subset of SGML
+# from Marc Prud'hommeaux (marc@apocalypse.org)
+0      search/1/cwt    \<?xml                  XML document text
+!:mime text/xml
+!:strength + 5
+0      string/t                \<?xml\ version\ "      XML
+!:mime text/xml
+!:strength + 5
+0      string/t                \<?xml\ version="       XML
+!:mime text/xml
+!:strength + 5
+>15    string/t        >\0                     %.3s document text
+>>23   search/1        \<xsl:stylesheet        (XSL stylesheet)
+>>24   search/1        \<xsl:stylesheet        (XSL stylesheet)
+0      string          \<?xml\ version='       XML
+!:mime text/xml
+!:strength + 5
+>15    string/t        >\0                     %.3s document text
+>>23   search/1        \<xsl:stylesheet        (XSL stylesheet)
+>>24   search/1        \<xsl:stylesheet        (XSL stylesheet)
+0      search/1/wt     \<?XML                  broken XML document text
+!:mime text/xml
+!:strength - 10
+
+
+# SGML, mostly from rph@sq
+0      search/4096/cwt \<!doctype              exported SGML document text
+0      search/4096/cwt \<!subdoc               exported SGML subdocument text
+0      search/4096/cwt \<!--                   exported SGML document text
+!:strength - 10
+
+# Web browser cookie files
+# (Mozilla, Galeon, Netscape 4, Konqueror..)
+# Ulf Harnhammar <ulfh@update.uu.se>
+0      search/1        #\ HTTP\ Cookie\ File   Web browser cookie text
+0      search/1        #\ Netscape\ HTTP\ Cookie\ File Netscape cookie text
+0      search/1        #\ KDE\ Cookie\ File    Konqueror cookie text
+
+# XML-based format representing braille pages in a digital format.
+#
+# Specification:
+# http://files.pef-format.org/specifications/pef-2008-1/pef-specification.html
+#
+# Simon Aittamaa <simon.aittamaa@gmail.com>
+0   string      \<?xml\ version=
+>14 regex       ['"\ \t]*[0-9.]+['"\ \t]*
+>>19    search/4096 \<pef           Portable Embosser Format
+!:mime  application/x-pef+xml
\ No newline at end of file
diff --git a/magic/Magdir/sharc b/magic/Magdir/sharc
new file mode 100644 (file)
index 0000000..e54088b
--- /dev/null
@@ -0,0 +1,23 @@
+
+#------------------------------------------------------------------------
+# $File: sharc,v 1.8 2017/03/17 21:35:28 christos Exp $
+# file(1) magic for sharc files
+#
+# SHARC DSP, MIDI SysEx and RiscOS filetype definitions added by
+# FutureGroove Music (dsp@futuregroove.de)
+
+#------------------------------------------------------------------------
+#0     string                  Draw            RiscOS Drawfile
+#0     string                  PACK            RiscOS PackdDir archive
+
+#------------------------------------------------------------------------
+# SHARC DSP stuff (based on the FGM SHARC DSP SDK)
+
+#0     string                  =!              Assembler source
+#0     string                  Analog          ADi asm listing file
+0      string                  .SYSTEM         SHARC architecture file
+0      string                  .system         SHARC architecture file
+
+0      leshort                 0x521C          SHARC COFF binary
+>2     leshort                 >1              , %d sections
+>>12   lelong                  >0              , not stripped
diff --git a/magic/Magdir/sinclair b/magic/Magdir/sinclair
new file mode 100644 (file)
index 0000000..bd4f120
--- /dev/null
@@ -0,0 +1,38 @@
+
+#------------------------------------------------------------------------------
+# $File: sinclair,v 1.5 2009/09/19 16:28:12 christos Exp $
+# sinclair:  file(1) sinclair QL
+
+# additions to /etc/magic by Thomas M. Ott (ThMO)
+
+# Sinclair QL floppy disk formats (ThMO)
+0      string  =QL5            QL disk dump data,
+>3     string  =A              720 KB,
+>3     string  =B              1.44 MB,
+>3     string  =C              3.2 MB,
+>4     string  >\0             label:%.10s
+
+# Sinclair QL OS dump (ThMO)
+0              belong  =0x30000
+>49124         belong  <47104
+>>49128                belong  <47104
+>>>49132       belong  <47104
+>>>>49136      belong  <47104  QL OS dump data,
+>>>>>49148     string  >\0     type %.3s,
+>>>>>49142     string  >\0     version %.4s
+
+# Sinclair QL firmware executables (ThMO)
+0      string  NqNqNq`\004     QL firmware executable (BCPL)
+
+# Sinclair QL libraries (was ThMO)
+0      beshort 0xFB01          QDOS object
+>2     pstring x               '%s'
+
+# Sinclair QL executables (was ThMO)
+4      belong  0x4AFB          QDOS executable
+>9     pstring x               '%s'
+
+# Sinclair QL ROM (ThMO)
+0      belong  =0x4AFB0001     QL plugin-ROM data,
+>9     pstring =\0             un-named
+>9     pstring >\0             named: %s
diff --git a/magic/Magdir/sisu b/magic/Magdir/sisu
new file mode 100644 (file)
index 0000000..ba7104f
--- /dev/null
@@ -0,0 +1,18 @@
+# Type: SiSU Markup Language
+# URL:  http://www.sisudoc.org/
+# From: Ralph Amissah <ralph.amissah@gmail.com>
+
+0      regex   \^%?[\ \t]*SiSU[\ \t]+insert    SiSU text insert
+>5     regex   [0-9.]+                         %s
+
+0      regex   \^%[\ \t]+SiSU[\ \t]+master     SiSU text master
+>5     regex   [0-9.]+                         %s
+
+0      regex   \^%?[\ \t]*SiSU[\ \t]+text      SiSU text
+>5     regex   [0-9.]+                         %s
+
+0      regex   \^%?[\ \t]*SiSU[\ \t][0-9.]+    SiSU text
+>5     regex   [0-9.]+                         %s
+
+0      regex   \^%*[\ \t]*sisu-[0-9.]+         SiSU text
+>5     regex   [0-9.]+                         %s
diff --git a/magic/Magdir/sketch b/magic/Magdir/sketch
new file mode 100644 (file)
index 0000000..ee731dd
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File: sketch,v 1.5 2017/03/17 21:35:28 christos Exp $
+# Sketch Drawings: http://sketch.sourceforge.net/
+# From: Edwin Mons <e@ik.nu>
+0      search/1        ##Sketch        Sketch document text
diff --git a/magic/Magdir/smalltalk b/magic/Magdir/smalltalk
new file mode 100644 (file)
index 0000000..46e6c31
--- /dev/null
@@ -0,0 +1,25 @@
+
+#-----------------------------------------------
+# $File$
+# GNU Smalltalk image, starting at version 1.6.2
+# From: catull_us@yahoo.com
+#
+0      string  GSTIm\0\0       GNU SmallTalk
+# little-endian
+>7     byte&1  =0              LE image version
+>>10   byte    x               %d.
+>>9    byte    x               \b%d.
+>>8    byte    x               \b%d
+#>>12  lelong  x               , data: %ld
+#>>16  lelong  x               , table: %ld
+#>>20  lelong  x               , memory: %ld
+# big-endian
+>7     byte&1  =1              BE image version
+>>8    byte    x               %d.
+>>9    byte    x               \b%d.
+>>10   byte    x               \b%d
+#>>12  belong  x               , data: %ld
+#>>16  belong  x               , table: %ld
+#>>20  belong  x               , memory: %ld
+
+
diff --git a/magic/Magdir/smile b/magic/Magdir/smile
new file mode 100644 (file)
index 0000000..bbdc96b
--- /dev/null
@@ -0,0 +1,34 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# smile:  file(1) magic for Smile serialization
+#
+# The Smile serialization format uses a 4-byte header:
+#
+#   Constant byte #0: 0x3A (ASCII ':')
+#   Constant byte #1: 0x29 (ASCII ')')
+#   Constant byte #2: 0x0A (ASCII linefeed, '\n')
+#   Variable byte #3, consisting of bits:
+#     Bits 4-7 (4 MSB): 4-bit version number
+#     Bits 3: Reserved
+#     Bit 2 (mask 0x04): Whether raw binary (unescaped 8-bit) values may be present in content
+#     Bit 1 (mask 0x02): Whether shared String value checking was enabled during encoding, default false
+#     Bit 0 (mask 0x01): Whether shared property name checking was enabled during encoding, default true
+#
+# Reference: http://wiki.fasterxml.com/SmileFormatSpec
+# Created by: Pierre-Alexandre Meyer <pierre@mouraf.org>
+
+# Detection
+0      string          :)\n    Smile binary data
+
+# Versioning
+>3     byte&0xF0       x               version %d:
+
+# Properties
+>3     byte&0x04       0x04            binary raw,
+>3     byte&0x04       0x00            binary encoded,
+>3     byte&0x02       0x02            shared String values enabled,
+>3     byte&0x02       0x00            shared String values disabled,
+>3     byte&0x01       0x01            shared field names enabled
+>3     byte&0x01       0x00            shared field names disabled
+
diff --git a/magic/Magdir/sniffer b/magic/Magdir/sniffer
new file mode 100644 (file)
index 0000000..14a23ab
--- /dev/null
@@ -0,0 +1,357 @@
+
+#------------------------------------------------------------------------------
+# $File: sniffer,v 1.25 2019/05/05 17:03:41 christos Exp $
+# sniffer:  file(1) magic for packet capture files
+#
+# From: guy@alum.mit.edu (Guy Harris)
+#
+
+#
+# Microsoft Network Monitor 1.x capture files.
+#
+0      string          RTSS            NetMon capture file
+>5     byte            x               - version %d
+>4     byte            x               \b.%d
+>6     leshort         0               (Unknown)
+>6     leshort         1               (Ethernet)
+>6     leshort         2               (Token Ring)
+>6     leshort         3               (FDDI)
+>6     leshort         4               (ATM)
+>6     leshort         >4              (type %d)
+
+#
+# Microsoft Network Monitor 2.x capture files.
+#
+0      string          GMBU            NetMon capture file
+>5     byte            x               - version %d
+>4     byte            x               \b.%d
+>6     leshort         0               (Unknown)
+>6     leshort         1               (Ethernet)
+>6     leshort         2               (Token Ring)
+>6     leshort         3               (FDDI)
+>6     leshort         4               (ATM)
+>6     leshort         5               (IP-over-IEEE 1394)
+>6     leshort         6               (802.11)
+>6     leshort         7               (Raw IP)
+>6     leshort         8               (Raw IP)
+>6     leshort         9               (Raw IP)
+>6     leshort         >9              (type %d)
+
+#
+# Network General Sniffer capture files.
+# Sorry, make that "Network Associates Sniffer capture files."
+# Sorry, make that "Network General old DOS Sniffer capture files."
+#
+0      string          TRSNIFF\040data\040\040\040\040\032     Sniffer capture file
+>33    byte            2               (compressed)
+>23    leshort         x               - version %d
+>25    leshort         x               \b.%d
+>32    byte            0               (Token Ring)
+>32    byte            1               (Ethernet)
+>32    byte            2               (ARCNET)
+>32    byte            3               (StarLAN)
+>32    byte            4               (PC Network broadband)
+>32    byte            5               (LocalTalk)
+>32    byte            6               (Znet)
+>32    byte            7               (Internetwork Analyzer)
+>32    byte            9               (FDDI)
+>32    byte            10              (ATM)
+
+#
+# Cinco Networks NetXRay capture files.
+# Sorry, make that "Network General Sniffer Basic capture files."
+# Sorry, make that "Network Associates Sniffer Basic capture files."
+# Sorry, make that "Network Associates Sniffer Basic, and Windows
+# Sniffer Pro", capture files."
+# Sorry, make that "Network General Sniffer capture files."
+# Sorry, make that "NetScout Sniffer capture files."
+#
+0      string          XCP\0           NetXRay capture file
+>4     string          >\0             - version %s
+>44    leshort         0               (Ethernet)
+>44    leshort         1               (Token Ring)
+>44    leshort         2               (FDDI)
+>44    leshort         3               (WAN)
+>44    leshort         8               (ATM)
+>44    leshort         9               (802.11)
+
+#
+# "libpcap" capture files.
+# https://www.tcpdump.org/manpages/pcap-savefile.5.html
+# (We call them "tcpdump capture file(s)" for now, as "tcpdump" is
+# the main program that uses that format, but there are other programs
+# that use "libpcap", or that use the same capture file format.)
+#
+0      name            pcap-be
+>4     beshort         x               - version %d
+>6     beshort         x               \b.%d
+# clear that continuation level match
+>20    clear           x
+>20    belong          0               (No link-layer encapsulation
+>20    belong          1               (Ethernet
+>20    belong          2               (3Mb Ethernet
+>20    belong          3               (AX.25
+>20    belong          4               (ProNET
+>20    belong          5               (CHAOS
+>20    belong          6               (Token Ring
+>20    belong          7               (BSD ARCNET
+>20    belong          8               (SLIP
+>20    belong          9               (PPP
+>20    belong          10              (FDDI
+>20    belong          11              (RFC 1483 ATM
+>20    belong          12              (raw IP
+>20    belong          13              (BSD/OS SLIP
+>20    belong          14              (BSD/OS PPP
+>20    belong          19              (Linux ATM Classical IP
+>20    belong          50              (PPP or Cisco HDLC
+>20    belong          51              (PPP-over-Ethernet
+>20    belong          99              (Symantec Enterprise Firewall
+>20    belong          100             (RFC 1483 ATM
+>20    belong          101             (raw IP
+>20    belong          102             (BSD/OS SLIP
+>20    belong          103             (BSD/OS PPP
+>20    belong          104             (BSD/OS Cisco HDLC
+>20    belong          105             (802.11
+>20    belong          106             (Linux Classical IP over ATM
+>20    belong          107             (Frame Relay
+>20    belong          108             (OpenBSD loopback
+>20    belong          109             (OpenBSD IPsec encrypted
+>20    belong          112             (Cisco HDLC
+>20    belong          113             (Linux cooked v1
+>20    belong          114             (LocalTalk
+>20    belong          117             (OpenBSD PFLOG
+>20    belong          119             (802.11 with Prism header
+>20    belong          122             (RFC 2625 IP over Fibre Channel
+>20    belong          123             (SunATM
+>20    belong          127             (802.11 with radiotap header
+>20    belong          129             (Linux ARCNET
+>20    belong          130             (Juniper Multi-Link PPP
+>20    belong          131             (Juniper Multi-Link Frame Relay
+>20    belong          132             (Juniper Encryption Services PIC
+>20    belong          133             (Juniper GGSN PIC
+>20    belong          134             (Juniper FRF.16 Frame Relay
+>20    belong          135             (Juniper ATM2 PIC
+>20    belong          136             (Juniper Advanced Services PIC
+>20    belong          137             (Juniper ATM1 PIC
+>20    belong          138             (Apple IP over IEEE 1394
+>20    belong          139             (SS7 MTP2 with pseudo-header
+>20    belong          140             (SS7 MTP2
+>20    belong          141             (SS7 MTP3
+>20    belong          142             (SS7 SCCP
+>20    belong          143             (DOCSIS
+>20    belong          144             (Linux IrDA
+>20    belong          147             (Private use 0
+>20    belong          148             (Private use 1
+>20    belong          149             (Private use 2
+>20    belong          150             (Private use 3
+>20    belong          151             (Private use 4
+>20    belong          152             (Private use 5
+>20    belong          153             (Private use 6
+>20    belong          154             (Private use 7
+>20    belong          155             (Private use 8
+>20    belong          156             (Private use 9
+>20    belong          157             (Private use 10
+>20    belong          158             (Private use 11
+>20    belong          159             (Private use 12
+>20    belong          160             (Private use 13
+>20    belong          161             (Private use 14
+>20    belong          162             (Private use 15
+>20    belong          163             (802.11 with AVS header
+>20    belong          164             (Juniper Passive Monitor PIC
+>20    belong          165             (BACnet MS/TP
+>20    belong          166             (PPPD
+>20    belong          167             (Juniper PPPoE
+>20    belong          168             (Juniper PPPoE/ATM
+>20    belong          169             (GPRS LLC
+>20    belong          170             (GPF-T
+>20    belong          171             (GPF-F
+>20    belong          174             (Juniper PIC Peer
+>20    belong          175             (Ethernet with Endace ERF header
+>20    belong          176             (Packet-over-SONET with Endace ERF header
+>20    belong          177             (Linux LAPD
+>20    belong          178             (Juniper Ethernet
+>20    belong          179             (Juniper PPP
+>20    belong          180             (Juniper Frame Relay
+>20    belong          181             (Juniper C-HDLC
+>20    belong          182             (FRF.16 Frame Relay
+>20    belong          183             (Juniper Voice PIC
+>20    belong          184             (Arinc 429
+>20    belong          185             (Arinc 653 Interpartition Communication
+>20    belong          186             (USB with FreeBSD header
+>20    belong          187             (Bluetooth HCI H4
+>20    belong          188             (802.16 MAC Common Part Sublayer
+>20    belong          189             (Linux USB
+>20    belong          190             (Controller Area Network (CAN) v. 2.0B
+>20    belong          191             (802.15.4 with Linux padding
+>20    belong          192             (PPI
+>20    belong          193             (802.16 MAC Common Part Sublayer plus radiotap header
+>20    belong          194             (Juniper Integrated Service Module
+>20    belong          195             (802.15.4 with FCS
+>20    belong          196             (SITA
+>20    belong          197             (Endace ERF
+>20    belong          198             (Ethernet with u10 Networks pseudo-header
+>20    belong          199             (IPMB
+>20    belong          200             (Juniper Secure Tunnel
+>20    belong          201             (Bluetooth HCI H4 with pseudo-header
+>20    belong          202             (AX.25 with KISS header
+>20    belong          203             (LAPD
+>20    belong          204             (PPP with direction pseudo-header
+>20    belong          205             (Cisco HDLC with direction pseudo-header
+>20    belong          206             (Frame Relay with direction pseudo-header
+>20    belong          209             (Linux IPMB
+>20    belong          215             (802.15.4 with non-ASK PHY header
+>20    belong          216             (Linux evdev events
+>20    belong          219             (MPLS with label as link-layer header
+>20    belong          220             (Memory-mapped Linux USB
+>20    belong          221             (DECT
+>20    belong          222             (AOS Space Data Link protocol
+>20    belong          223             (Wireless HART
+>20    belong          224             (Fibre Channel FC-2
+>20    belong          225             (Fibre Channel FC-2 with frame delimiters
+>20    belong          226             (Solaris IPNET
+>20    belong          227             (SocketCAN
+>20    belong          228             (Raw IPv4
+>20    belong          229             (Raw IPv6
+>20    belong          230             (802.15.4 without FCS
+>20    belong          231             (D-Bus messages
+>20    belong          232             (Juniper Virtual Server
+>20    belong          233             (Juniper SRX E2E
+>20    belong          234             (Juniper Fibre Channel
+>20    belong          235             (DVB-CI
+>20    belong          236             (MUX27010
+>20    belong          237             (STANAG 5066 D_PDUs
+>20    belong          238             (Juniper ATM CEMIC
+>20    belong          239             (Linux netfilter log messages
+>20    belong          240             (Hilscher netAnalyzer
+>20    belong          241             (Hilscher netAnalyzer with delimiters
+>20    belong          242             (IP-over-Infiniband
+>20    belong          243             (MPEG-2 Transport Stream packets
+>20    belong          244             (ng4t ng40
+>20    belong          245             (NFC LLCP
+>20    belong          246             (Packet filter state syncing
+>20    belong          247             (InfiniBand
+>20    belong          248             (SCTP
+>20    belong          249             (USB with USBPcap header
+>20    belong          250             (Schweitzer Engineering Laboratories RTAC packets
+>20    belong          251             (Bluetooth Low Energy air interface
+>20    belong          252             (Wireshark Upper PDU export
+>20    belong          253             (Linux netlink
+>20    belong          254             (Bluetooth Linux Monitor
+>20    belong          255             (Bluetooth Basic Rate/Enhanced Data Rate baseband packets
+>20    belong          256             (Bluetooth Low Energy air interface with pseudo-header
+>20    belong          257             (PROFIBUS data link layer
+>20    belong          258             (Apple DLT_PKTAP
+>20    belong          259             (Ethernet with 802.3 Clause 65 EPON preamble
+>20    belong          260             (IPMI trace packets
+>20    belong          261             (Z-Wave RF profile R1 and R2 packets
+>20    belong          262             (Z-Wave RF profile R3 packets
+>20    belong          263             (WattStopper Digital Lighting Mngmt/Legrand Nitoo Open Proto
+>20    belong          264             (ISO 14443 messages
+>20    belong          265             (IEC 62106 Radio Data System groups
+>20    belong          266             (USB with Darwin header
+>20    belong          267             (OpenBSD DLT_OPENFLOW
+>20    belong          268             (IBM SDLC frames
+>20    belong          269             (TI LLN sniffer frames
+>20    belong          271             (Linux vsock
+>20    belong          272             (Nordic Semiconductor Bluetooth LE sniffer frames
+>20    belong          273             (Excentis XRA-31 DOCSIS 3.1 RF sniffer frames
+>20    belong          274             (802.3br mPackets
+>20    belong          275             (DisplayPort AUX channel monitoring data
+>20    belong          276             (Linux cooked v2
+>20    belong          278             (OpenVizsla USB
+>20    belong          279             (Elektrobit High Speed Capture and Replay (EBHSCR)
+>20    belong          281             (Broadcom tag
+>20    belong          282             (Broadcom tag (prepended)
+# print default match
+>20    default         x
+>>20   belong          x               (linktype#%u
+>16    belong          x               \b, capture length %u)
+
+# packets time stamps in seconds and microseconds.
+0      ubelong         0xa1b2c3d4      pcap capture file, microseconds ts (big-endian)
+!:mime application/vnd.tcpdump.pcap
+>0     use     pcap-be
+0      ulelong         0xa1b2c3d4      pcap capture file, microsecond ts (little-endian)
+!:mime application/vnd.tcpdump.pcap
+>0     use     \^pcap-be
+
+# packets time stamps in seconds and nanoseconds.
+0      ubelong         0xa1b23c4d      pcap capture file, nanosecond ts (big-endian)
+!:mime application/vnd.tcpdump.pcap
+>0     use     pcap-be
+0      ulelong         0xa1b23c4d      pcap capture file, nanosecond ts (little-endian)
+!:mime application/vnd.tcpdump.pcap
+>0     use     \^pcap-be
+
+#
+# "libpcap"-with-Alexey-Kuznetsov's-patches capture files.
+#
+0      ubelong         0xa1b2cd34      pcap capture file, microsecond ts, extensions (big-endian)
+>0     use     pcap-be
+0      ulelong         0xa1b2cd34      pcap capture file, microsecond ts, extensions (little-endian)
+>0     use     \^pcap-be
+
+#
+# "pcapng" capture files.
+# https://github.com/pcapng/pcapng
+# Pcapng files can contain multiple sections. Printing the endianness,
+# snaplen, or other information from the first SHB may be misleading.
+#
+0      ubelong         0x0a0d0d0a
+>8     ubelong         0x1a2b3c4d      pcapng capture file
+>>12   beshort         x               - version %d
+>>14   beshort         x               \b.%d
+0      ulelong         0x0a0d0d0a
+>8     ulelong         0x1a2b3c4d      pcapng capture file
+>>12   leshort         x               - version %d
+>>14   leshort         x               \b.%d
+
+#
+# AIX "iptrace" capture files.
+#
+0      string          iptrace\0401.0  AIX iptrace capture file
+0      string          iptrace\0402.0  AIX iptrace capture file
+
+#
+# Novell LANalyzer capture files.
+#
+0      leshort         0x1001          Novell LANalyzer capture file
+0      leshort         0x1007          Novell LANalyzer capture file
+
+#
+# HP-UX "nettl" capture files.
+#
+0      string          \x54\x52\x00\x64\x00    HP/UX nettl capture file
+
+#
+# RADCOM WAN/LAN Analyzer capture files.
+#
+0      string          \x42\xd2\x00\x34\x12\x66\x22\x88        RADCOM WAN/LAN Analyzer capture file
+
+#
+# NetStumbler log files.  Not really packets, per se, but about as
+# close as you can get.  These are log files from NetStumbler, a
+# Windows program, that scans for 802.11b networks.
+#
+0      string          NetS            NetStumbler log file
+>8     lelong          x               \b, %d stations found
+
+#
+# *Peek tagged capture files.
+#
+0      string          \177ver         EtherPeek/AiroPeek/OmniPeek capture file
+
+#
+# Visual Networks traffic capture files.
+#
+0      string          \x05VNF         Visual Networks traffic capture file
+
+#
+# Network Instruments Observer capture files.
+#
+0      string          ObserverPktBuffe        Network Instruments Observer capture file
+
+#
+# Files from Accellent Group's 5View products.
+#
+0      string          \xaa\xaa\xaa\xaa        5View capture file
diff --git a/magic/Magdir/softquad b/magic/Magdir/softquad
new file mode 100644 (file)
index 0000000..e756c1d
--- /dev/null
@@ -0,0 +1,37 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# softquad:  file(1) magic for SoftQuad Publishing Software
+#
+# Author/Editor and RulesBuilder
+#
+# XXX - byte order?
+#
+0      string          \<!SQ\ DTD>     Compiled SGML rules file
+>9     string          >\0              Type %s
+0      string          \<!SQ\ A/E>     A/E SGML Document binary
+>9     string          >\0              Type %s
+0      string          \<!SQ\ STS>     A/E SGML binary styles file
+>9     string          >\0              Type %s
+0      short           0xc0de          Compiled PSI (v1) data
+0      short           0xc0da          Compiled PSI (v2) data
+>3     string          >\0             (%s)
+# Binary sqtroff font/desc files...
+0      short           0125252         SoftQuad DESC or font file binary
+>2     short           >0              - version %d
+# Bitmaps...
+0      search/1        SQ\ BITMAP1     SoftQuad Raster Format text
+#0     string          SQ\ BITMAP2     SoftQuad Raster Format data
+# sqtroff intermediate language (replacement for ditroff int. lang.)
+0      string          X\              SoftQuad troff Context intermediate
+>2     string          495             for AT&T 495 laser printer
+>2     string          hp              for Hewlett-Packard LaserJet
+>2     string          impr            for IMAGEN imPRESS
+>2     string          ps              for PostScript
+
+# From: Michael Piefel <piefel@debian.org>
+# sqtroff intermediate language (replacement for ditroff int. lang.)
+0      string          X\ 495          SoftQuad troff Context intermediate for AT&T 495 laser printer
+0      string          X\ hp           SoftQuad troff Context intermediate for HP LaserJet
+0      string          X\ impr         SoftQuad troff Context intermediate for IMAGEN imPRESS
+0      string          X\ ps           SoftQuad troff Context intermediate for PostScript
diff --git a/magic/Magdir/spec b/magic/Magdir/spec
new file mode 100644 (file)
index 0000000..55c10b3
--- /dev/null
@@ -0,0 +1,21 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# spec:  file(1) magic for SPEC raw results (*.raw, *.rsf)
+#
+# Cloyce D. Spradling <cloyce@headgear.org>
+
+0      string  spec                    SPEC
+>4     string  .cpu                    CPU
+>>8    string  <:                      \b%.4s
+>>12   string  .                       raw result text
+
+17     string  version=SPECjbb         SPECjbb
+>32    string  <:                      \b%.4s
+>>37   string  <:                      v%.4s raw result text
+
+0      string  BEGIN\040SPECWEB        SPECweb
+>13    string  <:                      \b%.2s
+>>15   string  _SSL                    \b_SSL
+>>>20  string  <:                      v%.4s raw result text
+>>16   string  <:                      v%.4s raw result text
diff --git a/magic/Magdir/spectrum b/magic/Magdir/spectrum
new file mode 100644 (file)
index 0000000..e8304d7
--- /dev/null
@@ -0,0 +1,80 @@
+
+#------------------------------------------------------------------------------
+# $File: spectrum,v 1.8 2017/09/11 23:51:12 christos Exp $
+# spectrum:  file(1) magic for Spectrum emulator files.
+#
+# John Elliott <jce@seasip.demon.co.uk>
+
+#
+# Spectrum +3DOS header
+#
+0       string          PLUS3DOS\032    Spectrum +3 data
+>15     byte            0               - BASIC program
+>15     byte            1               - number array
+>15     byte            2               - character array
+>15     byte            3               - memory block
+>>16    belong          0x001B0040      (screen)
+>15     byte            4               - Tasword document
+>15     string          TAPEFILE        - ZXT tapefile
+#
+# Tape file. This assumes the .TAP starts with a Spectrum-format header,
+# which nearly all will.
+#
+# Update: Sanity-check string contents to be printable.
+#  -Adam Buchbinder <adam.buchbinder@gmail.com>
+#
+0       string          \023\000\000
+>4      string          >\0
+>>4     string          <\177           Spectrum .TAP data "%-10.10s"
+>>>3    byte            0               - BASIC program
+>>>3    byte            1               - number array
+>>>3    byte            2               - character array
+>>>3    byte            3               - memory block
+>>>>14  belong          0x001B0040      (screen)
+
+# The following three blocks are from pak21-spectrum@srcf.ucam.org
+# TZX tape images
+0      string          ZXTape!\x1a     Spectrum .TZX data
+>8     byte            x               version %d
+>9     byte            x               \b.%d
+
+# RZX input recording files
+0      string          RZX!            Spectrum .RZX data
+>4     byte            x               version %d
+>5     byte            x               \b.%d
+
+# Floppy disk images
+0      string          MV\ -\ CPCEMU\ Disk-Fil Amstrad/Spectrum .DSK data
+0      string          MV\ -\ CPC\ format\ Dis Amstrad/Spectrum DU54 .DSK data
+0      string          EXTENDED\ CPC\ DSK\ Fil Amstrad/Spectrum Extended .DSK data
+0      string          SINCLAIR        Spectrum .SCL Betadisk image
+
+# Hard disk images
+0      string          RS-IDE\x1a      Spectrum .HDF hard disk image
+>7     byte            x               \b, version 0x%02x
+
+# SZX snapshots (fuse and spectaculator)
+# Martin M. S. Pedersen <martin@linux.com>
+# http://www.spectaculator.com/docs/zx-state/header.shtml
+#
+0      string          ZXST           zx-state snapshot
+>4     byte            x              version %d
+>5     byte            x              \b.%d
+>>6    byte            0              16k ZX Spectrum
+>>6    byte            1              48k ZX Spectrum/ZX Spectrum+
+>>6    byte            2              ZX Spectrum 128
+>>6    byte            3              ZX Spectrum +2
+>>6    byte            4              ZX Spectrum +2A/+2B
+>>6    byte            5              ZX Spectrum +3
+>>6    byte            6              ZX Spectrum +3e
+>>6    byte            7              Pentagon 128
+>>6    byte            8              Timex Sinclair TC2048
+>>6    byte            9              Timex Sinclair TC2068
+>>6    byte           10              Scorpion ZS-256
+>>6    byte           11              ZX Spectrum SE
+>>6    byte           12              Timex Sinclair TS2068
+>>6    byte           13              Pentagon 512
+>>6    byte           14              Pentagon 1024
+>>6    byte           15              48k ZX Spectrum (NTSC)
+>>6    byte           16              ZX Spectrum 12Ke
+>>>7   byte            1              (alternate timings)
diff --git a/magic/Magdir/sql b/magic/Magdir/sql
new file mode 100644 (file)
index 0000000..28d89e6
--- /dev/null
@@ -0,0 +1,141 @@
+
+#------------------------------------------------------------------------------
+# $File: sql,v 1.22 2019/04/19 00:42:27 christos Exp $
+# sql:  file(1) magic for SQL files
+#
+# From: "Marty Leisner" <mleisner@eng.mc.xerox.com>
+# Recognize some MySQL files.
+# Elan Ruusamae <glen@delfi.ee>, added MariaDB signatures
+# from https://bazaar.launchpad.net/~maria-captains/maria/5.5/view/head:/support-files/magic
+#
+0      beshort                 0xfe01          MySQL table definition file
+>2     byte                    x               Version %d
+>3     byte                    0               \b, type UNKNOWN
+>3     byte                    1               \b, type DIAM_ISAM
+>3     byte                    2               \b, type HASH
+>3     byte                    3               \b, type MISAM
+>3     byte                    4               \b, type PISAM
+>3     byte                    5               \b, type RMS_ISAM
+>3     byte                    6               \b, type HEAP
+>3     byte                    7               \b, type ISAM
+>3     byte                    8               \b, type MRG_ISAM
+>3     byte                    9               \b, type MYISAM
+>3     byte                    10              \b, type MRG_MYISAM
+>3     byte                    11              \b, type BERKELEY_DB
+>3     byte                    12              \b, type INNODB
+>3     byte                    13              \b, type GEMINI
+>3     byte                    14              \b, type NDBCLUSTER
+>3     byte                    15              \b, type EXAMPLE_DB
+>3     byte                    16              \b, type CSV_DB
+>3     byte                    17              \b, type FEDERATED_DB
+>3     byte                    18              \b, type BLACKHOLE_DB
+>3     byte                    19              \b, type PARTITION_DB
+>3     byte                    20              \b, type BINLOG
+>3     byte                    21              \b, type SOLID
+>3     byte                    22              \b, type PBXT
+>3     byte                    23              \b, type TABLE_FUNCTION
+>3     byte                    24              \b, type MEMCACHE
+>3     byte                    25              \b, type FALCON
+>3     byte                    26              \b, type MARIA
+>3     byte                    27              \b, type PERFORMANCE_SCHEMA
+>3     byte                    127             \b, type DEFAULT
+>0x0033        ulong                   x               \b, MySQL version %d
+0      belong&0xffffff00       0xfefe0500      MySQL ISAM index file
+>3     byte                    x               Version %d
+0      belong&0xffffff00       0xfefe0600      MySQL ISAM compressed data file
+>3     byte                    x               Version %d
+0      belong&0xffffff00       0xfefe0700      MySQL MyISAM index file
+>3     byte                    x               Version %d
+>14    beshort                 x               \b, %d key parts
+>16    beshort                 x               \b, %d unique key parts
+>18    byte                    x               \b, %d keys
+>28    bequad                  x               \b, %lld records
+>36    bequad                  x               \b, %lld deleted records
+0      belong&0xffffff00       0xfefe0800      MySQL MyISAM compressed data file
+>3     byte                    x               Version %d
+0      belong&0xffffff00       0xfefe0900      MySQL Maria index file
+>3     byte                    x               Version %d
+0      belong&0xffffff00       0xfefe0a00      MySQL Maria compressed data file
+>3     byte                    x               Version %d
+0      belong&0xffffff00       0xfefe0c00
+>4     string                  MACF            MySQL Maria control file
+>>3    byte                    x               Version %d
+0      string                  \376bin MySQL replication log,
+>9     long                    x               server id %d
+>8     byte                    1
+>>13   long                    69              \b, MySQL V3.2.3
+>>>19  string                  x               \b, server version %s
+>>13   long                    75              \b, MySQL V4.0.2-V4.1
+>>>25  string                  x               \b, server version %s
+>8     byte                    15              MySQL V5+,
+>>25   string                  x               server version %s
+>4     string                  MARIALOG        MySQL Maria transaction log file
+>>3    byte                    x               Version %d
+
+#------------------------------------------------------------------------------
+# iRiver H Series database file
+# From Ken Guest <ken@linux.ie>
+# As observed from iRivNavi.iDB and unencoded firmware
+#
+0   string             iRivDB  iRiver Database file
+>11  string    >\0     Version %s
+>39  string            iHP-100 [H Series]
+
+#------------------------------------------------------------------------------
+# SQLite database files
+# Ken Guest <ken@linux.ie>, Ty Sarna, Zack Weinberg
+#
+# Version 1 used GDBM internally; its files cannot be distinguished
+# from other GDBM files.
+#
+# Version 2 used this format:
+0      string  **\ This\ file\ contains\ an\ SQLite  SQLite 2.x database
+
+# Version 3 of SQLite allows applications to embed their own "user version"
+# number in the database at offset 60.  Later, SQLite added an "application id"
+# at offset 68 that is preferred over "user version" for indicating the
+# associated application.
+#
+0   string  SQLite\ format\ 3  SQLite 3.x database
+!:mime application/x-sqlite3
+# seldom found extension sqlite3 like in SyncData.sqlite3
+# db
+# Avira Antivir use extension "dbe" like in avevtdb.dbe, avguard_tchk.dbe
+# Unfortunately extension sqlite also used for other databases starting with string
+# "TTCONTAINER" like in tracks.sqlite contentconsumer.sqlite contentproducerrepository.sqlite
+# and with string "ZV-zlib" in like extra.sqlite
+!:ext sqlite/sqlite3/db/dbe
+>60 belong  =0x5f4d544e  (Monotone source repository)
+>68 belong  =0x0f055112  (Fossil checkout)
+>68 belong  =0x0f055113  (Fossil global configuration)
+>68 belong  =0x0f055111  (Fossil repository)
+>68 belong  =0x42654462  (Bentley Systems BeSQLite Database)
+>68 belong  =0x42654c6e  (Bentley Systems Localization File)
+>68 belong  =0x47504b47  (OGC GeoPackage file)
+>68 default x
+>>68 belong  !0          \b, application id %u
+>>60 belong  !0          \b, user version %d
+>96 belong  x            \b, last written using SQLite version %d
+
+
+# SQLite Write-Ahead Log from SQLite version >= 3.7.0
+# https://www.sqlite.org/fileformat.html#walformat
+0      belong&0xfffffffe       0x377f0682      SQLite Write-Ahead Log,
+!:ext sqlite-wal/db-wal
+>4     belong  x       version %d
+
+# SQLite Rollback Journal
+# https://www.sqlite.org/fileformat.html#rollbackjournal
+0      string  \xd9\xd5\x05\xf9\x20\xa1\x63\xd7        SQLite Rollback Journal
+
+# Panasonic channel list database svl.bin or svl.db added by Joerg Jenderek
+# https://github.com/PredatH0r/ChanSort
+0      string          PSDB\0                  Panasonic channel list DataBase
+!:ext db/bin
+#!:mime        application/x-db-svl-panasonic
+>126   string          SQLite\ format\ 3
+#!:mime        application/x-panasonic-sqlite3
+>>&-15 indirect        x                       \b; contains
+
+# H2 Database from https://www.h2database.com/
+0      string          --\ H2\ 0.5/B\ --\ \n   H2 Database file
diff --git a/magic/Magdir/ssh b/magic/Magdir/ssh
new file mode 100644 (file)
index 0000000..ca64564
--- /dev/null
@@ -0,0 +1,13 @@
+# Type:        OpenSSH key files
+# From:        Nicolas Collignon <tsointsoin@gmail.com>
+
+0      string  SSH\ PRIVATE\ KEY       OpenSSH RSA1 private key,
+>28    string  >\0                     version %s
+0      string  -----BEGIN\ OPENSSH\ PRIVATE\ KEY-----  OpenSSH private key
+
+0      string  ssh-dss\                OpenSSH DSA public key
+0      string  ssh-rsa\                OpenSSH RSA public key
+0      string  ecdsa-sha2-nistp256     OpenSSH ECDSA public key
+0      string  ecdsa-sha2-nistp384     OpenSSH ECDSA public key
+0      string  ecdsa-sha2-nistp521     OpenSSH ECDSA public key
+0      string  ssh-ed25519             OpenSSH ED25519 public key
diff --git a/magic/Magdir/ssl b/magic/Magdir/ssl
new file mode 100644 (file)
index 0000000..2309392
--- /dev/null
@@ -0,0 +1,20 @@
+
+#------------------------------------------------------------------------------
+# $File: ssl,v 1.5 2017/12/29 04:00:07 christos Exp $
+# ssl:  file(1) magic for SSL file formats
+
+# Type: OpenSSL certificates/key files
+# From: Nicolas Collignon <tsointsoin@gmail.com>
+
+0      string  -----BEGIN\040CERTIFICATE-----  PEM certificate
+0      string  -----BEGIN\040CERTIFICATE\040REQ        PEM certificate request
+0      string  -----BEGIN\040RSA\040PRIVATE    PEM RSA private key
+0      string  -----BEGIN\040DSA\040PRIVATE    PEM DSA private key
+0      string  -----BEGIN\040EC\040PRIVATE     PEM EC private key
+0      string  -----BEGIN\040ECDSA\040PRIVATE  PEM ECDSA private key
+
+# From Luc Gommans
+# OpenSSL enc file (recognized by a magic string preceding the password's salt)
+0      string  Salted__        openssl enc'd data with salted password
+# Using the -a or -base64 option, OpenSSL will base64-encode the data.
+0      string U2FsdGVkX1       openssl enc'd data with salted password, base64 encoded
diff --git a/magic/Magdir/sun b/magic/Magdir/sun
new file mode 100644 (file)
index 0000000..df83834
--- /dev/null
@@ -0,0 +1,141 @@
+
+#------------------------------------------------------------------------------
+# $File: sun,v 1.28 2019/04/19 00:42:27 christos Exp $
+# sun:  file(1) magic for Sun machines
+#
+# Values for big-endian Sun (MC680x0, SPARC) binaries on pre-5.x
+# releases.  (5.x uses ELF.)  Entries for executables without an
+# architecture type, used before the 68020-based Sun-3's came out,
+# are in aout, as they're indistinguishable from other big-endian
+# 32-bit a.out files.
+#
+0      belong&077777777        0600413         a.out SunOS SPARC demand paged
+>0     byte            &0x80
+>>20   belong          <4096           shared library
+>>20   belong          =4096           dynamically linked executable
+>>20   belong          >4096           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0600410         a.out SunOS SPARC pure
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0600407         a.out SunOS SPARC
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0400413         a.out SunOS mc68020 demand paged
+>0     byte            &0x80
+>>20   belong          <4096           shared library
+>>20   belong          =4096           dynamically linked executable
+>>20   belong          >4096           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0400410         a.out SunOS mc68020 pure
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0400407         a.out SunOS mc68020
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0200413         a.out SunOS mc68010 demand paged
+>0     byte            &0x80
+>>20   belong          <4096           shared library
+>>20   belong          =4096           dynamically linked executable
+>>20   belong          >4096           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0200410         a.out SunOS mc68010 pure
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+0      belong&077777777        0200407         a.out SunOS mc68010
+>0     byte            &0x80           dynamically linked executable
+>0     byte            ^0x80           executable
+>16    belong          >0              not stripped
+
+#
+# Core files.  "SPARC 4.x BCP" means "core file from a SunOS 4.x SPARC
+# binary executed in compatibility mode under SunOS 5.x".
+#
+0      belong          0x080456        SunOS core file
+>4     belong          432             (SPARC)
+>>132  string          >\0             from '%s'
+>>116  belong          =3              (quit)
+>>116  belong          =4              (illegal instruction)
+>>116  belong          =5              (trace trap)
+>>116  belong          =6              (abort)
+>>116  belong          =7              (emulator trap)
+>>116  belong          =8              (arithmetic exception)
+>>116  belong          =9              (kill)
+>>116  belong          =10             (bus error)
+>>116  belong          =11             (segmentation violation)
+>>116  belong          =12             (bad argument to system call)
+>>116  belong          =29             (resource lost)
+>>120  belong          x               (T=%dK,
+>>124  belong          x               D=%dK,
+>>128  belong          x               S=%dK)
+>4     belong          826             (68K)
+>>128  string          >\0             from '%s'
+>4     belong          456             (SPARC 4.x BCP)
+>>152  string          >\0             from '%s'
+# Sun SunPC
+0      long            0xfa33c08e      SunPC 4.0 Hard Disk
+0      string          #SUNPC_CONFIG   SunPC 4.0 Properties Values
+# Sun snoop (see RFC 1761, which describes the capture file format,
+# RFC 3827, which describes some additional datalink types, and
+# https://www.iana.org/assignments/snoop-datalink-types/snoop-datalink-types.xml,
+# which is the IANA registry of Snoop datalink types)
+#
+0      string          snoop           Snoop capture file
+>8     belong          >0              - version %d
+>12    belong          0               (IEEE 802.3)
+>12    belong          1               (IEEE 802.4)
+>12    belong          2               (IEEE 802.5)
+>12    belong          3               (IEEE 802.6)
+>12    belong          4               (Ethernet)
+>12    belong          5               (HDLC)
+>12    belong          6               (Character synchronous)
+>12    belong          7               (IBM channel-to-channel adapter)
+>12    belong          8               (FDDI)
+>12    belong          9               (Other)
+>12    belong          10              (type %d)
+>12    belong          11              (type %d)
+>12    belong          12              (type %d)
+>12    belong          13              (type %d)
+>12    belong          14              (type %d)
+>12    belong          15              (type %d)
+>12    belong          16              (Fibre Channel)
+>12    belong          17              (ATM)
+>12    belong          18              (ATM Classical IP)
+>12    belong          19              (type %d)
+>12    belong          20              (type %d)
+>12    belong          21              (type %d)
+>12    belong          22              (type %d)
+>12    belong          23              (type %d)
+>12    belong          24              (type %d)
+>12    belong          25              (type %d)
+>12    belong          26              (IP over Infiniband)
+>12    belong          >26             (type %d)
+
+#---------------------------------------------------------------------------
+# The following entries have been tested by Duncan Laurie <duncan@sun.com> (a
+# lead Sun/Cobalt developer) who agrees that they are good and worthy of
+# inclusion.
+
+# Boot ROM images for Sun/Cobalt Linux server appliances
+0       string  Cobalt\ Networks\ Inc.\nFirmware\ v     Paged COBALT boot rom
+>38     string x        V%.4s
+
+# New format for Sun/Cobalt boot ROMs is annoying, it stores the version code
+# at the very end where file(1) can't get it.
+0       string CRfs     COBALT boot rom data (Flat boot rom or file system)
diff --git a/magic/Magdir/symbos b/magic/Magdir/symbos
new file mode 100644 (file)
index 0000000..c97a42e
--- /dev/null
@@ -0,0 +1,42 @@
+
+#------------------------------------------------------------------------------
+# msx:  file(1) magic for the SymbOS operating system
+# http://www.symbos.de
+# Fabio R. Schmidlin <frs@pop.com.br>
+
+# SymbOS EXE file
+0x30   string          SymExe          SymbOS executable
+>0x36  ubyte           x               v%c
+>0x37  ubyte           x               \b.%c
+>0xF   string          x               \b, name: %s
+
+# SymbOS DOX document
+0      string          INFOq\0         SymbOS DOX document
+
+# Symbos driver
+0      string          SMD1            SymbOS driver
+>19    byte            x               \b, name: %c
+>20    byte            x               \b%c
+>21    byte            x               \b%c
+>22    byte            x               \b%c
+>23    byte            x               \b%c
+>24    byte            x               \b%c
+>25    byte            x               \b%c
+>26    byte            x               \b%c
+>27    byte            x               \b%c
+>28    byte            x               \b%c
+>29    byte            x               \b%c
+>30    byte            x               \b%c
+>31    byte            x               \b%c
+
+# Symbos video
+0      string          SymVid          SymbOS video
+>6     ubyte           x               v%c
+>7     ubyte           x               \b.%c
+
+# Soundtrakker 128 ST2 music
+0      byte            0
+>0xC   string          \x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x40\x00        Soundtrakker 128 ST2 music,
+>>1    string          x               name: %s
+
+
diff --git a/magic/Magdir/sysex b/magic/Magdir/sysex
new file mode 100644 (file)
index 0000000..967ac0c
--- /dev/null
@@ -0,0 +1,320 @@
+
+#------------------------------------------------------------------------
+# $File: sysex,v 1.10 2019/04/19 00:42:27 christos Exp $
+# sysex: file(1) magic for MIDI sysex files
+#
+# GRR: original 1 byte test at offset was too general as it catches also many FATs of DOS filesystems
+# where real SYStem EXclusive messages at offset 1 are limited to seven bits
+# https://en.wikipedia.org/wiki/MIDI
+0      ubeshort&0xFF80         0xF000          SysEx File -
+
+# North American Group
+>1     byte                    0x01            Sequential
+>1     byte                    0x02            IDP
+>1     byte                    0x03            OctavePlateau
+>1     byte                    0x04            Moog
+>1     byte                    0x05            Passport
+>1     byte                    0x06            Lexicon
+>1     byte                    0x07            Kurzweil/Future Retro
+>>3    byte                    0x77            777
+>>4    byte                    0x00            Bank
+>>4    byte                    0x01            Song
+>>5    byte                    0x0f            16
+>>5    byte                    0x0e            15
+>>5    byte                    0x0d            14
+>>5    byte                    0x0c            13
+>>5    byte                    0x0b            12
+>>5    byte                    0x0a            11
+>>5    byte                    0x09            10
+>>5    byte                    0x08            9
+>>5    byte                    0x07            8
+>>5    byte                    0x06            7
+>>5    byte                    0x05            6
+>>5    byte                    0x04            5
+>>5    byte                    0x03            4
+>>5    byte                    0x02            3
+>>5    byte                    0x01            2
+>>5    byte                    0x00            1
+>>5    byte                    0x10            (ALL)
+>>2    byte                    x                       \b, Channel %d
+>1     byte                    0x08            Fender
+>1     byte                    0x09            Gulbransen
+>1     byte                    0x0a            AKG
+>1     byte                    0x0b            Voyce
+>1     byte                    0x0c            Waveframe
+>1     byte                    0x0d            ADA
+>1     byte                    0x0e            Garfield
+>1     byte                    0x0f            Ensoniq
+>1     byte                    0x10            Oberheim
+>>2    byte                    0x06            Matrix 6 series
+>>3    byte                    0x0A            Dump (All)
+>>3    byte                    0x01            Dump (Bank)
+>>4 belong                     0x0002040E              Matrix 1000
+>>>11 byte                     <2                      User bank %d
+>>>11 byte                     >1                      Preset bank %d
+>1     byte                    0x11            Apple
+>1     byte                    0x12            GreyMatter
+>1     byte                    0x14            PalmTree
+>1     byte                    0x15            JLCooper
+>1     byte                    0x16            Lowrey
+>1     byte                    0x17            AdamsSmith
+>1     byte                    0x18            E-mu
+>1     byte                    0x19            Harmony
+>1     byte                    0x1a            ART
+>1     byte                    0x1b            Baldwin
+>1     byte                    0x1c            Eventide
+>1     byte                    0x1d            Inventronics
+>1     byte                    0x1f            Clarity
+
+# European Group
+>1     byte                    0x21            SIEL
+>1     byte                    0x22            Synthaxe
+>1     byte                    0x24            Hohner
+>1     byte                    0x25            Twister
+>1     byte                    0x26            Solton
+>1     byte                    0x27            Jellinghaus
+>1     byte                    0x28            Southworth
+>1     byte                    0x29            PPG
+>1     byte                    0x2a            JEN
+>1     byte                    0x2b            SSL
+>1     byte                    0x2c            AudioVertrieb
+
+>1     byte                    0x2f            ELKA
+>>3    byte                    0x09            EK-44
+
+>1     byte                    0x30            Dynacord
+>1     byte                    0x31            Jomox
+>1     byte                    0x33            Clavia
+>1     byte                    0x39            Soundcraft
+# Some Waldorf info from http://Stromeko.Synth.net/Downloads#WaldorfDocs
+>1     byte                    0x3e            Waldorf
+>>2    byte                    0x00            microWave
+>>2    byte                    0x0E            microwave2 / XT
+>>2    byte                    0x0F            Q / Q+
+>>3    byte                    =0                      (default id)
+>>3 byte                       >0                      (
+>>>3 byte                      <0x7F           \bdevice %d)
+>>>3 byte                      =0x7F           \bbroadcast id)
+>>3    byte                    0x7f            Microwave I
+>>>4   byte                    0x00            SNDR (Sound Request)
+>>>4   byte                    0x10            SNDD (Sound Dump)
+>>>4   byte                    0x20            SNDP (Sound Parameter Change)
+>>>4   byte                    0x30            SNDQ (Sound Parameter Inquiry)
+>>>4   byte                    0x70            BOOT (Sound Reserved)
+>>>4   byte                    0x01            MULR (Multi Request)
+>>>4   byte                    0x11            MULD (Multi Dump)
+>>>4   byte                    0x21            MULP (Multi Parameter Change)
+>>>4   byte                    0x31            MULQ (Multi Parameter Inquiry)
+>>>4   byte                    0x71            OS (Multi Reserved)
+>>>4   byte                    0x02            DRMR (Drum Map Request)
+>>>4   byte                    0x12            DRMD (Drum Map Dump)
+>>>4   byte                    0x22            DRMP (Drum Map Parameter Change)
+>>>4   byte                    0x32            DRMQ (Drum Map Parameter Inquiry)
+>>>4   byte                    0x72            BIN (Drum Map Reserved)
+>>>4   byte                    0x03            PATR (Sequencer Pattern Request)
+>>>4   byte                    0x13            PATD (Sequencer Pattern Dump)
+>>>4   byte                    0x23            PATP (Sequencer Pattern Parameter Change)
+>>>4   byte                    0x33            PATQ (Sequencer Pattern Parameter Inquiry)
+>>>4   byte                    0x73            AFM (Sequencer Pattern Reserved)
+>>>4   byte                    0x04            GLBR (Global Parameter Request)
+>>>4   byte                    0x14            GLBD (Global Parameter Dump)
+>>>4   byte                    0x24            GLBP (Global Parameter Parameter Change)
+>>>4   byte                    0x34            GLBQ (Global Parameter Parameter Inquiry)
+>>>4   byte                    0x07            MODR (Mode Parameter Request)
+>>>4   byte                    0x17            MODD (Mode Parameter Dump)
+>>>4   byte                    0x27            MODP (Mode Parameter Parameter Change)
+>>>4   byte                    0x37            MODQ (Mode Parameter Parameter Inquiry)
+>>2    byte                    0x10            microQ
+>>>4   byte                    0x00            SNDR (Sound Request)
+>>>4   byte                    0x10            SNDD (Sound Dump)
+>>>4   byte                    0x20            SNDP (Sound Parameter Change)
+>>>4   byte                    0x30            SNDQ (Sound Parameter Inquiry)
+>>>4   byte                    0x70            (Sound Reserved)
+>>>4   byte                    0x01            MULR (Multi Request)
+>>>4   byte                    0x11            MULD (Multi Dump)
+>>>4   byte                    0x21            MULP (Multi Parameter Change)
+>>>4   byte                    0x31            MULQ (Multi Parameter Inquiry)
+>>>4   byte                    0x71            OS (Multi Reserved)
+>>>4   byte                    0x02            DRMR (Drum Map Request)
+>>>4   byte                    0x12            DRMD (Drum Map Dump)
+>>>4   byte                    0x22            DRMP (Drum Map Parameter Change)
+>>>4   byte                    0x32            DRMQ (Drum Map Parameter Inquiry)
+>>>4   byte                    0x72            BIN (Drum Map Reserved)
+>>>4   byte                    0x04            GLBR (Global Parameter Request)
+>>>4   byte                    0x14            GLBD (Global Parameter Dump)
+>>>4   byte                    0x24            GLBP (Global Parameter Parameter Change)
+>>>4   byte                    0x34            GLBQ (Global Parameter Parameter Inquiry)
+>>2    byte                    0x11            rackAttack
+>>>4   byte                    0x00            SNDR (Sound Parameter Request)
+>>>4   byte                    0x10            SNDD (Sound Parameter Dump)
+>>>4   byte                    0x20            SNDP (Sound Parameter Parameter Change)
+>>>4   byte                    0x30            SNDQ (Sound Parameter Parameter Inquiry)
+>>>4   byte                    0x01            PRGR (Program Parameter Request)
+>>>4   byte                    0x11            PRGD (Program Parameter Dump)
+>>>4   byte                    0x21            PRGP (Program Parameter Parameter Change)
+>>>4   byte                    0x31            PRGQ (Program Parameter Parameter Inquiry)
+>>>4   byte                    0x71            OS (Program Parameter Reserved)
+>>>4   byte                    0x03            PATR (Pattern Parameter Request)
+>>>4   byte                    0x13            PATD (Pattern Parameter Dump)
+>>>4   byte                    0x23            PATP (Pattern Parameter Parameter Change)
+>>>4   byte                    0x33            PATQ (Pattern Parameter Parameter Inquiry)
+>>>4   byte                    0x04            GLBR (Global Parameter Request)
+>>>4   byte                    0x14            GLBD (Global Parameter Dump)
+>>>4   byte                    0x24            GLBP (Global Parameter Parameter Change)
+>>>4   byte                    0x34            GLBQ (Global Parameter Parameter Inquiry)
+>>>4   byte                    0x05            EFXR (FX Parameter Request)
+>>>4   byte                    0x15            EFXD (FX Parameter Dump)
+>>>4   byte                    0x25            EFXP (FX Parameter Parameter Change)
+>>>4   byte                    0x35            EFXQ (FX Parameter Parameter Inquiry)
+>>>4   byte                    0x07            MODR (Mode Command Request)
+>>>4   byte                    0x17            MODD (Mode Command Dump)
+>>>4   byte                    0x27            MODP (Mode Command Parameter Change)
+>>>4   byte                    0x37            MODQ (Mode Command Parameter Inquiry)
+>>2    byte                    0x03            Wave
+>>>4   byte                    0x00            SBPR (Soundprogram)
+>>>4   byte                    0x01            SAPR (Performance)
+>>>4   byte                    0x02            SWAVE (Wave)
+>>>4   byte                    0x03            SWTBL (Wave control table)
+>>>4   byte                    0x04            SVT (Velocity Curve)
+>>>4   byte                    0x05            STT (Tuning Table)
+>>>4   byte                    0x06            SGLB (Global Parameters)
+>>>4   byte                    0x07            SARRMAP (Performance Program Change Map)
+>>>4   byte                    0x08            SBPRMAP (Sound Program Change Map)
+>>>4   byte                    0x09            SBPRPAR (Sound Parameter)
+>>>4   byte                    0x0A            SARRPAR (Performance Parameter)
+>>>4   byte                    0x0B            SINSPAR (Instrument/External Parameter)
+>>>4   byte                    0x0F            SBULK (Bulk Switch on/off)
+
+# Japanese Group
+>1     byte                    0x40            Kawai
+>>3    byte                    0x20            K1
+>>3    byte                    0x22            K4
+
+>1     byte                    0x41            Roland
+>>3    byte                    0x14            D-50
+>>3    byte                    0x2b            U-220
+>>3    byte                    0x02            TR-707
+
+>1     byte                    0x42            Korg
+>>3    byte                    0x19            M1
+
+>1     byte                    0x43            Yamaha
+>1     byte                    0x44            Casio
+>1     byte                    0x46            Kamiya
+>1     byte                    0x47            Akai
+>1     byte                    0x48            Victor
+>1     byte                    0x49            Mesosha
+>1     byte                    0x4b            Fujitsu
+>1     byte                    0x4c            Sony
+>1     byte                    0x4e            Teac
+>1     byte                    0x50            Matsushita
+>1     byte                    0x51            Fostex
+>1     byte                    0x52            Zoom
+>1     byte                    0x54            Matsushita
+>1     byte                    0x57            Acoustic tech. lab.
+# https://www.midi.org/techspecs/manid.php
+>1     belong&0xffffff00       0x00007400      Ta Horng
+>1     belong&0xffffff00       0x00007500      e-Tek
+>1     belong&0xffffff00       0x00007600      E-Voice
+>1     belong&0xffffff00       0x00007700      Midisoft
+>1     belong&0xffffff00       0x00007800      Q-Sound
+>1     belong&0xffffff00       0x00007900      Westrex
+>1     belong&0xffffff00       0x00007a00      Nvidia*
+>1     belong&0xffffff00       0x00007b00      ESS
+>1     belong&0xffffff00       0x00007c00      Mediatrix
+>1     belong&0xffffff00       0x00007d00      Brooktree
+>1     belong&0xffffff00       0x00007e00      Otari
+>1     belong&0xffffff00       0x00007f00      Key Electronics
+>1     belong&0xffffff00       0x00010000      Shure
+>1     belong&0xffffff00       0x00010100      AuraSound
+>1     belong&0xffffff00       0x00010200      Crystal
+>1     belong&0xffffff00       0x00010300      Rockwell
+>1     belong&0xffffff00       0x00010400      Silicon Graphics
+>1     belong&0xffffff00       0x00010500      Midiman
+>1     belong&0xffffff00       0x00010600      PreSonus
+>1     belong&0xffffff00       0x00010800      Topaz
+>1     belong&0xffffff00       0x00010900      Cast Lightning
+>1     belong&0xffffff00       0x00010a00      Microsoft
+>1     belong&0xffffff00       0x00010b00      Sonic Foundry
+>1     belong&0xffffff00       0x00010c00      Line 6
+>1     belong&0xffffff00       0x00010d00      Beatnik Inc.
+>1     belong&0xffffff00       0x00010e00      Van Koerving
+>1     belong&0xffffff00       0x00010f00      Altech Systems
+>1     belong&0xffffff00       0x00011000      S & S Research
+>1     belong&0xffffff00       0x00011100      VLSI Technology
+>1     belong&0xffffff00       0x00011200      Chromatic
+>1     belong&0xffffff00       0x00011300      Sapphire
+>1     belong&0xffffff00       0x00011400      IDRC
+>1     belong&0xffffff00       0x00011500      Justonic Tuning
+>1     belong&0xffffff00       0x00011600      TorComp
+>1     belong&0xffffff00       0x00011700      Newtek Inc.
+>1     belong&0xffffff00       0x00011800      Sound Sculpture
+>1     belong&0xffffff00       0x00011900      Walker Technical
+>1     belong&0xffffff00       0x00011a00      Digital Harmony
+>1     belong&0xffffff00       0x00011b00      InVision
+>1     belong&0xffffff00       0x00011c00      T-Square
+>1     belong&0xffffff00       0x00011d00      Nemesys
+>1     belong&0xffffff00       0x00011e00      DBX
+>1     belong&0xffffff00       0x00011f00      Syndyne
+>1     belong&0xffffff00       0x00012000      Bitheadz
+>1     belong&0xffffff00       0x00012100      Cakewalk
+>1     belong&0xffffff00       0x00012200      Staccato
+>1     belong&0xffffff00       0x00012300      National Semicon.
+>1     belong&0xffffff00       0x00012400      Boom Theory
+>1     belong&0xffffff00       0x00012500      Virtual DSP Corp
+>1     belong&0xffffff00       0x00012600      Antares
+>1     belong&0xffffff00       0x00012700      Angel Software
+>1     belong&0xffffff00       0x00012800      St Louis Music
+>1     belong&0xffffff00       0x00012900      Lyrrus dba G-VOX
+>1     belong&0xffffff00       0x00012a00      Ashley Audio
+>1     belong&0xffffff00       0x00012b00      Vari-Lite
+>1     belong&0xffffff00       0x00012c00      Summit Audio
+>1     belong&0xffffff00       0x00012d00      Aureal Semicon.
+>1     belong&0xffffff00       0x00012e00      SeaSound
+>1     belong&0xffffff00       0x00012f00      U.S. Robotics
+>1     belong&0xffffff00       0x00013000      Aurisis
+>1     belong&0xffffff00       0x00013100      Nearfield Multimedia
+>1     belong&0xffffff00       0x00013200      FM7 Inc.
+>1     belong&0xffffff00       0x00013300      Swivel Systems
+>1     belong&0xffffff00       0x00013400      Hyperactive
+>1     belong&0xffffff00       0x00013500      MidiLite
+>1     belong&0xffffff00       0x00013600      Radical
+>1     belong&0xffffff00       0x00013700      Roger Linn
+>1     belong&0xffffff00       0x00013800      Helicon
+>1     belong&0xffffff00       0x00013900      Event
+>1     belong&0xffffff00       0x00013a00      Sonic Network
+>1     belong&0xffffff00       0x00013b00      Realtime Music
+>1     belong&0xffffff00       0x00013c00      Apogee Digital
+
+>1     belong&0xffffff00       0x00202b00      Medeli Electronics
+>1     belong&0xffffff00       0x00202c00      Charlie Lab
+>1     belong&0xffffff00       0x00202d00      Blue Chip Music
+>1     belong&0xffffff00       0x00202e00      BEE OH Corp
+>1     belong&0xffffff00       0x00202f00      LG Semicon America
+>1     belong&0xffffff00       0x00203000      TESI
+>1     belong&0xffffff00       0x00203100      EMAGIC
+>1     belong&0xffffff00       0x00203200      Behringer
+>1     belong&0xffffff00       0x00203300      Access Music
+>1     belong&0xffffff00       0x00203400      Synoptic
+>1     belong&0xffffff00       0x00203500      Hanmesoft Corp
+>1     belong&0xffffff00       0x00203600      Terratec
+>1     belong&0xffffff00       0x00203700      Proel SpA
+>1     belong&0xffffff00       0x00203800      IBK MIDI
+>1     belong&0xffffff00       0x00203900      IRCAM
+>1     belong&0xffffff00       0x00203a00      Propellerhead Software
+>1     belong&0xffffff00       0x00203b00      Red Sound Systems
+>1     belong&0xffffff00       0x00203c00      Electron ESI AB
+>1     belong&0xffffff00       0x00203d00      Sintefex Audio
+>1     belong&0xffffff00       0x00203e00      Music and More
+>1     belong&0xffffff00       0x00203f00      Amsaro
+>1     belong&0xffffff00       0x00204000      CDS Advanced Technology
+>1     belong&0xffffff00       0x00204100      Touched by Sound
+>1     belong&0xffffff00       0x00204200      DSP Arts
+>1     belong&0xffffff00       0x00204300      Phil Rees Music
+>1     belong&0xffffff00       0x00204400      Stamer Musikanlagen GmbH
+>1     belong&0xffffff00       0x00204500      Soundart
+>1     belong&0xffffff00       0x00204600      C-Mexx Software
+>1     belong&0xffffff00       0x00204700      Klavis Tech.
+>1     belong&0xffffff00       0x00204800      Noteheads AB
+
+0      string                  T707            Roland TR-707 Data
diff --git a/magic/Magdir/tcl b/magic/Magdir/tcl
new file mode 100644 (file)
index 0000000..edc3ec4
--- /dev/null
@@ -0,0 +1,29 @@
+#------------------------------------------------------------------------------
+# file:  file(1) magic for Tcl scripting language
+# URL:  https://www.tcl.tk/
+# From: gustaf neumann
+
+# Tcl scripts
+0      search/1/w      #!\ /usr/bin/tcl        Tcl script text executable
+!:mime text/x-tcl
+0      search/1/w      #!\ /usr/local/bin/tcl  Tcl script text executable
+!:mime text/x-tcl
+0      search/1        #!/usr/bin/env\ tcl     Tcl script text executable
+!:mime text/x-tcl
+0      search/1        #!\ /usr/bin/env\ tcl   Tcl script text executable
+!:mime text/x-tcl
+0      search/1/w      #!\ /usr/bin/wish       Tcl/Tk script text executable
+!:mime text/x-tcl
+0      search/1/w      #!\ /usr/local/bin/wish Tcl/Tk script text executable
+!:mime text/x-tcl
+0      search/1        #!/usr/bin/env\ wish    Tcl/Tk script text executable
+!:mime text/x-tcl
+0      search/1        #!\ /usr/bin/env\ wish  Tcl/Tk script text executable
+!:mime text/x-tcl
+
+# check the first line
+0      search/1        package\ req
+>0     regex           \^package[\ \t]+req     Tcl script
+# not 'p', check other lines
+0      search/1        !p
+>0     regex           \^package[\ \t]+req     Tcl script
diff --git a/magic/Magdir/teapot b/magic/Magdir/teapot
new file mode 100644 (file)
index 0000000..cde0a1f
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# teapot:  file(1) magic for "teapot" spreadsheet
+#
+0       string          #!teapot\012xdr      teapot work sheet (XDR format)
diff --git a/magic/Magdir/terminfo b/magic/Magdir/terminfo
new file mode 100644 (file)
index 0000000..fc3bf74
--- /dev/null
@@ -0,0 +1,62 @@
+
+#------------------------------------------------------------------------------
+# $File: terminfo,v 1.11 2019/04/19 00:42:27 christos Exp $
+# terminfo:  file(1) magic for terminfo
+#
+# URL: https://invisible-island.net/ncurses/man/term.5.html
+# URL: https://invisible-island.net/ncurses/man/scr_dump.5.html
+#
+# Workaround for Targa image type by Joerg Jenderek
+# GRR: line below too general as it catches also
+# Targa image type 1 with 26 long identification field
+# and HELP.DSK
+0      string          \032\001
+# 5th character of terminal name list, but not Targa image pixel size (15 16 24 32)
+>16    ubyte           >32
+# namelist, if more than 1 separated by "|" like "st|stterm| simpleterm 0.4.1"
+>>12   regex           \^[a-zA-Z0-9][a-zA-Z0-9.][^|]*  Compiled terminfo entry "%-s"
+!:mime application/x-terminfo
+# no extension
+#!:ext
+#
+#------------------------------------------------------------------------------
+# The following was added for ncurses6 development:
+#------------------------------------------------------------------------------
+#
+0      string          \036\002
+# imitate the legacy compiled-format, to get the entry-name printed
+>16    ubyte           >32
+# namelist, if more than 1 separated by "|" like "st|stterm| simpleterm 0. 4.1"
+>>12   regex           \^[a-zA-Z0-9][a-zA-Z0-9.][^|]*  Compiled 32-bit terminfo entry "%-s"
+!:mime application/x-terminfo2
+#
+# While the compiled terminfo uses little-endian format irregardless of
+# platform, SystemV screen dumps do not.  They came later, and that detail was
+# overlooked.
+#
+# AIX and HPUX use the SVr4 big-endian format
+# Solaris uses the SVr3 formats (sparc and x86 differ endian-ness)
+0      beshort         0433            SVr2 curses screen image, big-endian
+0      beshort         0434            SVr3 curses screen image, big-endian
+0      beshort         0435            SVr4 curses screen image, big-endian
+#
+0      leshort         0433            SVr2 curses screen image, little-endian
+0      leshort         0434            SVr3 curses screen image, little-endian
+0      leshort         0435            SVr4 curses screen image, little-endian
+#
+# Rather than SVr4, Solaris "xcurses" writes this header:
+0      regex           \^MAX=[0-9]+,[0-9]+$
+>1     regex           \^BEG=[0-9]+,[0-9]+$
+>2     regex           \^SCROLL=[0-9]+,[0-9]+$
+>3     regex           \^VMIN=[0-9]+$
+>4     regex           \^VTIME=[0-9]+$
+>5     regex           \^FLAGS=0x[[:xdigit:]]+$
+>6     regex           \^FG=[0-9],[0-9]+$
+>7     regex           \^BG=[0-9]+,[0-9]+,     Solaris xcurses screen image
+#
+# ncurses5 (and before) did not use a magic number, making screen dumps "data".
+# ncurses6 (2015) uses this format, ignoring byte-order
+0      string  \210\210\210\210ncurses ncurses6 screen image
+#
+# PDCurses added this in 2005
+0      string          PDC\001         PDCurses screen image
diff --git a/magic/Magdir/tex b/magic/Magdir/tex
new file mode 100644 (file)
index 0000000..aaeae16
--- /dev/null
@@ -0,0 +1,139 @@
+
+#------------------------------------------------------------------------------
+# $File: tex,v 1.21 2019/04/19 00:42:27 christos Exp $
+# tex:  file(1) magic for TeX files
+#
+# XXX - needs byte-endian stuff (big-endian and little-endian DVI?)
+#
+# From <conklin@talisman.kaleida.com>
+
+# Although we may know the offset of certain text fields in TeX DVI
+# and font files, we can't use them reliably because they are not
+# zero terminated. [but we do anyway, christos]
+0      string          \367\002        TeX DVI file
+!:mime application/x-dvi
+>16    string          >\0             (%s)
+0      string          \367\203        TeX generic font data
+0      string          \367\131        TeX packed font data
+>3     string          >\0             (%s)
+0      string          \367\312        TeX virtual font data
+0      search/1        This\ is\ TeX,  TeX transcript text
+0      search/1        This\ is\ METAFONT,     METAFONT transcript text
+
+# There is no way to detect TeX Font Metric (*.tfm) files without
+# breaking them apart and reading the data.  The following patterns
+# match most *.tfm files generated by METAFONT or afm2tfm.
+2      string          \000\021        TeX font metric data
+!:mime application/x-tex-tfm
+>33    string          >\0             (%s)
+2      string          \000\022        TeX font metric data
+!:mime application/x-tex-tfm
+>33    string          >\0             (%s)
+
+# Texinfo and GNU Info, from Daniel Quinlan (quinlan@yggdrasil.com)
+0      search/1        \\input\ texinfo        Texinfo source text
+!:mime text/x-texinfo
+0      search/1        This\ is\ Info\ file    GNU Info text
+!:mime text/x-info
+
+# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
+0      search/4096     \\input         TeX document text
+!:mime text/x-tex
+!:strength + 15
+0      search/4096     \\begin         LaTeX document text
+!:mime text/x-tex
+!:strength + 15
+0      search/4096     \\section       LaTeX document text
+!:mime text/x-tex
+!:strength + 18
+0      search/4096     \\setlength     LaTeX document text
+!:mime text/x-tex
+!:strength + 15
+0      search/4096     \\documentstyle LaTeX document text
+!:mime text/x-tex
+!:strength + 18
+0      search/4096     \\chapter       LaTeX document text
+!:mime text/x-tex
+!:strength + 18
+0      search/4096     \\documentclass LaTeX 2e document text
+!:mime text/x-tex
+!:strength + 15
+0      search/4096     \\relax         LaTeX auxiliary file
+!:mime text/x-tex
+!:strength + 15
+0      search/4096     \\contentsline  LaTeX table of contents
+!:mime text/x-tex
+!:strength + 15
+0      search/4096     %\ -*-latex-*-  LaTeX document text
+!:mime text/x-tex
+
+# Tex document, from Hendrik Scholz <hendrik@scholz.net>
+0      search/1        \\ifx           TeX document text
+
+# Index and glossary files
+0      search/4096     \\indexentry    LaTeX raw index file
+0      search/4096     \\begin{theindex}       LaTeX sorted index
+0      search/4096     \\glossaryentry LaTeX raw glossary
+0      search/4096     \\begin{theglossary}    LaTeX sorted glossary
+0      search/4096     This\ is\ makeindex     Makeindex log file
+
+# End of TeX
+
+#------------------------------------------------------------------------------
+# file(1) magic for BibTex text files
+# From Hendrik Scholz <hendrik@scholz.net>
+
+0      search/1/c      @article{       BibTeX text file
+0      search/1/c      @book{          BibTeX text file
+0      search/1/c      @inbook{        BibTeX text file
+0      search/1/c      @incollection{  BibTeX text file
+0      search/1/c      @inproceedings{ BibTeX text file
+0      search/1/c      @manual{        BibTeX text file
+0      search/1/c      @misc{          BibTeX text file
+0      search/1/c      @preamble{      BibTeX text file
+0      search/1/c      @phdthesis{     BibTeX text file
+0      search/1/c      @techreport{    BibTeX text file
+0      search/1/c      @unpublished{   BibTeX text file
+
+73     search/1        %%%\ \          BibTeX-file{ BibTex text file (with full header)
+
+73     search/1        %%%\ \ @BibTeX-style-file{   BibTeX style text file (with full header)
+
+0      search/1        %\ BibTeX\ standard\ bibliography\      BibTeX standard bibliography style text file
+
+0      search/1        %\ BibTeX\ `    BibTeX custom bibliography style text file
+
+0      search/1        @c\ @mapfile{   TeX font aliases text file
+
+0      string          #LyX            LyX document text
+
+# ConTeXt documents
+#      https://wiki.contextgarden.net/
+0      search/4096     \\setupcolors[          ConTeXt document text
+!:strength + 15
+0      search/4096     \\definecolor[          ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupinteraction[     ConTeXt document text
+!:strength + 15
+0      search/4096     \\useURL[               ConTeXt document text
+!:strength + 15
+0      search/4096     \\setuppapersize[       ConTeXt document text
+!:strength + 15
+0      search/4096     \\setuplayout[          ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupfooter[          ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupfootertexts[     ConTeXt document text
+!:strength + 15
+0      search/4096     \\setuppagenumbering[   ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupbodyfont[        ConTeXt document text
+!:strength + 15
+0      search/4096     \\setuphead[            ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupitemize[         ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupwhitespace[      ConTeXt document text
+!:strength + 15
+0      search/4096     \\setupindenting[       ConTeXt document text
+!:strength + 15
diff --git a/magic/Magdir/tgif b/magic/Magdir/tgif
new file mode 100644 (file)
index 0000000..1548609
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File: tgif,v 1.6 2010/09/20 18:55:20 rrt Exp $
+# file(1) magic for tgif(1) files
+# From Hendrik Scholz <hendrik@scholz.net>
+0      string  %TGIF\                  Tgif file version
+>6     string  x                       %s
diff --git a/magic/Magdir/ti-8x b/magic/Magdir/ti-8x
new file mode 100644 (file)
index 0000000..a858882
--- /dev/null
@@ -0,0 +1,239 @@
+
+#------------------------------------------------------------------------------
+# $File: ti-8x,v 1.6 2009/09/19 16:28:12 christos Exp $
+# ti-8x: file(1) magic for the TI-8x and TI-9x Graphing Calculators.
+#
+# From: Ryan McGuire (rmcguire@freenet.columbus.oh.us).
+#
+# Update: Romain Lievin (roms@lpg.ticalc.org).
+#
+# NOTE: This list is not complete.
+# Files for the TI-80 and TI-81 are pretty rare. I'm not going to put the
+# program/group magic numbers in here because I cannot find any.
+0              string          **TI80**        TI-80 Graphing Calculator File.
+0              string          **TI81**        TI-81 Graphing Calculator File.
+#
+# Magic Numbers for the TI-73
+#
+0              string          **TI73**        TI-73 Graphing Calculator
+>0x00003B      byte            0x00            (real number)
+>0x00003B      byte            0x01            (list)
+>0x00003B      byte            0x02            (matrix)
+>0x00003B      byte            0x03            (equation)
+>0x00003B      byte            0x04            (string)
+>0x00003B      byte            0x05            (program)
+>0x00003B      byte            0x06            (assembly program)
+>0x00003B      byte            0x07            (picture)
+>0x00003B      byte            0x08            (gdb)
+>0x00003B      byte            0x0C            (complex number)
+>0x00003B      byte            0x0F            (window settings)
+>0x00003B      byte            0x10            (zoom)
+>0x00003B      byte            0x11            (table setup)
+>0x00003B      byte            0x13            (backup)
+
+# Magic Numbers for the TI-82
+#
+0              string          **TI82**        TI-82 Graphing Calculator
+>0x00003B      byte            0x00            (real)
+>0x00003B      byte            0x01            (list)
+>0x00003B      byte            0x02            (matrix)
+>0x00003B      byte            0x03            (Y-variable)
+>0x00003B      byte            0x05            (program)
+>0x00003B      byte            0x06            (protected prgm)
+>0x00003B      byte            0x07            (picture)
+>0x00003B      byte            0x08            (gdb)
+>0x00003B      byte            0x0B            (window settings)
+>0x00003B      byte            0x0C            (window settings)
+>0x00003B      byte            0x0D            (table setup)
+>0x00003B      byte            0x0E            (screenshot)
+>0x00003B      byte            0x0F            (backup)
+#
+# Magic Numbers for the TI-83
+#
+0              string          **TI83**        TI-83 Graphing Calculator
+>0x00003B      byte            0x00            (real)
+>0x00003B      byte            0x01            (list)
+>0x00003B      byte            0x02            (matrix)
+>0x00003B      byte            0x03            (Y-variable)
+>0x00003B      byte            0x04            (string)
+>0x00003B      byte            0x05            (program)
+>0x00003B      byte            0x06            (protected prgm)
+>0x00003B      byte            0x07            (picture)
+>0x00003B      byte            0x08            (gdb)
+>0x00003B      byte            0x0B            (window settings)
+>0x00003B      byte            0x0C            (window settings)
+>0x00003B      byte            0x0D            (table setup)
+>0x00003B      byte            0x0E            (screenshot)
+>0x00003B      byte            0x13            (backup)
+#
+# Magic Numbers for the TI-83+
+#
+0              string          **TI83F*        TI-83+ Graphing Calculator
+>0x00003B      byte            0x00            (real number)
+>0x00003B      byte            0x01            (list)
+>0x00003B      byte            0x02            (matrix)
+>0x00003B      byte            0x03            (equation)
+>0x00003B      byte            0x04            (string)
+>0x00003B      byte            0x05            (program)
+>0x00003B      byte            0x06            (assembly program)
+>0x00003B      byte            0x07            (picture)
+>0x00003B      byte            0x08            (gdb)
+>0x00003B      byte            0x0C            (complex number)
+>0x00003B      byte            0x0F            (window settings)
+>0x00003B      byte            0x10            (zoom)
+>0x00003B      byte            0x11            (table setup)
+>0x00003B      byte            0x13            (backup)
+>0x00003B      byte            0x15            (application variable)
+>0x00003B      byte            0x17            (group of variable)
+
+#
+# Magic Numbers for the TI-85
+#
+0              string          **TI85**        TI-85 Graphing Calculator
+>0x00003B      byte            0x00            (real number)
+>0x00003B      byte            0x01            (complex number)
+>0x00003B      byte            0x02            (real vector)
+>0x00003B      byte            0x03            (complex vector)
+>0x00003B      byte            0x04            (real list)
+>0x00003B      byte            0x05            (complex list)
+>0x00003B      byte            0x06            (real matrix)
+>0x00003B      byte            0x07            (complex matrix)
+>0x00003B      byte            0x08            (real constant)
+>0x00003B      byte            0x09            (complex constant)
+>0x00003B      byte            0x0A            (equation)
+>0x00003B      byte            0x0C            (string)
+>0x00003B      byte            0x0D            (function GDB)
+>0x00003B      byte            0x0E            (polar GDB)
+>0x00003B      byte            0x0F            (parametric GDB)
+>0x00003B      byte            0x10            (diffeq GDB)
+>0x00003B      byte            0x11            (picture)
+>0x00003B      byte            0x12            (program)
+>0x00003B      byte            0x13            (range)
+>0x00003B      byte            0x17            (window settings)
+>0x00003B      byte            0x18            (window settings)
+>0x00003B      byte            0x19            (window settings)
+>0x00003B      byte            0x1A            (window settings)
+>0x00003B      byte            0x1B            (zoom)
+>0x00003B      byte            0x1D            (backup)
+>0x00003B      byte            0x1E            (unknown)
+>0x00003B      byte            0x2A            (equation)
+>0x000032      string          ZS4             - ZShell Version 4 File.
+>0x000032      string          ZS3             - ZShell Version 3 File.
+#
+# Magic Numbers for the TI-86
+#
+0              string          **TI86**        TI-86 Graphing Calculator
+>0x00003B      byte            0x00            (real number)
+>0x00003B      byte            0x01            (complex number)
+>0x00003B      byte            0x02            (real vector)
+>0x00003B      byte            0x03            (complex vector)
+>0x00003B      byte            0x04            (real list)
+>0x00003B      byte            0x05            (complex list)
+>0x00003B      byte            0x06            (real matrix)
+>0x00003B      byte            0x07            (complex matrix)
+>0x00003B      byte            0x08            (real constant)
+>0x00003B      byte            0x09            (complex constant)
+>0x00003B      byte            0x0A            (equation)
+>0x00003B      byte            0x0C            (string)
+>0x00003B      byte            0x0D            (function GDB)
+>0x00003B      byte            0x0E            (polar GDB)
+>0x00003B      byte            0x0F            (parametric GDB)
+>0x00003B      byte            0x10            (diffeq GDB)
+>0x00003B      byte            0x11            (picture)
+>0x00003B      byte            0x12            (program)
+>0x00003B      byte            0x13            (range)
+>0x00003B      byte            0x17            (window settings)
+>0x00003B      byte            0x18            (window settings)
+>0x00003B      byte            0x19            (window settings)
+>0x00003B      byte            0x1A            (window settings)
+>0x00003B      byte            0x1B            (zoom)
+>0x00003B      byte            0x1D            (backup)
+>0x00003B      byte            0x1E            (unknown)
+>0x00003B      byte            0x2A            (equation)
+#
+# Magic Numbers for the TI-89
+#
+0              string          **TI89**        TI-89 Graphing Calculator
+>0x000048      byte            0x00            (expression)
+>0x000048      byte            0x04            (list)
+>0x000048      byte            0x06            (matrix)
+>0x000048      byte            0x0A            (data)
+>0x000048      byte            0x0B            (text)
+>0x000048      byte            0x0C            (string)
+>0x000048      byte            0x0D            (graphic data base)
+>0x000048      byte            0x0E            (figure)
+>0x000048      byte            0x10            (picture)
+>0x000048      byte            0x12            (program)
+>0x000048      byte            0x13            (function)
+>0x000048      byte            0x14            (macro)
+>0x000048      byte            0x1C            (zipped)
+>0x000048      byte            0x21            (assembler)
+#
+# Magic Numbers for the TI-92
+#
+0              string          **TI92**        TI-92 Graphing Calculator
+>0x000048      byte            0x00            (expression)
+>0x000048      byte            0x04            (list)
+>0x000048      byte            0x06            (matrix)
+>0x000048      byte            0x0A            (data)
+>0x000048      byte            0x0B            (text)
+>0x000048      byte            0x0C            (string)
+>0x000048      byte            0x0D            (graphic data base)
+>0x000048      byte            0x0E            (figure)
+>0x000048      byte            0x10            (picture)
+>0x000048      byte            0x12            (program)
+>0x000048      byte            0x13            (function)
+>0x000048      byte            0x14            (macro)
+>0x000048      byte            0x1D            (backup)
+#
+# Magic Numbers for the TI-92+/V200
+#
+0              string          **TI92P*        TI-92+/V200 Graphing Calculator
+>0x000048      byte            0x00            (expression)
+>0x000048      byte            0x04            (list)
+>0x000048      byte            0x06            (matrix)
+>0x000048      byte            0x0A            (data)
+>0x000048      byte            0x0B            (text)
+>0x000048      byte            0x0C            (string)
+>0x000048      byte            0x0D            (graphic data base)
+>0x000048      byte            0x0E            (figure)
+>0x000048      byte            0x10            (picture)
+>0x000048      byte            0x12            (program)
+>0x000048      byte            0x13            (function)
+>0x000048      byte            0x14            (macro)
+>0x000048      byte            0x1C            (zipped)
+>0x000048      byte            0x21            (assembler)
+#
+# Magic Numbers for the TI-73/83+/89/92+/V200 FLASH upgrades
+#
+0x0000016      string          Advanced        TI-XX Graphing Calculator (FLASH)
+0              string          **TIFL**        TI-XX Graphing Calculator (FLASH)
+>8             byte            >0              - Revision %d
+>>9            byte            x               \b.%d,
+>12            byte            >0              Revision date %02x
+>>13           byte            x               \b/%02x
+>>14           beshort         x               \b/%04x,
+>17            string          >/0             name: '%s',
+>48            byte            0x74            device: TI-73,
+>48            byte            0x73            device: TI-83+,
+>48            byte            0x98            device: TI-89,
+>48            byte            0x88            device: TI-92+,
+>49            byte            0x23            type: OS upgrade,
+>49            byte            0x24            type: application,
+>49            byte            0x25            type: certificate,
+>49            byte            0x3e            type: license,
+>74            lelong          >0              size: %d bytes
+
+# VTi & TiEmu skins (TI Graphing Calculators).
+# From: Romain Lievin (roms@lpg.ticalc.org).
+# Magic Numbers for the VTi skins
+0               string          VTI            Virtual TI skin
+>3             string          v               - Version
+>>4            byte            >0              \b %c
+>>6            byte            x               \b.%c
+# Magic Numbers for the TiEmu skins
+0              string          TiEmu           TiEmu skin
+>6              string          v               - Version
+>>7             byte            >0              \b %c
+>>9             byte            x               \b.%c
+>>10           byte            x               \b%c
diff --git a/magic/Magdir/timezone b/magic/Magdir/timezone
new file mode 100644 (file)
index 0000000..8566d0e
--- /dev/null
@@ -0,0 +1,32 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# timezone:  file(1) magic for timezone data
+#
+# from Daniel Quinlan (quinlan@yggdrasil.com)
+# this should work on Linux, SunOS, and maybe others
+# Added new official magic number for recent versions of the Olson code
+0      string  TZif    timezone data
+>4     byte    0       \b, old version
+>4     byte    >0      \b, version %c
+>20    belong  0       \b, no gmt time flags
+>20    belong  1       \b, 1 gmt time flag
+>20    belong  >1      \b, %d gmt time flags
+>24    belong  0       \b, no std time flags
+>20    belong  1       \b, 1 std time flag
+>24    belong  >1      \b, %d std time flags
+>28    belong  0       \b, no leap seconds
+>28    belong  1       \b, 1 leap second
+>28    belong  >1      \b, %d leap seconds
+>32    belong  0       \b, no transition times
+>32    belong  1       \b, 1 transition time
+>32    belong  >1      \b, %d transition times
+>36    belong  0       \b, no abbreviation chars
+>36    belong  1       \b, 1 abbreviation char
+>36    belong  >1      \b, %d abbreviation chars
+0      string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0      old timezone data
+0      string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\0      old timezone data
+0      string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0      old timezone data
+0      string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0      old timezone data
+0      string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0      old timezone data
+0      string  \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\0      old timezone data
diff --git a/magic/Magdir/tplink b/magic/Magdir/tplink
new file mode 100644 (file)
index 0000000..6ba6822
--- /dev/null
@@ -0,0 +1,86 @@
+
+#------------------------------------------------------------------------------
+# $File: tplink,v 1.4 2019/04/19 00:42:27 christos Exp $
+# tplink: File magic for openwrt firmware files
+
+# URL: https://wiki.openwrt.org/doc/techref/header
+# Reference: https://git.openwrt.org/?p=openwrt.git;a=blob;f=tools/firmware-utils/src/mktplinkfw.c
+# From: Joerg Jenderek
+# check for valid header version 1 or 2
+0              ulelong         <3
+>0             ulelong         !0
+# test for header padding with nulls
+>>0x100                long            0
+# skip Norton Commander Cleanup Utility NCCLEAN.INI by looking for valid vendor
+>>>4           ubelong         >0x1F000000
+>>>>0          use             firmware-tplink
+
+0              name            firmware-tplink
+>0             ubyte           x               firmware
+!:mime application/x-tplink-bin
+!:ext  bin
+# hardware id like 10430001 07410001 09410004 09410006
+>0x40          ubeshort        x               %x
+>0x42          ubeshort        x               v%x
+# hardware revision like 1
+>0x44          ubelong         !1              (revision %u)
+# vendor_name[24] like OpenWrt or TP-LINK Technologies
+>4             string          x               %.24s
+# fw_version[36] like r49389 or ver. 1.0
+>0x1c          string          x               %.36s
+# header version 1 or 2
+>0             ubyte           !1              V%X
+# ver_hi.ver_mid.ver_lo
+>0x98          long            !0              \b, version
+>>0x98         ubeshort        x               %u
+>>0x9A         ubeshort        x               \b.%u
+>>0x9C         ubeshort        x               \b.%u
+# region code 0~universal 1~US
+>0x48          ubelong         x
+#>>0x48                ubelong         0               (universal)
+>>0x48         ubelong         1               (US)
+>>0x48         ubelong         >1              (region %u)
+# total length of the firmware. not always true
+>0x7C          ubelong         x               \b, %u bytes or less
+# unknown 1
+>0x48          ubelong         !0              \b, UNKNOWN1 0x%x
+# md5sum1[16]
+#>0x4c         ubequad         x               \b, MD5 %llx
+#>>0x54                ubequad         x               \b%llx
+# unknown 2
+>0x5c          ubelong         !0              \b, UNKNOWN2 0x%x
+# md5sum2[16]
+#>0x60         ubequad         !0              \b, 2nd MD5 %llx
+#>>0x68                ubequad         x               \b%llx
+# unknown 3
+>0x70          ubelong         !0              \b, UNKNOWN3 0x%x
+# kernel load address
+#>0x74         ubelong         x               \b, 0x%x load
+# kernel entry point
+#>0x78         ubelong         x               \b, 0x%x entry
+# kernel data offset. 200h means direct after header
+>0x80          ubelong         x               \b, at 0x%x
+# kernel data length and 1 space
+>0x84          ubelong         x               %u bytes 
+# look for kernel type (gzip compressed vmlinux.bin by ./compress)
+>(0x80.L)      indirect        x
+# root file system data offset
+# WRONG in 5.35 with above indirect expression
+>0x88          ubelong         x               \b, at 0x%x
+# rootfs data length and 1 space
+>0x8C          ubelong         x               %u bytes 
+# in 5.32 only true for offset ~< FILE_BYTES_MAX=9 MB defined in ../../src/file.h 
+>(0x88.L)      indirect        x
+# 'qshs' for wr940nv1_en_3_13_7_up(111228).bin
+#>(0x88.L)     string          x               \b, file system '%.4s'
+#>(0x88.L)     ubequad         x               \b, file system 0x%llx
+# bootloader data offset
+>0x90          ubelong         !0              \b, at 0x%x
+# bootloader data length only resonable if bootloader offset not null
+>>0x94         ubelong         !0              %u bytes
+# pad[354] should be 354 null bytes.
+#>0x9E         ubequad         !0              \b, padding 0x%llx
+# But at 0x120 18 non null bytes in examples like
+# wr940nv4_eu_3_16_9_up_boot(160620).bin
+# wr940nv6_us_3_18_1_up_boot(171030).bin
+#>0x120                ubequad         !0              \b, other padding 0x%llx
diff --git a/magic/Magdir/troff b/magic/Magdir/troff
new file mode 100644 (file)
index 0000000..be477c4
--- /dev/null
@@ -0,0 +1,38 @@
+
+#------------------------------------------------------------------------------
+# $File: troff,v 1.10 2009/09/19 16:28:12 christos Exp $
+# troff:  file(1) magic for *roff
+#
+# updated by Daniel Quinlan (quinlan@yggdrasil.com)
+
+# troff input
+0      search/1        .\\"            troff or preprocessor input text
+!:mime text/troff
+0      search/1        '\\"            troff or preprocessor input text
+!:mime text/troff
+0      search/1        '.\\"           troff or preprocessor input text
+!:mime text/troff
+0      search/1        \\"             troff or preprocessor input text
+!:mime text/troff
+0      search/1        '''             troff or preprocessor input text
+!:mime text/troff
+0      regex/20l       \^\\.[A-Za-z0-9][A-Za-z0-9][\ \t]       troff or preprocessor input text
+!:mime text/troff
+0      regex/20l       \^\\.[A-Za-z0-9][A-Za-z0-9]$    troff or preprocessor input text
+!:mime text/troff
+
+# ditroff intermediate output text
+0      search/1        x\ T            ditroff output text
+>4     search/1        cat             for the C/A/T phototypesetter
+>4     search/1        ps              for PostScript
+>4     search/1        dvi             for DVI
+>4     search/1        ascii           for ASCII
+>4     search/1        lj4             for LaserJet 4
+>4     search/1        latin1          for ISO 8859-1 (Latin 1)
+>4     search/1        X75             for xditview at 75dpi
+>>7    search/1        -12             (12pt)
+>4     search/1        X100            for xditview at 100dpi
+>>8    search/1        -12             (12pt)
+
+# output data formats
+0      string          \100\357        very old (C/A/T) troff output data
diff --git a/magic/Magdir/tuxedo b/magic/Magdir/tuxedo
new file mode 100644 (file)
index 0000000..5386abf
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# tuxedo:      file(1) magic for BEA TUXEDO data files
+#
+# from Ian Springer <ispringer@hotmail.com>
+#
+0      string          \0\0\1\236\0\0\0\0\0\0\0\0\0\0\0\0      BEA TUXEDO DES mask data
diff --git a/magic/Magdir/typeset b/magic/Magdir/typeset
new file mode 100644 (file)
index 0000000..d1b6a54
--- /dev/null
@@ -0,0 +1,8 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# typeset:  file(1) magic for other typesetting
+#
+0      string          Interpress/Xerox        Xerox InterPress data
+>16    string          /                       (version
+>>17   string          >\0                     %s)
diff --git a/magic/Magdir/unicode b/magic/Magdir/unicode
new file mode 100644 (file)
index 0000000..7ca61ba
--- /dev/null
@@ -0,0 +1,15 @@
+
+#------------------------------------------------------------------------------
+# $File: unicode,v 1.7 2019/02/19 20:34:42 christos Exp $
+# Unicode:  BOM prefixed text files - Adrian Havill <havill@turbolinux.co.jp>
+# These types are recognised in file_ascmagic so these encodings can be
+# treated by text patterns.  Missing types are already dealt with internally.
+#
+0      string  +/v8                    Unicode text, UTF-7
+0      string  +/v9                    Unicode text, UTF-7
+0      string  +/v+                    Unicode text, UTF-7
+0      string  +/v/                    Unicode text, UTF-7
+0      string  \335\163\146\163        Unicode text, UTF-8-EBCDIC
+0      string  \000\000\376\377        Unicode text, UTF-32, big-endian
+0      string  \377\376\000\000        Unicode text, UTF-32, little-endian
+0      string  \016\376\377            Unicode text, SCSU (Standard Compression Scheme for Unicode)
diff --git a/magic/Magdir/unknown b/magic/Magdir/unknown
new file mode 100644 (file)
index 0000000..bac7a6e
--- /dev/null
@@ -0,0 +1,34 @@
+
+#------------------------------------------------------------------------------
+# $File: unknown,v 1.7 2009/09/19 16:28:13 christos Exp $
+# unknown:  file(1) magic for unknown machines
+#
+# 0x107 is 0407, 0x108 is 0410, and 0x109 is 0411; those are all PDP-11
+# (executable, pure, and split I&D, respectively), but the PDP-11 version
+# doesn't have the "version %ld", which may be a bogus COFFism (I don't
+# think there was ever COFF for the PDP-11).
+#
+# 0x10B is 0413; that's VAX demand-paged, but this is a short, not a
+# long, as it would be on a VAX.  In any case, that could collide with
+# VAX demand-paged files, as the magic number is little-endian on those
+# binaries, so the first 16 bits of the file would contain 0x10B.
+#
+# Therefore, those entries are commented out.
+#
+# 0x10C is 0414 and 0x10E is 0416; those *are* unknown.
+#
+#0     short           0x107           unknown machine executable
+#>8    short           >0              not stripped
+#>15   byte            >0              - version %ld
+#0     short           0x108           unknown pure executable
+#>8    short           >0              not stripped
+#>15   byte            >0              - version %ld
+#0     short           0x109           PDP-11 separate I&D
+#>8    short           >0              not stripped
+#>15   byte            >0              - version %ld
+#0     short           0x10b           unknown pure executable
+#>8    short           >0              not stripped
+#>15   byte            >0              - version %ld
+0      long            0x10c           unknown demand paged pure executable
+>16    long            >0              not stripped
+0      long            0x10e           unknown readable demand paged pure executable
diff --git a/magic/Magdir/uterus b/magic/Magdir/uterus
new file mode 100644 (file)
index 0000000..95567dd
--- /dev/null
@@ -0,0 +1,16 @@
+
+#------------------------------------------------------------------------------
+# $File: uterus,v 1.2 2014/04/28 12:04:50 christos Exp $
+# file(1) magic for uterus files
+# http://freecode.com/projects/uterus
+#
+0      string          UTE+    uterus file
+>4     string          v       \b, version
+>5     byte            x       %c
+>6     string          .       \b.
+>7     byte            x       \b%c
+>8     string          \<\>    \b, big-endian
+>>16   belong          >0      \b, slut size %u
+>8     string          \>\<    \b, litte-endian
+>>16   lelong          >0      \b, slut size %u
+>10    byte            &8      \b, compressed
diff --git a/magic/Magdir/uuencode b/magic/Magdir/uuencode
new file mode 100644 (file)
index 0000000..471b028
--- /dev/null
@@ -0,0 +1,31 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# uuencode:  file(1) magic for ASCII-encoded files
+#
+
+# GRR:  the first line of xxencoded files is identical to that in uuencoded
+# files, but the first character in most subsequent lines is 'h' instead of
+# 'M'.  (xxencoding uses lowercase letters in place of most of uuencode's
+# punctuation and survives BITNET gateways better.)  If regular expressions
+# were supported, this entry could possibly be split into two with
+# "begin\040\.\*\012M" or "begin\040\.\*\012h" (where \. and \* are REs).
+0      search/1        begin\          uuencoded or xxencoded text
+
+# btoa(1) is an alternative to uuencode that requires less space.
+0      search/1        xbtoa\ Begin    btoa'd text
+
+# ship(1) is another, much cooler alternative to uuencode.
+# Greg Roelofs, newt@uchicago.edu
+0      search/1        $\012ship       ship'd binary text
+
+# bencode(8) is used to encode compressed news batches (Bnews/Cnews only?)
+# Greg Roelofs, newt@uchicago.edu
+0      search/1        Decode\ the\ following\ with\ bdeco     bencoded News text
+
+# BinHex is the Macintosh ASCII-encoded file format (see also "apple")
+# Daniel Quinlan, quinlan@yggdrasil.com
+11     search/1        must\ be\ converted\ with\ BinHex       BinHex binary text
+>41    search/1        x                                       \b, version %.3s
+
+# GRR: handle BASE64
diff --git a/magic/Magdir/vacuum-cleaner b/magic/Magdir/vacuum-cleaner
new file mode 100644 (file)
index 0000000..88e1140
--- /dev/null
@@ -0,0 +1,54 @@
+
+#------------------------------------------------------------------------------
+# $File: vax,v 1.9 2014/04/30 21:41:02 christos Exp $
+# vacuum cleaner magic by Thomas M. Ott (ThMO)
+#
+# navigation map for LG robot vacuum cleaner models VR62xx, VR64xx, VR63xx
+# file: MAPDATAyyyymmddhhmmss_xxxxxx_cc.blk
+# -> yyyymmdd: year, month, day of cleaning
+# -> hhmmss: hour, minute, second of cleaning
+# -> xxxxxx: 6 digits
+# -> cc: cleaning runs counter
+# size: 136044 bytes
+#
+# struct maphdr {
+#     int32_t  map_cnt;             /*  0: single map */
+#     int32_t  min_ceil;     /*  4: 100 mm == 10 cm == min. ceil */
+#     int32_t  max_ceil;     /*  8: 10000 mm == 100 m == max. ceil */
+#     int32_t  max_climb;    /* 12: 50 mm = 5 cm == max. height to climb */
+#     int32_t  unknown;             /* 16: 50000 ??? */
+#     int32_t  cell_bytes;   /* 20: # of bytes for cells per block */
+#     int32_t  block_max;    /* 24: 1000 == max. # of blocks */
+#     int32_t  route_max;    /* 28: 1000 == max. # of routes */
+#     int32_t  used_blocks;  /* 32: 5/45/33/... == # of block entries used! */
+#     int32_t  cell_dim;     /* 36: 10 == cell dimension */
+#     int32_t  clock_tick;   /* 40: 100 == clock ticks */
+# #if  0
+#     struct {              /* 44: 1000 blocks for 10x10 cells */
+#         int32_t  yoffset;
+#         int32_t  xoffset;
+#         int32_t  posxy;
+#         int32_t  timecode;
+#       }      blocks[ 1000];
+#     char     cells[ 1000* 100]; /* 16044: 1000 10x10 cells */
+#     int16_t  routes[ 1000* 10]; /* 116044: 1000 10-routes */
+# #endif
+#   };
+
+0                lelong =1
+>4               lelong =100
+>>8              lelong =10000
+>>>12            lelong =50
+>>>>16           lelong =50000
+>>>>>20          lelong =100
+>>>>>>24         lelong =1000
+>>>>>>>28        lelong =1000
+>>>>>>>>36       lelong =10
+>>>>>>>>>40      lelong =100
+>>>>>>>>>>32     lelong x       LG robot VR6[234]xx %dm^2 navigation
+>>>>>>>>>>136040 lelong =-1     reuse map data
+>>>>>>>>>>136040 lelong =0      map data
+>>>>>>>>>>136040 lelong >0      spurious map data
+>>>>>>>>>>136040 lelong <-1     spurious map data
+
+
diff --git a/magic/Magdir/varied.out b/magic/Magdir/varied.out
new file mode 100644 (file)
index 0000000..00e45a7
--- /dev/null
@@ -0,0 +1,46 @@
+
+#------------------------------------------------------------------------------
+# $File: varied.out,v 1.22 2010/07/02 00:06:27 christos Exp $
+# varied.out:  file(1) magic for various USG systems
+#
+#      Herewith many of the object file formats used by USG systems.
+#      Most have been moved to files for a particular processor,
+#      and deleted if they duplicate other entries.
+#
+0      short           0610            Perkin-Elmer executable
+# AMD 29K
+0      beshort         0572            amd 29k coff noprebar executable
+0      beshort         01572           amd 29k coff prebar executable
+0      beshort         0160007         amd 29k coff archive
+# Cray
+6      beshort         0407            unicos (cray) executable
+# Ultrix 4.3
+596    string          \130\337\377\377        Ultrix core file
+>600   string          >\0             from '%s'
+# BeOS and MAcOS PEF executables
+# From: hplus@zilker.net (Jon Watte)
+0      string          Joy!peffpwpc    header for PowerPC PEF executable
+#
+# ava assembler/linker Uros Platise <uros.platise@ijs.si>
+0       string          avaobj  AVR assembler object code
+>7      string          >\0     version '%s'
+# gnu gmon magic From: Eugen Dedu <dedu@ese-metz.fr>
+0      string          gmon            GNU prof performance data
+>4     long            x               - version %d
+# From: Dave Pearson <davep@davep.org>
+# Harbour <URL:http://harbour-project.org/> HRB files.
+0      string          \xc0HRB         Harbour HRB file
+>4     leshort         x               version %d
+# Harbour HBV files
+0      string          \xc0HBV         Harbour variable dump file
+>4     leshort         x               version %d
+
+# From: Alex Beregszaszi <alex@fsn.hu>
+# 0    string          exec            BugOS executable
+# 0    string          pack            BugOS archive
+
+# From: Jason Spence <jspence@lightconsulting.com>
+# Generated by the "examples" in STM's ST40 devkit, and derived code.
+0      lelong          0x13a9f17e      ST40 component image format
+>4     string          >\0             \b, name '%s'
+
diff --git a/magic/Magdir/varied.script b/magic/Magdir/varied.script
new file mode 100644 (file)
index 0000000..11e6eb5
--- /dev/null
@@ -0,0 +1,51 @@
+#------------------------------------------------------------------------------
+# $File: varied.script,v 1.12 2019/04/19 00:42:27 christos Exp $
+# varied.script:  file(1) magic for various interpreter scripts
+
+0      string/t                #!\ /                   a
+>3     string          >\0                     %s script text executable
+
+0      string/b                #!\ /                   a
+>3     string          >\0                     %s script executable (binary data)
+
+0      string/t                #!\t/                   a
+>3     string          >\0                     %s script text executable
+
+0      string/b                #!\t/                   a
+>3     string          >\0                     %s script executable (binary data)
+
+0      string/t                #!/                     a
+>2     string          >\0                     %s script text executable
+
+0      string/b                #!/                     a
+>2     string          >\0                     %s script executable (binary data)
+
+0      string/t                #!\                     script text executable
+>3     string          >\0                     for %s
+
+0      string/b                #!\                     script executable
+>3     string          >\0                     for %s (binary data)
+
+# using env
+0      string/t        #!/usr/bin/env          a
+>15    string/t        >\0                     %s script text executable
+!:strength / 10
+
+0      string/b        #!/usr/bin/env          a
+>15    string/b        >\0                     %s script executable (binary data)
+!:strength / 10
+
+0      string/t        #!\ /usr/bin/env        a
+>16    string/t        >\0                     %s script text executable
+!:strength / 10
+
+0      string/b        #!\ /usr/bin/env        a
+>16    string/b        >\0                     %s script executable (binary data)
+!:strength / 10
+
+# From: arno <arenevier@fdn.fr>
+# mozilla xpconnect typelib
+# see https://www.mozilla.org/scriptable/typelib_file.html
+0      string          XPCOM\nTypeLib\r\n\032          XPConnect Typelib
+>0x10  byte        x       version %d
+>>0x11 byte        x      \b.%d
diff --git a/magic/Magdir/vax b/magic/Magdir/vax
new file mode 100644 (file)
index 0000000..21c5b8d
--- /dev/null
@@ -0,0 +1,27 @@
+
+#------------------------------------------------------------------------------
+# $File: vax,v 1.8 2013/01/09 22:37:24 christos Exp $
+# vax:  file(1) magic for VAX executable/object and APL workspace
+#
+0      lelong          0101557         VAX single precision APL workspace
+0      lelong          0101556         VAX double precision APL workspace
+
+#
+# VAX a.out (BSD; others collide with 386 and other 32-bit little-endian
+# executables, and are handled in aout)
+#
+0      lelong          0420            a.out VAX demand paged (first page unmapped) pure executable
+>16    lelong          >0              not stripped
+
+#
+# VAX COFF
+#
+# The `versions' were commented out, but have been un-commented out.
+# (Was the problem just one of endianness?)
+#
+0      leshort         0570            VAX COFF executable
+>12    lelong          >0              not stripped
+>22    leshort         >0              - version %d
+0      leshort         0575            VAX COFF pure executable
+>12    lelong          >0              not stripped
+>22    leshort         >0              - version %d
diff --git a/magic/Magdir/vicar b/magic/Magdir/vicar
new file mode 100644 (file)
index 0000000..bbd62dd
--- /dev/null
@@ -0,0 +1,17 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# vicar:  file(1) magic for VICAR files.
+#
+# From: Ossama Othman <othman@astrosun.tn.cornell.edu
+# VICAR is JPL's in-house spacecraft image processing program
+# VICAR image
+0      string  LBLSIZE=        VICAR image data
+>32    string  BYTE            \b, 8 bits  = VAX byte
+>32    string  HALF            \b, 16 bits = VAX word     = Fortran INTEGER*2
+>32    string  FULL            \b, 32 bits = VAX longword = Fortran INTEGER*4
+>32    string  REAL            \b, 32 bits = VAX longword = Fortran REAL*4
+>32    string  DOUB            \b, 64 bits = VAX quadword = Fortran REAL*8
+>32    string  COMPLEX         \b, 64 bits = VAX quadword = Fortran COMPLEX*8
+# VICAR label file
+43     string  SFDU_LABEL      VICAR label file
diff --git a/magic/Magdir/virtual b/magic/Magdir/virtual
new file mode 100644 (file)
index 0000000..347895a
--- /dev/null
@@ -0,0 +1,307 @@
+
+#------------------------------------------------------------------------------
+# $File: virtual,v 1.10 2019/04/19 00:42:27 christos Exp $
+# From: James Nobis <quel@quelrod.net>
+# Microsoft hard disk images for:
+# Virtual Server
+# Virtual PC
+# VirtualBox
+# URL: http://fileformats.archiveteam.org/wiki/VHD_(Virtual_Hard_Disk)
+# Reference: https://download.microsoft.com/download/f/f/e/ffef50a5-07dd-4cf8-aaa3-442c0673a029/
+# Virtual%20Hard%20Disk%20Format%20Spec_10_18_06.doc
+0      string  conectix        Microsoft Disk Image, Virtual Server or Virtual PC
+# alternative shorter names
+#0     string  conectix        Microsoft Virtual Hard Disk image
+#0     string  conectix        Microsoft Virtual HD image
+!:mime application/x-virtualbox-vhd
+!:ext   vhd
+# Features is a bit field used to indicate specific feature support
+#>8    ubelong         !0x00000002     \b, Features 0x%x
+# Reserved. This bit must always be set to 1.
+#>8    ubelong         &0x00000002     \b, Reserved 0x%x
+# File Format Version for the current specification 0x00010000
+#>12   ubelong         !0x00010000     \b, Version 0x%8.8x
+# Data Offset only found 0x200
+#>16   ubequad         !0x200          \b, Data Offset 0x%llx
+#>16   ubequad         x               \b, at 0x%llx
+# Dynamic Disk Header cookie like cxsparse
+#>(16.Q)       string          x               "%-.8s"
+# This field contains a Unicode string (UTF-16) of the parent hard disk filename
+#>(16.Q+64)    ubequad x               \b, parent name 0x%llx
+# Creator Application
+# vpc~Microsoft Virtual PC, vs~Microsoft Virtual Server, vbox~VirtualBox, d2v~disk2vhd
+>28    string          x               \b, Creator %-4.4s
+# Creator Version: 0x00010000~Virtual Server 2004, 0x00050000~Virtual PC 2004
+# holds the major/minor version of the application that created the image
+>32    ubeshort        x               %x
+>34    ubeshort        x               \b.%x
+#>32   ubelong         x               \b, Version 0x%8.8x
+# Creator Host OS: 0x5769326B~Windows (Wi2k), 0x4D616320~Macintosh (Mac)
+>36    ubelong         x               (
+>>36   ubelong         0x5769326B      \bW2k
+>>36   ubelong         0x4D616320      \bMac
+>>36   default         x               \b0x
+>>>36  ubelong         x               \b%8.8x
+# creation Time in seconds since 1 Jan 2000 UTC~946684800 sec. since Unix Epoch
+>24    bedate+946684800        x       \b) %s
+# Original Size
+#>40   ubequad         x               \b, o.-Size 0x%llx
+# Current Size is same as original size, but change when disk is expanded
+#>48   ubequad         x               \b, Size 0x%llx
+>48    ubequad         x               \b, %llu bytes
+# Disk Geometry: cylinder, heads, and sectors/track for hard disk
+#>56   ubeshort        x               \b, Cylinder 0x%x
+>56    ubeshort        x               \b, CHS %u
+# Heads
+#>58   ubyte           x               \b, Heads 0x%x
+>58    ubyte           x               \b/%u
+# Sectors per track
+#>59   ubyte           x               \b, Sectors 0x%x
+>59    ubyte           x               \b/%u
+# Disk Type: 3~Dynamic hard disk
+>60    ubelong         !0x3            \b, type 0x%x
+# Checksum
+#>64   ubelong         x               \b, cksum 0x%x
+# universally unique identifier (UUID) to associate a parent with its differencing image
+#>68   ubequad         x               \b, id 0x%16.16llx
+#>76   ubequad         x               \b-%16.16llx
+# Saved State: 1~Saved State
+>84    ubyte           !0              \b, State 0x%x
+# Reserved 427 bytes with nils
+#>85   ubequad !0                      \b, Reserved 0x%16.16llx
+
+# From: Joerg Jenderek
+# URL: https://msdn.microsoft.com/en-us/library/mt740058.aspx
+# Reference: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/
+# MS-VHDX/[MS-VHDX].pdf
+# Note: extends the VHD format with new capabilities, such as a 16TB maximum size
+# TODO:        find and display values like virtual size, disk size, cluster_size, etc
+#      display id in GUID format
+#
+# VHDX_FILE_IDENTIFIER signature 0x656C696678646876
+0      string                  vhdxfile
+# VHDX_HEADER signature. 1 header is stored at offset 64KB and the other at 128KB
+>0x10000       string          head            Microsoft Disk Image eXtended
+#>0x20000      string                  head    \b, 2nd header
+#!:mime        application/x-virtualbox-vhdx
+!:ext  vhdx
+# Creator[256] like "QEMU v3.0.0", "Microsoft Windows 6.3.9600.18512"
+>>8            lestring16              x       \b, by %.256s
+# The Checksum field is a CRC-32C hash over the entire 4 KB structure
+#>>0x10004     ulelong                 x       \b, CRC 0x%x
+# SequenceNumber
+>>0x10008      ulequad                 x       \b, sequence 0x%llx
+# FileWriteGuid
+#>>0x10010     ubequad                 x       \b, file id 0x%llx
+#>>>0x10018    ubequad                 x       \b-%llx
+# DataWriteGuid
+#>>0x10020     ubequad                 x       \b, data id 0x%llx
+#>>>0x10028    ubequad                 x       \b-%llx
+# LogGuid. If this field is zero, then the log is empty or has no valid entries 
+>>0x10030      ubequad                 >0      \b, log id 0x%llx
+>>>0x10038     ubequad                 x       \b-%llx
+# LogVersion. If not 0 there is a log to replay
+>>0x10040      uleshort                >0      \b, LogVersion 0x%x
+# Version. This field must be set to 1
+>>0x10042      uleshort                !1      \b, Version 0x%x
+# LogLength must be multiples of 1 MB
+>>0x10044      ulelong/1048576         >1      \b, LogLength %u MB
+# LogOffset (normally 0x100000 when log direct after header); multiples of 1 MB
+>>0x10048      ulequad                 !0x100000 \b, LogOffset 0x%llx
+# Log Entry Signature must be 0x65676F6C~loge
+>>(0x10048.q)  ulelong                 !0x65676F6C \b, NO Log Signature
+>>(0x10048.q)  ulelong                 =0x65676F6C     \b; LOG
+# Log Entry Checksum
+#>>>(0x10048.q+4)      ulelong         x       \b, Log CRC 0x%x
+# Log Entry Length must be a multiple of 4 KB
+>>>(0x10048.q+8)       ulelong/1024    >4      \b, EntryLength %u KB
+# Log Entry Tail must be a multiple of 4 KB
+#>>>(0x10048.q+12)     ulelong         x       \b, Tail 0x%x
+# Log Entry SequenceNumber
+#>>>(0x10048.q+16)     ulequad         x       \b, # 0x%llx
+# Log Entry DescriptorCount may be zero. only 4 bytes in other docs instead 8
+#>>>(0x10048.q+24)     ulelong         x       \b, DescriptorCount 0x%llx
+# Log Entry Reserved must be set to 0
+>>>(0x10048.q+28)      ulelong         !0      \b, Reserved 0x%x
+# Log Entry LogGuid
+#>>>(0x10048.q+32)     ubequad         x       \b, Log id 0x%llx
+#>>>(0x10048.q+40)     ubequad         x       \b-%llx
+# Log Entry FlushedFileOffset should VHDX size when entry is written.
+#>>>(0x10048.q+48)     ulequad         x       \b, FlushedFileOffset %llu
+# Log Entry LastFileOffset
+#>>>(0x10048.q+56)     ulequad         x       \b, LastFileOffset %llu
+# filling
+#>>>(0x10048.q+64)     ulequad         >0      \b, filling %llx
+# Reserved[4016]
+#>>0x10050     ulequad                 >0      \b, Reserved 0x%llx
+# VHDX_REGION_TABLE_HEADER Signature 0x69676572~regi at offset 192 KB and 256 KB
+>0x30000       ulelong                 !0x69676572 \b, 1st region INVALID
+>0x30000       ulelong                 =0x69676572 \b; region
+# region Checksum. CRC-32C hash over the entire 64-KB table
+#>>0x30004     ulelong                 x       \b, CRC 0x%x
+# The EntryCount specifies number of valid entries; Found 2; This must be =< 2047. 
+>>0x30008      ulelong                 x       \b, %u entries
+# reserved must be zero
+#>>0x3000C     ulelong                 !0      \b, RESERVED 0x%x
+# Region Table Entry starts with identifier for the object. often BAT id
+>>0x30010      use                     vhdx-id
+# FileOffset
+>>0x30020      ulequad         x               \b, at 0x%llx
+# Length. Specifies the length of the object within the file
+#>>0x30028     ulelong         x               \b, Length 0x%x
+# 1 means region entry is required. if region not recognized, then REFUSE to load VHDX
+>>0x3002C      ulelong         x               \b, Required %u
+# 2nd region entry often metadata id
+>>0x30030      use                     vhdx-id
+# 2nd entry FileOffset
+>>0x30040      ulequad         x               \b, at 0x%llx
+# 1 means region entry is required. if region not recognized, then REFUSE to load VHDX
+>>0x3004C      ulelong         x               \b, Required %u
+# 2nd region
+>>0x40000      ulelong         !0x69676572     \b, 2nd region INVALID
+# check in vhdx images for known id and show names instead hexadecimal
+0      name            vhdx-id
+# https://www.windowstricks.in/online-windows-guid-converter
+# 2DC27766-F623-4200-9D64-115E9BFD4A08         BAT GUID
+# 6677C22D23F600429D64115E9BFD4A08             BAT ID
+>0     ubequad         =0x6677C22D23F60042
+>>8    ubequad         =0x9D64115E9BFD4A08     \b, id BAT
+# no BAT id
+>>8    default         x
+>>>0   use             vhdx-id-hex
+# 8B7CA206-4790-4B9A-B8FE-575F050F886E         Metadata region GUID
+# 06A27C8B90479A4BB8FE575F050F886E             Metadata region ID
+>0     ubequad         =0x06A27C8B90479A4B
+>>8    ubequad         =0xB8FE575F050F886E     \b, id Metadata
+# no Metadata id
+>>8    default         x
+>>>0   use             vhdx-id-hex
+# 2FA54224-CD1B-4876-B211-5DBED83BF4B8         Virtual Disk Size GUID
+# 2442A52F1BCD7648B2115DBED83BF4B8             Virtual Disk Size ID
+# value "virtual size" can be verified by command `qemu-img info `
+>0     ubequad         =0x2442A52F1BCD7648
+>>8    ubequad         =0xB2115DBED83BF4B8     \b, id vsize
+# no Virtual Disk Size ID
+>>8    default         x
+>>>0   use             vhdx-id-hex
+# other ids
+>0     default         x
+>>0    use             vhdx-id-hex
+# in vhdx images show id as hexadecimal
+0      name            vhdx-id-hex
+>0     ubequad         x                       \b, ID 0x%16.16llx
+>8     ubequad         x                       \b-%16.16llx
+#
+# libvirt
+# From: Philipp Hahn <hahn@univention.de>
+0      string  LibvirtQemudSave        Libvirt QEMU Suspend Image
+>0x10  lelong  x       \b, version %u
+>0x14  lelong  x       \b, XML length %u
+>0x18  lelong  1       \b, running
+>0x1c  lelong  1       \b, compressed
+
+0      string  LibvirtQemudPart        Libvirt QEMU partial Suspend Image
+# From: Alex Beregszaszi <alex@fsn.hu>
+0      string/b        COWD            VMWare3
+>4     byte    3               disk image
+>>32   lelong  x               (%d/
+>>36   lelong  x               \b%d/
+>>40   lelong  x               \b%d)
+>4     byte    2               undoable disk image
+>>32   string  >\0             (%s)
+
+0      string/b        VMDK             VMware4 disk image
+0      string/b        KDMV             VMware4 disk image
+
+#--------------------------------------------------------------------
+# Qemu Emulator Images
+# Lines written by Friedrich Schwittay (f.schwittay@yousable.de)
+# Updated by Adam Buchbinder (adam.buchbinder@gmail.com)
+# Made by reading sources, reading documentation, and doing trial and error
+# on existing QCOW files
+0      string/b        QFI\xFB
+
+# Uncomment the following line to display Magic (only used for debugging
+# this magic number)
+#>0    string/b        x       , Magic: %s
+
+# There are currently 2 Versions: "1" and "2".
+# https://www.gnome.org/~markmc/qcow-image-format-version-1.html
+>4     belong          !1      QEMU QCOW2 Image
+>4     belong          1       QEMU QCOW Image (v1)
+
+# Using the existence of the Backing File Offset to determine whether
+# to read Backing File Information
+>>12   belong   >0      \b, has backing file (
+# Note that this isn't a null-terminated string; the length is actually
+# (16.L). Assuming a null-terminated string happens to work usually, but it
+# may spew junk until it reaches a \0 in some cases.
+>>>(12.L)       string >\0     \bpath %s
+
+# Modification time of the Backing File
+# Really useful if you want to know if your backing
+# file is still usable together with this image
+>>>>20 bedate >0       \b, mtime %s)
+>>>>20 default x       \b)
+
+# Size is stored in bytes in a big-endian u64.
+>>24   bequad  x        \b, %lld bytes
+
+# 1 for AES encryption, 0 for none.
+>>36   belong  1       \b, AES-encrypted
+
+# https://www.gnome.org/~markmc/qcow-image-format.html
+>4     belong  2       (v2)
+# Using the existence of the Backing File Offset to determine whether
+# to read Backing File Information
+>>8    bequad  >0       \b, has backing file
+# Note that this isn't a null-terminated string; the length is actually
+# (16.L). Assuming a null-terminated string happens to work usually, but it
+# may spew junk until it reaches a \0 in some cases. Also, since there's no
+# .Q modifier, we just use the bottom four bytes as an offset. Note that if
+# the file is over 4G, and the backing file path is stored after the first 4G,
+# the wrong filename will be printed. (This should be (8.Q), when that syntax
+# is introduced.)
+>>>(12.L)       string >\0     (path %s)
+>>24   bequad  x       \b, %lld bytes
+>>32   belong  1       \b, AES-encrypted
+
+>4     belong  3       (v3)
+# Using the existence of the Backing File Offset to determine whether
+# to read Backing File Information
+>>8    bequad  >0       \b, has backing file
+# Note that this isn't a null-terminated string; the length is actually
+# (16.L). Assuming a null-terminated string happens to work usually, but it
+# may spew junk until it reaches a \0 in some cases. Also, since there's no
+# .Q modifier, we just use the bottom four bytes as an offset. Note that if
+# the file is over 4G, and the backing file path is stored after the first 4G,
+# the wrong filename will be printed. (This should be (8.Q), when that syntax
+# is introduced.)
+>>>(12.L)       string >\0     (path %s)
+>>24   bequad  x       \b, %lld bytes
+>>32   belong  1       \b, AES-encrypted
+
+>4     default x       (unknown version)
+
+0      string/b        QEVM            QEMU suspend to disk image
+
+# QEMU QED Image
+# https://wiki.qemu.org/Features/QED/Specification
+0      string/b        QED\0           QEMU QED Image
+
+# VDI Image
+# Sun xVM VirtualBox Disk Image
+# From: Richard W.M. Jones <rich@annexia.org>
+# VirtualBox Disk Image
+0x40   ulelong         0xbeda107f      VirtualBox Disk Image
+>0x44  uleshort        >0              \b, major %u
+>0x46  uleshort        >0              \b, minor %u
+>0     string          >\0             (%s)
+>368   lequad          x                \b, %lld bytes
+
+0      string/b        Bochs\ Virtual\ HD\ Image       Bochs disk image,
+>32    string  x                               type %s,
+>48    string  x                               subtype %s
+
+0      lelong  0x02468ace                      Bochs Sparse disk image
+
diff --git a/magic/Magdir/virtutech b/magic/Magdir/virtutech
new file mode 100644 (file)
index 0000000..71e1328
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# Virtutech Compressed Random Access File Format
+#
+# From <gustav@virtutech.com>
+0      string          \211\277\036\203        Virtutech CRAFF
+>4     belong          x               v%d
+>20    belong          0               uncompressed
+>20    belong          1               bzipp2ed
+>20    belong          2               gzipped
+>24    belong          0               not clean
diff --git a/magic/Magdir/visx b/magic/Magdir/visx
new file mode 100644 (file)
index 0000000..02499d2
--- /dev/null
@@ -0,0 +1,32 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# visx:  file(1) magic for Visx format files
+#
+0      short           0x5555          VISX image file
+>2     byte            0               (zero)
+>2     byte            1               (unsigned char)
+>2     byte            2               (short integer)
+>2     byte            3               (float 32)
+>2     byte            4               (float 64)
+>2     byte            5               (signed char)
+>2     byte            6               (bit-plane)
+>2     byte            7               (classes)
+>2     byte            8               (statistics)
+>2     byte            10              (ascii text)
+>2     byte            15              (image segments)
+>2     byte            100             (image set)
+>2     byte            101             (unsigned char vector)
+>2     byte            102             (short integer vector)
+>2     byte            103             (float 32 vector)
+>2     byte            104             (float 64 vector)
+>2     byte            105             (signed char vector)
+>2     byte            106             (bit plane vector)
+>2     byte            121             (feature vector)
+>2     byte            122             (feature vector library)
+>2     byte            124             (chain code)
+>2     byte            126             (bit vector)
+>2     byte            130             (graph)
+>2     byte            131             (adjacency graph)
+>2     byte            132             (adjacency graph library)
+>2     string          .VISIX          (ascii text)
diff --git a/magic/Magdir/vms b/magic/Magdir/vms
new file mode 100644 (file)
index 0000000..56d57ae
--- /dev/null
@@ -0,0 +1,30 @@
+
+#------------------------------------------------------------------------------
+# $File: vms,v 1.10 2017/03/17 21:35:28 christos Exp $
+# vms:  file(1) magic for VMS executables (experimental)
+#
+# VMS .exe formats, both VAX and AXP (Greg Roelofs, newt@uchicago.edu)
+
+# GRR 950122:  I'm just guessing on these, based on inspection of the headers
+# of three executables each for Alpha and VAX architectures.  The VAX files
+# all had headers similar to this:
+#
+#   00000  b0 00 30 00 44 00 60 00  00 00 00 00 30 32 30 35  ..0.D.`.....0205
+#   00010  01 01 00 00 ff ff ff ff  ff ff ff ff 00 00 00 00  ................
+#
+0      string  \xb0\0\x30\0    VMS VAX executable
+>44032 string  PK\003\004      \b, Info-ZIP SFX archive v5.12 w/decryption
+#
+# The AXP files all looked like this, except that the byte at offset 0x22
+# was 06 in some of them and 07 in others:
+#
+#   00000  03 00 00 00 00 00 00 00  ec 02 00 00 10 01 00 00  ................
+#   00010  68 00 00 00 98 00 00 00  b8 00 00 00 00 00 00 00  h...............
+#   00020  00 00 07 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
+#   00030  00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  ................
+#   00040  00 00 00 00 ff ff ff ff  ff ff ff ff 02 00 00 00  ................
+#
+# GRR this test is still too general as it catches example adressen.dbt
+0      belong  0x03000000
+>8     ubelong 0xec020000      VMS Alpha executable
+>>75264        string  PK\003\004      \b, Info-ZIP SFX archive v5.12 w/decryption
diff --git a/magic/Magdir/vmware b/magic/Magdir/vmware
new file mode 100644 (file)
index 0000000..cd1a9d9
--- /dev/null
@@ -0,0 +1,6 @@
+
+#------------------------------------------------------------------------------
+# $File: vmware,v 1.8 2017/03/17 21:35:28 christos Exp $
+# VMware specific files (deducted from version 1.1 and log file entries)
+# Anthon van der Neut (anthon@mnt.org)
+0      belong  0x4d52564e      VMware nvram
diff --git a/magic/Magdir/vorbis b/magic/Magdir/vorbis
new file mode 100644 (file)
index 0000000..b4a8f33
--- /dev/null
@@ -0,0 +1,155 @@
+
+#------------------------------------------------------------------------------
+# $File: vorbis,v 1.24 2018/03/14 04:38:44 christos Exp $
+# vorbis:  file(1) magic for Ogg/Vorbis files
+#
+# From Felix von Leitner <leitner@fefe.de>
+# Extended by Beni Cherniavsky <cben@crosswinds.net>
+# Further extended by Greg Wooledge <greg@wooledge.org>
+#
+# Most (everything but the number of channels and bitrate) is commented
+# out with `##' as it's not interesting to the average user.  The most
+# probable things advanced users would want to uncomment are probably
+# the number of comments and the encoder version.
+#
+# FIXME: The first match has been made a search, so that it can skip
+# over prepended ID3 tags. This will work for MIME type detection, but
+# won't work for detecting other properties of the file (they all need
+# to be made relative to the search). In any case, if the file has ID3
+# tags, the ID3 information will be printed, not the Ogg information,
+# so until that's fixed, this doesn't matter.
+# FIXME[2]: Disable the above for now, since search assumes text mode.
+#
+# --- Ogg Framing ---
+#0             search/1000     OggS            Ogg data
+0              string  OggS            Ogg data
+>4             byte            !0              UNKNOWN REVISION %u
+##>4           byte            0               revision 0
+>4             byte            0
+##>>14         lelong          x               (Serial %lX)
+# non-Vorbis content: FLAC (Free Lossless Audio Codec, http://flac.sourceforge.net)
+>>28           string          \x7fFLAC        \b, FLAC audio
+# non-Vorbis content: Theora
+!:mime         audio/ogg
+>>28           string          \x80theora      \b, Theora video
+!:mime         video/ogg
+# non-Vorbis content: Kate
+>>28           string          \x80kate\0\0\0\0        \b, Kate (Karaoke and Text)
+!:mime         application/ogg
+>>>37          ubyte           x               v%u
+>>>38          ubyte           x               \b.%u,
+>>>40          byte            0               utf8 encoding,
+>>>40          byte            !0              unknown character encoding,
+>>>60          string          >\0             language %s,
+>>>60          string          \0              no language set,
+>>>76          string          >\0             category %s
+>>>76          string          \0              no category set
+# non-Vorbis content: Skeleton
+>>28           string          fishead\0       \b, Skeleton
+!:mime         video/ogg
+>>>36          leshort         x               v%u
+>>>40          leshort         x               \b.%u
+# non-Vorbis content: Speex
+>>28           string          Speex\ \ \      \b, Speex audio
+!:mime         audio/ogg
+# non-Vorbis content: OGM
+>>28           string          \x01video\0\0\0 \b, OGM video
+!:mime         video/ogg
+>>>37          string/c        div3            (DivX 3)
+>>>37          string/c        divx            (DivX 4)
+>>>37          string/c        dx50            (DivX 5)
+>>>37          string/c        xvid            (XviD)
+# --- First vorbis packet - general header ---
+>>28           string          \x01vorbis      \b, Vorbis audio,
+!:mime         audio/ogg
+>>>35          lelong          !0              UNKNOWN VERSION %u,
+##>>>35                lelong          0               version 0,
+>>>35          lelong          0
+>>>>39         ubyte           1               mono,
+>>>>39         ubyte           2               stereo,
+>>>>39         ubyte           >2              %u channels,
+>>>>40         lelong          x               %u Hz
+# Minimal, nominal and maximal bitrates specified when encoding
+>>>>48         string          <\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff       \b,
+# The above tests if at least one of these is specified:
+>>>>>52                lelong          !-1
+# Vorbis RC2 has a bug which puts -1000 in the min/max bitrate fields
+# instead of -1.
+# Vorbis 1.0 uses 0 instead of -1.
+>>>>>>52       lelong          !0
+>>>>>>>52      lelong          !-1000
+>>>>>>>>52     lelong          x               <%u
+>>>>>48                lelong          !-1
+>>>>>>48       lelong          x               ~%u
+>>>>>44                lelong          !-1
+>>>>>>44       lelong          !-1000
+>>>>>>>44      lelong          !0
+>>>>>>>>44     lelong          x               >%u
+>>>>>48                string          <\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff       bps
+# -- Second vorbis header packet - the comments
+# A kludge to read the vendor string.  It's a counted string, not a
+# zero-terminated one, so file(1) can't read it in a generic way.
+# libVorbis is the only one existing currently, so I detect specifically
+# it.  The interesting value is the cvs date (8 digits decimal).
+# Post-RC1 Ogg files have the second header packet (and thus the version)
+# in a different place, so we must use an indirect offset.
+>>>(84.b+85)           string          \x03vorbis
+>>>>(84.b+96)          string/c        Xiphophorus\ libVorbis\ I       \b, created by: Xiphophorus libVorbis I
+>>>>>(84.b+120)                string          >00000000
+# Map to beta version numbers:
+>>>>>>(84.b+120)       string          <20000508       (<beta1, prepublic)
+>>>>>>(84.b+120)       string          20000508        (1.0 beta 1 or beta 2)
+>>>>>>(84.b+120)       string          >20000508
+>>>>>>>(84.b+120)      string          <20001031       (beta2-3)
+>>>>>>(84.b+120)       string          20001031        (1.0 beta 3)
+>>>>>>(84.b+120)       string          >20001031
+>>>>>>>(84.b+120)      string          <20010225       (beta3-4)
+>>>>>>(84.b+120)       string          20010225        (1.0 beta 4)
+>>>>>>(84.b+120)       string          >20010225
+>>>>>>>(84.b+120)      string          <20010615       (beta4-RC1)
+>>>>>>(84.b+120)       string          20010615        (1.0 RC1)
+>>>>>>(84.b+120)       string          20010813        (1.0 RC2)
+>>>>>>(84.b+120)       string          20010816        (RC2 - Garf tuned v1)
+>>>>>>(84.b+120)       string          20011014        (RC2 - Garf tuned v2)
+>>>>>>(84.b+120)       string          20011217        (1.0 RC3)
+>>>>>>(84.b+120)       string          20011231        (1.0 RC3)
+# Some pre-1.0 CVS snapshots still had "Xiphphorus"...
+>>>>>>(84.b+120)       string          >20011231       (pre-1.0 CVS)
+# For the 1.0 release, Xiphophorus is replaced by Xiph.Org
+>>>>(84.b+96)          string/c        Xiph.Org\ libVorbis\ I  \b, created by: Xiph.Org libVorbis I
+>>>>>(84.b+117)                string          >00000000
+>>>>>>(84.b+117)       string          <20020717       (pre-1.0 CVS)
+>>>>>>(84.b+117)       string          20020717        (1.0)
+>>>>>>(84.b+117)       string          20030909        (1.0.1)
+>>>>>>(84.b+117)       string          20040629        (1.1.0 RC1)
+>>>>>>(84.b+117)       string          20050304        (1.1.2)
+>>>>>>(84.b+117)       string          20070622        (1.2.0)
+>>>>>>(84.b+117)       string          20090624        (1.2.2)
+>>>>>>(84.b+117)       string          20090709        (1.2.3)
+>>>>>>(84.b+117)       string          20100325        (1.3.1)
+>>>>>>(84.b+117)       string          20101101        (1.3.2)
+>>>>>>(84.b+117)       string          20120203        (1.3.3)
+>>>>>>(84.b+117)       string          20140122        (1.3.4)
+>>>>>>(84.b+117)       string          20150105        (1.3.5)
+
+# non-Vorbis content: Opus https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
+>>28           string          OpusHead        \b, Opus audio,
+!:mime         audio/ogg
+>>>36          ubyte           >0x0F           UNKNOWN VERSION %u,
+>>>36          ubyte           &0x0F           version 0.%d
+>>>>46         ubyte           >1
+>>>>>46                ubyte           !255            unknown channel mapping family %u,
+>>>>>37                ubyte           x               %u channels
+>>>>46         ubyte           0
+>>>>>37                ubyte           1               mono
+>>>>>37                ubyte           2               stereo
+>>>>46         ubyte           1
+>>>>>37                ubyte           1               mono
+>>>>>37                ubyte           2               stereo
+>>>>>37                ubyte           3               linear surround
+>>>>>37                ubyte           4               quadraphonic
+>>>>>37                ubyte           5               5.0 surround
+>>>>>37                ubyte           6               5.1 surround
+>>>>>37                ubyte           7               6.1 surround
+>>>>>37                ubyte           8               7.1 surround
+>>>>40         lelong          !0              \b, %u Hz
diff --git a/magic/Magdir/vxl b/magic/Magdir/vxl
new file mode 100644 (file)
index 0000000..093fb85
--- /dev/null
@@ -0,0 +1,14 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# VXL: file(1) magic for VXL binary IO data files
+#
+# from Ian Scott <scottim@sf.net>
+#
+# VXL is a collection of C++ libraries for Computer Vision.
+# See the vsl chapter in the VXL Book for more info
+# http://www.isbe.man.ac.uk/public_vxl_doc/books/vxl/book.html
+# http:/vxl.sf.net
+
+2      lelong  0x472b2c4e      VXL data file,
+>0     leshort >0              schema version no %d
diff --git a/magic/Magdir/warc b/magic/Magdir/warc
new file mode 100644 (file)
index 0000000..5942867
--- /dev/null
@@ -0,0 +1,16 @@
+
+#------------------------------------------------------------------------------
+# $File: warc,v 1.4 2019/04/19 00:42:27 christos Exp $
+# warc:  file(1) magic for WARC files
+
+0      string  WARC/   WARC Archive
+>5     string  x       version %.4s
+!:mime application/warc
+
+#------------------------------------------------------------------------------
+# Arc File Format from Internet Archive
+# see https://www.archive.org/web/researcher/ArcFileFormat.php
+0      string          filedesc://     Internet Archive File
+!:mime application/x-ia-arc
+>11    search/256      \x0A    \b
+>>&0   ubyte   >0      \b version %c
diff --git a/magic/Magdir/weak b/magic/Magdir/weak
new file mode 100644 (file)
index 0000000..6dc1793
--- /dev/null
@@ -0,0 +1,16 @@
+
+#------------------------------------------------------------------------------
+# weak:  file(1) magic for very weak magic entries, disabled by default
+#
+# These entries are so weak that they might interfere identification of
+# other formats. Example include:
+# - Only identify for 1 or 2 bytes
+# - Match against very wide range of values
+# - Match against generic word in some spoken languages (e.g. English)
+
+# Summary: Computer Graphics Metafile
+# Extension: .cgm
+#0     beshort&0xffe0  0x0020          binary Computer Graphics Metafile
+#0     beshort         0x3020          character Computer Graphics Metafile
+
+#0     string          =!!             Bennet Yee's "face" format
diff --git a/magic/Magdir/webassembly b/magic/Magdir/webassembly
new file mode 100644 (file)
index 0000000..3b1d37e
--- /dev/null
@@ -0,0 +1,15 @@
+#------------------------------------------------------------------------------
+# $File: webassembly,v 1.3 2019/04/19 00:42:27 christos Exp $
+# webassembly:  file(1) magic for WebAssembly modules
+#
+# WebAssembly is a virtual architecture developed by a W3C Community
+# Group at https://webassembly.org/. The file extension is .wasm, and
+# the MIME type is application/wasm.
+#
+# https://webassembly.org/docs/binary-encoding/ is the main
+# document describing the binary format.
+# From: Pip Cet <pipcet@gmail.com> and Joel Martin
+
+0      string  \0asm   WebAssembly (wasm) binary module
+>4     lelong  =1      version %#x (MVP)
+>4     lelong  >1      version %#x
diff --git a/magic/Magdir/windows b/magic/Magdir/windows
new file mode 100644 (file)
index 0000000..39ed3e2
--- /dev/null
@@ -0,0 +1,881 @@
+
+#------------------------------------------------------------------------------
+# $File: windows,v 1.26 2019/05/01 17:55:25 christos Exp $
+# windows:  file(1) magic for Microsoft Windows
+#
+# This file is mainly reserved for files where programs
+# using them are run almost always on MS Windows 3.x or
+# above, or files only used exclusively in Windows OS,
+# where there is no better category to allocate for.
+# For example, even though WinZIP almost run on Windows
+# only, it is better to treat them as "archive" instead.
+# For format usable in DOS, such as generic executable
+# format, please specify under "msdos" file.
+#
+
+
+# Summary: Outlook Express DBX file
+# Extension: .dbx
+# Created by: Christophe Monniez
+0      string  \xCF\xAD\x12\xFE        MS Outlook Express DBX file
+>4     byte    =0xC5                   \b, message database
+>4     byte    =0xC6                   \b, folder database
+>4     byte    =0xC7                   \b, account information
+>4     byte    =0x30                   \b, offline database
+
+
+# Summary: Windows crash dump
+# Extension: .dmp
+# Created by: Andreas Schuster (https://computer.forensikblog.de/)
+# Reference (1): https://computer.forensikblog.de/en/2008/02/64bit_magic.html
+# Modified by (1): Abel Cheung (Avoid match with first 4 bytes only)
+0      string          PAGE
+>4     string          DUMP            MS Windows 32bit crash dump
+>>0x05c        byte            0               \b, no PAE
+>>0x05c        byte            1               \b, PAE
+>>0xf88        lelong          1               \b, full dump
+>>0xf88        lelong          2               \b, kernel dump
+>>0xf88        lelong          3               \b, small dump
+>>0x068        lelong          x               \b, %d pages
+>4     string          DU64            MS Windows 64bit crash dump
+>>0xf98        lelong          1               \b, full dump
+>>0xf98        lelong          2               \b, kernel dump
+>>0xf98        lelong          3               \b, small dump
+>>0x090        lequad          x               \b, %lld pages
+
+
+# Summary: Vista Event Log
+# Extension: .evtx
+# Created by: Andreas Schuster (https://computer.forensikblog.de/)
+# Reference (1): https://computer.forensikblog.de/en/2007/05/some_magic.html
+0      string          ElfFile\0       MS Windows Vista Event Log
+>0x2a  leshort         x               \b, %d chunks
+>>0x10 lelong          x               \b (no. %d in use)
+>0x18  lelong          >1              \b, next record no. %d
+>0x18  lelong          =1              \b, empty
+>0x78  lelong          &1              \b, DIRTY
+>0x78  lelong          &2              \b, FULL
+
+# Summary: Windows System Deployment Image
+# Created by: Joerg Jenderek
+# URL: http://en.wikipedia.org/wiki/System_Deployment_Image
+# Reference: http://skolk.livejournal.com/1320.html
+0      string                  $SDI
+>4     string                  0001            System Deployment Image
+!:mime application/x-ms-sdi
+#!:mime        application/octet-stream
+# \Boot\boot.sdi
+!:ext  sdi
+# MDBtype: 0~Unspecified 1~RAM 2~ROM
+>>8    ulequad                 !0              \b, MDBtype 0x%llx
+# BootCodeOffset
+>>16   ulequad                 !0              \b, BootCodeOffset 0x%llx
+# BootCodeSize
+>>24   ulequad                 !0              \b, BootCodeSize 0x%llx
+# VendorID
+>>32   ulequad                 !0              \b, VendorID 0x%llx
+# DeviceID
+>>40   ulequad                 !0              \b, DeviceID 0x%llx
+# DeviceModel
+>>48   ulequad                 !0              \b, DeviceModel 0x%llx
+>>>56  ulequad                 !0              \b%llx
+# DeviceRole
+>>64   ulequad                 !0              \b, DeviceRole 0x%llx
+# Reserved1; reserved fields and gaps between BLOBs are padded with \0
+#>>72  ulequad                 !0              \b, Reserved1 0x%llx
+# RuntimeGUID
+>>80   ulequad                 !0              \b, RuntimeGUID 0x%llx
+>>>88  ulequad                 !0              \b%llx
+# RuntimeOEMrev
+>>96   ulequad                 !0              \b, RuntimeOEMrev 0x%llx
+# Reserved2
+#>>104 ulequad                 !0              \b, Reserved2 0x%llx
+# BLOB alignment value in pages, as specified in sdimgr /pack: 1~4K 2~8k
+>>112  ulequad                 !0              \b, PageAlignment %llu
+# Reserved3[48]
+#>>120 ulequad                 !0              \b, Reserved3 0x%llx
+# SDI checksum 39h
+>>0x1f8        ulequad                 x               \b, checksum 0x%llx
+# BLOBtype[8] \0-padded: PART, WIM , BOOT, LOAD, DISK
+>>0x400        string                  >\0             \b, type %-3.8s
+# 0~non-filesystem 7~NTFS 6~BIGFAT
+>>>0x420       ulequad         !0              (0x%llx)
+# ATTRibutes
+>>>0x408       ulequad         !0              0x%llx attributes
+# Offset
+>>>0x410       ulequad         x               at 0x%llx
+# print 1 space after size and then handles NTFS boot sector by ./filesystems
+>>>0x418       ulequad         >0              %llu bytes 
+>>>>(0x410.l)  indirect        x
+# 2nd BLOB: WIM
+>>0x440                string          >\0             \b, type %-3.8s
+>>>0x428       ulequad         !0              (0x%llx)
+# ATTRibutes
+>>>0x448       ulequad         !0              0x%llx attributes
+# Offset
+>>>0x450       ulequad         x               at 0x%llx
+>>>0x458       ulequad         >0              %llu bytes 
+>>>>(0x450.l)  indirect        x
+# 3rd BLOB
+>>0x480                string          >\0             \b, type %-3.8s
+
+# Summary:     Windows Error Report text files
+# URL:         https://en.wikipedia.org/wiki/Windows_Error_Reporting
+# Reference:   https://www.nirsoft.net/utils/app_crash_view.html
+# Created by:  Joerg Jenderek
+# Note:                in directories  %ProgramData%\Microsoft\Windows\WER\{ReportArchive,ReportQueue}
+#                              %LOCALAPPDATA%\Microsoft\Windows\WER\{ReportArchive,ReportQueue}
+0      lestring16      Version=        
+>22    lestring16      EventType       Windows Error Report
+!:mime text/plain
+# Report.wer
+!:ext  wer
+
+# Summary: Windows 3.1 group files
+# Extension: .grp
+# Created by: unknown
+0      string          \120\115\103\103        MS Windows 3.1 group files
+
+
+# Summary: Old format help files
+# URL: https://en.wikipedia.org/wiki/WinHelp
+# Reference: https://www.oocities.org/mwinterhoff/helpfile.htm
+# Update: Joerg Jenderek
+# Created by: Dirk Jagdmann <doj@cubic.org>
+#
+# check and then display version and date inside MS Windows HeLP file fragment
+0      name                            help-ver-date
+# look for Magic of SYSTEMHEADER
+>0     leshort         0x036C
+# version Major                1 for right file fragment
+>>4    leshort         1               Windows
+# print non empty string above to avoid error message
+# Warning: Current entry does not yet have a description for adding a MIME type
+!:mime application/winhelp
+!:ext  hlp
+# version Minor of help file format is hint for windows version
+>>>2   leshort         0x0F            3.x
+>>>2   leshort         0x15            3.0
+>>>2   leshort         0x21            3.1
+>>>2   leshort         0x27            x.y
+>>>2   leshort         0x33            95
+>>>2   default         x               y.z
+>>>>2  leshort         x               0x%x
+# to complete message string like "MS Windows 3.x help file"
+>>>2   leshort         x               help
+# GenDate often older than file creation date
+>>>6   ldate           x               \b, %s
+#
+# Magic for HeLP files
+0      lelong          0x00035f3f
+# ./windows (version 5.25) labeled the entry as "MS Windows 3.x help file"
+# file header magic 0x293B at DirectoryStart+9
+>(4.l+9)       uleshort        0x293B          MS
+# look for @VERSION    bmf.. like IBMAVW.ANN
+>>0xD4         string  =\x62\x6D\x66\x01\x00   Windows help annotation
+!:mime application/x-winhelp
+!:ext  ann
+>>0xD4         string  !\x62\x6D\x66\x01\x00
+# "GID Help index" by TrID
+>>>(4.l+0x65)  string  =|Pete                  Windows help Global Index
+!:mime application/x-winhelp
+!:ext  gid
+# HeLP Bookmark or
+# "Windows HELP File" by TrID
+>>>(4.l+0x65)          string          !|Pete
+# maybe there exist a cleaner way to detect HeLP fragments
+# brute search for Magic 0x036C with matching Major maximal 7 iterations
+# discapp.hlp
+>>>>16                 search/0x49AF/s \x6c\x03
+>>>>>&0                        use             help-ver-date
+>>>>>&4                        leshort         !1
+# putty.hlp
+>>>>>>&0               search/0x69AF/s \x6c\x03
+>>>>>>>&0              use             help-ver-date
+>>>>>>>&4              leshort         !1
+>>>>>>>>&0             search/0x49AF/s \x6c\x03
+>>>>>>>>>&0            use             help-ver-date
+>>>>>>>>>&4            leshort         !1
+>>>>>>>>>>&0           search/0x49AF/s \x6c\x03
+>>>>>>>>>>>&0          use             help-ver-date
+>>>>>>>>>>>&4          leshort         !1
+>>>>>>>>>>>>&0         search/0x49AF/s \x6c\x03
+>>>>>>>>>>>>>&0                use             help-ver-date
+>>>>>>>>>>>>>&4                leshort         !1
+>>>>>>>>>>>>>>&0       search/0x49AF/s \x6c\x03
+>>>>>>>>>>>>>>>&0      use             help-ver-date
+>>>>>>>>>>>>>>>&4      leshort         !1
+>>>>>>>>>>>>>>>>&0     search/0x49AF/s \x6c\x03
+# GCC.HLP is detected after 7 iterations
+>>>>>>>>>>>>>>>>>&0    use             help-ver-date
+# this only happens if bigger hlp file is detected after used search iterations
+>>>>>>>>>>>>>>>>>&4    leshort         !1              Windows y.z help
+!:mime application/winhelp
+!:ext  hlp
+# repeat search again or following default line does not work
+>>>>16                 search/0x49AF/s \x6c\x03
+# remaining files should be HeLP Bookmark WinHlp32.BMK (XP 32-bit) or WinHlp32 (Windows 8.1 64-bit)
+>>>>16 default                         x       Windows help Bookmark
+!:mime application/x-winhelp
+!:ext  bmk
+## FirstFreeBlock normally FFFFFFFFh 10h for *ANN
+##>>8  lelong                  x               \b, FirstFreeBlock 0x%8.8x
+# EntireFileSize
+>>12   lelong                  x               \b, %d bytes
+## ReservedSpace normally 042Fh AFh for *.ANN
+#>>(4.l)       lelong          x               \b, ReservedSpace 0x%8.8x
+## UsedSpace normally 0426h A6h for *.ANN
+#>>(4.l+4)     lelong          x               \b, UsedSpace 0x%8.8x
+## FileFlags normally 04...
+#>>(4.l+5)     lelong          x               \b, FileFlags 0x%8.8x
+## file header magic 0x293B
+#>>(4.l+9)     uleshort        x               \b, file header magic 0x%4.4x
+## file header Flags           0x0402
+#>>(4.l+11)    uleshort        x               \b, file header Flags 0x%4.4x
+## file header PageSize        0400h 80h for *.ANN
+#>>(4.l+13)    uleshort        x               \b, PageSize 0x%4.4x
+## Structure[16]               z4
+#>>(4.l+15)    string          >\0             \b, Structure_"%-.16s"
+## MustBeZero                  0
+#>>(4.l+31)    uleshort        x               \b, MustBeZero 0x%4.4x
+## PageSplits
+#>>(4.l+33)    uleshort        x               \b, PageSplits 0x%4.4x
+## RootPage
+#>>(4.l+35)    uleshort        x               \b, RootPage 0x%4.4x
+## MustBeNegOne                        0xffff
+#>>(4.l+37)    uleshort        x               \b, MustBeNegOne 0x%4.4x
+## TotalPages                  1
+#>>(4.l+39)    uleshort        x               \b, TotalPages 0x%4.4x
+## NLevels                     0x0001
+#>>(4.l+41)    uleshort        x               \b, NLevels 0x%4.4x
+## TotalBtreeEntries
+#>>(4.l+43)    ulelong         x               \b, TotalBtreeEntries 0x%8.8x
+## pages of the B+ tree
+#>>(4.l+47)    ubequad         x               \b, PageStart 0x%16.16llx
+
+# start with colon or semicolon for comment line like Back2Life.cnt
+0              regex           \^(:|;)
+# look for first keyword Base
+>0             search/45       :Base
+>>&0                           use             cnt-name
+# only solution to search again from beginning , because relative offsets changes when use is called
+>0             search/45       :Base
+>0             default         x
+# look for other keyword Title like in putty.cnt
+>>0            search/45       :Title
+>>>&0                          use             cnt-name
+#
+# display mime type and name of Windows help Content source
+0      name                            cnt-name
+# skip space at beginning
+>0     string          \040
+# name without extension and greater character or name with hlp extension
+>>1    regex/c         \^([^\xd>]*|.*\.hlp)    MS Windows help file Content, based "%s"
+!:mime text/plain
+!:apple        ????TEXT
+!:ext  cnt
+#
+# Windows creates an full text search from hlp file, if the user clicks the "Find" tab and enables keyword indexing
+0      string          tfMR                    MS Windows help Full Text Search index
+!:mime application/x-winhelp-fts
+!:ext  fts
+>16    string          >\0                     for "%s"
+
+# Summary: Hyper terminal
+# Extension: .ht
+# Created by: unknown
+0      string          HyperTerminal\040
+>15    string          1.0\ --\ HyperTerminal\ data\ file      MS Windows HyperTerminal profile
+
+# https://ithreats.files.wordpress.com/2009/05/\040
+# lnk_the_windows_shortcut_file_format.pdf
+# Summary: Windows shortcut
+# Extension: .lnk
+# Created by: unknown
+# 'L' + GUUID
+0      string          \114\0\0\0\001\024\002\0\0\0\0\0\300\0\0\0\0\0\0\106    MS Windows shortcut
+>20    lelong&1        1       \b, Item id list present
+>20    lelong&2        2       \b, Points to a file or directory
+>20    lelong&4        4       \b, Has Description string
+>20    lelong&8        8       \b, Has Relative path
+>20    lelong&16       16      \b, Has Working directory
+>20    lelong&32       32      \b, Has command line arguments
+>20    lelong&64       64      \b, Icon
+>>56   lelong          x       \b number=%d
+>24    lelong&1        1       \b, Read-Only
+>24    lelong&2        2       \b, Hidden
+>24    lelong&4        4       \b, System
+>24    lelong&8        8       \b, Volume Label
+>24    lelong&16       16      \b, Directory
+>24    lelong&32       32      \b, Archive
+>24    lelong&64       64      \b, Encrypted
+>24    lelong&128      128     \b, Normal
+>24    lelong&256      256     \b, Temporary
+>24    lelong&512      512     \b, Sparse
+>24    lelong&1024     1024    \b, Reparse point
+>24    lelong&2048     2048    \b, Compressed
+>24    lelong&4096     4096    \b, Offline
+>28    leqwdate        x       \b, ctime=%s
+>36    leqwdate        x       \b, mtime=%s
+>44    leqwdate        x       \b, atime=%s
+>52    lelong          x       \b, length=%u, window=
+>60    lelong&1        1       \bhide
+>60    lelong&2        2       \bnormal
+>60    lelong&4        4       \bshowminimized
+>60    lelong&8        8       \bshowmaximized
+>60    lelong&16       16      \bshownoactivate
+>60    lelong&32       32      \bminimize
+>60    lelong&64       64      \bshowminnoactive
+>60    lelong&128      128     \bshowna
+>60    lelong&256      256     \brestore
+>60    lelong&512      512     \bshowdefault
+#>20   lelong&1        0
+#>>20  lelong&2        2
+#>>>(72.l-64)  pstring/h       x       \b [%s]
+#>20   lelong&1        1
+#>>20  lelong&2        2
+#>>>(72.s)     leshort x
+#>>>&75        pstring/h       x       \b [%s]
+
+# Summary: Outlook Personal Folders
+# Created by: unknown
+0      lelong          0x4E444221      Microsoft Outlook email folder
+>10    leshort         0x0e            (<=2002)
+>10    leshort         0x17            (>=2003)
+
+
+# Summary: Windows help cache
+# Created by: unknown
+0      string          \164\146\115\122\012\000\000\000\001\000\000\000        MS Windows help cache
+
+
+# Summary: IE cache file
+# Created by: Christophe Monniez
+0      string  Client\ UrlCache\ MMF   Internet Explorer cache file
+>20    string  >\0                     version %s
+
+
+# Summary: Registry files
+# Created by: unknown
+# Modified by (1): Joerg Jenderek
+0      string          regf            MS Windows registry file, NT/2000 or above
+0      string          CREG            MS Windows 95/98/ME registry file
+0      string          SHCC3           MS Windows 3.1 registry file
+
+
+# Summary: Windows Registry text
+# URL: https://en.wikipedia.org/wiki/Windows_Registry#.REG_files
+# Reference: http://fileformats.archiveteam.org/wiki/Windows_Registry
+# Submitted by: Abel Cheung <abelcheung@gmail.com>
+# Update: Joerg Jenderek
+#              Windows 3-9X variant
+0      string          REGEDIT
+# skip ASCII text like "REGEDITor.txt" but match
+# L1WMAP.REG with only 1 CRNL or org.gnome.gnumeric.reg with 2 NL
+>7     search/3        \n                      Windows Registry text
+!:mime text/x-ms-regedit
+!:ext  reg
+#              Windows 9X variant
+>>0    string          REGEDIT4                (Win95 or above)
+#              Windows 2K ANSI variant
+0      string          Windows\ Registry\ Editor\ 
+>&0    string          Version\ 5.00\r\n\r\n   Windows Registry text (Win2K or above)
+!:mime text/x-ms-regedit
+!:ext  reg
+#              Windows 2K UTF-16 variant
+2      lestring16      Windows\ Registry\ Editor\ 
+>0x32  lestring16      Version\ 5.00\r\n\r\n   Windows Registry little-endian text (Win2K or above)
+# relative offset not working
+#>&0   lestring16      Version\ 5.00\r\n\r\n   Windows Registry little-endian text (Win2K or above)
+!:mime text/x-ms-regedit
+!:ext  reg
+#              WINE variant
+# URL: https://en.wikipedia.org/wiki/Wine_(software)
+# Reference: https://www.winehq.org/pipermail/wine-cvs/2005-October/018763.html
+# Note:        WINE use text based registry (system.reg,user.reg,userdef.reg)
+#      instead binary hiv structure like Windows
+0      string  WINE\ REGISTRY\ Version\        WINE registry text
+# version 2
+>&0    string  x                               \b, version %s
+!:mime text/x-wine-extension-reg
+!:ext  reg
+
+# Windows *.INF *.INI files updated by Joerg Jenderek at Apr 2013, Feb 2018
+# empty ,comment , section
+# PR/383: remove unicode BOM because it is not portable across regex impls
+#0     regex/s         \\`(\\r\\n|;|[[])
+# empty line CRLF
+0      ubeshort        0x0D0A
+>0     use             ini-file
+# comment line
+0      string          ;
+>0     use             ini-file
+# section line
+0      string          [
+>0     use             ini-file
+# check and then display Windows INItialization configuration
+0      name            ini-file
+# look for left bracket in section line
+>0     search/8192     [
+# https://en.wikipedia.org/wiki/Autorun.inf
+# https://msdn.microsoft.com/en-us/library/windows/desktop/cc144200.aspx
+# space after right bracket
+# or AutoRun.Amd64 for 64 bit systems
+# or only NL separator
+>>&0   regex/c         \^(autorun)
+# but sometimes total commander directory tree file "treeinfo.wc" with lines like
+# [AUTORUN]
+# [boot]
+>>>&0  string          =]\r\n[                                 Total commander directory treeinfo.wc
+!:mime text/plain
+!:ext  wc
+# From: Pal Tamas <folti@balabit.hu>
+# Autorun File
+>>>&0  string          !]\r\n[                                 Microsoft Windows Autorun file
+!:mime application/x-setupscript
+!:ext  inf
+# https://msdn.microsoft.com/en-us/library/windows/hardware/ff549520(v=vs.85).aspx
+# version strings ASCII coded case-independent for Windows setup information script file
+>>&0   regex/c         \^(version|strings)]                            Windows setup INFormation
+!:mime application/x-setupscript
+#!:mime application/x-wine-extension-inf
+!:ext  inf
+# NETCRC.INF OEMCPL.INF
+>>&0   regex/c         \^(WinsockCRCList|OEMCPL)]                      Windows setup INFormation
+!:mime application/x-setupscript
+!:ext  inf
+# http://www.winfaq.de/faq_html/Content/tip2500/onlinefaq.php?h=tip2653.htm
+# https://msdn.microsoft.com/en-us/library/windows/desktop/cc144102.aspx
+# .ShellClassInfo DeleteOnCopy LocalizedFileNames ASCII coded case-independent
+>>&0   regex/c \^(\.ShellClassInfo|DeleteOnCopy|LocalizedFileNames)]   Windows desktop.ini
+!:mime application/x-wine-extension-ini
+#!:mime text/plain
+# https://support.microsoft.com/kb/84709/
+>>&0   regex/c         \^(don't\ load)]                                Windows CONTROL.INI
+!:mime application/x-wine-extension-ini
+!:ext  ini
+>>&0   regex/c         \^(ndishlp\\$|protman\\$|NETBEUI\\$)]           Windows PROTOCOL.INI
+!:mime application/x-wine-extension-ini
+!:ext  ini
+# https://technet.microsoft.com/en-us/library/cc722567.aspx
+# http://www.winfaq.de/faq_html/Content/tip0000/onlinefaq.php?h=tip0137.htm
+>>&0   regex/c         \^(windows|Compatibility|embedding)]            Windows WIN.INI
+!:mime application/x-wine-extension-ini
+!:ext  ini
+# https://en.wikipedia.org/wiki/SYSTEM.INI
+>>&0   regex/c         \^(boot|386enh|drivers)]                        Windows SYSTEM.INI
+!:mime application/x-wine-extension-ini
+!:ext  ini
+# http://www.mdgx.com/newtip6.htm
+>>&0   regex/c         \^(SafeList)]                                   Windows IOS.INI
+!:mime application/x-wine-extension-ini
+!:ext  ini
+# https://en.wikipedia.org/wiki/NTLDR  Windows Boot Loader information
+>>&0   regex/c         \^(boot\x20loader)]                             Windows boot.ini
+!:mime application/x-wine-extension-ini
+!:ext  ini
+# https://en.wikipedia.org/wiki/CONFIG.SYS
+>>&0   regex/c         \^(menu)]                                       MS-DOS CONFIG.SYS
+# @CONFIG.UI configuration file of previous DOS version saved by Caldera OPENDOS INSTALL.EXE
+# CONFIG.PSS saved version of file CONFIG.SYS created by %WINDIR%\SYTEM\MSCONFIG.EXE
+# CONFIG.TSH renamed file CONFIG.SYS.BAT by %WINDIR%\SYTEM\MSCONFIG.EXE
+# dos and w40 used in dual booting scene
+!:ext  sys/dos/w40
+# https://support.microsoft.com/kb/118579/
+>>&0   regex/c         \^(Paths)]\r\n                                  MS-DOS MSDOS.SYS
+!:ext  sys/dos
+# http://chmspec.nongnu.org/latest/INI.html#HHP
+>>&0   regex/c         \^(options)]\r\n                                Microsoft HTML Help Project
+!:mime text/plain
+!:ext  hhp
+# unknown keyword after opening bracket
+>>&0   default                         x
+#>>>&0 string/c                        x       UNKNOWN [%s
+# look for left bracket of second section
+>>>&0  search/8192                     [
+# version Strings FileIdentification
+>>>>&0 string/c                        version                         Windows setup INFormation
+!:mime application/x-setupscript
+!:ext  inf
+# https://en.wikipedia.org/wiki/Initialization_file    Windows Initialization File or other
+>>>>&0 default                         x
+>>>>>&0        ubyte                           x
+# characters, digits, underscore and white space followed by right bracket
+# terminated by CR implies section line to skip BOOTLOG.TXT DETLOG.TXT
+>>>>>>&-1      regex                   \^([A-Za-z0-9_\(\)\ ]+)\]\r     Generic INItialization configuration [%-.40s
+# NETDEF.INF multiarc.ini 
+#!:mime        application/x-setupscript
+!:mime application/x-wine-extension-ini
+#!:mime        text/plain
+!:ext  ini/inf
+# UTF-16 BOM followed by CR~0D00 , comment~semicolon~3B00 , section~bracket~5B00
+0      ubelong&0xFFff89FF      =0xFFFE0900
+# look for left bracket in section line
+>2     search/8192             [
+# keyword without 1st letter which is maybe up-/down-case
+>>&3   lestring16              ersion]                 Windows setup INFormation
+!:mime application/x-setupscript
+!:ext  inf
+>>&3   lestring16              trings]                 Windows setup INFormation
+!:mime application/x-setupscript
+!:ext  inf
+>>&3   lestring16              ourceDisksNames]        Windows setup INFormation
+!:mime application/x-setupscript
+!:ext  inf
+# netnwcli.inf start with ;---[ NetNWCli.INX ]
+>>&3   default                 x
+# look for NL followed by left bracket
+>>>&0  search/8192             \x0A\x00\x5b
+>>>>&3 lestring16              ersion]                 Windows setup INFormation
+!:mime application/x-setupscript
+!:ext  inf
+
+# Windows Precompiled INF files *.PNF added by Joerg Jenderek at Mar 2013 of _PNF_HEADER inf.h
+# http://read.pudn.com/downloads3/sourcecode/windows/248345/win2k/private/windows/setup/setupapi/inf.h__.htm
+# GRR: line below too general as it catches also PDP-11 UNIX/RT ldp
+0              leshort&0xFeFe  0x0000
+!:strength -5
+# test for unused null bits in PNF_FLAGs
+>4     ulelong&0xFCffFe00      0x00000000
+# only found 58h for Offset of WinDirPath immediately after _PNF_HEADER structure
+>>68           ulelong         >0x57
+# test for zero high byte of InfValueBlockSize, followed by WinDirPath like
+# C:\WINDOWS (ASCII 0x433a5c.. , unicode 0x43003a005c..) or X:\MININT
+>>>(68.l-1)    ubelong&0xffE0C519      =0x00400018     Windows Precompiled iNF
+!:mime application/x-pnf
+# currently only found Major Version=1 and Minor Version=1
+#>>>>0         uleshort        =0x0101
+#>>>>>1                ubyte           x               \b, version %u
+#>>>>>0                ubyte           x               \b.%u
+>>>>0          uleshort        !0x0101
+>>>>>1         ubyte           x               \b, version %u
+>>>>>0         ubyte           x               \b.%u
+# 1 ,2 (windows 98 SE)
+#>>>>2         uleshort        =2              \b, InfStyle %u
+>>>>2          uleshort        !2              \b, InfStyle %u
+#      PNF_FLAG_IS_UNICODE             0x00000001
+#      PNF_FLAG_HAS_STRINGS            0x00000002
+#      PNF_FLAG_SRCPATH_IS_URL         0x00000004
+#      PNF_FLAG_HAS_VOLATILE_DIRIDS    0x00000008
+#      PNF_FLAG_INF_VERIFIED           0x00000010
+#      PNF_FLAG_INF_DIGITALLY_SIGNED   0x00000020
+#      ??                              0x00000100
+#      ??                              0x01000000
+#      ??                              0x02000000
+>>>>4  ulelong&0x00000001      0x00000001      \b, unicoded
+>>>>4  ulelong&0x00000020      0x00000020      \b, digitally signed
+#>>>>8         ulelong         x               \b, InfSubstValueListOffset 0x%x
+# many 0, 1 lmouusb.PNF, 2 linkfx10.PNF , f webfdr16.PNF
+#>>>>12                uleshort        x               \b, InfSubstValueCount 0x%x
+# only < 9 found
+#>>>>14                uleshort        x               \b, InfVersionDatumCount 0x%x
+# only found values lower 0x0000ffff
+#>>>>16                ulelong         x               \b, InfVersionDataSize 0x%x
+# only found positive values lower 0x00ffFFff for InfVersionDataOffset
+>>>>20         ulelong         x               \b, at 0x%x
+>>>>4  ulelong&0x00000001      =0x00000001
+# case independent: CatalogFile Class DriverVer layoutfile LayoutFile SetupClass signature Signature
+>>>>>(20.l)    lestring16      x               "%s"
+>>>>4  ulelong&0x00000001      !0x00000001
+>>>>>(20.l)    string          x               "%s"
+# FILETIME is number of 100-nanosecond intervals since 1 January 1601
+#>>>>24                ulequad         x               \b, InfVersionLastWriteTime %16.16llx
+# only found values lower 0x00ffFFff
+#>>>>32                ulelong         x               \b, StringTableBlockOffset 0x%x
+#>>>>36                ulelong         x               \b, StringTableBlockSize 0x%x
+#>>>>40                ulelong         x               \b, InfSectionCount 0x%x
+#>>>>44                ulelong         x               \b, InfSectionBlockOffset 0x%x
+#>>>>48                ulelong         x               \b, InfSectionBlockSize 0x%x
+#>>>>52                ulelong         x               \b, InfLineBlockOffset 0x%x
+#>>>>56                ulelong         x               \b, InfLineBlockSize 0x%x
+#>>>>60                ulelong         x               \b, InfValueBlockOffset 0x%x
+#>>>>64                ulelong         x               \b, InfValueBlockSize 0x%x
+# WinDirPathOffset
+#>>>>68                ulelong         x               \b, at 0x%x
+>>>>68         ulelong         >0x57
+>>>>>4 ulelong&0x00000001      =0x00000001
+>>>>>>(68.l)   ubequad         =0x43003a005c005700
+# normally unicoded C:\Windows
+#>>>>>>>(68.l) lestring16      x               \b, WinDirPath "%s"
+>>>>>>(68.l)   ubequad         !0x43003a005c005700
+>>>>>>>(68.l)  lestring16      x               \b, WinDirPath "%s"
+>>>>>4 ulelong&0x00000001      !0x00000001
+# normally ASCII C:\WINDOWS
+#>>>>>>(68.l)  string          =C:\\WINDOWS    \b, WinDirPath "%s"
+>>>>>>(68.l)   string          !C:\\WINDOWS    \b, WinDirPath "%s"
+# found OsLoaderPathOffset values often 0 , once 70h corelist.PNF, once 68h ASCII machine.PNF
+#>>>>72                ulelong         >0              \b, at 0x%x
+>>>>72         ulelong         >0              \b,
+>>>>>4 ulelong&0x00000001      =0x00000001
+>>>>>>(72.l)   lestring16      x               OsLoaderPath "%s"
+>>>>>4 ulelong&0x00000001      !0x00000001
+# seldom C:\ instead empty
+>>>>>>(72.l)   string          x               OsLoaderPath "%s"
+# 1fdh
+#>>>>76                uleshort        x               \b, StringTableHashBucketCount 0x%x
+>>>>78         uleshort        !0x407          \b, LanguageId %x
+# only 407h found
+#>>>>78                uleshort        =0x407          \b, LanguageId %x
+# InfSourcePathOffset often 0
+#>>>>80                ulelong         >0              \b, at 0x%x
+>>>>80         ulelong         >0              \b,
+>>>>>4 ulelong&0x00000001      =0x00000001
+>>>>>>(80.l)   lestring16      x               SourcePath "%s"
+>>>>>4 ulelong&0x00000001      !0x00000001
+>>>>>>(80.l)   string          >\0             SourcePath "%s"
+# OriginalInfNameOffset often 0
+#>>>>84                ulelong         >0              \b, at 0x%x
+>>>>84         ulelong         >0              \b,
+>>>>>4 ulelong&0x00000001      =0x00000001
+>>>>>>(84.l)   lestring16      x               InfName "%s"
+>>>>>4 ulelong&0x00000001      !0x00000001
+>>>>>>(84.l)   string          >\0             InfName "%s"
+
+# Summary: backup file created with utility like NTBACKUP.EXE shipped with Windows NT/2K/XP/2003
+# Extension: .bkf
+# Created by: Joerg Jenderek
+# URL: https://en.wikipedia.org/wiki/NTBackup
+# Reference: http://laytongraphics.com/mtf/MTF_100a.PDF
+# Descriptor BloCK name of Microsoft Tape Format
+0      string                  TAPE
+# Format Logical Address is zero
+>20    ulequad                 0
+# Reserved for MBC is zero
+>>28   uleshort                0
+# Control Block ID is zero
+>>>36  ulelong                 0
+# BIT4-BIT15, BIT18-BIT31 of block attributes are unused
+>>>>4  ulelong&0xFFfcFFe0      0               Windows NTbackup archive
+#!:mime application/x-ntbackup
+!:ext bkf
+# OS ID
+>>>>>10        ubyte                   1               \b NetWare
+>>>>>10        ubyte                   13              \b NetWare SMS
+>>>>>10        ubyte                   14              \b NT
+>>>>>10        ubyte                   24              \b 3
+>>>>>10        ubyte                   25              \b OS/2
+>>>>>10        ubyte                   26              \b 95
+>>>>>10        ubyte                   27              \b Macintosh
+>>>>>10        ubyte                   28              \b UNIX
+# OS Version (2)
+#>>>>>11       ubyte                   x               OS V=%x
+# MTF_CONTINUATION     Media Sequence Number > 1
+#>>>>>4        ulelong&0x00000001      !0              \b, continued
+# MTF_COMPRESSION
+>>>>>4 ulelong&0x00000004      !0              \b, compressed
+# MTF_EOS_AT_EOM       End Of Medium was hit during end of set processing
+>>>>>4 ulelong&0x00000008      !0              \b, End Of Medium hit
+>>>>>4 ulelong&0x00020000      0
+# MTF_SET_MAP_EXISTS   A Media Based Catalog Set Map may exist on tape
+>>>>>>4        ulelong&0x00010000      !0              \b, with catalog
+# MTF_FDD_ALLOWED      However File/Directory Detail can only exist if a Set Map is also present
+>>>>>4 ulelong&0x00020000      !0              \b, with file catalog
+# Offset To First Event 238h,240h,28Ch
+#>>>>>8        uleshort                x               \b, event offset %4.4x
+# Displayable Size (20e0230h 20e024ch 20e0224h)
+#>>>>>8        ulequad                 x               dis. size %16.16llx
+# Media Family ID (455288C4h 4570BD1Ah 45708F2Fh 4570BBF5h)
+#>>>>>52       ulelong                 x               family ID %8.8x
+# TAPE Attributes (3)
+#>>>>>56       ulelong                 x               TAPE %8.8x
+# Media Sequence Number
+>>>>>60        uleshort                >1              \b, sequence %u
+# Password Encryption Algorithm (3)
+>>>>>62        uleshort                >0              \b, 0x%x encrypted
+# Soft Filemark Block Size * 512 (2)
+#>>>>>64       uleshort                =2              \b, soft size %u*512
+>>>>>64        uleshort                !2              \b, soft size %u*512
+# Media Based Catalog Type (1,2)
+#>>>>>66       uleshort                x               \b, catalog type %4.4x
+# size of Media Name (66,68,6Eh)
+>>>>>68        uleshort                >0
+# offset of Media Name (5Eh)
+>>>>>>70       uleshort        >0
+# 0~, 1~ANSI, 2~UNICODE
+>>>>>>>48      ubyte           1
+# size terminated ansi coded string normally followed by "MTF Media Label"
+>>>>>>>>(70.s) string          >\0             \b, name: %s
+>>>>>>>48      ubyte           2
+# Not null, but size terminated unicoded string
+>>>>>>>>(70.s) lestring16      x               \b, name: %s
+# size of Media Label (104h)
+>>>>>72        uleshort                >0
+# offset of Media Label (C4h,C6h,CCh)
+>>>>>74                uleshort        >0
+>>>>>>48       ubyte           1
+#Tag|Version|Vendor|Vendor ID|Creation Time Stamp|Cartridge Label|Side|Media ID|Media Domain ID|Vendor Specific fields
+>>>>>>>(74.s)  string          >\0             \b, label: %s
+>>>>>>48       ubyte           2
+>>>>>>>(74.s)  lestring16      x               \b, label: %s
+# size of password name (0,1Ch)
+#>>>>>76       uleshort                >0              \b, password size %4.4x
+# Software Vendor ID (CBEh)
+>>>>>86        uleshort                x               \b, software (0x%x)
+# size of Software Name (6Eh)
+>>>>>80        uleshort                >0
+# offset of Software Name (1C8h,1CAh,1D0h)
+>>>>>>82       uleshort        >0
+# 1~ANSI, 2~UNICODE
+>>>>>>>48      ubyte           1
+>>>>>>>>(82.s) string          >\0             \b: %s
+>>>>>>>48      ubyte           2
+# size terminated unicoded coded string normally followed by "SPAD"
+>>>>>>>>(82.s) lestring16      x               \b: %s
+# Format Logical Block Size (512,1024)
+#>>>>>84       uleshort                =1024           \b, block size %u
+>>>>>84        uleshort                !1024           \b, block size %u
+# Media Date of MTF_DATE_TIME type with 5 bytes
+#>>>>>>88      ubequad                 x               DATE %16.16llx
+# MTF Major Version (1)
+#>>>>>>93      ubyte           x               \b, MFT version %x
+#
+
+# URL: https://en.wikipedia.org/wiki/PaintShop_Pro
+# Reference: https://www.cryer.co.uk/file-types/p/pal.htm
+# Created by: Joerg Jenderek
+# Note: there exist other color palette formats also with .pal extension
+0      string  JASC-PAL\r\n    PaintShop Pro color palette
+#!:mime        text/plain
+# PspPalette extension is used by newer (probably 8) PaintShopPro versions
+!:ext  pal/PspPalette
+# 2nd line contains palette file version. For example "0100"
+>10    string  !0100           \b, version %.4s
+# third line contains the number of colours: 16 256 ...
+>16    string  x               \b, %.3s colors
+
+# URL: https://en.wikipedia.org/wiki/Innosetup
+# Reference: https://github.com/jrsoftware/issrc/blob/master/Projects/Undo.pas
+# Created by: Joerg Jenderek
+# Note:        created by like "InnoSetup self-extracting archive" inside ./msdos
+# TrID labeles the entry as "Inno Setup Uninstall Log"
+#      TUninstallLogID
+0      string  Inno\ Setup\ Uninstall\ Log\ (b)        InnoSetup Log
+!:mime application/x-innosetup
+# unins000.dat, unins001.dat, ...
+!:ext  dat
+# " 64-bit" variant
+>0x1c  string          >\0                             \b%.7s
+# AppName[0x80] like "Minimal SYStem", ClamWin Free Antivirus , ...
+>0xc0  string          x                               %s
+# AppId[0x80] is simliar to AppName or
+# GUID like {4BB0DCDC-BC24-49EC-8937-72956C33A470} start with left brace
+>0x40  ubyte           0x7b
+>>0x40 string          x                               %-.38s
+# do not know how this log version correlates to program version
+>0x140 ulelong         x                               \b, version 0x%x
+# NumRecs
+#>0x144        ulelong         x                               \b, 0x%4.4x records
+# EndOffset means files size
+>0x148 ulelong         x                               \b, %u bytes
+# Flags 5 25h 35h
+#>0x14c        ulelong         x                               \b, flags %8.8x
+# Reserved: array[0..26] of Longint
+# the non Unicode HighestSupportedVersion may never become greater than or equal to 1000
+>0x140 ulelong         <1000
+# hostname
+>>0x1d6        pstring         x                               \b, %s
+# user name
+>>>&0  pstring         x                               \b\%s
+# directory like C:\Program Files (x86)\GnuWin32
+>>>>&0 pstring         x                               \b, "%s"
+# version 1000 or higher implies unicode
+>0x140 ulelong         >999
+# hostname
+>>0x1db        lestring16      x                               \b, %-.9s
+# utf string variant with prepending fe??ffFFff
+>>0x1db        search/43       \xFF\xFF\xFF                    
+# user name
+>>>&0  lestring16      x                               \b\%-.9s
+>>>&0  search/43       \xFF\xFF\xFF                    
+# directory like C:\Program Files\GIMP 2
+>>>>&0 lestring16      x                               \b, %-.42s
+
+# Windows Imaging (WIM) Image
+# Update: Joerg Jenderek at Mar 2019
+# URL: https://en.wikipedia.org/wiki/Windows_Imaging_Format
+# Reference: https://download.microsoft.com/download/f/e/f/
+# fefdc36e-392d-4678-9e4e-771ffa2692ab/Windows%20Imaging%20File%20Format.rtf
+# Note: verified by like `7z t boot.wim` `wiminfo install.esd --header`
+0      string          MSWIM\000\000\000
+>0     use             wim-archive
+# https://wimlib.net/man1/wimoptimize.html
+0      string          WLPWM\000\000\000
+>0     use             wim-archive
+0      name            wim-archive
+# _WIMHEADER_V1_PACKED ImageTag[8]
+>0     string          x                       Windows imaging
+!:mime application/x-ms-wim
+# TO avoid in file version 5.36 error like
+# Magdir/windows, 760: Warning: Current entry does not yet have a description
+# file: could not find any valid magic files! (No error)
+# splitted WIM
+>16    ulelong         &0x00000008             (SWM
+!:ext  swm
+# usPartNumber; 1, unless the file was split into multiple parts
+>>40   uleshort        x                       \b %u
+# usTotalParts; The total number of WIM file parts in a spanned set
+>>42   uleshort        x                       \b of %u) image
+# non splitted WIM
+>16    ulelong         ^0x00000008
+# https://wimlib.net/man1/wimmount.html
+# solid WIMs; version 3584; usually contain LZMS-compressed and the .esd extension
+>>12   ulelong         3584                    (ESD) image
+!:ext  esd
+>>12   ulelong         !3584                   (WIM) image
+!:ext  wim
+>0     string/b        WLPWM\000\000\000       \b, wimlib pipable format
+# cbSize size of the WIM header in bytes like 208
+#>8    ulelong         x                       \b, headersize %u
+# dwVersion version of the WIM file 00010d00h~1.13 00000e00h~0.14
+>14    uleshort        x                       v%u
+>13    ubyte           x                       \b.%u
+# dwImageCount; The number of images contained in the WIM file
+>44    ulelong         >1                      \b, %u images
+# dwBootIndex
+# 1-based index of the bootable image of the WIM, or 0 if no image is bootable
+>0x78  ulelong         >0                      \b, bootable no. %u
+# dwFlags
+#>16   ulelong         x                       \b, flags 0x%8.8x
+#define FLAG_HEADER_COMPRESSION                0x00000002
+#define FLAG_HEADER_READONLY            0x00000004
+#define FLAG_HEADER_SPANNED            0x00000008
+#define FLAG_HEADER_RESOURCE_ONLY       0x00000010
+#define FLAG_HEADER_METADATA_ONLY       0x00000020
+#define FLAG_HEADER_WRITE_IN_PROGRESS   0x00000040
+#define FLAG_HEADER_RP_FIX             0x00000080 reparse point fixup
+#define FLAG_HEADER_COMPRESS_RESERVED   0x00010000
+#define FLAG_HEADER_COMPRESS_XPRESS     0x00020000
+#define FLAG_HEADER_COMPRESS_LZX       0x00040000
+#define FLAG_HEADER_COMPRESS_LZMS      0x00080000
+#define FLAG_HEADER_COMPRESS_XPRESS2    0x00100000 wimlib-1.13.0\include\wimlib\header.h 
+# XPRESS, with small chunk size
+>16    ulelong         &0x00100000             \b, XPRESS2
+>16    ulelong         &0x00080000             \b, LZMS
+>16    ulelong         &0x00040000             \b, LZX
+>16    ulelong         &0x00020000             \b, XPRESS
+>16    ulelong         &0x00000002             compressed
+>16    ulelong         &0x00000004             \b, read only
+>16    ulelong         &0x00000010             \b, resource only
+>16    ulelong         &0x00000020             \b, metadata only
+>16    ulelong         &0x00000080             \b, reparse point fixup
+#>16   ulelong         &0x00010000             \b, RESERVED
+# dwCompressionSize; Uncompressed chunk size for resources or 0 if uncompressed
+#>20   ulelong         >0                      \b, chunk size %u bytes
+# gWIMGuid
+#>24   ubequad         x                       \b, GUID 0x%16.16llx
+#>>32  ubequad         x                       \b%16.16llx
+# rhOffsetTable; the location of the resource lookup table
+# wim_reshdr_disk[24]= u8 size_in_wim[7] + u8 flags + le64 offset_in_wim + le64 uncompressed_size
+#>48   ubequad         x                       \b, rhOffsetTable 0x%16.16llx
+# rhXmlData; the location of the XML data
+#>0x50 ulelong         x                       \b, at 0x%8.8x
+# NOT WORKING \xff\xfe<\0W\0I\0M\0
+#>(0x50.l)     ubequad x                       \b, xml=%16.16llx
+# rhBootMetadata; the location of the metadata resource
+#>0x60 ubequad         x                       \b, rhBootMetadata 0x%16.16llx
+# rhIntegrity; the location of integrity table used to verify files
+#>0x7c ubequad         x                       \b, rhIntegrity 0x%16.16llx
+# Unused[60]
+#>148  ubequad         !0                      \b,unused 0x%16.16llx
+#
+
diff --git a/magic/Magdir/wireless b/magic/Magdir/wireless
new file mode 100644 (file)
index 0000000..f3c2801
--- /dev/null
@@ -0,0 +1,7 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# wireless-regdb:        file(1) magic for CRDA wireless-regdb file format
+#
+0      string  RGDB    CRDA wireless regulatory database file
+>4     belong  19      (Version 1)
diff --git a/magic/Magdir/wordprocessors b/magic/Magdir/wordprocessors
new file mode 100644 (file)
index 0000000..4b08c43
--- /dev/null
@@ -0,0 +1,262 @@
+
+#------------------------------------------------------------------------------
+# $File: wordprocessors,v 1.20 2019/04/19 00:42:27 christos Exp $
+# wordprocessors:  file(1) magic fo word processors.
+#
+####### PWP file format used on Smith Corona Personal Word Processors:
+2      string  \040\040\040\040\040\040\040\040\040\040\040ML4D\040'92 Smith Corona PWP
+>24    byte    2       \b, single spaced
+>24    byte    3       \b, 1.5 spaced
+>24    byte    4       \b, double spaced
+>25    byte    0x42    \b, letter
+>25    byte    0x54    \b, legal
+>26    byte    0x46    \b, A4
+
+# Corel/WordPerfect
+0      string  \xffWPC
+# WordPerfect
+>8     byte    1
+>>9    byte    1       WordPerfect macro
+>>9    byte    2       WordPerfect help file
+>>9    byte    3       WordPerfect keyboard file
+>>9    byte    10      WordPerfect document
+>>9    byte    11      WordPerfect dictionary
+>>9    byte    12      WordPerfect thesaurus
+>>9    byte    13      WordPerfect block
+>>9    byte    14      WordPerfect rectangular block
+>>9    byte    15      WordPerfect column block
+>>9    byte    16      WordPerfect printer data
+>>9    byte    19      WordPerfect printer data
+>>9    byte    20      WordPerfect driver resource data
+>>9    byte    22      WordPerfect graphic image
+>>9    byte    23      WordPerfect hyphenation code
+>>9    byte    24      WordPerfect hyphenation data
+>>9    byte    25      WordPerfect macro resource data
+>>9    byte    27      WordPerfect hyphenation lex
+>>9    byte    29      WordPerfect wordlist
+>>9    byte    30      WordPerfect equation resource data
+>>9    byte    33      WordPerfect spell rules
+>>9    byte    34      WordPerfect dictionary rules
+>>9    byte    39      WordPerfect spell rules (Microlytics)
+>>9    byte    43      WordPerfect settings file
+>>9    byte    44      WordPerfect 3.5 document
+>>9    byte    45      WordPerfect 4.2 document
+>>9    byte    69      WordPerfect dialog file
+>>9    byte    76      WordPerfect button bar
+>>9    default x
+>>>9   byte    x       Corel WordPerfect: Unknown filetype %d
+# Corel Shell
+>8     byte    2
+>>9    byte    1       Corel shell macro
+>>9    byte    10      Corel shell definition
+>>9    default x
+>>>9   byte    x       Corel Shell: Unknown filetype %d
+# Corel Notebook
+>8     byte    3
+>>9    byte    1       Corel Notebook macro
+>>9    byte    2       Corel Notebook help file
+>>9    byte    3       Corel Notebook keyboard file
+>>9    byte    10      Corel Notebook definition
+>>9    default x
+>>>9   byte    x       Corel Notebook: Unknown filetype %d
+# Corel Calculator
+>8     byte    4
+>>9    byte    2       Corel Calculator help file
+>>9    default x
+>>>9   byte    x       Corel Calculator: Unknown filetype %d
+# Corel File Manager
+>8     byte    5
+>>9    default x
+>>>9   byte    x       Corel File Manager: Unknown filetype %d
+# Corel Calendar
+>8     byte    6
+>>9    byte    2       Corel Calendar help file
+>>9    byte    10      Corel Calendar data file
+>>9    default x
+>>>9   byte    x       Corel Calendar: Unknown filetype %d
+# Corel Program Editor/Ed Editor
+>8     byte    7
+>>9    byte    1       Corel Editor macro
+>>9    byte    2       Corel Editor help file
+>>9    byte    3       Corel Editor keyboard file
+>>9    byte    25      Corel Editor macro resource file
+>>9    default x
+>>>9   byte    x       Corel Program Editor/Ed Editor: Unknown filetype %d
+# Corel Macro Editor
+>8     byte    8
+>>9    byte    1       Corel Macro editor macro
+>>9    byte    2       Corel Macro editor help file
+>>9    byte    3       Corel Macro editor keyboard file
+>>9    default x
+>>>9   byte    x       Corel Macro Editor: Unknown filetype %d
+# Corel Plan Perfect
+>8     byte    9
+>>9    default x
+>>>9   byte    x       Corel Plan Perfect: Unknown filetype %d
+# Corel DataPerfect
+>8     byte    10
+# CHECK: Don't these belong into product 9?
+>>9    byte    1       Corel PlanPerfect macro
+>>9    byte    2       Corel PlanPerfect help file
+>>9    byte    3       Corel PlanPerfect keyboard file
+>>9    byte    10      Corel PlanPerfect worksheet
+>>9    byte    15      Corel PlanPerfect printer definition
+>>9    byte    18      Corel PlanPerfect graphic definition
+>>9    byte    19      Corel PlanPerfect data
+>>9    byte    20      Corel PlanPerfect temporary printer
+>>9    byte    25      Corel PlanPerfect macro resource data
+>>9    default x
+>>>9   byte    x       Corel DataPerfect: Unknown filetype %d
+# Corel Mail
+>8     byte    11
+>>9    byte    2       Corel Mail help file
+>>9    byte    5       Corel Mail distribution list
+>>9    byte    10      Corel Mail out box
+>>9    byte    11      Corel Mail in box
+>>9    byte    20      Corel Mail users archived mailbox
+>>9    byte    21      Corel Mail archived message database
+>>9    byte    22      Corel Mail archived attachments
+>>9    default x
+>>>9   byte    x       Corel Mail: Unknown filetype %d
+# Corel Printer
+>8     byte    12
+>>9    byte    11      Corel Printer temporary file
+>>9    default x
+>>>9   byte    x       Corel Printer: Unknown filetype %d
+# Corel Scheduler
+>8     byte    13
+>>9    byte    2       Corel Scheduler help file
+>>9    byte    10      Corel Scheduler in file
+>>9    byte    11      Corel Scheduler out file
+>>9    default x
+>>>9   byte    x       Corel Scheduler: Unknown filetype %d
+# Corel WordPerfect Office
+>8     byte    14
+>>9    byte    10      Corel GroupWise settings file
+>>9    byte    17      Corel GroupWise directory services
+>>9    byte    43      Corel GroupWise settings file
+>>9    default x
+>>>9   byte    x       Corel WordPerfect Office: Unknown filetype %d
+# Corel DrawPerfect
+>8     byte    15
+>>9    default x
+>>>9   byte    x       Corel DrawPerfect: Unknown filetype %d
+# Corel LetterPerfect
+>8     byte    16
+>>9    default x
+>>>9   byte    x       Corel LetterPerfect: Unknown filetype %d
+# Corel Terminal
+>8     byte    17
+>>9    byte    10      Corel Terminal resource data
+>>9    byte    11      Corel Terminal resource data
+>>9    byte    43      Corel Terminal resource data
+>>9    default x
+>>>9   byte    x       Corel Terminal: Unknown filetype %d
+# Corel loadable file
+>8     byte    18
+>>9    byte    10      Corel loadable file
+>>9    byte    11      Corel GUI loadable text
+>>9    byte    12      Corel graphics resource data
+>>9    byte    13      Corel printer settings file
+>>9    byte    14      Corel port definition file
+>>9    byte    15      Corel print queue parameters
+>>9    byte    16      Corel compressed file
+>>9    default x
+>>>9   byte    x       Corel loadable file: Unknown filetype %d
+>>15   byte    0       \b, optimized for Intel
+>>15   byte    1       \b, optimized for Non-Intel
+# Network service
+>8     byte    20
+>>9    byte    10      Corel Network service msg file
+>>9    byte    11      Corel Network service msg file
+>>9    byte    12      Corel Async gateway login msg
+>>9    byte    14      Corel GroupWise message file
+>>9    default x
+>>>9   byte    x       Corel Network service: Unknown filetype %d
+# GroupWise
+>8     byte    31
+>>9    byte    20      GroupWise admin domain database
+>>9    byte    21      GroupWise admin host database
+>>9    byte    23      GroupWise admin remote host database
+>>9    byte    24      GroupWise admin ADS deferment data file
+>>9    default x
+>>>9   byte    x       GroupWise: Unknown filetype %d
+# IntelliTAG
+>8     byte    33
+>>9    byte    10      IntelliTAG (SGML) compiled DTD
+>>9    default x
+>>>9   byte    x       IntelliTAG: Unknown filetype %d
+# everything else
+>8     default x
+>>8    byte    x       Unknown Corel/Wordperfect product %d,
+>>>9   byte    x       file type %d
+>10    byte    0       \b, v5.
+>10    byte    !0      \b, v%d.
+>11    byte    x       \b%d
+
+# Hangul (Korean) Word Processor File
+0      string  HWP\ Document\ File     Hangul (Korean) Word Processor File 3.0
+# From: Won-Kyu Park <wkpark@kldp.org>
+512    string          R\0o\0o\0t\0    Hangul (Korean) Word Processor File 2000
+!:mime application/x-hwp
+
+# CosmicBook, from Benoit Rouits
+0       string  CSBK    Ted Neslson's CosmicBook hypertext file
+
+2       string  EYWR    AmigaWriter file
+
+# chi:  file(1) magic for ChiWriter files
+0       string          \\1cw\          ChiWriter file
+>5      string          >\0             version %s
+0       string          \\1cw           ChiWriter file
+
+# Quark Express from https://www.garykessler.net/library/file_sigs.html
+2      string  IIXPR3                  Intel Quark Express Document (English)
+2      string  IIXPRa                  Intel Quark Express Document (Korean)
+2      string  MMXPR3                  Motorola Quark Express Document (English)
+!:mime application/x-quark-xpress-3
+2      string  MMXPRa                  Motorola Quark Express Document (Korean)
+
+# adobe indesign (document, whatever...) from querkan
+0      belong  0x0606edf5              Adobe InDesign
+>16    string  DOCUMENT                Document
+
+#------------------------------------------------------------------------------
+# ichitaro456: file(1) magic for Just System Word Processor Ichitaro
+#
+# Contributor kenzo-:
+# Reversed-engineered JS Ichitaro magic numbers
+#
+
+0      string          DOC
+>43    byte            0x14    Just System Word Processor Ichitaro v4
+!:mime application/x-ichitaro4
+>144   string  JDASH           application/x-ichitaro4
+
+0      string          DOC
+>43    byte            0x15    Just System Word Processor Ichitaro v5
+!:mime application/x-ichitaro5
+
+0      string          DOC
+>43    byte            0x16    Just System Word Processor Ichitaro v6
+!:mime application/x-ichitaro6
+
+# Type: Freemind mindmap documents
+# From: Jamie Thompson <debian-bugs@jamie-thompson.co.uk>
+0      string/w        \<map\ version  Freemind document
+!:mime application/x-freemind
+
+# Type: Freeplane mindmap documents
+# From: Felix Natter <fnatter@gmx.net>
+0       string/w        \<map\ version="freeplane  Freeplane document
+!:mime  application/x-freeplane
+
+# Type:        Scribus
+# From:        Werner Fink <werner@suse.de>
+0      string  \<SCRIBUSUTF8\ Version          Scribus Document
+0      string  \<SCRIBUSUTF8NEW\ Version       Scribus Document
+!:mime application/x-scribus
+
+# help files .hlp compiled from html and used by gfxboot added by Joerg Jenderek
+# markups page=0x04,label=0x12, followed by strings like "opt" or "main" and title=0x14
+0      ulelong&0x8080FFFF      0x00001204      gfxboot compiled html help file
diff --git a/magic/Magdir/wsdl b/magic/Magdir/wsdl
new file mode 100644 (file)
index 0000000..35edafc
--- /dev/null
@@ -0,0 +1,23 @@
+
+#------------------------------------------------------------------------------
+# $File: wsdl,v 1.5 2019/04/19 00:42:27 christos Exp $
+# wsdl: PHP WSDL Cache, https://www.php.net/manual/en/book.soap.php
+# Cache format extracted from source:
+# https://svn.php.net/viewvc/php/php-src/trunk/ext/soap/php_sdl.c?revision=HEAD&view=markup
+# Requires file >= 5.05
+# By Elan Ruusamae <glen@delfi.ee>, Patryk Zawadzki <patrys@pld-linux.org>, 2010-2011
+0              string          wsdl            PHP WSDL cache,
+>4             byte            x               version 0x%02x
+>6             ledate          x               \b, created %s
+
+# uri
+>10            lelong          <0x7fffffff
+>>10           pstring/l       x               \b, uri: "%s"
+
+# source
+>>>&0          lelong          <0x7fffffff
+>>>>&-4                pstring/l       x               \b, source: "%s"
+
+# target_ns
+>>>>>&0                lelong          <0x7fffffff
+>>>>>>&-4      pstring/l       x               \b, target_ns: "%s"
diff --git a/magic/Magdir/x68000 b/magic/Magdir/x68000
new file mode 100644 (file)
index 0000000..927b96d
--- /dev/null
@@ -0,0 +1,25 @@
+#------------------------------------------------------------------------------
+# x68000:  file(1) magic for the Sharp Home Computer
+# v1.0
+# Fabio R. Schmidlin <sd-snatcher@users.sourceforge.net>
+
+# Yanagisawa PIC picture
+0      string          PIC
+>3     search/0x200    \x1A
+>>&0   search/0x200    \x0
+>>>&0  ubyte           0               Yanagisawa PIC image file,
+>>>>&0 ubyte&15        0               model: X68000,
+>>>>&0 ubyte&15        1               model: PC-88VA,
+>>>>&0 ubyte&15        2               model: FM-TOWNS,
+>>>>&0 ubyte&15        3               model: MAC,
+>>>>&0 ubyte&15        15              model: Generic,
+>>>>&3 ubeshort        x               %dx
+>>>>&5 ubeshort        x               \b%d,
+>>>>&1 ubeshort        4               colors: 16
+>>>>&1 ubeshort        8               colors: 256
+>>>>&1 ubeshort        12              colors: 4096
+>>>>&1 ubeshort        15              colors: 32768
+>>>>&1 ubeshort        16              colors: 65536
+>>>>&1 ubeshort        >16             colors: %d-bit
+
+
diff --git a/magic/Magdir/xdelta b/magic/Magdir/xdelta
new file mode 100644 (file)
index 0000000..73cb9e7
--- /dev/null
@@ -0,0 +1,13 @@
+
+#------------------------------------------------------------------------------
+# $File: xdelta,v 1.4 2009/09/19 16:28:13 christos Exp $
+# file(1) magic(5) data for xdelta  Josh MacDonald <jmacd@CS.Berkeley.EDU>
+#
+0      string  %XDELTA%        XDelta binary patch file 0.14
+0      string  %XDZ000%        XDelta binary patch file 0.18
+0      string  %XDZ001%        XDelta binary patch file 0.20
+0      string  %XDZ002%        XDelta binary patch file 1.0
+0      string  %XDZ003%        XDelta binary patch file 1.0.4
+0      string  %XDZ004%        XDelta binary patch file 1.1
+
+0      string \xD6\xC3\xC4\x00 VCDIFF binary diff
diff --git a/magic/Magdir/xenix b/magic/Magdir/xenix
new file mode 100644 (file)
index 0000000..fb83faa
--- /dev/null
@@ -0,0 +1,92 @@
+
+#------------------------------------------------------------------------------
+# $File: xenix,v 1.11 2017/03/17 21:35:28 christos Exp $
+# xenix:  file(1) magic for Microsoft Xenix
+#
+# "Middle model" stuff, and "Xenix 8086 relocatable or 80286 small
+# model" lifted from "magic.xenix", with comment "derived empirically;
+# treat as folklore until proven"
+#
+# "small model", "large model", "huge model" stuff lifted from XXX
+#
+# XXX - "x.out" collides with PDP-11 archives
+#
+0      string          core            core file (Xenix)
+# URL: http://www.polarhome.com/service/man/?qf=86rel&tf=2&of=Xenix
+# Reference: http://www.azillionmonkeys.com/qed/Omfg.pdf
+# Update: Joerg Jenderek
+# recordtype~TranslatorHEADerRecord
+0      byte            0x80
+# GRR: line above is too general as it catches also Extensible storage engine DataBase
+# skip examples like GENA.SND Switch.Snd by looking for record length maximal 1024-3
+>1     uleshort        <1022
+# skip examples like GAME.PICTURE Strange.Pic by looking for positiv record length
+>>1    uleshort        >0
+# skip examples like Xtable.Data FRACTAL.GEN SHR.VIEW by looking for positiv string length
+>>>3   ubyte           >0
+# skip examples like OMBRE.6 with "UUUUUU" by looking for filename like "hello.c"
+>>>>4  regex   [a-zA-Z_/]{1,8}[.]      8086 relocatable (Microsoft)
+#!:mime        application/octet-stream
+!:mime application/x-object
+!:ext  o/a
+>>>>>3 pstring         x               \b, "%s"
+# checksum
+#>>>>>(3.b+4)  ubyte   x               \b, checksum 0x%2.2x
+0      leshort         0xff65          x.out
+>2     string          __.SYMDEF        randomized
+>0     byte            x               archive
+0      leshort         0x206           Microsoft a.out
+>8     leshort         1               Middle model
+>0x1e  leshort         &0x10           overlay
+>0x1e  leshort         &0x2            separate
+>0x1e  leshort         &0x4            pure
+>0x1e  leshort         &0x800          segmented
+>0x1e  leshort         &0x400          standalone
+>0x1e  leshort         &0x8            fixed-stack
+>0x1c  byte            &0x80           byte-swapped
+>0x1c  byte            &0x40           word-swapped
+>0x10  lelong          >0              not-stripped
+>0x1e  leshort         ^0xc000         pre-SysV
+>0x1e  leshort         &0x4000         V2.3
+>0x1e  leshort         &0x8000         V3.0
+>0x1c  byte            &0x4            86
+>0x1c  byte            &0xb            186
+>0x1c  byte            &0x9            286
+>0x1c  byte            &0xa            386
+>0x1f  byte            <0x040          small model
+>0x1f  byte            =0x048          large model
+>0x1f  byte            =0x049          huge model
+>0x1e  leshort         &0x1            executable
+>0x1e  leshort         ^0x1            object file
+>0x1e  leshort         &0x40           Large Text
+>0x1e  leshort         &0x20           Large Data
+>0x1e  leshort         &0x120          Huge Objects Enabled
+>0x10  lelong          >0              not stripped
+
+0      leshort         0x140           old Microsoft 8086 x.out
+>0x3   byte            &0x4            separate
+>0x3   byte            &0x2            pure
+>0     byte            &0x1            executable
+>0     byte            ^0x1            relocatable
+>0x14  lelong          >0              not stripped
+
+0      lelong          0x206           b.out
+>0x1e  leshort         &0x10           overlay
+>0x1e  leshort         &0x2            separate
+>0x1e  leshort         &0x4            pure
+>0x1e  leshort         &0x800          segmented
+>0x1e  leshort         &0x400          standalone
+>0x1e  leshort         &0x1            executable
+>0x1e  leshort         ^0x1            object file
+>0x1e  leshort         &0x4000         V2.3
+>0x1e  leshort         &0x8000         V3.0
+>0x1c  byte            &0x4            86
+>0x1c  byte            &0xb            186
+>0x1c  byte            &0x9            286
+>0x1c  byte            &0x29           286
+>0x1c  byte            &0xa            386
+>0x1e  leshort         &0x4            Large Text
+>0x1e  leshort         &0x2            Large Data
+>0x1e  leshort         &0x102          Huge Objects Enabled
+
+0      leshort         0x580           XENIX 8086 relocatable or 80286 small model
diff --git a/magic/Magdir/xilinx b/magic/Magdir/xilinx
new file mode 100644 (file)
index 0000000..a521977
--- /dev/null
@@ -0,0 +1,40 @@
+
+#------------------------------------------------------------------------------
+# $File: xilinx,v 1.8 2017/03/17 21:35:28 christos Exp $
+# This is Aaron's attempt at a MAGIC file for Xilinx .bit files.
+# Xilinx-Magic@RevRagnarok.com
+# Got the info from FPGA-FAQ 0026
+#
+# Rewritten to use pstring/H instead of hardcoded lengths by O. Freyermuth,
+# fixes at least reading of bitfiles from Spartan 2, 3, 6.
+# http://www.fpga-faq.com/FAQ_Pages/0026_Tell_me_about_bit_files.htm
+#
+# First there is the sync header and its length
+0      beshort 0x0009
+>2     belong  =0x0ff00ff0
+>>&0   belong  =0x0ff00ff0
+>>>&0  byte    =0x00
+>>>&1   beshort =0x0001
+>>>&3  string  a       Xilinx BIT data
+# Next is a Pascal-style string with the NCD name. We want to capture that.
+>>>>&0    pstring/H    x       - from %s
+# And then 'b'
+>>>>>&1    string b
+# Then the model / part number:
+>>>>>>&0   pstring/H    x       - for %s
+# Then 'c'
+>>>>>>>&1 string c
+# Then the build-date
+>>>>>>>>&0 pstring/H    x       - built %s
+# Then 'd'
+>>>>>>>>>&1   string d
+# Then the build-time
+>>>>>>>>>>&0  pstring/H x        \b(%s)
+# Then 'e'
+>>>>>>>>>>>&1  string e
+# And length of data
+>>>>>>>>>>>>&0 belong x          - data length 0x%x
+
+# Raw bitstream files
+0      long    0xffffffff
+>&0    belong  0xaa995566      Xilinx RAW bitstream (.BIN)
diff --git a/magic/Magdir/xo65 b/magic/Magdir/xo65
new file mode 100644 (file)
index 0000000..e513771
--- /dev/null
@@ -0,0 +1,30 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# xo65 object files
+# From: "Ullrich von Bassewitz" <uz@cc65.org>
+#
+0      string          \x55\x7A\x6E\x61        xo65 object,
+>4     leshort         x                       version %d,
+>6     leshort&0x0001 =0x0001                  with debug info
+>6     leshort&0x0001 =0x0000                  no debug info
+
+# xo65 library files
+0      string          \x6E\x61\x55\x7A        xo65 library,
+>4     leshort         x                       version %d
+
+# o65 object files
+0      string          \x01\x00\x6F\x36\x35    o65
+>6     leshort&0x1000  =0x0000                 executable,
+>6     leshort&0x1000  =0x1000                 object,
+>5     byte            x                       version %d,
+>6     leshort&0x8000  =0x8000                 65816,
+>6     leshort&0x8000  =0x0000                 6502,
+>6     leshort&0x2000  =0x2000                 32 bit,
+>6     leshort&0x2000  =0x0000                 16 bit,
+>6     leshort&0x4000  =0x4000                 page reloc,
+>6     leshort&0x4000  =0x0000                 byte reloc,
+>6     leshort&0x0003  =0x0000                 alignment 1
+>6     leshort&0x0003  =0x0001                 alignment 2
+>6     leshort&0x0003  =0x0002                 alignment 4
+>6     leshort&0x0003  =0x0003                 alignment 256
diff --git a/magic/Magdir/xwindows b/magic/Magdir/xwindows
new file mode 100644 (file)
index 0000000..7118cad
--- /dev/null
@@ -0,0 +1,35 @@
+
+#------------------------------------------------------------------------------
+# $File: xwindows,v 1.11 2019/04/19 00:42:27 christos Exp $
+# xwindows:  file(1) magic for various X/Window system file formats.
+
+# Compiled X Keymap
+# XKM (compiled X keymap) files (including version and byte ordering)
+1      string  mkx                             Compiled XKB Keymap: lsb,
+>0     byte    >0                              version %d
+>0     byte    =0                              obsolete
+0      string  xkm                             Compiled XKB Keymap: msb,
+>3     byte    >0                              version %d
+>3     byte    =0                              obsolete
+
+# xfsdump archive
+0      string  xFSdump0                        xfsdump archive
+>8     belong  x       (version %d)
+
+# Jaleo XFS files
+0      long    395726                          Jaleo XFS file
+>4     long    x                               - version %d
+>8     long    x                               - [%d -
+>20    long    x                               \b%dx
+>24    long    x                               \b%dx
+>28    long    1008                            \bYUV422]
+>28    long    1000                            \bRGB24]
+
+# Xcursor data
+# X11 mouse cursor format defined in libXcursor, see
+# https://www.x.org/archive/X11R6.8.1/doc/Xcursor.3.html
+# https://cgit.freedesktop.org/xorg/lib/libXcursor/tree/include/X11/Xcursor/Xcursor.h
+0      string          Xcur            Xcursor data
+!:mime image/x-xcursor
+>10    leshort         x               version %d
+>>8    leshort         x               \b.%d
diff --git a/magic/Magdir/yara b/magic/Magdir/yara
new file mode 100644 (file)
index 0000000..e581c43
--- /dev/null
@@ -0,0 +1,17 @@
+
+
+#------------------------------------------------------------------------------
+# $File: yara,v 1.3 2019/04/19 00:42:27 christos Exp $
+# yara:  file(1) magic for https://virustotal.github.io/yara/
+#
+
+0      string  YARA
+>4     lelong  >2047
+>8     byte    <20     YARA 3.x compiled rule set
+# version
+>>8    clear   x
+>>8    byte    6       created with version 3.3.0
+>>8    byte    8       created with version 3.4.0
+>>8    byte    11      created with version 3.5.0
+>>8    default x
+>>>8   byte    x       development version 0x%02x
diff --git a/magic/Magdir/zfs b/magic/Magdir/zfs
new file mode 100644 (file)
index 0000000..77675ed
--- /dev/null
@@ -0,0 +1,96 @@
+#------------------------------------------------------------------------------
+# zfs: file(1) magic for ZFS dumps
+#
+# From <rea-fbsd@codelabs.ru>
+# ZFS dump header has the following structure (as per zfs_ioctl.h
+# in FreeBSD with drr_type is set to DRR_BEGIN)
+#
+#   enum {
+#      DRR_BEGIN, DRR_OBJECT, DRR_FREEOBJECTS,
+#      DRR_WRITE, DRR_FREE, DRR_END,
+#   } drr_type;
+#   uint32_t drr_pad;
+#   uint64_t drr_magic;
+#   uint64_t drr_version;
+#   uint64_t drr_creation_time;
+#   dmu_objset_type_t drr_type;
+#   uint32_t drr_pad;
+#   uint64_t drr_toguid;
+#   uint64_t drr_fromguid;
+#   char drr_toname[MAXNAMELEN];
+#
+# Backup magic is 0x00000002f5bacbac (quad word)
+# The drr_type is defined as
+#   typedef enum dmu_objset_type {
+#        DMU_OST_NONE,
+#        DMU_OST_META,
+#        DMU_OST_ZFS,
+#        DMU_OST_ZVOL,
+#        DMU_OST_OTHER,                  /* For testing only! */
+#        DMU_OST_ANY,                    /* Be careful! */
+#        DMU_OST_NUMTYPES
+#  } dmu_objset_type_t;
+#
+# Almost all uint64_t fields are printed as the 32-bit ones (with high
+# 32 bits zeroed), because there is no simple way to print them as the
+# full 64-bit values.
+
+# Big-endian values
+8      string  \000\000\000\002\365\272\313\254 ZFS shapshot (big-endian machine),
+>20    belong  x       version %u,
+>32    belong  0       type: NONE,
+>32    belong  1       type: META,
+>32    belong  2       type: ZFS,
+>32    belong  3       type: ZVOL,
+>32    belong  4       type: OTHER,
+>32    belong  5       type: ANY,
+>32    belong  >5      type: UNKNOWN (%u),
+>40    byte    x       destination GUID: %02X
+>41    byte    x       %02X
+>42    byte    x       %02X
+>43    byte    x       %02X
+>44    byte    x       %02X
+>45    byte    x       %02X
+>46    byte    x       %02X
+>47    byte    x       %02X,
+>48    ulong   >0
+>>52   ulong   >0
+>>>48  byte    x       source GUID: %02X
+>>>49  byte    x       %02X
+>>>50  byte    x       %02X
+>>>51  byte    x       %02X
+>>>52  byte    x       %02X
+>>>53  byte    x       %02X
+>>>54  byte    x       %02X
+>>>55  byte    x       %02X,
+>56    string  >\0     name: '%s'
+
+# Little-endian values
+8      string  \254\313\272\365\002\000\000\000        ZFS shapshot (little-endian machine),
+>16    lelong  x       version %u,
+>32    lelong  0       type: NONE,
+>32    lelong  1       type: META,
+>32    lelong  2       type: ZFS,
+>32    lelong  3       type: ZVOL,
+>32    lelong  4       type: OTHER,
+>32    lelong  5       type: ANY,
+>32    lelong  >5      type: UNKNOWN (%u),
+>47    byte    x       destination GUID: %02X
+>46    byte    x       %02X
+>45    byte    x       %02X
+>44    byte    x       %02X
+>43    byte    x       %02X
+>42    byte    x       %02X
+>41    byte    x       %02X
+>40    byte    x       %02X,
+>48    ulong   >0
+>>52   ulong   >0
+>>>55  byte    x       source GUID: %02X
+>>>54  byte    x       %02X
+>>>53  byte    x       %02X
+>>>52  byte    x       %02X
+>>>51  byte    x       %02X
+>>>50  byte    x       %02X
+>>>49  byte    x       %02X
+>>>48  byte    x       %02X,
+>56    string  >\0     name: '%s'
diff --git a/magic/Magdir/zilog b/magic/Magdir/zilog
new file mode 100644 (file)
index 0000000..a7eb232
--- /dev/null
@@ -0,0 +1,12 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# zilog:  file(1) magic for Zilog Z8000.
+#
+# Was it big-endian or little-endian?  My Product Specification doesn't
+# say.
+#
+0      long            0xe807          object file (z8000 a.out)
+0      long            0xe808          pure object file (z8000 a.out)
+0      long            0xe809          separate object file (z8000 a.out)
+0      long            0xe805          overlay object file (z8000 a.out)
diff --git a/magic/Magdir/zip b/magic/Magdir/zip
new file mode 100644 (file)
index 0000000..f214ad0
--- /dev/null
@@ -0,0 +1,63 @@
+#------------------------------------------------------------------------------
+# $File: zip,v 1.2 2019/04/09 18:34:15 christos Exp $
+# zip:  file(1) magic for zip files; this is not use
+# Note the version of magic in archive is currently stronger, this is
+# just an example until negative offsets are supported better
+
+# Zip Central Cirectory record
+0      name            zipcd
+>0     string          PK\001\002      Zip archive data
+>>4    leshort         x               \b, made by
+>>4    use             zipversion
+>>6    leshort         x               \b, extract using at least
+>>6    use             zipversion
+>>12   ledate          x               \b, last modified %s
+>>24   lelong          >0              \b, uncompressed size %d
+>>10   leshort         x               \b, method=
+>>10   use             zipcompression
+
+# Zip known compressions
+0      name            zipcompression
+>0     leshort         0               \bstore
+>0     leshort         8               \bdeflate
+>0     leshort         9               \bdeflate64
+>0     leshort         12              \bbzip2
+>0     leshort         14              \blzma
+>0     leshort         94              \bMP3
+>0     leshort         95              \bxz
+>0     leshort         96              \bJpeg
+>0     leshort         97              \bWavPack
+>0     leshort         98              \bPPMd
+>0     leshort         99              \bAES Encrypted
+>0     default         x
+>>0    leshort         x               \b[%#x]
+
+# Zip known versions
+0      name            zipversion
+>0     leshort         0x09            v0.9
+>0     leshort         0x0a            v1.0
+>0     leshort         0x0b            v1.1
+>0     leshort         0x14            v2.0
+>0     leshort         0x15            v2.1
+>0     leshort         0x19            v2.5
+>0     leshort         0x1b            v2.7
+>0     leshort         0x2d            v4.5
+>0     leshort         0x2e            v4.6
+>0     leshort         0x32            v5.0
+>0     leshort         0x33            v5.1
+>0     leshort         0x34            v5.2
+>0     leshort         0x3d            v6.1
+>0     leshort         0x3e            v6.2
+>0     leshort         0x3f            v6.3
+>0     default         x
+>>0    leshort         x               v?[%#x]
+
+# Zip End Of Central Directory record
+-22    string          PK\005\006
+#>4    leshort         >1              \b, %d disks
+#>6    leshort         >1              \b, central directory disk %d
+#>8    leshort         >1              \b, %d central directories on this disk
+#>10   leshort         >1              \b, %d central directories
+#>12   lelong          x               \b, %d central directory bytes
+>(16.l)        use             zipcd
+>20    pstring/l       >0              \b, %s
diff --git a/magic/Magdir/zyxel b/magic/Magdir/zyxel
new file mode 100644 (file)
index 0000000..abcbb4c
--- /dev/null
@@ -0,0 +1,17 @@
+
+#------------------------------------------------------------------------------
+# $File$
+# zyxel:  file(1) magic for ZyXEL modems
+#
+# From <rob@pe1chl.ampr.org>
+# These are the /etc/magic entries to decode datafiles as used for the
+# ZyXEL U-1496E DATA/FAX/VOICE modems.  (This header conforms to a
+# ZyXEL-defined standard)
+
+0      string          ZyXEL\002       ZyXEL voice data
+>10    byte            0               - CELP encoding
+>10    byte&0x0B       1               - ADPCM2 encoding
+>10    byte&0x0B       2               - ADPCM3 encoding
+>10    byte&0x0B       3               - ADPCM4 encoding
+>10    byte&0x0B       8               - New ADPCM3 encoding
+>10    byte&0x04       4               with resync
diff --git a/magic/Makefile.am b/magic/Makefile.am
new file mode 100644 (file)
index 0000000..a52f522
--- /dev/null
@@ -0,0 +1,342 @@
+#
+# $File: Makefile.am,v 1.143 2019/05/09 16:24:36 christos Exp $
+#
+MAGIC_FRAGMENT_BASE = Magdir
+MAGIC_DIR = $(top_srcdir)/magic
+MAGIC_FRAGMENT_DIR = $(MAGIC_DIR)/$(MAGIC_FRAGMENT_BASE)
+
+pkgdata_DATA = magic.mgc
+
+EXTRA_DIST = \
+$(MAGIC_DIR)/Header \
+$(MAGIC_DIR)/Localstuff \
+$(MAGIC_FRAGMENT_DIR)/acorn \
+$(MAGIC_FRAGMENT_DIR)/adi \
+$(MAGIC_FRAGMENT_DIR)/adventure \
+$(MAGIC_FRAGMENT_DIR)/algol68 \
+$(MAGIC_FRAGMENT_DIR)/allegro \
+$(MAGIC_FRAGMENT_DIR)/alliant \
+$(MAGIC_FRAGMENT_DIR)/amanda \
+$(MAGIC_FRAGMENT_DIR)/amigaos \
+$(MAGIC_FRAGMENT_DIR)/android \
+$(MAGIC_FRAGMENT_DIR)/animation \
+$(MAGIC_FRAGMENT_DIR)/aout \
+$(MAGIC_FRAGMENT_DIR)/apache \
+$(MAGIC_FRAGMENT_DIR)/apl \
+$(MAGIC_FRAGMENT_DIR)/apple \
+$(MAGIC_FRAGMENT_DIR)/application \
+$(MAGIC_FRAGMENT_DIR)/applix \
+$(MAGIC_FRAGMENT_DIR)/apt \
+$(MAGIC_FRAGMENT_DIR)/archive \
+$(MAGIC_FRAGMENT_DIR)/assembler \
+$(MAGIC_FRAGMENT_DIR)/asterix \
+$(MAGIC_FRAGMENT_DIR)/att3b \
+$(MAGIC_FRAGMENT_DIR)/audio \
+$(MAGIC_FRAGMENT_DIR)/basis \
+$(MAGIC_FRAGMENT_DIR)/beetle \
+$(MAGIC_FRAGMENT_DIR)/ber \
+$(MAGIC_FRAGMENT_DIR)/bflt \
+$(MAGIC_FRAGMENT_DIR)/bhl \
+$(MAGIC_FRAGMENT_DIR)/bioinformatics \
+$(MAGIC_FRAGMENT_DIR)/biosig \
+$(MAGIC_FRAGMENT_DIR)/blackberry \
+$(MAGIC_FRAGMENT_DIR)/blcr \
+$(MAGIC_FRAGMENT_DIR)/blender \
+$(MAGIC_FRAGMENT_DIR)/blit \
+$(MAGIC_FRAGMENT_DIR)/bout \
+$(MAGIC_FRAGMENT_DIR)/bsdi \
+$(MAGIC_FRAGMENT_DIR)/bsi \
+$(MAGIC_FRAGMENT_DIR)/btsnoop \
+$(MAGIC_FRAGMENT_DIR)/c-lang \
+$(MAGIC_FRAGMENT_DIR)/c64 \
+$(MAGIC_FRAGMENT_DIR)/cad \
+$(MAGIC_FRAGMENT_DIR)/cafebabe \
+$(MAGIC_FRAGMENT_DIR)/cbor \
+$(MAGIC_FRAGMENT_DIR)/cddb \
+$(MAGIC_FRAGMENT_DIR)/chord \
+$(MAGIC_FRAGMENT_DIR)/cisco \
+$(MAGIC_FRAGMENT_DIR)/citrus \
+$(MAGIC_FRAGMENT_DIR)/clarion \
+$(MAGIC_FRAGMENT_DIR)/claris \
+$(MAGIC_FRAGMENT_DIR)/clipper \
+$(MAGIC_FRAGMENT_DIR)/clojure \
+$(MAGIC_FRAGMENT_DIR)/coff \
+$(MAGIC_FRAGMENT_DIR)/commands \
+$(MAGIC_FRAGMENT_DIR)/communications \
+$(MAGIC_FRAGMENT_DIR)/compress \
+$(MAGIC_FRAGMENT_DIR)/console \
+$(MAGIC_FRAGMENT_DIR)/convex \
+$(MAGIC_FRAGMENT_DIR)/coverage \
+$(MAGIC_FRAGMENT_DIR)/cracklib \
+$(MAGIC_FRAGMENT_DIR)/ctags \
+$(MAGIC_FRAGMENT_DIR)/ctf \
+$(MAGIC_FRAGMENT_DIR)/cubemap \
+$(MAGIC_FRAGMENT_DIR)/cups \
+$(MAGIC_FRAGMENT_DIR)/dact \
+$(MAGIC_FRAGMENT_DIR)/database \
+$(MAGIC_FRAGMENT_DIR)/dataone \
+$(MAGIC_FRAGMENT_DIR)/dbpf \
+$(MAGIC_FRAGMENT_DIR)/der \
+$(MAGIC_FRAGMENT_DIR)/diamond \
+$(MAGIC_FRAGMENT_DIR)/diff \
+$(MAGIC_FRAGMENT_DIR)/digital \
+$(MAGIC_FRAGMENT_DIR)/dolby \
+$(MAGIC_FRAGMENT_DIR)/dump \
+$(MAGIC_FRAGMENT_DIR)/dyadic \
+$(MAGIC_FRAGMENT_DIR)/ebml \
+$(MAGIC_FRAGMENT_DIR)/edid \
+$(MAGIC_FRAGMENT_DIR)/editors \
+$(MAGIC_FRAGMENT_DIR)/efi \
+$(MAGIC_FRAGMENT_DIR)/elf \
+$(MAGIC_FRAGMENT_DIR)/encore \
+$(MAGIC_FRAGMENT_DIR)/epoc \
+$(MAGIC_FRAGMENT_DIR)/erlang \
+$(MAGIC_FRAGMENT_DIR)/espressif \
+$(MAGIC_FRAGMENT_DIR)/esri \
+$(MAGIC_FRAGMENT_DIR)/fcs \
+$(MAGIC_FRAGMENT_DIR)/filesystems \
+$(MAGIC_FRAGMENT_DIR)/finger \
+$(MAGIC_FRAGMENT_DIR)/flash \
+$(MAGIC_FRAGMENT_DIR)/flif \
+$(MAGIC_FRAGMENT_DIR)/fonts \
+$(MAGIC_FRAGMENT_DIR)/fortran \
+$(MAGIC_FRAGMENT_DIR)/frame \
+$(MAGIC_FRAGMENT_DIR)/freebsd \
+$(MAGIC_FRAGMENT_DIR)/fsav \
+$(MAGIC_FRAGMENT_DIR)/fusecompress \
+$(MAGIC_FRAGMENT_DIR)/games \
+$(MAGIC_FRAGMENT_DIR)/gcc \
+$(MAGIC_FRAGMENT_DIR)/gconv \
+$(MAGIC_FRAGMENT_DIR)/geo \
+$(MAGIC_FRAGMENT_DIR)/geos \
+$(MAGIC_FRAGMENT_DIR)/gimp \
+$(MAGIC_FRAGMENT_DIR)/glibc \
+$(MAGIC_FRAGMENT_DIR)/gnome \
+$(MAGIC_FRAGMENT_DIR)/gnu \
+$(MAGIC_FRAGMENT_DIR)/gnumeric \
+$(MAGIC_FRAGMENT_DIR)/gpt \
+$(MAGIC_FRAGMENT_DIR)/gpu \
+$(MAGIC_FRAGMENT_DIR)/grace \
+$(MAGIC_FRAGMENT_DIR)/graphviz \
+$(MAGIC_FRAGMENT_DIR)/gringotts \
+$(MAGIC_FRAGMENT_DIR)/guile \
+$(MAGIC_FRAGMENT_DIR)/hardware \
+$(MAGIC_FRAGMENT_DIR)/hitachi-sh \
+$(MAGIC_FRAGMENT_DIR)/hp \
+$(MAGIC_FRAGMENT_DIR)/human68k \
+$(MAGIC_FRAGMENT_DIR)/ibm370 \
+$(MAGIC_FRAGMENT_DIR)/ibm6000 \
+$(MAGIC_FRAGMENT_DIR)/icc \
+$(MAGIC_FRAGMENT_DIR)/iff \
+$(MAGIC_FRAGMENT_DIR)/images \
+$(MAGIC_FRAGMENT_DIR)/inform \
+$(MAGIC_FRAGMENT_DIR)/intel \
+$(MAGIC_FRAGMENT_DIR)/interleaf \
+$(MAGIC_FRAGMENT_DIR)/island \
+$(MAGIC_FRAGMENT_DIR)/ispell \
+$(MAGIC_FRAGMENT_DIR)/isz \
+$(MAGIC_FRAGMENT_DIR)/java \
+$(MAGIC_FRAGMENT_DIR)/javascript \
+$(MAGIC_FRAGMENT_DIR)/jpeg \
+$(MAGIC_FRAGMENT_DIR)/karma \
+$(MAGIC_FRAGMENT_DIR)/kde \
+$(MAGIC_FRAGMENT_DIR)/keepass \
+$(MAGIC_FRAGMENT_DIR)/kerberos \
+$(MAGIC_FRAGMENT_DIR)/kicad \
+$(MAGIC_FRAGMENT_DIR)/kml \
+$(MAGIC_FRAGMENT_DIR)/lecter \
+$(MAGIC_FRAGMENT_DIR)/lex \
+$(MAGIC_FRAGMENT_DIR)/lif \
+$(MAGIC_FRAGMENT_DIR)/linux \
+$(MAGIC_FRAGMENT_DIR)/lisp \
+$(MAGIC_FRAGMENT_DIR)/llvm \
+$(MAGIC_FRAGMENT_DIR)/lua \
+$(MAGIC_FRAGMENT_DIR)/luks \
+$(MAGIC_FRAGMENT_DIR)/m4 \
+$(MAGIC_FRAGMENT_DIR)/mach \
+$(MAGIC_FRAGMENT_DIR)/macintosh \
+$(MAGIC_FRAGMENT_DIR)/macos \
+$(MAGIC_FRAGMENT_DIR)/magic \
+$(MAGIC_FRAGMENT_DIR)/mail.news \
+$(MAGIC_FRAGMENT_DIR)/make \
+$(MAGIC_FRAGMENT_DIR)/map \
+$(MAGIC_FRAGMENT_DIR)/maple \
+$(MAGIC_FRAGMENT_DIR)/marc21 \
+$(MAGIC_FRAGMENT_DIR)/mathcad \
+$(MAGIC_FRAGMENT_DIR)/mathematica \
+$(MAGIC_FRAGMENT_DIR)/matroska \
+$(MAGIC_FRAGMENT_DIR)/mcrypt \
+$(MAGIC_FRAGMENT_DIR)/measure \
+$(MAGIC_FRAGMENT_DIR)/mercurial \
+$(MAGIC_FRAGMENT_DIR)/metastore \
+$(MAGIC_FRAGMENT_DIR)/meteorological \
+$(MAGIC_FRAGMENT_DIR)/microfocus \
+$(MAGIC_FRAGMENT_DIR)/mime \
+$(MAGIC_FRAGMENT_DIR)/mips \
+$(MAGIC_FRAGMENT_DIR)/mirage \
+$(MAGIC_FRAGMENT_DIR)/misctools \
+$(MAGIC_FRAGMENT_DIR)/mkid \
+$(MAGIC_FRAGMENT_DIR)/mlssa \
+$(MAGIC_FRAGMENT_DIR)/mmdf \
+$(MAGIC_FRAGMENT_DIR)/modem \
+$(MAGIC_FRAGMENT_DIR)/motorola \
+$(MAGIC_FRAGMENT_DIR)/mozilla \
+$(MAGIC_FRAGMENT_DIR)/msdos \
+$(MAGIC_FRAGMENT_DIR)/msooxml \
+$(MAGIC_FRAGMENT_DIR)/msvc \
+$(MAGIC_FRAGMENT_DIR)/msx \
+$(MAGIC_FRAGMENT_DIR)/mup \
+$(MAGIC_FRAGMENT_DIR)/music \
+$(MAGIC_FRAGMENT_DIR)/nasa \
+$(MAGIC_FRAGMENT_DIR)/natinst \
+$(MAGIC_FRAGMENT_DIR)/ncr \
+$(MAGIC_FRAGMENT_DIR)/neko \
+$(MAGIC_FRAGMENT_DIR)/netbsd \
+$(MAGIC_FRAGMENT_DIR)/netscape \
+$(MAGIC_FRAGMENT_DIR)/netware \
+$(MAGIC_FRAGMENT_DIR)/news \
+$(MAGIC_FRAGMENT_DIR)/nitpicker \
+$(MAGIC_FRAGMENT_DIR)/numpy \
+$(MAGIC_FRAGMENT_DIR)/oasis \
+$(MAGIC_FRAGMENT_DIR)/ocaml \
+$(MAGIC_FRAGMENT_DIR)/octave \
+$(MAGIC_FRAGMENT_DIR)/ole2compounddocs \
+$(MAGIC_FRAGMENT_DIR)/olf \
+$(MAGIC_FRAGMENT_DIR)/os2 \
+$(MAGIC_FRAGMENT_DIR)/os400 \
+$(MAGIC_FRAGMENT_DIR)/os9 \
+$(MAGIC_FRAGMENT_DIR)/osf1 \
+$(MAGIC_FRAGMENT_DIR)/palm \
+$(MAGIC_FRAGMENT_DIR)/parix \
+$(MAGIC_FRAGMENT_DIR)/parrot \
+$(MAGIC_FRAGMENT_DIR)/pascal \
+$(MAGIC_FRAGMENT_DIR)/pbf \
+$(MAGIC_FRAGMENT_DIR)/pbm \
+$(MAGIC_FRAGMENT_DIR)/pc88 \
+$(MAGIC_FRAGMENT_DIR)/pc98 \
+$(MAGIC_FRAGMENT_DIR)/pdf \
+$(MAGIC_FRAGMENT_DIR)/pdp \
+$(MAGIC_FRAGMENT_DIR)/perl \
+$(MAGIC_FRAGMENT_DIR)/pgf \
+$(MAGIC_FRAGMENT_DIR)/pgp \
+$(MAGIC_FRAGMENT_DIR)/pkgadd \
+$(MAGIC_FRAGMENT_DIR)/plan9 \
+$(MAGIC_FRAGMENT_DIR)/plus5 \
+$(MAGIC_FRAGMENT_DIR)/polyml \
+$(MAGIC_FRAGMENT_DIR)/printer \
+$(MAGIC_FRAGMENT_DIR)/project \
+$(MAGIC_FRAGMENT_DIR)/psdbms \
+$(MAGIC_FRAGMENT_DIR)/psl \
+$(MAGIC_FRAGMENT_DIR)/pulsar \
+$(MAGIC_FRAGMENT_DIR)/pwsafe \
+$(MAGIC_FRAGMENT_DIR)/pyramid \
+$(MAGIC_FRAGMENT_DIR)/python \
+$(MAGIC_FRAGMENT_DIR)/qt \
+$(MAGIC_FRAGMENT_DIR)/revision \
+$(MAGIC_FRAGMENT_DIR)/riff \
+$(MAGIC_FRAGMENT_DIR)/rpi \
+$(MAGIC_FRAGMENT_DIR)/rpm \
+$(MAGIC_FRAGMENT_DIR)/rpmsg \
+$(MAGIC_FRAGMENT_DIR)/rtf \
+$(MAGIC_FRAGMENT_DIR)/ruby \
+$(MAGIC_FRAGMENT_DIR)/sc \
+$(MAGIC_FRAGMENT_DIR)/sccs \
+$(MAGIC_FRAGMENT_DIR)/scientific \
+$(MAGIC_FRAGMENT_DIR)/securitycerts \
+$(MAGIC_FRAGMENT_DIR)/selinux \
+$(MAGIC_FRAGMENT_DIR)/sendmail \
+$(MAGIC_FRAGMENT_DIR)/sequent \
+$(MAGIC_FRAGMENT_DIR)/sereal \
+$(MAGIC_FRAGMENT_DIR)/sgi \
+$(MAGIC_FRAGMENT_DIR)/sgml \
+$(MAGIC_FRAGMENT_DIR)/sharc \
+$(MAGIC_FRAGMENT_DIR)/sinclair \
+$(MAGIC_FRAGMENT_DIR)/sisu \
+$(MAGIC_FRAGMENT_DIR)/sketch \
+$(MAGIC_FRAGMENT_DIR)/smalltalk \
+$(MAGIC_FRAGMENT_DIR)/smile \
+$(MAGIC_FRAGMENT_DIR)/sniffer \
+$(MAGIC_FRAGMENT_DIR)/softquad \
+$(MAGIC_FRAGMENT_DIR)/spec \
+$(MAGIC_FRAGMENT_DIR)/spectrum \
+$(MAGIC_FRAGMENT_DIR)/sql \
+$(MAGIC_FRAGMENT_DIR)/ssh \
+$(MAGIC_FRAGMENT_DIR)/ssl \
+$(MAGIC_FRAGMENT_DIR)/sun \
+$(MAGIC_FRAGMENT_DIR)/symbos \
+$(MAGIC_FRAGMENT_DIR)/sysex \
+$(MAGIC_FRAGMENT_DIR)/tcl \
+$(MAGIC_FRAGMENT_DIR)/teapot \
+$(MAGIC_FRAGMENT_DIR)/terminfo \
+$(MAGIC_FRAGMENT_DIR)/tex \
+$(MAGIC_FRAGMENT_DIR)/tgif \
+$(MAGIC_FRAGMENT_DIR)/ti-8x \
+$(MAGIC_FRAGMENT_DIR)/timezone \
+$(MAGIC_FRAGMENT_DIR)/tplink \
+$(MAGIC_FRAGMENT_DIR)/troff \
+$(MAGIC_FRAGMENT_DIR)/tuxedo \
+$(MAGIC_FRAGMENT_DIR)/typeset \
+$(MAGIC_FRAGMENT_DIR)/unicode \
+$(MAGIC_FRAGMENT_DIR)/unknown \
+$(MAGIC_FRAGMENT_DIR)/uterus \
+$(MAGIC_FRAGMENT_DIR)/uuencode \
+$(MAGIC_FRAGMENT_DIR)/vacuum-cleaner \
+$(MAGIC_FRAGMENT_DIR)/varied.out \
+$(MAGIC_FRAGMENT_DIR)/varied.script \
+$(MAGIC_FRAGMENT_DIR)/vax \
+$(MAGIC_FRAGMENT_DIR)/vicar \
+$(MAGIC_FRAGMENT_DIR)/virtual \
+$(MAGIC_FRAGMENT_DIR)/virtutech \
+$(MAGIC_FRAGMENT_DIR)/visx \
+$(MAGIC_FRAGMENT_DIR)/vms \
+$(MAGIC_FRAGMENT_DIR)/vmware \
+$(MAGIC_FRAGMENT_DIR)/vorbis \
+$(MAGIC_FRAGMENT_DIR)/vxl \
+$(MAGIC_FRAGMENT_DIR)/warc \
+$(MAGIC_FRAGMENT_DIR)/weak \
+$(MAGIC_FRAGMENT_DIR)/webassembly \
+$(MAGIC_FRAGMENT_DIR)/windows \
+$(MAGIC_FRAGMENT_DIR)/wireless \
+$(MAGIC_FRAGMENT_DIR)/wordprocessors \
+$(MAGIC_FRAGMENT_DIR)/wsdl \
+$(MAGIC_FRAGMENT_DIR)/x68000 \
+$(MAGIC_FRAGMENT_DIR)/xdelta \
+$(MAGIC_FRAGMENT_DIR)/xenix \
+$(MAGIC_FRAGMENT_DIR)/xilinx \
+$(MAGIC_FRAGMENT_DIR)/xo65 \
+$(MAGIC_FRAGMENT_DIR)/xwindows \
+$(MAGIC_FRAGMENT_DIR)/yara \
+$(MAGIC_FRAGMENT_DIR)/zfs \
+$(MAGIC_FRAGMENT_DIR)/zilog \
+$(MAGIC_FRAGMENT_DIR)/zip \
+$(MAGIC_FRAGMENT_DIR)/zyxel
+
+MAGIC = magic.mgc
+CLEANFILES = ${MAGIC} $(MAGIC_FRAGMENT_DIR)/Localstuff
+
+# FIXME: Build file natively as well so that it can be used to compile
+# the target's magic file; for now we bail if the local version does not match
+if IS_CROSS_COMPILE
+FILE_COMPILE = file${EXEEXT}
+FILE_COMPILE_DEP =
+else
+FILE_COMPILE = $(top_builddir)/src/file${EXEEXT}
+FILE_COMPILE_DEP = $(FILE_COMPILE)
+endif
+
+${MAGIC}: $(EXTRA_DIST) $(FILE_COMPILE_DEP)
+       @rm -fr magic
+       @mkdir magic && cp -p $(EXTRA_DIST) magic
+       @(if expr "${FILE_COMPILE}" : '.*/.*' > /dev/null; then \
+           echo "Using ${FILE_COMPILE} to generate ${MAGIC}" > /dev/null; \
+         else \
+           v=$$(${FILE_COMPILE} --version | sed -e s/file-// -e q); \
+           if [ "$$v" != "${PACKAGE_VERSION}" ]; then \
+               echo "Cannot use the installed version of file ($$v) to"; \
+               echo "cross-compile file ${PACKAGE_VERSION}"; \
+               echo "Please install file ${PACKAGE_VERSION} locally first"; \
+               exit 1; \
+           fi; \
+         fi)
+       $(FILE_COMPILE) -C -m magic
+       @rm -fr magic
diff --git a/magic/scripts/create_filemagic_flac b/magic/scripts/create_filemagic_flac
new file mode 100755 (executable)
index 0000000..2730303
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+## bash script to generate file magic support for flac.
+## https://github.com/file/file/blob/master/magic/Magdir/audio
+## below "#some common sample rates" (line 471), ie:
+## >>17        belong&0xfffff0         0x2ee000        \b, 192 kHz
+
+LANG=C
+
+target=magic/Magdir/audio
+
+## construct static list of sample rates based on standard crystal
+## oscillator frequencies.
+## 16.384  MHz Unknown audio application
+##             (16384 kHz  = 32 kHz * 512 = 32 * 2^9)
+## 22.5792 MHz Redbook/CD
+##             (22579.2 kHz = 44.1kHz * 512 = 44.1 * 2^9)
+##             also used: 11.2896, 16.9344, 33.8688 and 45.1584
+## 24.576  MHz DAT/Video
+##             (24576 kHz = 48 kHz * 512 = 48 * 2^9)
+##             also used: 49.1520
+
+## 33.8688 > 16.9344
+## 36.864  > 18.432000
+declare -a a_ground_fs=(16384000 22579200 24576000)
+
+## multiply ground clock frequencies by 1953 to get usable base
+## frequencies, for instance:
+##  DAT/video:  24.576  MHz * 1000000 / 512 = 48000Hz
+##  Redbook/CD: 22.5792 MHz * 1000000 / 512 = 44100Hz
+## use base rates for calculating derived rates
+declare -a samplerates
+## min divider: fs/n
+def_fs_n=512
+min_fs_n=4
+## start at base_fs/(def_fs*min_fs)
+## add each derived sample rate to the array
+for base_fs in "${a_ground_fs[@]}"; do 
+    min_fs=$( echo "${base_fs} / ( ${def_fs_n} * ${min_fs_n} )" | bc)
+    ## max multiplier: fs*n*min_fs
+    max_fs_n=$(( 8 * min_fs_n ))
+    n=${max_fs_n}
+    while [[ ${n} -ge 1 ]]; do
+       sample_rate=$(( min_fs * n ))
+       samplerates+=(${sample_rate})
+       n=$(( n / 2 ))
+    done
+done
+
+declare -a stripped_rates
+declare -a lines
+for samplerate in "${samplerates[@]}"; do
+    ## use bc with sed to convert and format Hz to kHz
+    stripped_rate="$(LANG=C bc <<< "scale=5; ${samplerate} / 1000" | \
+                             sed 's#[0\.]*$##g')"
+    ## only add uniq sample rates (should be neccessary
+    if [[ ! "${stripped_rates[@]}" =~ ${stripped_rate} ]]; then
+       printf -v line ">>17\tbelong&%#-15x\t%#08x\t%s, %s kHz\n" \
+              "16777200" \
+              "$(( samplerate * 16 ))" \
+              "\b" \
+              "${stripped_rate}"
+       stripped_rates+=("${stripped_rate}")
+       lines+=("${line}")
+    fi
+
+done
+printf "## start cutting >>> \n"
+## print out the formatted lines
+printf "%s" "${lines[@]}" | sort -k5 -n
+printf "## <<< stop cutting\n"
diff --git a/python/.cvsignore b/python/.cvsignore
new file mode 100644 (file)
index 0000000..c5e7207
--- /dev/null
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+build
+temp
+Magic_file_extensions.egg-info
+magic.pyc
+.gitignore
diff --git a/python/CHANGELOG.md b/python/CHANGELOG.md
new file mode 100644 (file)
index 0000000..ac3c0c0
--- /dev/null
@@ -0,0 +1,16 @@
+# Python `file-magic` Log of Changes
+
+## `0.4.0`
+
+- Sync with current version of file:
+  * Retain python 2 compatibility, factoring out the conversion functions.
+  * Avoid double encoding with python3
+  * Restore python-2 compatibility.
+
+
+## `0.3.0`
+
+- Fix `setup.py` so we can upload to PyPI
+- Add function `detect_from_filename`
+- Add function `detect_from_fobj`
+- Add function `detect_from_content`
diff --git a/python/LICENSE b/python/LICENSE
new file mode 100644 (file)
index 0000000..46cfc24
--- /dev/null
@@ -0,0 +1,25 @@
+Copyright (c) Ian F. Darwin 1986-1995.
+Software written by Ian F. Darwin and others;
+maintained 1995-present by Christos Zoulas and others.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice immediately at the beginning of the file, without modification,
+   this list of conditions, and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/python/Makefile.am b/python/Makefile.am
new file mode 100644 (file)
index 0000000..f2d3412
--- /dev/null
@@ -0,0 +1,4 @@
+
+EXTRA_DIST = LICENSE CHANGELOG.md README.md example.py magic.py setup.py \
+       tests.py
+
diff --git a/python/README.md b/python/README.md
new file mode 100644 (file)
index 0000000..d626e31
--- /dev/null
@@ -0,0 +1,31 @@
+# `file-magic`: Python Bindings
+
+This library is a Python ctypes interface to `libmagic`.
+
+
+## Installing
+
+You can install `file-magic` either with:
+
+    python setup.py install
+    # or
+    easy_install .
+    # or
+    pip install file-magic
+
+
+## Using
+
+    import magic
+
+    detected = magic.detect_from_filename('magic.py')
+    print 'Detected MIME type: {}'.format(detected.mime_type)
+    print 'Detected encoding: {}'.format(detected.encoding)
+    print 'Detected file type name: {}'.format(detected.name)
+
+
+## Developing/Contributing
+
+To run the tests:
+
+    python setup.py test
diff --git a/python/example.py b/python/example.py
new file mode 100644 (file)
index 0000000..0cd0b5e
--- /dev/null
@@ -0,0 +1,17 @@
+#! /usr/bin/python
+
+import magic
+
+ms = magic.open(magic.NONE)
+ms.load()
+tp = ms.file("/bin/ls")
+print (tp)
+
+f = open("/bin/ls", "rb")
+buf = f.read(4096)
+f.close()
+
+tp = ms.buffer(buf)
+print (tp)
+
+ms.close()
diff --git a/python/file_magic/__init__.py b/python/file_magic/__init__.py
new file mode 100644 (file)
index 0000000..c71f124
--- /dev/null
@@ -0,0 +1 @@
+name = 'file_magic'
diff --git a/python/magic.py b/python/magic.py
new file mode 100644 (file)
index 0000000..4c1ff7a
--- /dev/null
@@ -0,0 +1,288 @@
+# coding: utf-8
+
+'''
+Python bindings for libmagic
+'''
+
+import ctypes
+
+from collections import namedtuple
+
+from ctypes import *
+from ctypes.util import find_library
+
+
+def _init():
+    """
+    Loads the shared library through ctypes and returns a library
+    L{ctypes.CDLL} instance
+    """
+    return ctypes.cdll.LoadLibrary(find_library('magic'))
+
+_libraries = {}
+_libraries['magic'] = _init()
+
+# Flag constants for open and setflags
+MAGIC_NONE = NONE = 0
+MAGIC_DEBUG = DEBUG = 1
+MAGIC_SYMLINK = SYMLINK = 2
+MAGIC_COMPRESS = COMPRESS = 4
+MAGIC_DEVICES = DEVICES = 8
+MAGIC_MIME_TYPE = MIME_TYPE = 16
+MAGIC_CONTINUE = CONTINUE = 32
+MAGIC_CHECK = CHECK = 64
+MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128
+MAGIC_RAW = RAW = 256
+MAGIC_ERROR = ERROR = 512
+MAGIC_MIME_ENCODING = MIME_ENCODING = 1024
+MAGIC_MIME = MIME = 1040  # MIME_TYPE + MIME_ENCODING
+MAGIC_APPLE = APPLE = 2048
+
+MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096
+MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192
+MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384
+MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768
+MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536
+MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072
+MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144
+MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576
+MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152
+
+MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824
+
+FileMagic = namedtuple('FileMagic', ('mime_type', 'encoding', 'name'))
+
+
+class magic_set(Structure):
+    pass
+magic_set._fields_ = []
+magic_t = POINTER(magic_set)
+
+_open = _libraries['magic'].magic_open
+_open.restype = magic_t
+_open.argtypes = [c_int]
+
+_close = _libraries['magic'].magic_close
+_close.restype = None
+_close.argtypes = [magic_t]
+
+_file = _libraries['magic'].magic_file
+_file.restype = c_char_p
+_file.argtypes = [magic_t, c_char_p]
+
+_descriptor = _libraries['magic'].magic_descriptor
+_descriptor.restype = c_char_p
+_descriptor.argtypes = [magic_t, c_int]
+
+_buffer = _libraries['magic'].magic_buffer
+_buffer.restype = c_char_p
+_buffer.argtypes = [magic_t, c_void_p, c_size_t]
+
+_error = _libraries['magic'].magic_error
+_error.restype = c_char_p
+_error.argtypes = [magic_t]
+
+_setflags = _libraries['magic'].magic_setflags
+_setflags.restype = c_int
+_setflags.argtypes = [magic_t, c_int]
+
+_load = _libraries['magic'].magic_load
+_load.restype = c_int
+_load.argtypes = [magic_t, c_char_p]
+
+_compile = _libraries['magic'].magic_compile
+_compile.restype = c_int
+_compile.argtypes = [magic_t, c_char_p]
+
+_check = _libraries['magic'].magic_check
+_check.restype = c_int
+_check.argtypes = [magic_t, c_char_p]
+
+_list = _libraries['magic'].magic_list
+_list.restype = c_int
+_list.argtypes = [magic_t, c_char_p]
+
+_errno = _libraries['magic'].magic_errno
+_errno.restype = c_int
+_errno.argtypes = [magic_t]
+
+
+class Magic(object):
+    def __init__(self, ms):
+        self._magic_t = ms
+
+    def close(self):
+        """
+        Closes the magic database and deallocates any resources used.
+        """
+        _close(self._magic_t)
+
+    @staticmethod
+    def __tostr(s):
+        if s is None:
+            return None
+        if isinstance(s, str):
+            return s
+        try:  # keep Python 2 compatibility
+            return str(s, 'utf-8')
+        except TypeError:
+            return str(s)
+
+    @staticmethod
+    def __tobytes(b):
+        if b is None:
+            return None
+        if isinstance(b, bytes):
+            return b
+        try:  # keep Python 2 compatibility
+            return bytes(b, 'utf-8')
+        except TypeError:
+            return bytes(b)
+
+    def file(self, filename):
+        """
+        Returns a textual description of the contents of the argument passed
+        as a filename or None if an error occurred and the MAGIC_ERROR flag
+        is set. A call to errno() will return the numeric error code.
+        """
+        return Magic.__tostr(_file(self._magic_t, Magic.__tobytes(filename)))
+
+    def descriptor(self, fd):
+        """
+        Returns a textual description of the contents of the argument passed
+        as a file descriptor or None if an error occurred and the MAGIC_ERROR
+        flag is set. A call to errno() will return the numeric error code.
+        """
+        return Magic.__tostr(_descriptor(self._magic_t, fd))
+
+    def buffer(self, buf):
+        """
+        Returns a textual description of the contents of the argument passed
+        as a buffer or None if an error occurred and the MAGIC_ERROR flag
+        is set. A call to errno() will return the numeric error code.
+        """
+        return Magic.__tostr(_buffer(self._magic_t, buf, len(buf)))
+
+    def error(self):
+        """
+        Returns a textual explanation of the last error or None
+        if there was no error.
+        """
+        return Magic.__tostr(_error(self._magic_t))
+
+    def setflags(self, flags):
+        """
+        Set flags on the magic object which determine how magic checking
+        behaves; a bitwise OR of the flags described in libmagic(3), but
+        without the MAGIC_ prefix.
+
+        Returns -1 on systems that don't support utime(2) or utimes(2)
+        when PRESERVE_ATIME is set.
+        """
+        return _setflags(self._magic_t, flags)
+
+    def load(self, filename=None):
+        """
+        Must be called to load entries in the colon separated list of database
+        files passed as argument or the default database file if no argument
+        before any magic queries can be performed.
+
+        Returns 0 on success and -1 on failure.
+        """
+        return _load(self._magic_t, Magic.__tobytes(filename))
+
+    def compile(self, dbs):
+        """
+        Compile entries in the colon separated list of database files
+        passed as argument or the default database file if no argument.
+        The compiled files created are named from the basename(1) of each file
+        argument with ".mgc" appended to it.
+
+        Returns 0 on success and -1 on failure.
+        """
+        return _compile(self._magic_t, Magic.__tobytes(dbs))
+
+    def check(self, dbs):
+        """
+        Check the validity of entries in the colon separated list of
+        database files passed as argument or the default database file
+        if no argument.
+
+        Returns 0 on success and -1 on failure.
+        """
+        return _check(self._magic_t, Magic.__tobytes(dbs))
+
+    def list(self, dbs):
+        """
+        Check the validity of entries in the colon separated list of
+        database files passed as argument or the default database file
+        if no argument.
+
+        Returns 0 on success and -1 on failure.
+        """
+        return _list(self._magic_t, Magic.__tobytes(dbs))
+
+    def errno(self):
+        """
+        Returns a numeric error code. If return value is 0, an internal
+        magic error occurred. If return value is non-zero, the value is
+        an OS error code. Use the errno module or os.strerror() can be used
+        to provide detailed error information.
+        """
+        return _errno(self._magic_t)
+
+
+def open(flags):
+    """
+    Returns a magic object on success and None on failure.
+    Flags argument as for setflags.
+    """
+    return Magic(_open(flags))
+
+
+# Objects used by `detect_from_` functions
+mime_magic = Magic(_open(MAGIC_MIME))
+mime_magic.load()
+none_magic = Magic(_open(MAGIC_NONE))
+none_magic.load()
+
+
+def _create_filemagic(mime_detected, type_detected):
+    try:
+        mime_type, mime_encoding = mime_detected.split('; ')
+    except ValueError:
+        raise ValueError(mime_detected)
+
+    return FileMagic(name=type_detected, mime_type=mime_type,
+                     encoding=mime_encoding.replace('charset=', ''))
+
+
+def detect_from_filename(filename):
+    '''Detect mime type, encoding and file type from a filename
+
+    Returns a `FileMagic` namedtuple.
+    '''
+
+    return _create_filemagic(mime_magic.file(filename),
+                             none_magic.file(filename))
+
+
+def detect_from_fobj(fobj):
+    '''Detect mime type, encoding and file type from file-like object
+
+    Returns a `FileMagic` namedtuple.
+    '''
+
+    file_descriptor = fobj.fileno()
+    return _create_filemagic(mime_magic.descriptor(file_descriptor),
+                             none_magic.descriptor(file_descriptor))
+
+
+def detect_from_content(byte_content):
+    '''Detect mime type, encoding and file type from bytes
+
+    Returns a `FileMagic` namedtuple.
+    '''
+
+    return _create_filemagic(mime_magic.buffer(byte_content),
+                             none_magic.buffer(byte_content))
diff --git a/python/setup.py b/python/setup.py
new file mode 100644 (file)
index 0000000..a864b1e
--- /dev/null
@@ -0,0 +1,27 @@
+# coding: utf-8
+
+from __future__ import unicode_literals
+
+from setuptools import setup
+
+with open('README.md', 'r') as fh:
+      long_description = fh.read()
+
+
+setup(name='file-magic',
+      version='0.4.0',
+      author='Reuben Thomas, Álvaro Justen',
+      author_email='rrt@sc3d.org, alvarojusten@gmail.com',
+      url='https://github.com/file/file',
+      license='BSD',
+      description='(official) libmagic Python bindings',
+      long_description=long_description,
+      long_description_content_type='text/markdown',
+      py_modules=['magic'],
+      test_suite='tests',
+      classifiers = [
+          'Intended Audience :: Developers',
+          'License :: OSI Approved :: BSD License',
+          'Natural Language :: English',
+          'Topic :: Software Development :: Libraries :: Python Modules',
+      ])
diff --git a/python/tests.py b/python/tests.py
new file mode 100644 (file)
index 0000000..197a8fc
--- /dev/null
@@ -0,0 +1,32 @@
+# coding: utf-8
+
+import unittest
+
+import magic
+
+
+class MagicTestCase(unittest.TestCase):
+
+    filename = 'magic.py'
+    expected_mime_type = 'text/x-python'
+    expected_encoding = 'us-ascii'
+    expected_name = 'Python script, ASCII text executable'
+
+    def assert_result(self, result):
+        self.assertEqual(result.mime_type, self.expected_mime_type)
+        self.assertEqual(result.encoding, self.expected_encoding)
+        self.assertEqual(result.name, self.expected_name)
+
+    def test_detect_from_filename(self):
+        result = magic.detect_from_filename(self.filename)
+        self.assert_result(result)
+
+    def test_detect_from_fobj(self):
+        with open(self.filename) as fobj:
+            result = magic.detect_from_fobj(fobj)
+        self.assert_result(result)
+
+    def test_detect_from_content(self):
+        with open(self.filename) as fobj:
+            result = magic.detect_from_content(fobj.read(4096))
+        self.assert_result(result)
diff --git a/src/.cvsignore b/src/.cvsignore
new file mode 100644 (file)
index 0000000..629f03c
--- /dev/null
@@ -0,0 +1,15 @@
+.deps
+Makefile
+config.h
+config.log
+config.status
+libtool
+stamp-h1
+.libs
+*.lo
+*.la
+Makefile.in
+file
+test
+.gitignore
+magic.h
diff --git a/src/BNF b/src/BNF
new file mode 100644 (file)
index 0000000..243532f
--- /dev/null
+++ b/src/BNF
@@ -0,0 +1,151 @@
+This is a first attempt to document the grammar used by magic(5), with
+hopes of eventually incorporating something like this into the manpage.
+
+Note: Currently, the parser varies slightly from this, but only in
+very minor ways, e.g., the strflags maybe separated by '/' characters
+and at most one strcount is allowed; likewise for regflags.
+
+------------------------------------------------------------------------
+magic = 1*query
+
+query = line *( 1*level line )
+
+level = ">"            ;; Increment the level by 1.
+                       ;; The first line of a query is at level 0.
+
+line = offset HWS type HWS test HWS message EOL
+
+------------------------------------------------------------------------
+offset = absoffset | reloffset | indoffset
+                       ;; The offset in the file at which to apply
+                       ;; the <test>.
+
+absoffset = NUMBER     ;; An absolute offset from the start of the file.
+
+reloffset = "&" NUMBER ;; The offset relative to the last match offset
+                       ;; at one level up.
+                       ;; Not allowed at level == 0.
+
+indoffset = indoff | relindoff
+
+indoff = "(" offset1 [ "." size ] [ op disp ] ")"
+                       ;; Read the file at <offset1> of width <size>.
+                       ;; If size is not specified, assume a long.
+                       ;; If <op> is given, then preform that
+                       ;; operation on the result and the <disp>.
+
+offset1 = absoffset | reloffset
+
+size = byte | leshort | beshort | lelong | belong | melong
+
+byte = "B" | "b" | "C" | "c"   ;; A one-byte value.
+leshort = "s" | "h"            ;; A two-byte little-endian value.
+beshort = "S" | "H"            ;; A two-byte big-endian value.
+lelong = "l"                   ;; A four-byte little-endian value.
+belong = "L"                   ;; A four-byte big-endian value.
+melong = "m"                   ;; A four-byte middle-endian value.
+
+op = [ invert ] ( "+" | "-" | "*" | "/" | "%" | "&" | "|" | "^" )
+
+invert = "~"           ;; Flip the bits on result of the <op>.
+
+disp =  NUMBER | memvalue
+
+memvalue = "(" NUMBER ")"
+                       ;; NUMBER is interpreted as an absolute or
+                       ;; relative offset matching that of <offset1>.
+                       ;; Read the file at the resulting offset with
+                       ;; the same size as <offset1>
+
+relindoff = "&" indoff ;; add <indoff> to the last match offset at
+                       ;; one level up.
+
+------------------------------------------------------------------------
+type = [ unsigned ] ( numeric | strtype | default )
+
+unsigned = "u"         ;; The value is unsigned.
+                       ;; This affects the sign extension of numeric
+                       ;; types and the '<' and '>' compares.  It is
+                       ;; intended for numeric types, but allowed on
+                       ;; all types.
+
+numeric = ( numtype | datatype ) [ nummask ]
+
+numtype = byte | short | long | quad
+
+byte = "byte"
+short = "short" | "beshort" | "leshort"
+long = "long" | "lelong" | "belong" | "melong"
+quad = "quad" | "lequad" | "bequad"
+
+datetype = udate32 | ldate32 | udate64 | ldate64
+
+udate32 = "date" | "bedate" | "ledate" | "medate"      ;; UTC dates
+ldate32 = "ldate" | "beldate" | "leldate" | "meldate"  ;; local dates
+udate64 = "qdate" | "leqdate" | "beqdate"              ;; UTC dates
+ldate64 = "qldate" | "leqldate" | "beqldate"           ;; local dates
+
+nummask = op NUMBER
+
+strtype = regex | search | string8 | string16
+
+regex = "regex" [ "/" 1*regflag ]
+
+regflag = "c" | "s" | linecnt
+
+linecnt = NUMBER       ;; The number of lines to search.  If this
+                       ;; is missing or zero, the rest of the
+                       ;; file is searched.
+
+search = "string" [ "/" 1*srchflag ]
+
+srchflag = strflag | srchcnt
+
+srchcnt = NUMBER       ;; The number of search tries.  If this
+                       ;; is missing or zero, the rest of the
+                       ;; file is searched.
+
+string8 = ( "string" | "pstring" ) [ "/" 1*strflag ]
+
+strflag = "b" | "B" | "c" | "C"
+
+string16 = "bestring16" | "lestring16"
+
+default = "default"    ;; This is intended to be used with the
+                       ;; <truetest> ("x" below).  It is matched if
+                       ;; there has been no previous match at its
+                       ;; level or none since the last default at
+                       ;; that level.  It is useful for implementing
+                       ;; switch-like and if/else constructions.
+
+------------------------------------------------------------------------
+test = numtest | strtest | truetest
+                               ;; Test to preform on <type> read from file.
+
+numtest = [ compare ] NUMBER   ;; If compare is missing, "=" is assumed.
+
+strtest = [ compare ] STRING   ;; If compare is missing, "=" is assumed.
+                               ;; Note: If the STRING begins with a <compare>
+                               ;; character, the <compare> field cannot be
+                               ;; omitted.
+
+compare = "=" | "!" | "<" | ">" | "&" | "^"
+
+truetest = "x"         ;; This always returns true.
+                       ;; To test for the string "x" use "=x".
+
+------------------------------------------------------------------------
+message = [ nospflag ] ( STRING | FMT_STRING )
+                       ;; Message to print if test result is true.
+
+nospflag = %x08 | "\\b"        ;; Do not insert a space before the message.
+                       ;; By default, messages are separated by a " ".
+
+------------------------------------------------------------------------
+HWS = <horizontal white space>
+EOL = <end of line marker>
+NUMBER = <C-style unsigned number>
+STRING = <C-style string without delimiting quotes>
+FMTSTR = <printf format string with exactly one % construct>
+
+------------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..2fbefdb
--- /dev/null
@@ -0,0 +1,30 @@
+MAGIC = $(pkgdatadir)/magic
+lib_LTLIBRARIES = libmagic.la
+nodist_include_HEADERS = magic.h
+
+bin_PROGRAMS = file
+
+AM_CPPFLAGS = -DMAGIC='"$(MAGIC)"'
+AM_CFLAGS = $(CFLAG_VISIBILITY) @WARNINGS@
+
+libmagic_la_SOURCES = buffer.c magic.c apprentice.c softmagic.c ascmagic.c \
+       encoding.c compress.c is_json.c is_tar.c readelf.c print.c fsmagic.c \
+       funcs.c file.h readelf.h tar.h apptype.c der.c der.h \
+       file_opts.h elfclass.h mygetopt.h cdf.c cdf_time.c readcdf.c cdf.h
+libmagic_la_LDFLAGS = -no-undefined -version-info 1:0:0
+if MINGW
+MINGWLIBS = -lgnurx -lshlwapi
+else
+MINGWLIBS =
+endif
+libmagic_la_LIBADD = $(LTLIBOBJS) $(MINGWLIBS)
+
+file_SOURCES = file.c seccomp.c
+file_LDADD = libmagic.la
+CLEANFILES = magic.h
+EXTRA_DIST = magic.h.in
+HDR= $(top_srcdir)/src/magic.h.in
+BUILT_SOURCES = magic.h
+
+magic.h:       ${HDR}
+       sed -e "s/X.YY/$$(echo @VERSION@ | tr -d .)/" < ${HDR} > $@
diff --git a/src/Makefile.std b/src/Makefile.std
new file mode 100644 (file)
index 0000000..e522d7d
--- /dev/null
@@ -0,0 +1,167 @@
+# Makefile for file(1) cmd.
+# Copyright (c) Ian F. Darwin 86/09/01 - see LEGAL.NOTICE.
+# @(#)$Id: Makefile.std,v 1.20 2018/09/09 20:33:28 christos Exp $
+#
+# This software is not subject to any license of the American Telephone
+# and Telegraph Company or of the Regents of the University of California.
+#
+# Permission is granted to anyone to use this software for any purpose on
+# any computer system, and to alter it and redistribute it freely, subject
+# to the following restrictions:
+#
+# 1. The author is not responsible for the consequences of use of this
+#    software, no matter how awful, even if they arise from flaws in it.
+#
+# 2. The origin of this software must not be misrepresented, either by
+#    explicit claim or by omission.  Since few users ever read sources,
+#    credits must appear in the documentation.
+#
+# 3. Altered versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.  Since few users
+#    ever read sources, credits must appear in the documentation.
+#
+# 4. This notice may not be removed or altered.
+#
+VERSION        = 3.41
+SHELL  = /bin/sh
+#MAGIC = /etc/magic
+MAGIC  = /usr/local/etc/magic
+DEFS   = -DMAGIC='"$(MAGIC)"' -DBUILTIN_ELF # -Dvoid=int
+CC     = cc
+COPTS  = -O -g         # newer compilers allow both; else drop -O
+# For truly antique environments, use this for (dummy) include files:
+COPTS  = -O # -Ilocalinc
+CFLAGS = $(COPTS) $(DEFS)
+LDFLAGS        = $(COPTS) # -Bstatic   # older gdb couldn't handle shared libs
+SHAR   = bundle
+OFILE  = /usr/bin/file         # old or distributed version, for comparison
+# Where new binary lives; typically /usr/local (BSD), /usr/lbin (USG).
+BINDIR = /usr/local/bin
+# For installing our man pages;
+# MANCxxx is manual section for Commands, MANFxxx is section for file formats.
+# MANxDIR is directory names; MANxEXT is the filename extension. Usual values:
+# Variable     V7              4BSD            Sys V
+# MANCDIR      /usr/man/man1   /usr/man/man1   /usr/man/u_man/man1
+# MANFDIR      /usr/man/man5   /usr/man/man5   /usr/man/u_man/man4
+# MANCEXT      1               1               1
+# MANFEXT      5               5               4
+# --- possible alternative for 4BSD ---
+# MANCDIR                      /usr/local/man/man1
+# MANCEXT                      1
+# or
+# MANCDIR                      /usr/man/manl
+# MANCEXT                      l
+# --- possible alternative for USG ---
+# MANCDIR                      /usr/man/local/man1
+# MANCEXT                      1
+
+MANCDIR        = /usr/local/man/man1
+MANCEXT        = 1
+MANFDIR        = /usr/local/man/man4
+MANFEXT        = 4
+
+# There are no system-dependent configuration options (except maybe CFLAGS).
+# Uncomment any of these that is missing from your "standard" library.
+LOCALSRCS = # localsrc/getopt.c localsrc/strtol.c \
+#              localsrc/strtok.c localsrc/strchr.c
+LOCALOBJS = # localsrc/getopt.o localsrc/strtol.o \
+#              localsrc/strtok.o localsrc/strchr.o
+# These are not compiled in unless you use -Ilocalinc, but
+# are not commented out as "make dist" &c use them.
+LOCALINC = # localinc/*.h localinc/sys/*.h
+
+SRCS = file.c apprentice.c fsmagic.c softmagic.c ascmagic.c \
+       compress.c is_tar.c readelf.c \
+       print.c $(LOCALSRCS) $(LOCALINC)
+OBJS = file.o apprentice.o fsmagic.o softmagic.o ascmagic.o \
+       compress.o is_tar.o readelf.o \
+       print.o $(LOCALOBJS)
+HDRS = file.h readelf.h tar.h
+
+AUTOSRC=configure configure.in install-sh config.h.in Makefile.in
+ALLSRC = LEGAL.NOTICE README MAINT PORTING $(SRCS) $(HDRS) \
+        Makefile.std file.man magic.man magic2mime $(AUTOSRC) \
+        Localstuff Header
+ALLMAGIC =   Magdir/[a-z]*
+
+all:           file magic file.${MANCEXT} magic.${MANFEXT}
+
+TESTFILES = * tst/*
+try:           all $(OFILE)
+               cd tst; $(MAKE)
+               time $(OFILE) $(TESTFILES) >/tmp/t1 # can't use ./magic
+               time ./file -m ./magic $(TESTFILES) >/tmp/t2
+               -diff -b /tmp/t[12]
+               what ./file >lastnocore
+
+file:          $(OBJS)
+               $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@
+lint:          $(SRCS)
+               lint -ha $(DEFS) $(SRCS) | tee $@
+magic:         Localstuff Header Magdir
+               cat Header Localstuff Magdir/[a-z] > $@
+
+ascmagic.o:    names.h
+
+compress.o apprentice.o ascmagic.o file.o fsmagic.o print.o softmagic.o: file.h
+
+install:       file magic
+               cp file $(BINDIR)/file
+               cp magic $(MAGIC)
+
+install.man: file.${MANCEXT} magic.${MANFEXT}
+               cp file.${MANCEXT} $(MANCDIR)/file.$(MANCEXT)
+               cp magic.${MANFEXT} $(MANFDIR)/magic.$(MANFEXT)
+
+clean:
+               rm -f *.o core file magic lint dist.* MANIFEST \
+                     magic.${MANFEXT} file.${MANCEXT} \
+                     config.h config.status config.cache config.log
+clobber:
+               cd tst; $(MAKE) clean
+
+
+magic.${MANFEXT} :     Makefile magic.man
+               @rm -f $@
+               sed -e s@__CSECTION__@${MANCEXT}@g \
+                   -e s@__FSECTION__@${MANFEXT}@g \
+                   -e s@__VERSION__@${VERSION}@g \
+                   -e s@__MAGIC__@${MAGIC}@g magic.man > $@
+
+file.${MANCEXT} :      Makefile file.man
+               @rm -f $@
+               sed -e s@__CSECTION__@${MANCEXT}@g \
+                   -e s@__FSECTION__@${MANFEXT}@g \
+                   -e s@__VERSION__@${VERSION}@g \
+                   -e s@__MAGIC__@${MAGIC}@g file.man > $@
+
+send:          dist
+               ftp ftp.cs
+
+dist:          dist.src dist.magic
+               @echo Now check this patchlevel!
+               ident patchlevel.h
+
+dist.src:      $(ALLSRC) MANIFEST
+#              Some versions of shar can't handle a single file from
+#              a subdirectory, so we manually insert mkdir as needed.
+#              The point is to exclude all the generable targets in tst.
+               (echo mkdir localinc localinc/sys localsrc tst; \
+                       $(SHAR) $(ALLSRC) MANIFEST) > $@
+
+rcsdiff:       $(ALLSRC)
+               rcsdiff -q RCS/*
+
+MANIFEST:      $(ALLSRC)
+               ident $(ALLSRC) > MANIFEST
+dist.magic:    Magdir
+#              As above, but to exclude Magdir/RCS from being shipped.
+               (echo mkdir Magdir; $(SHAR) $(ALLMAGIC)) >$@
+
+tar:           $(ALLSRC) $(ALLMAGIC)
+               -rm -fr file-${VERSION}
+               -mkdir file-${VERSION} file-${VERSION}/Magdir
+               ln $(ALLSRC) file-${VERSION}
+               ln ${ALLMAGIC} file-${VERSION}/Magdir
+               tar cvf file-${VERSION}.tar file-${VERSION}
+               -rm -fr file-${VERSION}
diff --git a/src/apprentice.c b/src/apprentice.c
new file mode 100644 (file)
index 0000000..eca3ae0
--- /dev/null
@@ -0,0 +1,3456 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * apprentice - make one pass through /etc/magic, learning its secrets.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: apprentice.c,v 1.283 2019/02/20 02:35:27 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include <fcntl.h>
+#ifdef QUICK
+#include <sys/mman.h>
+#endif
+#include <dirent.h>
+#include <limits.h>
+
+
+#define        EATAB {while (isascii(CAST(unsigned char, *l)) && \
+                     isspace(CAST(unsigned char, *l)))  ++l;}
+#define LOWCASE(l) (isupper(CAST(unsigned char, l)) ? \
+                       tolower(CAST(unsigned char, l)) : (l))
+/*
+ * Work around a bug in headers on Digital Unix.
+ * At least confirmed for: OSF1 V4.0 878
+ */
+#if defined(__osf__) && defined(__DECC)
+#ifdef MAP_FAILED
+#undef MAP_FAILED
+#endif
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED (void *) -1
+#endif
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+#define ALLOC_CHUNK    CAST(size_t, 10)
+#define ALLOC_INCR     CAST(size_t, 200)
+
+#define MAP_TYPE_USER  0
+#define MAP_TYPE_MALLOC        1
+#define MAP_TYPE_MMAP  2
+
+struct magic_entry {
+       struct magic *mp;
+       uint32_t cont_count;
+       uint32_t max_count;
+};
+
+struct magic_entry_set {
+       struct magic_entry *me;
+       uint32_t count;
+       uint32_t max;
+};
+
+struct magic_map {
+       void *p;
+       size_t len;
+       int type;
+       struct magic *magic[MAGIC_SETS];
+       uint32_t nmagic[MAGIC_SETS];
+};
+
+int file_formats[FILE_NAMES_SIZE];
+const size_t file_nformats = FILE_NAMES_SIZE;
+const char *file_names[FILE_NAMES_SIZE];
+const size_t file_nnames = FILE_NAMES_SIZE;
+
+private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
+private int hextoint(int);
+private const char *getstr(struct magic_set *, struct magic *, const char *,
+    int);
+private int parse(struct magic_set *, struct magic_entry *, const char *,
+    size_t, int);
+private void eatsize(const char **);
+private int apprentice_1(struct magic_set *, const char *, int);
+private size_t apprentice_magic_strength(const struct magic *);
+private int apprentice_sort(const void *, const void *);
+private void apprentice_list(struct mlist *, int );
+private struct magic_map *apprentice_load(struct magic_set *,
+    const char *, int);
+private struct mlist *mlist_alloc(void);
+private void mlist_free(struct mlist *);
+private void byteswap(struct magic *, uint32_t);
+private void bs1(struct magic *);
+private uint16_t swap2(uint16_t);
+private uint32_t swap4(uint32_t);
+private uint64_t swap8(uint64_t);
+private char *mkdbname(struct magic_set *, const char *, int);
+private struct magic_map *apprentice_buf(struct magic_set *, struct magic *,
+    size_t);
+private struct magic_map *apprentice_map(struct magic_set *, const char *);
+private int check_buffer(struct magic_set *, struct magic_map *, const char *);
+private void apprentice_unmap(struct magic_map *);
+private int apprentice_compile(struct magic_set *, struct magic_map *,
+    const char *);
+private int check_format_type(const char *, int, const char **);
+private int check_format(struct magic_set *, struct magic *);
+private int get_op(char);
+private int parse_mime(struct magic_set *, struct magic_entry *, const char *);
+private int parse_strength(struct magic_set *, struct magic_entry *, const char *);
+private int parse_apple(struct magic_set *, struct magic_entry *, const char *);
+private int parse_ext(struct magic_set *, struct magic_entry *, const char *);
+
+
+private size_t magicsize = sizeof(struct magic);
+
+private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
+
+private struct {
+       const char *name;
+       size_t len;
+       int (*fun)(struct magic_set *, struct magic_entry *, const char *);
+} bang[] = {
+#define        DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name }
+       DECLARE_FIELD(mime),
+       DECLARE_FIELD(apple),
+       DECLARE_FIELD(ext),
+       DECLARE_FIELD(strength),
+#undef DECLARE_FIELD
+       { NULL, 0, NULL }
+};
+
+#ifdef COMPILE_ONLY
+
+int main(int, char *[]);
+
+int
+main(int argc, char *argv[])
+{
+       int ret;
+       struct magic_set *ms;
+       char *progname;
+
+       if ((progname = strrchr(argv[0], '/')) != NULL)
+               progname++;
+       else
+               progname = argv[0];
+
+       if (argc != 2) {
+               (void)fprintf(stderr, "Usage: %s file\n", progname);
+               return 1;
+       }
+
+       if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
+               (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
+               return 1;
+       }
+       ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
+       if (ret == 1)
+               (void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
+       magic_close(ms);
+       return ret;
+}
+#endif /* COMPILE_ONLY */
+
+struct type_tbl_s {
+       const char name[16];
+       const size_t len;
+       const int type;
+       const int format;
+};
+
+/*
+ * XXX - the actual Single UNIX Specification says that "long" means "long",
+ * as in the C data type, but we treat it as meaning "4-byte integer".
+ * Given that the OS X version of file 5.04 did the same, I guess that passes
+ * the actual test; having "long" be dependent on how big a "long" is on
+ * the machine running "file" is silly.
+ */
+static const struct type_tbl_s type_tbl[] = {
+# define XX(s)         s, (sizeof(s) - 1)
+# define XX_NULL       "", 0
+       { XX("invalid"),        FILE_INVALID,           FILE_FMT_NONE },
+       { XX("byte"),           FILE_BYTE,              FILE_FMT_NUM },
+       { XX("short"),          FILE_SHORT,             FILE_FMT_NUM },
+       { XX("default"),        FILE_DEFAULT,           FILE_FMT_NONE },
+       { XX("long"),           FILE_LONG,              FILE_FMT_NUM },
+       { XX("string"),         FILE_STRING,            FILE_FMT_STR },
+       { XX("date"),           FILE_DATE,              FILE_FMT_STR },
+       { XX("beshort"),        FILE_BESHORT,           FILE_FMT_NUM },
+       { XX("belong"),         FILE_BELONG,            FILE_FMT_NUM },
+       { XX("bedate"),         FILE_BEDATE,            FILE_FMT_STR },
+       { XX("leshort"),        FILE_LESHORT,           FILE_FMT_NUM },
+       { XX("lelong"),         FILE_LELONG,            FILE_FMT_NUM },
+       { XX("ledate"),         FILE_LEDATE,            FILE_FMT_STR },
+       { XX("pstring"),        FILE_PSTRING,           FILE_FMT_STR },
+       { XX("ldate"),          FILE_LDATE,             FILE_FMT_STR },
+       { XX("beldate"),        FILE_BELDATE,           FILE_FMT_STR },
+       { XX("leldate"),        FILE_LELDATE,           FILE_FMT_STR },
+       { XX("regex"),          FILE_REGEX,             FILE_FMT_STR },
+       { XX("bestring16"),     FILE_BESTRING16,        FILE_FMT_STR },
+       { XX("lestring16"),     FILE_LESTRING16,        FILE_FMT_STR },
+       { XX("search"),         FILE_SEARCH,            FILE_FMT_STR },
+       { XX("medate"),         FILE_MEDATE,            FILE_FMT_STR },
+       { XX("meldate"),        FILE_MELDATE,           FILE_FMT_STR },
+       { XX("melong"),         FILE_MELONG,            FILE_FMT_NUM },
+       { XX("quad"),           FILE_QUAD,              FILE_FMT_QUAD },
+       { XX("lequad"),         FILE_LEQUAD,            FILE_FMT_QUAD },
+       { XX("bequad"),         FILE_BEQUAD,            FILE_FMT_QUAD },
+       { XX("qdate"),          FILE_QDATE,             FILE_FMT_STR },
+       { XX("leqdate"),        FILE_LEQDATE,           FILE_FMT_STR },
+       { XX("beqdate"),        FILE_BEQDATE,           FILE_FMT_STR },
+       { XX("qldate"),         FILE_QLDATE,            FILE_FMT_STR },
+       { XX("leqldate"),       FILE_LEQLDATE,          FILE_FMT_STR },
+       { XX("beqldate"),       FILE_BEQLDATE,          FILE_FMT_STR },
+       { XX("float"),          FILE_FLOAT,             FILE_FMT_FLOAT },
+       { XX("befloat"),        FILE_BEFLOAT,           FILE_FMT_FLOAT },
+       { XX("lefloat"),        FILE_LEFLOAT,           FILE_FMT_FLOAT },
+       { XX("double"),         FILE_DOUBLE,            FILE_FMT_DOUBLE },
+       { XX("bedouble"),       FILE_BEDOUBLE,          FILE_FMT_DOUBLE },
+       { XX("ledouble"),       FILE_LEDOUBLE,          FILE_FMT_DOUBLE },
+       { XX("leid3"),          FILE_LEID3,             FILE_FMT_NUM },
+       { XX("beid3"),          FILE_BEID3,             FILE_FMT_NUM },
+       { XX("indirect"),       FILE_INDIRECT,          FILE_FMT_NUM },
+       { XX("qwdate"),         FILE_QWDATE,            FILE_FMT_STR },
+       { XX("leqwdate"),       FILE_LEQWDATE,          FILE_FMT_STR },
+       { XX("beqwdate"),       FILE_BEQWDATE,          FILE_FMT_STR },
+       { XX("name"),           FILE_NAME,              FILE_FMT_NONE },
+       { XX("use"),            FILE_USE,               FILE_FMT_NONE },
+       { XX("clear"),          FILE_CLEAR,             FILE_FMT_NONE },
+       { XX("der"),            FILE_DER,               FILE_FMT_STR },
+       { XX_NULL,              FILE_INVALID,           FILE_FMT_NONE },
+};
+
+/*
+ * These are not types, and cannot be preceded by "u" to make them
+ * unsigned.
+ */
+static const struct type_tbl_s special_tbl[] = {
+       { XX("der"),            FILE_DER,               FILE_FMT_STR },
+       { XX("name"),           FILE_NAME,              FILE_FMT_STR },
+       { XX("use"),            FILE_USE,               FILE_FMT_STR },
+       { XX_NULL,              FILE_INVALID,           FILE_FMT_NONE },
+};
+# undef XX
+# undef XX_NULL
+
+private int
+get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
+{
+       const struct type_tbl_s *p;
+
+       for (p = tbl; p->len; p++) {
+               if (strncmp(l, p->name, p->len) == 0) {
+                       if (t)
+                               *t = l + p->len;
+                       break;
+               }
+       }
+       return p->type;
+}
+
+private off_t
+maxoff_t(void) {
+       if (/*CONSTCOND*/sizeof(off_t) == sizeof(int))
+               return CAST(off_t, INT_MAX);
+       if (/*CONSTCOND*/sizeof(off_t) == sizeof(long))
+               return CAST(off_t, LONG_MAX);
+       return 0x7fffffff;
+}
+
+private int
+get_standard_integer_type(const char *l, const char **t)
+{
+       int type;
+
+       if (isalpha(CAST(unsigned char, l[1]))) {
+               switch (l[1]) {
+               case 'C':
+                       /* "dC" and "uC" */
+                       type = FILE_BYTE;
+                       break;
+               case 'S':
+                       /* "dS" and "uS" */
+                       type = FILE_SHORT;
+                       break;
+               case 'I':
+               case 'L':
+                       /*
+                        * "dI", "dL", "uI", and "uL".
+                        *
+                        * XXX - the actual Single UNIX Specification says
+                        * that "L" means "long", as in the C data type,
+                        * but we treat it as meaning "4-byte integer".
+                        * Given that the OS X version of file 5.04 did
+                        * the same, I guess that passes the actual SUS
+                        * validation suite; having "dL" be dependent on
+                        * how big a "long" is on the machine running
+                        * "file" is silly.
+                        */
+                       type = FILE_LONG;
+                       break;
+               case 'Q':
+                       /* "dQ" and "uQ" */
+                       type = FILE_QUAD;
+                       break;
+               default:
+                       /* "d{anything else}", "u{anything else}" */
+                       return FILE_INVALID;
+               }
+               l += 2;
+       } else if (isdigit(CAST(unsigned char, l[1]))) {
+               /*
+                * "d{num}" and "u{num}"; we only support {num} values
+                * of 1, 2, 4, and 8 - the Single UNIX Specification
+                * doesn't say anything about whether arbitrary
+                * values should be supported, but both the Solaris 10
+                * and OS X Mountain Lion versions of file passed the
+                * Single UNIX Specification validation suite, and
+                * neither of them support values bigger than 8 or
+                * non-power-of-2 values.
+                */
+               if (isdigit(CAST(unsigned char, l[2]))) {
+                       /* Multi-digit, so > 9 */
+                       return FILE_INVALID;
+               }
+               switch (l[1]) {
+               case '1':
+                       type = FILE_BYTE;
+                       break;
+               case '2':
+                       type = FILE_SHORT;
+                       break;
+               case '4':
+                       type = FILE_LONG;
+                       break;
+               case '8':
+                       type = FILE_QUAD;
+                       break;
+               default:
+                       /* XXX - what about 3, 5, 6, or 7? */
+                       return FILE_INVALID;
+               }
+               l += 2;
+       } else {
+               /*
+                * "d" or "u" by itself.
+                */
+               type = FILE_LONG;
+               ++l;
+       }
+       if (t)
+               *t = l;
+       return type;
+}
+
+private void
+init_file_tables(void)
+{
+       static int done = 0;
+       const struct type_tbl_s *p;
+
+       if (done)
+               return;
+       done++;
+
+       for (p = type_tbl; p->len; p++) {
+               assert(p->type < FILE_NAMES_SIZE);
+               file_names[p->type] = p->name;
+               file_formats[p->type] = p->format;
+       }
+       assert(p - type_tbl == FILE_NAMES_SIZE);
+}
+
+private int
+add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
+{
+       struct mlist *ml;
+
+       mlp->map = NULL;
+       if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
+               return -1;
+
+       ml->map = idx == 0 ? map : NULL;
+       ml->magic = map->magic[idx];
+       ml->nmagic = map->nmagic[idx];
+
+       mlp->prev->next = ml;
+       ml->prev = mlp->prev;
+       ml->next = mlp;
+       mlp->prev = ml;
+       return 0;
+}
+
+/*
+ * Handle one file or directory.
+ */
+private int
+apprentice_1(struct magic_set *ms, const char *fn, int action)
+{
+       struct magic_map *map;
+#ifndef COMPILE_ONLY
+       struct mlist *ml;
+       size_t i;
+#endif
+
+       if (magicsize != FILE_MAGICSIZE) {
+               file_error(ms, 0, "magic element size %lu != %lu",
+                   CAST(unsigned long, sizeof(*map->magic[0])),
+                   CAST(unsigned long, FILE_MAGICSIZE));
+               return -1;
+       }
+
+       if (action == FILE_COMPILE) {
+               map = apprentice_load(ms, fn, action);
+               if (map == NULL)
+                       return -1;
+               return apprentice_compile(ms, map, fn);
+       }
+
+#ifndef COMPILE_ONLY
+       map = apprentice_map(ms, fn);
+       if (map == RCAST(struct magic_map *, -1))
+               return -1;
+       if (map == NULL) {
+               if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "using regular magic file `%s'", fn);
+               map = apprentice_load(ms, fn, action);
+               if (map == NULL)
+                       return -1;
+       }
+
+       for (i = 0; i < MAGIC_SETS; i++) {
+               if (add_mlist(ms->mlist[i], map, i) == -1) {
+                       file_oomem(ms, sizeof(*ml));
+                       return -1;
+               }
+       }
+
+       if (action == FILE_LIST) {
+               for (i = 0; i < MAGIC_SETS; i++) {
+                       printf("Set %" SIZE_T_FORMAT "u:\nBinary patterns:\n",
+                           i);
+                       apprentice_list(ms->mlist[i], BINTEST);
+                       printf("Text patterns:\n");
+                       apprentice_list(ms->mlist[i], TEXTTEST);
+               }
+       }
+       return 0;
+#else
+       return 0;
+#endif /* COMPILE_ONLY */
+}
+
+protected void
+file_ms_free(struct magic_set *ms)
+{
+       size_t i;
+       if (ms == NULL)
+               return;
+       for (i = 0; i < MAGIC_SETS; i++)
+               mlist_free(ms->mlist[i]);
+       free(ms->o.pbuf);
+       free(ms->o.buf);
+       free(ms->c.li);
+       free(ms);
+}
+
+protected struct magic_set *
+file_ms_alloc(int flags)
+{
+       struct magic_set *ms;
+       size_t i, len;
+
+       if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u),
+           sizeof(struct magic_set)))) == NULL)
+               return NULL;
+
+       if (magic_setflags(ms, flags) == -1) {
+               errno = EINVAL;
+               goto free;
+       }
+
+       ms->o.buf = ms->o.pbuf = NULL;
+       len = (ms->c.len = 10) * sizeof(*ms->c.li);
+
+       if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
+               goto free;
+
+       ms->event_flags = 0;
+       ms->error = -1;
+       for (i = 0; i < MAGIC_SETS; i++)
+               ms->mlist[i] = NULL;
+       ms->file = "unknown";
+       ms->line = 0;
+       ms->indir_max = FILE_INDIR_MAX;
+       ms->name_max = FILE_NAME_MAX;
+       ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
+       ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
+       ms->elf_notes_max = FILE_ELF_NOTES_MAX;
+       ms->regex_max = FILE_REGEX_MAX;
+       ms->bytes_max = FILE_BYTES_MAX;
+       return ms;
+free:
+       free(ms);
+       return NULL;
+}
+
+private void
+apprentice_unmap(struct magic_map *map)
+{
+       size_t i;
+       if (map == NULL)
+               return;
+
+       switch (map->type) {
+       case MAP_TYPE_USER:
+               break;
+       case MAP_TYPE_MALLOC:
+               for (i = 0; i < MAGIC_SETS; i++) {
+                       void *b = map->magic[i];
+                       void *p = map->p;
+                       if (CAST(char *, b) >= CAST(char *, p) &&
+                           CAST(char *, b) <= CAST(char *, p) + map->len)
+                               continue;
+                       free(map->magic[i]);
+               }
+               free(map->p);
+               break;
+#ifdef QUICK
+       case MAP_TYPE_MMAP:
+               if (map->p && map->p != MAP_FAILED)
+                       (void)munmap(map->p, map->len);
+               break;
+#endif
+       default:
+               abort();
+       }
+       free(map);
+}
+
+private struct mlist *
+mlist_alloc(void)
+{
+       struct mlist *mlist;
+       if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
+               return NULL;
+       }
+       mlist->next = mlist->prev = mlist;
+       return mlist;
+}
+
+private void
+mlist_free_one(struct mlist *ml)
+{
+       if (ml->map)
+               apprentice_unmap(CAST(struct magic_map *, ml->map));
+       free(ml);
+}
+
+private void
+mlist_free(struct mlist *mlist)
+{
+       struct mlist *ml, *next;
+
+       if (mlist == NULL)
+               return;
+
+       for (ml = mlist->next; ml != mlist; ml = next) {
+               next = ml->next;
+               mlist_free_one(ml);
+       }
+       mlist_free_one(mlist);
+}
+
+#ifndef COMPILE_ONLY
+/* void **bufs: an array of compiled magic files */
+protected int
+buffer_apprentice(struct magic_set *ms, struct magic **bufs,
+    size_t *sizes, size_t nbufs)
+{
+       size_t i, j;
+       struct mlist *ml;
+       struct magic_map *map;
+
+       if (nbufs == 0)
+               return -1;
+
+       (void)file_reset(ms, 0);
+
+       init_file_tables();
+
+       for (i = 0; i < MAGIC_SETS; i++) {
+               mlist_free(ms->mlist[i]);
+               if ((ms->mlist[i] = mlist_alloc()) == NULL) {
+                       file_oomem(ms, sizeof(*ms->mlist[i]));
+                       goto fail;
+               }
+       }
+
+       for (i = 0; i < nbufs; i++) {
+               map = apprentice_buf(ms, bufs[i], sizes[i]);
+               if (map == NULL)
+                       goto fail;
+
+               for (j = 0; j < MAGIC_SETS; j++) {
+                       if (add_mlist(ms->mlist[j], map, j) == -1) {
+                               file_oomem(ms, sizeof(*ml));
+                               goto fail;
+                       }
+               }
+       }
+
+       return 0;
+fail:
+       for (i = 0; i < MAGIC_SETS; i++) {
+               mlist_free(ms->mlist[i]);
+               ms->mlist[i] = NULL;
+       }
+       return -1;
+}
+#endif
+
+/* const char *fn: list of magic files and directories */
+protected int
+file_apprentice(struct magic_set *ms, const char *fn, int action)
+{
+       char *p, *mfn;
+       int fileerr, errs = -1;
+       size_t i;
+
+       (void)file_reset(ms, 0);
+
+       if ((fn = magic_getpath(fn, action)) == NULL)
+               return -1;
+
+       init_file_tables();
+
+       if ((mfn = strdup(fn)) == NULL) {
+               file_oomem(ms, strlen(fn));
+               return -1;
+       }
+
+       for (i = 0; i < MAGIC_SETS; i++) {
+               mlist_free(ms->mlist[i]);
+               if ((ms->mlist[i] = mlist_alloc()) == NULL) {
+                       file_oomem(ms, sizeof(*ms->mlist[i]));
+                       while (i-- > 0) {
+                               mlist_free(ms->mlist[i]);
+                               ms->mlist[i] = NULL;
+                       }
+                       free(mfn);
+                       return -1;
+               }
+       }
+       fn = mfn;
+
+       while (fn) {
+               p = strchr(fn, PATHSEP);
+               if (p)
+                       *p++ = '\0';
+               if (*fn == '\0')
+                       break;
+               fileerr = apprentice_1(ms, fn, action);
+               errs = MAX(errs, fileerr);
+               fn = p;
+       }
+
+       free(mfn);
+
+       if (errs == -1) {
+               for (i = 0; i < MAGIC_SETS; i++) {
+                       mlist_free(ms->mlist[i]);
+                       ms->mlist[i] = NULL;
+               }
+               file_error(ms, 0, "could not find any valid magic files!");
+               return -1;
+       }
+
+#if 0
+       /*
+        * Always leave the database loaded
+        */
+       if (action == FILE_LOAD)
+               return 0;
+
+       for (i = 0; i < MAGIC_SETS; i++) {
+               mlist_free(ms->mlist[i]);
+               ms->mlist[i] = NULL;
+       }
+#endif
+
+       switch (action) {
+       case FILE_LOAD:
+       case FILE_COMPILE:
+       case FILE_CHECK:
+       case FILE_LIST:
+               return 0;
+       default:
+               file_error(ms, 0, "Invalid action %d", action);
+               return -1;
+       }
+}
+
+/*
+ * Compute the real length of a magic expression, for the purposes
+ * of determining how "strong" a magic expression is (approximating
+ * how specific its matches are):
+ *     - magic characters count 0 unless escaped.
+ *     - [] expressions count 1
+ *     - {} expressions count 0
+ *     - regular characters or escaped magic characters count 1
+ *     - 0 length expressions count as one
+ */
+private size_t
+nonmagic(const char *str)
+{
+       const char *p;
+       size_t rv = 0;
+
+       for (p = str; *p; p++)
+               switch (*p) {
+               case '\\':      /* Escaped anything counts 1 */
+                       if (!*++p)
+                               p--;
+                       rv++;
+                       continue;
+               case '?':       /* Magic characters count 0 */
+               case '*':
+               case '.':
+               case '+':
+               case '^':
+               case '$':
+                       continue;
+               case '[':       /* Bracketed expressions count 1 the ']' */
+                       while (*p && *p != ']')
+                               p++;
+                       p--;
+                       continue;
+               case '{':       /* Braced expressions count 0 */
+                       while (*p && *p != '}')
+                               p++;
+                       if (!*p)
+                               p--;
+                       continue;
+               default:        /* Anything else counts 1 */
+                       rv++;
+                       continue;
+               }
+
+       return rv == 0 ? 1 : rv;        /* Return at least 1 */
+}
+
+
+private size_t
+typesize(int type)
+{
+       switch (type) {
+       case FILE_BYTE:
+               return 1;
+
+       case FILE_SHORT:
+       case FILE_LESHORT:
+       case FILE_BESHORT:
+               return 2;
+
+       case FILE_LONG:
+       case FILE_LELONG:
+       case FILE_BELONG:
+       case FILE_MELONG:
+               return 4;
+
+       case FILE_DATE:
+       case FILE_LEDATE:
+       case FILE_BEDATE:
+       case FILE_MEDATE:
+       case FILE_LDATE:
+       case FILE_LELDATE:
+       case FILE_BELDATE:
+       case FILE_MELDATE:
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               return 4;
+
+       case FILE_QUAD:
+       case FILE_BEQUAD:
+       case FILE_LEQUAD:
+       case FILE_QDATE:
+       case FILE_LEQDATE:
+       case FILE_BEQDATE:
+       case FILE_QLDATE:
+       case FILE_LEQLDATE:
+       case FILE_BEQLDATE:
+       case FILE_QWDATE:
+       case FILE_LEQWDATE:
+       case FILE_BEQWDATE:
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               return 8;
+       default:
+               return CAST(size_t, ~0);
+       }
+}
+
+/*
+ * Get weight of this magic entry, for sorting purposes.
+ */
+private size_t
+apprentice_magic_strength(const struct magic *m)
+{
+#define MULT 10U
+       size_t ts, v;
+       ssize_t val = 2 * MULT; /* baseline strength */
+
+       switch (m->type) {
+       case FILE_DEFAULT:      /* make sure this sorts last */
+               if (m->factor_op != FILE_FACTOR_OP_NONE)
+                       abort();
+               return 0;
+
+       case FILE_BYTE:
+       case FILE_SHORT:
+       case FILE_LESHORT:
+       case FILE_BESHORT:
+       case FILE_LONG:
+       case FILE_LELONG:
+       case FILE_BELONG:
+       case FILE_MELONG:
+       case FILE_DATE:
+       case FILE_LEDATE:
+       case FILE_BEDATE:
+       case FILE_MEDATE:
+       case FILE_LDATE:
+       case FILE_LELDATE:
+       case FILE_BELDATE:
+       case FILE_MELDATE:
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+       case FILE_QUAD:
+       case FILE_BEQUAD:
+       case FILE_LEQUAD:
+       case FILE_QDATE:
+       case FILE_LEQDATE:
+       case FILE_BEQDATE:
+       case FILE_QLDATE:
+       case FILE_LEQLDATE:
+       case FILE_BEQLDATE:
+       case FILE_QWDATE:
+       case FILE_LEQWDATE:
+       case FILE_BEQWDATE:
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               ts = typesize(m->type);
+               if (ts == CAST(size_t, ~0))
+                       abort();
+               val += ts * MULT;
+               break;
+
+       case FILE_PSTRING:
+       case FILE_STRING:
+               val += m->vallen * MULT;
+               break;
+
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               val += m->vallen * MULT / 2;
+               break;
+
+       case FILE_SEARCH:
+               if (m->vallen == 0)
+                       break;
+               val += m->vallen * MAX(MULT / m->vallen, 1);
+               break;
+
+       case FILE_REGEX:
+               v = nonmagic(m->value.s);
+               val += v * MAX(MULT / v, 1);
+               break;
+
+       case FILE_INDIRECT:
+       case FILE_NAME:
+       case FILE_USE:
+               break;
+
+       case FILE_DER:
+               val += MULT;
+               break;
+
+       default:
+               (void)fprintf(stderr, "Bad type %d\n", m->type);
+               abort();
+       }
+
+       switch (m->reln) {
+       case 'x':       /* matches anything penalize */
+       case '!':       /* matches almost anything penalize */
+               val = 0;
+               break;
+
+       case '=':       /* Exact match, prefer */
+               val += MULT;
+               break;
+
+       case '>':
+       case '<':       /* comparison match reduce strength */
+               val -= 2 * MULT;
+               break;
+
+       case '^':
+       case '&':       /* masking bits, we could count them too */
+               val -= MULT;
+               break;
+
+       default:
+               (void)fprintf(stderr, "Bad relation %c\n", m->reln);
+               abort();
+       }
+
+       switch (m->factor_op) {
+       case FILE_FACTOR_OP_NONE:
+               break;
+       case FILE_FACTOR_OP_PLUS:
+               val += m->factor;
+               break;
+       case FILE_FACTOR_OP_MINUS:
+               val -= m->factor;
+               break;
+       case FILE_FACTOR_OP_TIMES:
+               val *= m->factor;
+               break;
+       case FILE_FACTOR_OP_DIV:
+               val /= m->factor;
+               break;
+       default:
+               abort();
+       }
+
+       if (val <= 0)   /* ensure we only return 0 for FILE_DEFAULT */
+               val = 1;
+
+       /*
+        * Magic entries with no description get a bonus because they depend
+        * on subsequent magic entries to print something.
+        */
+       if (m->desc[0] == '\0')
+               val++;
+       return val;
+}
+
+/*
+ * Sort callback for sorting entries by "strength" (basically length)
+ */
+private int
+apprentice_sort(const void *a, const void *b)
+{
+       const struct magic_entry *ma = CAST(const struct magic_entry *, a);
+       const struct magic_entry *mb = CAST(const struct magic_entry *, b);
+       size_t sa = apprentice_magic_strength(ma->mp);
+       size_t sb = apprentice_magic_strength(mb->mp);
+       if (sa == sb)
+               return 0;
+       else if (sa > sb)
+               return -1;
+       else
+               return 1;
+}
+
+/*
+ * Shows sorted patterns list in the order which is used for the matching
+ */
+private void
+apprentice_list(struct mlist *mlist, int mode)
+{
+       uint32_t magindex = 0;
+       struct mlist *ml;
+       for (ml = mlist->next; ml != mlist; ml = ml->next) {
+               for (magindex = 0; magindex < ml->nmagic; magindex++) {
+                       struct magic *m = &ml->magic[magindex];
+                       if ((m->flag & mode) != mode) {
+                               /* Skip sub-tests */
+                               while (magindex + 1 < ml->nmagic &&
+                                      ml->magic[magindex + 1].cont_level != 0)
+                                       ++magindex;
+                               continue; /* Skip to next top-level test*/
+                       }
+
+                       /*
+                        * Try to iterate over the tree until we find item with
+                        * description/mimetype.
+                        */
+                       while (magindex + 1 < ml->nmagic &&
+                              ml->magic[magindex + 1].cont_level != 0 &&
+                              *ml->magic[magindex].desc == '\0' &&
+                              *ml->magic[magindex].mimetype == '\0')
+                               magindex++;
+
+                       printf("Strength = %3" SIZE_T_FORMAT "u@%u: %s [%s]\n",
+                           apprentice_magic_strength(m),
+                           ml->magic[magindex].lineno,
+                           ml->magic[magindex].desc,
+                           ml->magic[magindex].mimetype);
+               }
+       }
+}
+
+private void
+set_test_type(struct magic *mstart, struct magic *m)
+{
+       switch (m->type) {
+       case FILE_BYTE:
+       case FILE_SHORT:
+       case FILE_LONG:
+       case FILE_DATE:
+       case FILE_BESHORT:
+       case FILE_BELONG:
+       case FILE_BEDATE:
+       case FILE_LESHORT:
+       case FILE_LELONG:
+       case FILE_LEDATE:
+       case FILE_LDATE:
+       case FILE_BELDATE:
+       case FILE_LELDATE:
+       case FILE_MEDATE:
+       case FILE_MELDATE:
+       case FILE_MELONG:
+       case FILE_QUAD:
+       case FILE_LEQUAD:
+       case FILE_BEQUAD:
+       case FILE_QDATE:
+       case FILE_LEQDATE:
+       case FILE_BEQDATE:
+       case FILE_QLDATE:
+       case FILE_LEQLDATE:
+       case FILE_BEQLDATE:
+       case FILE_QWDATE:
+       case FILE_LEQWDATE:
+       case FILE_BEQWDATE:
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+       case FILE_DER:
+               mstart->flag |= BINTEST;
+               break;
+       case FILE_STRING:
+       case FILE_PSTRING:
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               /* Allow text overrides */
+               if (mstart->str_flags & STRING_TEXTTEST)
+                       mstart->flag |= TEXTTEST;
+               else
+                       mstart->flag |= BINTEST;
+               break;
+       case FILE_REGEX:
+       case FILE_SEARCH:
+               /* Check for override */
+               if (mstart->str_flags & STRING_BINTEST)
+                       mstart->flag |= BINTEST;
+               if (mstart->str_flags & STRING_TEXTTEST)
+                       mstart->flag |= TEXTTEST;
+
+               if (mstart->flag & (TEXTTEST|BINTEST))
+                       break;
+
+               /* binary test if pattern is not text */
+               if (file_looks_utf8(m->value.us, CAST(size_t, m->vallen), NULL,
+                   NULL) <= 0)
+                       mstart->flag |= BINTEST;
+               else
+                       mstart->flag |= TEXTTEST;
+               break;
+       case FILE_DEFAULT:
+               /* can't deduce anything; we shouldn't see this at the
+                  top level anyway */
+               break;
+       case FILE_INVALID:
+       default:
+               /* invalid search type, but no need to complain here */
+               break;
+       }
+}
+
+private int
+addentry(struct magic_set *ms, struct magic_entry *me,
+   struct magic_entry_set *mset)
+{
+       size_t i = me->mp->type == FILE_NAME ? 1 : 0;
+       if (mset[i].count == mset[i].max) {
+               struct magic_entry *mp;
+
+               mset[i].max += ALLOC_INCR;
+               if ((mp = CAST(struct magic_entry *,
+                   realloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
+                   NULL) {
+                       file_oomem(ms, sizeof(*mp) * mset[i].max);
+                       return -1;
+               }
+               (void)memset(&mp[mset[i].count], 0, sizeof(*mp) *
+                   ALLOC_INCR);
+               mset[i].me = mp;
+       }
+       mset[i].me[mset[i].count++] = *me;
+       memset(me, 0, sizeof(*me));
+       return 0;
+}
+
+/*
+ * Load and parse one file.
+ */
+private void
+load_1(struct magic_set *ms, int action, const char *fn, int *errs,
+   struct magic_entry_set *mset)
+{
+       size_t lineno = 0, llen = 0;
+       char *line = NULL;
+       ssize_t len;
+       struct magic_entry me;
+
+       FILE *f = fopen(ms->file = fn, "r");
+       if (f == NULL) {
+               if (errno != ENOENT)
+                       file_error(ms, errno, "cannot read magic file `%s'",
+                                  fn);
+               (*errs)++;
+               return;
+       }
+
+       memset(&me, 0, sizeof(me));
+       /* read and parse this file */
+       for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
+           ms->line++) {
+               if (len == 0) /* null line, garbage, etc */
+                       continue;
+               if (line[len - 1] == '\n') {
+                       lineno++;
+                       line[len - 1] = '\0'; /* delete newline */
+               }
+               switch (line[0]) {
+               case '\0':      /* empty, do not parse */
+               case '#':       /* comment, do not parse */
+                       continue;
+               case '!':
+                       if (line[1] == ':') {
+                               size_t i;
+
+                               for (i = 0; bang[i].name != NULL; i++) {
+                                       if (CAST(size_t, len - 2) > bang[i].len &&
+                                           memcmp(bang[i].name, line + 2,
+                                           bang[i].len) == 0)
+                                               break;
+                               }
+                               if (bang[i].name == NULL) {
+                                       file_error(ms, 0,
+                                           "Unknown !: entry `%s'", line);
+                                       (*errs)++;
+                                       continue;
+                               }
+                               if (me.mp == NULL) {
+                                       file_error(ms, 0,
+                                           "No current entry for :!%s type",
+                                               bang[i].name);
+                                       (*errs)++;
+                                       continue;
+                               }
+                               if ((*bang[i].fun)(ms, &me,
+                                   line + bang[i].len + 2) != 0) {
+                                       (*errs)++;
+                                       continue;
+                               }
+                               continue;
+                       }
+                       /*FALLTHROUGH*/
+               default:
+               again:
+                       switch (parse(ms, &me, line, lineno, action)) {
+                       case 0:
+                               continue;
+                       case 1:
+                               (void)addentry(ms, &me, mset);
+                               goto again;
+                       default:
+                               (*errs)++;
+                               break;
+                       }
+               }
+       }
+       if (me.mp)
+               (void)addentry(ms, &me, mset);
+       free(line);
+       (void)fclose(f);
+}
+
+/*
+ * parse a file or directory of files
+ * const char *fn: name of magic file or directory
+ */
+private int
+cmpstrp(const void *p1, const void *p2)
+{
+        return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2));
+}
+
+
+private uint32_t
+set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
+    uint32_t starttest)
+{
+       static const char text[] = "text";
+       static const char binary[] = "binary";
+       static const size_t len = sizeof(text);
+
+       uint32_t i = starttest;
+
+       do {
+               set_test_type(me[starttest].mp, me[i].mp);
+               if ((ms->flags & MAGIC_DEBUG) == 0)
+                       continue;
+               (void)fprintf(stderr, "%s%s%s: %s\n",
+                   me[i].mp->mimetype,
+                   me[i].mp->mimetype[0] == '\0' ? "" : "; ",
+                   me[i].mp->desc[0] ? me[i].mp->desc : "(no description)",
+                   me[i].mp->flag & BINTEST ? binary : text);
+               if (me[i].mp->flag & BINTEST) {
+                       char *p = strstr(me[i].mp->desc, text);
+                       if (p && (p == me[i].mp->desc ||
+                           isspace(CAST(unsigned char, p[-1]))) &&
+                           (p + len - me[i].mp->desc == MAXstring
+                           || (p[len] == '\0' ||
+                           isspace(CAST(unsigned char, p[len])))))
+                               (void)fprintf(stderr, "*** Possible "
+                                   "binary test for text type\n");
+               }
+       } while (++i < nme && me[i].mp->cont_level != 0);
+       return i;
+}
+
+private void
+set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
+{
+       uint32_t i;
+       for (i = 0; i < nme; i++) {
+               if (me[i].mp->cont_level == 0 &&
+                   me[i].mp->type == FILE_DEFAULT) {
+                       while (++i < nme)
+                               if (me[i].mp->cont_level == 0)
+                                       break;
+                       if (i != nme) {
+                               /* XXX - Ugh! */
+                               ms->line = me[i].mp->lineno;
+                               file_magwarn(ms,
+                                   "level 0 \"default\" did not sort last");
+                       }
+                       return;
+               }
+       }
+}
+
+private int
+coalesce_entries(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
+    struct magic **ma, uint32_t *nma)
+{
+       uint32_t i, mentrycount = 0;
+       size_t slen;
+
+       for (i = 0; i < nme; i++)
+               mentrycount += me[i].cont_count;
+
+       slen = sizeof(**ma) * mentrycount;
+       if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) {
+               file_oomem(ms, slen);
+               return -1;
+       }
+
+       mentrycount = 0;
+       for (i = 0; i < nme; i++) {
+               (void)memcpy(*ma + mentrycount, me[i].mp,
+                   me[i].cont_count * sizeof(**ma));
+               mentrycount += me[i].cont_count;
+       }
+       *nma = mentrycount;
+       return 0;
+}
+
+private void
+magic_entry_free(struct magic_entry *me, uint32_t nme)
+{
+       uint32_t i;
+       if (me == NULL)
+               return;
+       for (i = 0; i < nme; i++)
+               free(me[i].mp);
+       free(me);
+}
+
+private struct magic_map *
+apprentice_load(struct magic_set *ms, const char *fn, int action)
+{
+       int errs = 0;
+       uint32_t i, j;
+       size_t files = 0, maxfiles = 0;
+       char **filearr = NULL, *mfn;
+       struct stat st;
+       struct magic_map *map;
+       struct magic_entry_set mset[MAGIC_SETS];
+       DIR *dir;
+       struct dirent *d;
+
+       memset(mset, 0, sizeof(mset));
+       ms->flags |= MAGIC_CHECK;       /* Enable checks for parsed files */
+
+
+       if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL)
+       {
+               file_oomem(ms, sizeof(*map));
+               return NULL;
+       }
+       map->type = MAP_TYPE_MALLOC;
+
+       /* print silly verbose header for USG compat. */
+       if (action == FILE_CHECK)
+               (void)fprintf(stderr, "%s\n", usg_hdr);
+
+       /* load directory or file */
+       if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
+               dir = opendir(fn);
+               if (!dir) {
+                       errs++;
+                       goto out;
+               }
+               while ((d = readdir(dir)) != NULL) {
+                       if (d->d_name[0] == '.')
+                               continue;
+                       if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
+                               file_oomem(ms,
+                                   strlen(fn) + strlen(d->d_name) + 2);
+                               errs++;
+                               closedir(dir);
+                               goto out;
+                       }
+                       if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
+                               free(mfn);
+                               continue;
+                       }
+                       if (files >= maxfiles) {
+                               size_t mlen;
+                               maxfiles = (maxfiles + 1) * 2;
+                               mlen = maxfiles * sizeof(*filearr);
+                               if ((filearr = CAST(char **,
+                                   realloc(filearr, mlen))) == NULL) {
+                                       file_oomem(ms, mlen);
+                                       free(mfn);
+                                       closedir(dir);
+                                       errs++;
+                                       goto out;
+                               }
+                       }
+                       filearr[files++] = mfn;
+               }
+               closedir(dir);
+               if (filearr) {
+                       qsort(filearr, files, sizeof(*filearr), cmpstrp);
+                       for (i = 0; i < files; i++) {
+                               load_1(ms, action, filearr[i], &errs, mset);
+                               free(filearr[i]);
+                       }
+                       free(filearr);
+               }
+       } else
+               load_1(ms, action, fn, &errs, mset);
+       if (errs)
+               goto out;
+
+       for (j = 0; j < MAGIC_SETS; j++) {
+               /* Set types of tests */
+               for (i = 0; i < mset[j].count; ) {
+                       if (mset[j].me[i].mp->cont_level != 0) {
+                               i++;
+                               continue;
+                       }
+                       i = set_text_binary(ms, mset[j].me, mset[j].count, i);
+               }
+               if (mset[j].me)
+                       qsort(mset[j].me, mset[j].count, sizeof(*mset[j].me),
+                           apprentice_sort);
+
+               /*
+                * Make sure that any level 0 "default" line is last
+                * (if one exists).
+                */
+               set_last_default(ms, mset[j].me, mset[j].count);
+
+               /* coalesce per file arrays into a single one */
+               if (coalesce_entries(ms, mset[j].me, mset[j].count,
+                   &map->magic[j], &map->nmagic[j]) == -1) {
+                       errs++;
+                       goto out;
+               }
+       }
+
+out:
+       for (j = 0; j < MAGIC_SETS; j++)
+               magic_entry_free(mset[j].me, mset[j].count);
+
+       if (errs) {
+               apprentice_unmap(map);
+               return NULL;
+       }
+       return map;
+}
+
+/*
+ * extend the sign bit if the comparison is to be signed
+ */
+protected uint64_t
+file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
+{
+       if (!(m->flag & UNSIGNED)) {
+               switch(m->type) {
+               /*
+                * Do not remove the casts below.  They are
+                * vital.  When later compared with the data,
+                * the sign extension must have happened.
+                */
+               case FILE_BYTE:
+                       v = CAST(signed char,  v);
+                       break;
+               case FILE_SHORT:
+               case FILE_BESHORT:
+               case FILE_LESHORT:
+                       v = CAST(short, v);
+                       break;
+               case FILE_DATE:
+               case FILE_BEDATE:
+               case FILE_LEDATE:
+               case FILE_MEDATE:
+               case FILE_LDATE:
+               case FILE_BELDATE:
+               case FILE_LELDATE:
+               case FILE_MELDATE:
+               case FILE_LONG:
+               case FILE_BELONG:
+               case FILE_LELONG:
+               case FILE_MELONG:
+               case FILE_FLOAT:
+               case FILE_BEFLOAT:
+               case FILE_LEFLOAT:
+                       v = CAST(int32_t, v);
+                       break;
+               case FILE_QUAD:
+               case FILE_BEQUAD:
+               case FILE_LEQUAD:
+               case FILE_QDATE:
+               case FILE_QLDATE:
+               case FILE_QWDATE:
+               case FILE_BEQDATE:
+               case FILE_BEQLDATE:
+               case FILE_BEQWDATE:
+               case FILE_LEQDATE:
+               case FILE_LEQLDATE:
+               case FILE_LEQWDATE:
+               case FILE_DOUBLE:
+               case FILE_BEDOUBLE:
+               case FILE_LEDOUBLE:
+                       v = CAST(int64_t, v);
+                       break;
+               case FILE_STRING:
+               case FILE_PSTRING:
+               case FILE_BESTRING16:
+               case FILE_LESTRING16:
+               case FILE_REGEX:
+               case FILE_SEARCH:
+               case FILE_DEFAULT:
+               case FILE_INDIRECT:
+               case FILE_NAME:
+               case FILE_USE:
+               case FILE_CLEAR:
+               case FILE_DER:
+                       break;
+               default:
+                       if (ms->flags & MAGIC_CHECK)
+                           file_magwarn(ms, "cannot happen: m->type=%d\n",
+                                   m->type);
+                       return ~0U;
+               }
+       }
+       return v;
+}
+
+private int
+string_modifier_check(struct magic_set *ms, struct magic *m)
+{
+       if ((ms->flags & MAGIC_CHECK) == 0)
+               return 0;
+
+       if ((m->type != FILE_REGEX || (m->str_flags & REGEX_LINE_COUNT) == 0) &&
+           (m->type != FILE_PSTRING && (m->str_flags & PSTRING_LEN) != 0)) {
+               file_magwarn(ms,
+                   "'/BHhLl' modifiers are only allowed for pascal strings\n");
+               return -1;
+       }
+       switch (m->type) {
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               if (m->str_flags != 0) {
+                       file_magwarn(ms,
+                           "no modifiers allowed for 16-bit strings\n");
+                       return -1;
+               }
+               break;
+       case FILE_STRING:
+       case FILE_PSTRING:
+               if ((m->str_flags & REGEX_OFFSET_START) != 0) {
+                       file_magwarn(ms,
+                           "'/%c' only allowed on regex and search\n",
+                           CHAR_REGEX_OFFSET_START);
+                       return -1;
+               }
+               break;
+       case FILE_SEARCH:
+               if (m->str_range == 0) {
+                       file_magwarn(ms,
+                           "missing range; defaulting to %d\n",
+                            STRING_DEFAULT_RANGE);
+                       m->str_range = STRING_DEFAULT_RANGE;
+                       return -1;
+               }
+               break;
+       case FILE_REGEX:
+               if ((m->str_flags & STRING_COMPACT_WHITESPACE) != 0) {
+                       file_magwarn(ms, "'/%c' not allowed on regex\n",
+                           CHAR_COMPACT_WHITESPACE);
+                       return -1;
+               }
+               if ((m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE) != 0) {
+                       file_magwarn(ms, "'/%c' not allowed on regex\n",
+                           CHAR_COMPACT_OPTIONAL_WHITESPACE);
+                       return -1;
+               }
+               break;
+       default:
+               file_magwarn(ms, "coding error: m->type=%d\n",
+                   m->type);
+               return -1;
+       }
+       return 0;
+}
+
+private int
+get_op(char c)
+{
+       switch (c) {
+       case '&':
+               return FILE_OPAND;
+       case '|':
+               return FILE_OPOR;
+       case '^':
+               return FILE_OPXOR;
+       case '+':
+               return FILE_OPADD;
+       case '-':
+               return FILE_OPMINUS;
+       case '*':
+               return FILE_OPMULTIPLY;
+       case '/':
+               return FILE_OPDIVIDE;
+       case '%':
+               return FILE_OPMODULO;
+       default:
+               return -1;
+       }
+}
+
+#ifdef ENABLE_CONDITIONALS
+private int
+get_cond(const char *l, const char **t)
+{
+       static const struct cond_tbl_s {
+               char name[8];
+               size_t len;
+               int cond;
+       } cond_tbl[] = {
+               { "if",         2,      COND_IF },
+               { "elif",       4,      COND_ELIF },
+               { "else",       4,      COND_ELSE },
+               { "",           0,      COND_NONE },
+       };
+       const struct cond_tbl_s *p;
+
+       for (p = cond_tbl; p->len; p++) {
+               if (strncmp(l, p->name, p->len) == 0 &&
+                   isspace(CAST(unsigned char, l[p->len]))) {
+                       if (t)
+                               *t = l + p->len;
+                       break;
+               }
+       }
+       return p->cond;
+}
+
+private int
+check_cond(struct magic_set *ms, int cond, uint32_t cont_level)
+{
+       int last_cond;
+       last_cond = ms->c.li[cont_level].last_cond;
+
+       switch (cond) {
+       case COND_IF:
+               if (last_cond != COND_NONE && last_cond != COND_ELIF) {
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms, "syntax error: `if'");
+                       return -1;
+               }
+               last_cond = COND_IF;
+               break;
+
+       case COND_ELIF:
+               if (last_cond != COND_IF && last_cond != COND_ELIF) {
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms, "syntax error: `elif'");
+                       return -1;
+               }
+               last_cond = COND_ELIF;
+               break;
+
+       case COND_ELSE:
+               if (last_cond != COND_IF && last_cond != COND_ELIF) {
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms, "syntax error: `else'");
+                       return -1;
+               }
+               last_cond = COND_NONE;
+               break;
+
+       case COND_NONE:
+               last_cond = COND_NONE;
+               break;
+       }
+
+       ms->c.li[cont_level].last_cond = last_cond;
+       return 0;
+}
+#endif /* ENABLE_CONDITIONALS */
+
+private int
+parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
+{
+       const char *l = *lp;
+
+       while (!isspace(CAST(unsigned char, *++l)))
+               switch (*l) {
+               case CHAR_INDIRECT_RELATIVE:
+                       m->str_flags |= INDIRECT_RELATIVE;
+                       break;
+               default:
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms, "indirect modifier `%c' "
+                                       "invalid", *l);
+                       *lp = l;
+                       return -1;
+               }
+       *lp = l;
+       return 0;
+}
+
+private void
+parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
+    int op)
+{
+       const char *l = *lp;
+       char *t;
+       uint64_t val;
+
+       ++l;
+       m->mask_op |= op;
+       val = CAST(uint64_t, strtoull(l, &t, 0));
+       l = t;
+       m->num_mask = file_signextend(ms, m, val);
+       eatsize(&l);
+       *lp = l;
+}
+
+private int
+parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
+{
+       const char *l = *lp;
+       char *t;
+       int have_range = 0;
+
+       while (!isspace(CAST(unsigned char, *++l))) {
+               switch (*l) {
+               case '0':  case '1':  case '2':
+               case '3':  case '4':  case '5':
+               case '6':  case '7':  case '8':
+               case '9':
+                       if (have_range && (ms->flags & MAGIC_CHECK))
+                               file_magwarn(ms, "multiple ranges");
+                       have_range = 1;
+                       m->str_range = CAST(uint32_t, strtoul(l, &t, 0));
+                       if (m->str_range == 0)
+                               file_magwarn(ms, "zero range");
+                       l = t - 1;
+                       break;
+               case CHAR_COMPACT_WHITESPACE:
+                       m->str_flags |= STRING_COMPACT_WHITESPACE;
+                       break;
+               case CHAR_COMPACT_OPTIONAL_WHITESPACE:
+                       m->str_flags |= STRING_COMPACT_OPTIONAL_WHITESPACE;
+                       break;
+               case CHAR_IGNORE_LOWERCASE:
+                       m->str_flags |= STRING_IGNORE_LOWERCASE;
+                       break;
+               case CHAR_IGNORE_UPPERCASE:
+                       m->str_flags |= STRING_IGNORE_UPPERCASE;
+                       break;
+               case CHAR_REGEX_OFFSET_START:
+                       m->str_flags |= REGEX_OFFSET_START;
+                       break;
+               case CHAR_BINTEST:
+                       m->str_flags |= STRING_BINTEST;
+                       break;
+               case CHAR_TEXTTEST:
+                       m->str_flags |= STRING_TEXTTEST;
+                       break;
+               case CHAR_TRIM:
+                       m->str_flags |= STRING_TRIM;
+                       break;
+               case CHAR_PSTRING_1_LE:
+#define SET_LENGTH(a) m->str_flags = (m->str_flags & ~PSTRING_LEN) | (a)
+                       if (m->type != FILE_PSTRING)
+                               goto bad;
+                       SET_LENGTH(PSTRING_1_LE);
+                       break;
+               case CHAR_PSTRING_2_BE:
+                       if (m->type != FILE_PSTRING)
+                               goto bad;
+                       SET_LENGTH(PSTRING_2_BE);
+                       break;
+               case CHAR_PSTRING_2_LE:
+                       if (m->type != FILE_PSTRING)
+                               goto bad;
+                       SET_LENGTH(PSTRING_2_LE);
+                       break;
+               case CHAR_PSTRING_4_BE:
+                       if (m->type != FILE_PSTRING)
+                               goto bad;
+                       SET_LENGTH(PSTRING_4_BE);
+                       break;
+               case CHAR_PSTRING_4_LE:
+                       switch (m->type) {
+                       case FILE_PSTRING:
+                       case FILE_REGEX:
+                               break;
+                       default:
+                               goto bad;
+                       }
+                       SET_LENGTH(PSTRING_4_LE);
+                       break;
+               case CHAR_PSTRING_LENGTH_INCLUDES_ITSELF:
+                       if (m->type != FILE_PSTRING)
+                               goto bad;
+                       m->str_flags |= PSTRING_LENGTH_INCLUDES_ITSELF;
+                       break;
+               default:
+               bad:
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms, "string modifier `%c' "
+                                       "invalid", *l);
+                       goto out;
+               }
+               /* allow multiple '/' for readability */
+               if (l[1] == '/' && !isspace(CAST(unsigned char, l[2])))
+                       l++;
+       }
+       if (string_modifier_check(ms, m) == -1)
+               goto out;
+       *lp = l;
+       return 0;
+out:
+       *lp = l;
+       return -1;
+}
+
+/*
+ * parse one line from magic file, put into magic[index++] if valid
+ */
+private int
+parse(struct magic_set *ms, struct magic_entry *me, const char *line,
+    size_t lineno, int action)
+{
+#ifdef ENABLE_CONDITIONALS
+       static uint32_t last_cont_level = 0;
+#endif
+       size_t i;
+       struct magic *m;
+       const char *l = line;
+       char *t;
+       int op;
+       uint32_t cont_level;
+       int32_t diff;
+
+       cont_level = 0;
+
+       /*
+        * Parse the offset.
+        */
+       while (*l == '>') {
+               ++l;            /* step over */
+               cont_level++;
+       }
+#ifdef ENABLE_CONDITIONALS
+       if (cont_level == 0 || cont_level > last_cont_level)
+               if (file_check_mem(ms, cont_level) == -1)
+                       return -1;
+       last_cont_level = cont_level;
+#endif
+       if (cont_level != 0) {
+               if (me->mp == NULL) {
+                       file_magerror(ms, "No current entry for continuation");
+                       return -1;
+               }
+               if (me->cont_count == 0) {
+                       file_magerror(ms, "Continuations present with 0 count");
+                       return -1;
+               }
+               m = &me->mp[me->cont_count - 1];
+               diff = CAST(int32_t, cont_level) - CAST(int32_t, m->cont_level);
+               if (diff > 1)
+                       file_magwarn(ms, "New continuation level %u is more "
+                           "than one larger than current level %u", cont_level,
+                           m->cont_level);
+               if (me->cont_count == me->max_count) {
+                       struct magic *nm;
+                       size_t cnt = me->max_count + ALLOC_CHUNK;
+                       if ((nm = CAST(struct magic *, realloc(me->mp,
+                           sizeof(*nm) * cnt))) == NULL) {
+                               file_oomem(ms, sizeof(*nm) * cnt);
+                               return -1;
+                       }
+                       me->mp = nm;
+                       me->max_count = CAST(uint32_t, cnt);
+               }
+               m = &me->mp[me->cont_count++];
+               (void)memset(m, 0, sizeof(*m));
+               m->cont_level = cont_level;
+       } else {
+               static const size_t len = sizeof(*m) * ALLOC_CHUNK;
+               if (me->mp != NULL)
+                       return 1;
+               if ((m = CAST(struct magic *, malloc(len))) == NULL) {
+                       file_oomem(ms, len);
+                       return -1;
+               }
+               me->mp = m;
+               me->max_count = ALLOC_CHUNK;
+               (void)memset(m, 0, sizeof(*m));
+               m->factor_op = FILE_FACTOR_OP_NONE;
+               m->cont_level = 0;
+               me->cont_count = 1;
+       }
+       m->lineno = CAST(uint32_t, lineno);
+
+       if (*l == '&') {  /* m->cont_level == 0 checked below. */
+                ++l;            /* step over */
+                m->flag |= OFFADD;
+        }
+       if (*l == '(') {
+               ++l;            /* step over */
+               m->flag |= INDIR;
+               if (m->flag & OFFADD)
+                       m->flag = (m->flag & ~OFFADD) | INDIROFFADD;
+
+               if (*l == '&') {  /* m->cont_level == 0 checked below */
+                       ++l;            /* step over */
+                       m->flag |= OFFADD;
+               }
+       }
+       /* Indirect offsets are not valid at level 0. */
+       if (m->cont_level == 0 && (m->flag & (OFFADD | INDIROFFADD))) {
+               if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "relative offset at level 0");
+               return -1;
+       }
+
+       /* get offset, then skip over it */
+       m->offset = CAST(int32_t, strtol(l, &t, 0));
+        if (l == t) {
+               if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "offset `%s' invalid", l);
+               return -1;
+       }
+#if 0
+        if (m->offset < 0 && cont_level != 0 &&
+           (m->flag & (OFFADD | INDIROFFADD)) == 0) {
+               if (ms->flags & MAGIC_CHECK) {
+                       file_magwarn(ms,
+                           "negative direct offset `%s' at level %u",
+                           l, cont_level);
+               }
+               return -1;
+       }
+#endif
+        l = t;
+
+       if (m->flag & INDIR) {
+               m->in_type = FILE_LONG;
+               m->in_offset = 0;
+               m->in_op = 0;
+               /*
+                * read [.,lbs][+-]nnnnn)
+                */
+               if (*l == '.' || *l == ',') {
+                       if (*l == ',')
+                               m->in_op |= FILE_OPSIGNED;
+                       l++;
+                       switch (*l) {
+                       case 'l':
+                               m->in_type = FILE_LELONG;
+                               break;
+                       case 'L':
+                               m->in_type = FILE_BELONG;
+                               break;
+                       case 'm':
+                               m->in_type = FILE_MELONG;
+                               break;
+                       case 'h':
+                       case 's':
+                               m->in_type = FILE_LESHORT;
+                               break;
+                       case 'H':
+                       case 'S':
+                               m->in_type = FILE_BESHORT;
+                               break;
+                       case 'c':
+                       case 'b':
+                       case 'C':
+                       case 'B':
+                               m->in_type = FILE_BYTE;
+                               break;
+                       case 'e':
+                       case 'f':
+                       case 'g':
+                               m->in_type = FILE_LEDOUBLE;
+                               break;
+                       case 'E':
+                       case 'F':
+                       case 'G':
+                               m->in_type = FILE_BEDOUBLE;
+                               break;
+                       case 'i':
+                               m->in_type = FILE_LEID3;
+                               break;
+                       case 'I':
+                               m->in_type = FILE_BEID3;
+                               break;
+                       case 'q':
+                               m->in_type = FILE_LEQUAD;
+                               break;
+                       case 'Q':
+                               m->in_type = FILE_BEQUAD;
+                               break;
+                       default:
+                               if (ms->flags & MAGIC_CHECK)
+                                       file_magwarn(ms,
+                                           "indirect offset type `%c' invalid",
+                                           *l);
+                               return -1;
+                       }
+                       l++;
+               }
+
+               if (*l == '~') {
+                       m->in_op |= FILE_OPINVERSE;
+                       l++;
+               }
+               if ((op = get_op(*l)) != -1) {
+                       m->in_op |= op;
+                       l++;
+               }
+               if (*l == '(') {
+                       m->in_op |= FILE_OPINDIRECT;
+                       l++;
+               }
+               if (isdigit(CAST(unsigned char, *l)) || *l == '-') {
+                       m->in_offset = CAST(int32_t, strtol(l, &t, 0));
+                       if (l == t) {
+                               if (ms->flags & MAGIC_CHECK)
+                                       file_magwarn(ms,
+                                           "in_offset `%s' invalid", l);
+                               return -1;
+                       }
+                       l = t;
+               }
+               if (*l++ != ')' ||
+                   ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms,
+                                   "missing ')' in indirect offset");
+                       return -1;
+               }
+       }
+       EATAB;
+
+#ifdef ENABLE_CONDITIONALS
+       m->cond = get_cond(l, &l);
+       if (check_cond(ms, m->cond, cont_level) == -1)
+               return -1;
+
+       EATAB;
+#endif
+
+       /*
+        * Parse the type.
+        */
+       if (*l == 'u') {
+               /*
+                * Try it as a keyword type prefixed by "u"; match what
+                * follows the "u".  If that fails, try it as an SUS
+                * integer type.
+                */
+               m->type = get_type(type_tbl, l + 1, &l);
+               if (m->type == FILE_INVALID) {
+                       /*
+                        * Not a keyword type; parse it as an SUS type,
+                        * 'u' possibly followed by a number or C/S/L.
+                        */
+                       m->type = get_standard_integer_type(l, &l);
+               }
+               /* It's unsigned. */
+               if (m->type != FILE_INVALID)
+                       m->flag |= UNSIGNED;
+       } else {
+               /*
+                * Try it as a keyword type.  If that fails, try it as
+                * an SUS integer type if it begins with "d" or as an
+                * SUS string type if it begins with "s".  In any case,
+                * it's not unsigned.
+                */
+               m->type = get_type(type_tbl, l, &l);
+               if (m->type == FILE_INVALID) {
+                       /*
+                        * Not a keyword type; parse it as an SUS type,
+                        * either 'd' possibly followed by a number or
+                        * C/S/L, or just 's'.
+                        */
+                       if (*l == 'd')
+                               m->type = get_standard_integer_type(l, &l);
+                       else if (*l == 's'
+                           && !isalpha(CAST(unsigned char, l[1]))) {
+                               m->type = FILE_STRING;
+                               ++l;
+                       }
+               }
+       }
+
+       if (m->type == FILE_INVALID) {
+               /* Not found - try it as a special keyword. */
+               m->type = get_type(special_tbl, l, &l);
+       }
+
+       if (m->type == FILE_INVALID) {
+               if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "type `%s' invalid", l);
+               return -1;
+       }
+
+       /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
+       /* New and improved: ~ & | ^ + - * / % -- exciting, isn't it? */
+
+       m->mask_op = 0;
+       if (*l == '~') {
+               if (!IS_STRING(m->type))
+                       m->mask_op |= FILE_OPINVERSE;
+               else if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "'~' invalid for string types");
+               ++l;
+       }
+       m->str_range = 0;
+       m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
+       if ((op = get_op(*l)) != -1) {
+               if (IS_STRING(m->type)) {
+                       int r;
+
+                       if (op != FILE_OPDIVIDE) {
+                               if (ms->flags & MAGIC_CHECK)
+                                       file_magwarn(ms,
+                                           "invalid string/indirect op: "
+                                           "`%c'", *t);
+                               return -1;
+                       }
+
+                       if (m->type == FILE_INDIRECT)
+                               r = parse_indirect_modifier(ms, m, &l);
+                       else
+                               r = parse_string_modifier(ms, m, &l);
+                       if (r == -1)
+                               return -1;
+               } else
+                       parse_op_modifier(ms, m, &l, op);
+       }
+
+       /*
+        * We used to set mask to all 1's here, instead let's just not do
+        * anything if mask = 0 (unless you have a better idea)
+        */
+       EATAB;
+
+       switch (*l) {
+       case '>':
+       case '<':
+               m->reln = *l;
+               ++l;
+               if (*l == '=') {
+                       if (ms->flags & MAGIC_CHECK) {
+                               file_magwarn(ms, "%c= not supported",
+                                   m->reln);
+                               return -1;
+                       }
+                  ++l;
+               }
+               break;
+       /* Old-style anding: "0 byte &0x80 dynamically linked" */
+       case '&':
+       case '^':
+       case '=':
+               m->reln = *l;
+               ++l;
+               if (*l == '=') {
+                  /* HP compat: ignore &= etc. */
+                  ++l;
+               }
+               break;
+       case '!':
+               m->reln = *l;
+               ++l;
+               break;
+       default:
+               m->reln = '=';  /* the default relation */
+               if (*l == 'x' && ((isascii(CAST(unsigned char, l[1])) &&
+                   isspace(CAST(unsigned char, l[1]))) || !l[1])) {
+                       m->reln = *l;
+                       ++l;
+               }
+               break;
+       }
+       /*
+        * Grab the value part, except for an 'x' reln.
+        */
+       if (m->reln != 'x' && getvalue(ms, m, &l, action))
+               return -1;
+
+       /*
+        * TODO finish this macro and start using it!
+        * #define offsetcheck {if (offset > ms->bytes_max -1)
+        *      magwarn("offset too big"); }
+        */
+
+       /*
+        * Now get last part - the description
+        */
+       EATAB;
+       if (l[0] == '\b') {
+               ++l;
+               m->flag |= NOSPACE;
+       } else if ((l[0] == '\\') && (l[1] == 'b')) {
+               ++l;
+               ++l;
+               m->flag |= NOSPACE;
+       }
+       for (i = 0; (m->desc[i++] = *l++) != '\0' && i < sizeof(m->desc); )
+               continue;
+       if (i == sizeof(m->desc)) {
+               m->desc[sizeof(m->desc) - 1] = '\0';
+               if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "description `%s' truncated", m->desc);
+       }
+
+        /*
+        * We only do this check while compiling, or if any of the magic
+        * files were not compiled.
+         */
+        if (ms->flags & MAGIC_CHECK) {
+               if (check_format(ms, m) == -1)
+                       return -1;
+       }
+#ifndef COMPILE_ONLY
+       if (action == FILE_CHECK) {
+               file_mdump(m);
+       }
+#endif
+       m->mimetype[0] = '\0';          /* initialise MIME type to none */
+       return 0;
+}
+
+/*
+ * parse a STRENGTH annotation line from magic file, put into magic[index - 1]
+ * if valid
+ */
+private int
+parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+       const char *l = line;
+       char *el;
+       unsigned long factor;
+       struct magic *m = &me->mp[0];
+
+       if (m->factor_op != FILE_FACTOR_OP_NONE) {
+               file_magwarn(ms,
+                   "Current entry already has a strength type: %c %d",
+                   m->factor_op, m->factor);
+               return -1;
+       }
+       if (m->type == FILE_NAME) {
+               file_magwarn(ms, "%s: Strength setting is not supported in "
+                   "\"name\" magic entries", m->value.s);
+               return -1;
+       }
+       EATAB;
+       switch (*l) {
+       case FILE_FACTOR_OP_NONE:
+       case FILE_FACTOR_OP_PLUS:
+       case FILE_FACTOR_OP_MINUS:
+       case FILE_FACTOR_OP_TIMES:
+       case FILE_FACTOR_OP_DIV:
+               m->factor_op = *l++;
+               break;
+       default:
+               file_magwarn(ms, "Unknown factor op `%c'", *l);
+               return -1;
+       }
+       EATAB;
+       factor = strtoul(l, &el, 0);
+       if (factor > 255) {
+               file_magwarn(ms, "Too large factor `%lu'", factor);
+               goto out;
+       }
+       if (*el && !isspace(CAST(unsigned char, *el))) {
+               file_magwarn(ms, "Bad factor `%s'", l);
+               goto out;
+       }
+       m->factor = CAST(uint8_t, factor);
+       if (m->factor == 0 && m->factor_op == FILE_FACTOR_OP_DIV) {
+               file_magwarn(ms, "Cannot have factor op `%c' and factor %u",
+                   m->factor_op, m->factor);
+               goto out;
+       }
+       return 0;
+out:
+       m->factor_op = FILE_FACTOR_OP_NONE;
+       m->factor = 0;
+       return -1;
+}
+
+private int
+goodchar(unsigned char x, const char *extra)
+{
+       return (isascii(x) && isalnum(x)) || strchr(extra, x);
+}
+
+private int
+parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
+    off_t off, size_t len, const char *name, const char *extra, int nt)
+{
+       size_t i;
+       const char *l = line;
+       struct magic *m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1];
+       char *buf = CAST(char *, CAST(void *, m)) + off;
+
+       if (buf[0] != '\0') {
+               len = nt ? strlen(buf) : len;
+               file_magwarn(ms, "Current entry already has a %s type "
+                   "`%.*s', new type `%s'", name, CAST(int, len), buf, l);
+               return -1;
+       }
+
+       if (*m->desc == '\0') {
+               file_magwarn(ms, "Current entry does not yet have a "
+                   "description for adding a %s type", name);
+               return -1;
+       }
+
+       EATAB;
+       for (i = 0; *l && i < len && goodchar(*l, extra); buf[i++] = *l++)
+               continue;
+
+       if (i == len && *l) {
+               if (nt)
+                       buf[len - 1] = '\0';
+               if (ms->flags & MAGIC_CHECK)
+                       file_magwarn(ms, "%s type `%s' truncated %"
+                           SIZE_T_FORMAT "u", name, line, i);
+       } else {
+               if (!isspace(CAST(unsigned char, *l)) && !goodchar(*l, extra))
+                       file_magwarn(ms, "%s type `%s' has bad char '%c'",
+                           name, line, *l);
+               if (nt)
+                       buf[i] = '\0';
+       }
+
+       if (i > 0)
+               return 0;
+
+       file_magerror(ms, "Bad magic entry '%s'", line);
+       return -1;
+}
+
+/*
+ * Parse an Apple CREATOR/TYPE annotation from magic file and put it into
+ * magic[index - 1]
+ */
+private int
+parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+       struct magic *m = &me->mp[0];
+
+       return parse_extra(ms, me, line,
+           CAST(off_t, offsetof(struct magic, apple)),
+           sizeof(m->apple), "APPLE", "!+-./?", 0);
+}
+
+/*
+ * Parse a comma-separated list of extensions
+ */
+private int
+parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+       struct magic *m = &me->mp[0];
+
+       return parse_extra(ms, me, line,
+           CAST(off_t, offsetof(struct magic, ext)),
+           sizeof(m->ext), "EXTENSION", ",!+-/@?_$", 0);
+}
+
+/*
+ * parse a MIME annotation line from magic file, put into magic[index - 1]
+ * if valid
+ */
+private int
+parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line)
+{
+       struct magic *m = &me->mp[0];
+
+       return parse_extra(ms, me, line,
+           CAST(off_t, offsetof(struct magic, mimetype)),
+           sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
+}
+
+private int
+check_format_type(const char *ptr, int type, const char **estr)
+{
+       int quad = 0, h;
+       size_t len, cnt;
+       if (*ptr == '\0') {
+               /* Missing format string; bad */
+               *estr = "missing format spec";
+               return -1;
+       }
+
+       switch (file_formats[type]) {
+       case FILE_FMT_QUAD:
+               quad = 1;
+               /*FALLTHROUGH*/
+       case FILE_FMT_NUM:
+               if (quad == 0) {
+                       switch (type) {
+                       case FILE_BYTE:
+                               h = 2;
+                               break;
+                       case FILE_SHORT:
+                       case FILE_BESHORT:
+                       case FILE_LESHORT:
+                               h = 1;
+                               break;
+                       case FILE_LONG:
+                       case FILE_BELONG:
+                       case FILE_LELONG:
+                       case FILE_MELONG:
+                       case FILE_LEID3:
+                       case FILE_BEID3:
+                       case FILE_INDIRECT:
+                               h = 0;
+                               break;
+                       default:
+                               abort();
+                       }
+               } else
+                       h = 0;
+               if (*ptr == '-')
+                       ptr++;
+               if (*ptr == '.')
+                       ptr++;
+               if (*ptr == '#')
+                       ptr++;
+#define CHECKLEN() do { \
+       for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \
+               len = len * 10 + (*ptr - '0'); \
+       if (cnt > 5 || len > 1024) \
+               goto toolong; \
+} while (/*CONSTCOND*/0)
+
+               CHECKLEN();
+               if (*ptr == '.')
+                       ptr++;
+               CHECKLEN();
+               if (quad) {
+                       if (*ptr++ != 'l')
+                               goto invalid;
+                       if (*ptr++ != 'l')
+                               goto invalid;
+               }
+
+               switch (*ptr++) {
+#ifdef STRICT_FORMAT   /* "long" formats are int formats for us */
+               /* so don't accept the 'l' modifier */
+               case 'l':
+                       switch (*ptr++) {
+                       case 'i':
+                       case 'd':
+                       case 'u':
+                       case 'o':
+                       case 'x':
+                       case 'X':
+                               if (h == 0)
+                                       return 0;
+                               /*FALLTHROUGH*/
+                       default:
+                               goto invalid;
+                       }
+
+               /*
+                * Don't accept h and hh modifiers. They make writing
+                * magic entries more complicated, for very little benefit
+                */
+               case 'h':
+                       if (h-- <= 0)
+                               goto invalid;
+                       switch (*ptr++) {
+                       case 'h':
+                               if (h-- <= 0)
+                                       goto invalid;
+                               switch (*ptr++) {
+                               case 'i':
+                               case 'd':
+                               case 'u':
+                               case 'o':
+                               case 'x':
+                               case 'X':
+                                       return 0;
+                               default:
+                                       goto invalid;
+                               }
+                       case 'i':
+                       case 'd':
+                       case 'u':
+                       case 'o':
+                       case 'x':
+                       case 'X':
+                               if (h == 0)
+                                       return 0;
+                               /*FALLTHROUGH*/
+                       default:
+                               goto invalid;
+                       }
+#endif
+               case 'c':
+                       if (h == 2)
+                               return 0;
+                       goto invalid;
+               case 'i':
+               case 'd':
+               case 'u':
+               case 'o':
+               case 'x':
+               case 'X':
+#ifdef STRICT_FORMAT
+                       if (h == 0)
+                               return 0;
+                       /*FALLTHROUGH*/
+#else
+                       return 0;
+#endif
+               default:
+                       goto invalid;
+               }
+
+       case FILE_FMT_FLOAT:
+       case FILE_FMT_DOUBLE:
+               if (*ptr == '-')
+                       ptr++;
+               if (*ptr == '.')
+                       ptr++;
+               CHECKLEN();
+               if (*ptr == '.')
+                       ptr++;
+               CHECKLEN();
+               switch (*ptr++) {
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'F':
+               case 'g':
+               case 'G':
+                       return 0;
+
+               default:
+                       goto invalid;
+               }
+
+
+       case FILE_FMT_STR:
+               if (*ptr == '-')
+                       ptr++;
+               while (isdigit(CAST(unsigned char, *ptr)))
+                       ptr++;
+               if (*ptr == '.') {
+                       ptr++;
+                       while (isdigit(CAST(unsigned char , *ptr)))
+                               ptr++;
+               }
+
+               switch (*ptr++) {
+               case 's':
+                       return 0;
+               default:
+                       goto invalid;
+               }
+
+       default:
+               /* internal error */
+               abort();
+       }
+invalid:
+       *estr = "not valid";
+toolong:
+       *estr = "too long";
+       return -1;
+}
+
+/*
+ * Check that the optional printf format in description matches
+ * the type of the magic.
+ */
+private int
+check_format(struct magic_set *ms, struct magic *m)
+{
+       char *ptr;
+       const char *estr;
+
+       for (ptr = m->desc; *ptr; ptr++)
+               if (*ptr == '%')
+                       break;
+       if (*ptr == '\0') {
+               /* No format string; ok */
+               return 1;
+       }
+
+       assert(file_nformats == file_nnames);
+
+       if (m->type >= file_nformats) {
+               file_magwarn(ms, "Internal error inconsistency between "
+                   "m->type and format strings");
+               return -1;
+       }
+       if (file_formats[m->type] == FILE_FMT_NONE) {
+               file_magwarn(ms, "No format string for `%s' with description "
+                   "`%s'", m->desc, file_names[m->type]);
+               return -1;
+       }
+
+       ptr++;
+       if (check_format_type(ptr, m->type, &estr) == -1) {
+               /*
+                * TODO: this error message is unhelpful if the format
+                * string is not one character long
+                */
+               file_magwarn(ms, "Printf format is %s for type "
+                   "`%s' in description `%s'", estr,
+                   file_names[m->type], m->desc);
+               return -1;
+       }
+
+       for (; *ptr; ptr++) {
+               if (*ptr == '%') {
+                       file_magwarn(ms,
+                           "Too many format strings (should have at most one) "
+                           "for `%s' with description `%s'",
+                           file_names[m->type], m->desc);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Read a numeric value from a pointer, into the value union of a magic
+ * pointer, according to the magic type.  Update the string pointer to point
+ * just after the number read.  Return 0 for success, non-zero for failure.
+ */
+private int
+getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
+{
+       char *ep;
+       uint64_t ull;
+
+       switch (m->type) {
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+       case FILE_STRING:
+       case FILE_PSTRING:
+       case FILE_REGEX:
+       case FILE_SEARCH:
+       case FILE_NAME:
+       case FILE_USE:
+       case FILE_DER:
+               *p = getstr(ms, m, *p, action == FILE_COMPILE);
+               if (*p == NULL) {
+                       if (ms->flags & MAGIC_CHECK)
+                               file_magwarn(ms, "cannot get string from `%s'",
+                                   m->value.s);
+                       return -1;
+               }
+               if (m->type == FILE_REGEX) {
+                       file_regex_t rx;
+                       int rc = file_regcomp(&rx, m->value.s, REG_EXTENDED);
+                       if (rc) {
+                               if (ms->flags & MAGIC_CHECK)
+                                       file_regerror(&rx, rc, ms);
+                       }
+                       file_regfree(&rx);
+                       return rc ? -1 : 0;
+               }
+               return 0;
+       default:
+               if (m->reln == 'x')
+                       return 0;
+               break;
+       }
+
+       switch (m->type) {
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               errno = 0;
+#ifdef HAVE_STRTOF
+               m->value.f = strtof(*p, &ep);
+#else
+               m->value.f = (float)strtod(*p, &ep);
+#endif
+               if (errno == 0)
+                       *p = ep;
+               return 0;
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               errno = 0;
+               m->value.d = strtod(*p, &ep);
+               if (errno == 0)
+                       *p = ep;
+               return 0;
+       default:
+               errno = 0;
+               ull = CAST(uint64_t, strtoull(*p, &ep, 0));
+               m->value.q = file_signextend(ms, m, ull);
+               if (*p == ep) {
+                       file_magwarn(ms, "Unparseable number `%s'", *p);
+               } else {
+                       size_t ts = typesize(m->type);
+                       uint64_t x;
+                       const char *q;
+
+                       if (ts == CAST(size_t, ~0)) {
+                               file_magwarn(ms,
+                                   "Expected numeric type got `%s'",
+                                   type_tbl[m->type].name);
+                       }
+                       for (q = *p; isspace(CAST(unsigned char, *q)); q++)
+                               continue;
+                       if (*q == '-')
+                               ull = -CAST(int64_t, ull);
+                       switch (ts) {
+                       case 1:
+                               x = CAST(uint64_t, ull & ~0xffULL);
+                               break;
+                       case 2:
+                               x = CAST(uint64_t, ull & ~0xffffULL);
+                               break;
+                       case 4:
+                               x = CAST(uint64_t, ull & ~0xffffffffULL);
+                               break;
+                       case 8:
+                               x = 0;
+                               break;
+                       default:
+                               abort();
+                       }
+                       if (x) {
+                               file_magwarn(ms, "Overflow for numeric"
+                                   " type `%s' value %#" PRIx64,
+                                   type_tbl[m->type].name, ull);
+                       }
+               }
+               if (errno == 0) {
+                       *p = ep;
+                       eatsize(p);
+               }
+               return 0;
+       }
+}
+
+/*
+ * Convert a string containing C character escapes.  Stop at an unescaped
+ * space or tab.
+ * Copy the converted version to "m->value.s", and the length in m->vallen.
+ * Return updated scan pointer as function result. Warn if set.
+ */
+private const char *
+getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
+{
+       const char *origs = s;
+       char    *p = m->value.s;
+       size_t  plen = sizeof(m->value.s);
+       char    *origp = p;
+       char    *pmax = p + plen - 1;
+       int     c;
+       int     val;
+
+       while ((c = *s++) != '\0') {
+               if (isspace(CAST(unsigned char, c)))
+                       break;
+               if (p >= pmax) {
+                       file_error(ms, 0, "string too long: `%s'", origs);
+                       return NULL;
+               }
+               if (c == '\\') {
+                       switch(c = *s++) {
+
+                       case '\0':
+                               if (warn)
+                                       file_magwarn(ms, "incomplete escape");
+                               s--;
+                               goto out;
+
+                       case '\t':
+                               if (warn) {
+                                       file_magwarn(ms,
+                                           "escaped tab found, use \\t instead");
+                                       warn = 0;       /* already did */
+                               }
+                               /*FALLTHROUGH*/
+                       default:
+                               if (warn) {
+                                       if (isprint(CAST(unsigned char, c))) {
+                                               /* Allow escaping of
+                                                * ``relations'' */
+                                               if (strchr("<>&^=!", c) == NULL
+                                                   && (m->type != FILE_REGEX ||
+                                                   strchr("[]().*?^$|{}", c)
+                                                   == NULL)) {
+                                                       file_magwarn(ms, "no "
+                                                           "need to escape "
+                                                           "`%c'", c);
+                                               }
+                                       } else {
+                                               file_magwarn(ms,
+                                                   "unknown escape sequence: "
+                                                   "\\%03o", c);
+                                       }
+                               }
+                               /*FALLTHROUGH*/
+                       /* space, perhaps force people to use \040? */
+                       case ' ':
+#if 0
+                       /*
+                        * Other things people escape, but shouldn't need to,
+                        * so we disallow them
+                        */
+                       case '\'':
+                       case '"':
+                       case '?':
+#endif
+                       /* Relations */
+                       case '>':
+                       case '<':
+                       case '&':
+                       case '^':
+                       case '=':
+                       case '!':
+                       /* and baskslash itself */
+                       case '\\':
+                               *p++ = CAST(char, c);
+                               break;
+
+                       case 'a':
+                               *p++ = '\a';
+                               break;
+
+                       case 'b':
+                               *p++ = '\b';
+                               break;
+
+                       case 'f':
+                               *p++ = '\f';
+                               break;
+
+                       case 'n':
+                               *p++ = '\n';
+                               break;
+
+                       case 'r':
+                               *p++ = '\r';
+                               break;
+
+                       case 't':
+                               *p++ = '\t';
+                               break;
+
+                       case 'v':
+                               *p++ = '\v';
+                               break;
+
+                       /* \ and up to 3 octal digits */
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                               val = c - '0';
+                               c = *s++;  /* try for 2 */
+                               if (c >= '0' && c <= '7') {
+                                       val = (val << 3) | (c - '0');
+                                       c = *s++;  /* try for 3 */
+                                       if (c >= '0' && c <= '7')
+                                               val = (val << 3) | (c-'0');
+                                       else
+                                               --s;
+                               }
+                               else
+                                       --s;
+                               *p++ = CAST(char, val);
+                               break;
+
+                       /* \x and up to 2 hex digits */
+                       case 'x':
+                               val = 'x';      /* Default if no digits */
+                               c = hextoint(*s++);     /* Get next char */
+                               if (c >= 0) {
+                                       val = c;
+                                       c = hextoint(*s++);
+                                       if (c >= 0)
+                                               val = (val << 4) + c;
+                                       else
+                                               --s;
+                               } else
+                                       --s;
+                               *p++ = CAST(char, val);
+                               break;
+                       }
+               } else
+                       *p++ = CAST(char, c);
+       }
+       --s;
+out:
+       *p = '\0';
+       m->vallen = CAST(unsigned char, (p - origp));
+       if (m->type == FILE_PSTRING)
+               m->vallen += CAST(unsigned char, file_pstring_length_size(m));
+       return s;
+}
+
+
+/* Single hex char to int; -1 if not a hex char. */
+private int
+hextoint(int c)
+{
+       if (!isascii(CAST(unsigned char, c)))
+               return -1;
+       if (isdigit(CAST(unsigned char, c)))
+               return c - '0';
+       if ((c >= 'a') && (c <= 'f'))
+               return c + 10 - 'a';
+       if (( c>= 'A') && (c <= 'F'))
+               return c + 10 - 'A';
+       return -1;
+}
+
+
+/*
+ * Print a string containing C character escapes.
+ */
+protected void
+file_showstr(FILE *fp, const char *s, size_t len)
+{
+       char    c;
+
+       for (;;) {
+               if (len == ~0U) {
+                       c = *s++;
+                       if (c == '\0')
+                               break;
+               }
+               else  {
+                       if (len-- == 0)
+                               break;
+                       c = *s++;
+               }
+               if (c >= 040 && c <= 0176)      /* TODO isprint && !iscntrl */
+                       (void) fputc(c, fp);
+               else {
+                       (void) fputc('\\', fp);
+                       switch (c) {
+                       case '\a':
+                               (void) fputc('a', fp);
+                               break;
+
+                       case '\b':
+                               (void) fputc('b', fp);
+                               break;
+
+                       case '\f':
+                               (void) fputc('f', fp);
+                               break;
+
+                       case '\n':
+                               (void) fputc('n', fp);
+                               break;
+
+                       case '\r':
+                               (void) fputc('r', fp);
+                               break;
+
+                       case '\t':
+                               (void) fputc('t', fp);
+                               break;
+
+                       case '\v':
+                               (void) fputc('v', fp);
+                               break;
+
+                       default:
+                               (void) fprintf(fp, "%.3o", c & 0377);
+                               break;
+                       }
+               }
+       }
+}
+
+/*
+ * eatsize(): Eat the size spec from a number [eg. 10UL]
+ */
+private void
+eatsize(const char **p)
+{
+       const char *l = *p;
+
+       if (LOWCASE(*l) == 'u')
+               l++;
+
+       switch (LOWCASE(*l)) {
+       case 'l':    /* long */
+       case 's':    /* short */
+       case 'h':    /* short */
+       case 'b':    /* char/byte */
+       case 'c':    /* char/byte */
+               l++;
+               /*FALLTHROUGH*/
+       default:
+               break;
+       }
+
+       *p = l;
+}
+
+/*
+ * handle a buffer containing a compiled file.
+ */
+private struct magic_map *
+apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len)
+{
+       struct magic_map *map;
+
+       if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
+               file_oomem(ms, sizeof(*map));
+               return NULL;
+       }
+       map->len = len;
+       map->p = buf;
+       map->type = MAP_TYPE_USER;
+       if (check_buffer(ms, map, "buffer") != 0) {
+               apprentice_unmap(map);
+               return NULL;
+       }
+       return map;
+}
+
+/*
+ * handle a compiled file.
+ */
+
+private struct magic_map *
+apprentice_map(struct magic_set *ms, const char *fn)
+{
+       int fd;
+       struct stat st;
+       char *dbname = NULL;
+       struct magic_map *map;
+       struct magic_map *rv = NULL;
+
+       fd = -1;
+       if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
+               file_oomem(ms, sizeof(*map));
+               goto error;
+       }
+       map->type = MAP_TYPE_USER;      /* unspecified */
+
+       dbname = mkdbname(ms, fn, 0);
+       if (dbname == NULL)
+               goto error;
+
+       if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
+               goto error;
+
+       if (fstat(fd, &st) == -1) {
+               file_error(ms, errno, "cannot stat `%s'", dbname);
+               goto error;
+       }
+       if (st.st_size < 8 || st.st_size > maxoff_t()) {
+               file_error(ms, 0, "file `%s' is too %s", dbname,
+                   st.st_size < 8 ? "small" : "large");
+               goto error;
+       }
+
+       map->len = CAST(size_t, st.st_size);
+#ifdef QUICK
+       map->type = MAP_TYPE_MMAP;
+       if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE,
+           MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) {
+               file_error(ms, errno, "cannot map `%s'", dbname);
+               goto error;
+       }
+#else
+       map->type = MAP_TYPE_MALLOC;
+       if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
+               file_oomem(ms, map->len);
+               goto error;
+       }
+       if (read(fd, map->p, map->len) != (ssize_t)map->len) {
+               file_badread(ms);
+               goto error;
+       }
+#define RET    1
+#endif
+       (void)close(fd);
+       fd = -1;
+
+       if (check_buffer(ms, map, dbname) != 0) {
+               rv = RCAST(struct magic_map *, -1);
+               goto error;
+       }
+#ifdef QUICK
+       if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) {
+               file_error(ms, errno, "cannot mprotect `%s'", dbname);
+               goto error;
+       }
+#endif
+
+       free(dbname);
+       return map;
+
+error:
+       if (fd != -1)
+               (void)close(fd);
+       apprentice_unmap(map);
+       free(dbname);
+       return rv;
+}
+
+private int
+check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
+{
+       uint32_t *ptr;
+       uint32_t entries, nentries;
+       uint32_t version;
+       int i, needsbyteswap;
+
+       ptr = CAST(uint32_t *, map->p);
+       if (*ptr != MAGICNO) {
+               if (swap4(*ptr) != MAGICNO) {
+                       file_error(ms, 0, "bad magic in `%s'", dbname);
+                       return -1;
+               }
+               needsbyteswap = 1;
+       } else
+               needsbyteswap = 0;
+       if (needsbyteswap)
+               version = swap4(ptr[1]);
+       else
+               version = ptr[1];
+       if (version != VERSIONNO) {
+               file_error(ms, 0, "File %s supports only version %d magic "
+                   "files. `%s' is version %d", VERSION,
+                   VERSIONNO, dbname, version);
+               return -1;
+       }
+       entries = CAST(uint32_t, map->len / sizeof(struct magic));
+       if ((entries * sizeof(struct magic)) != map->len) {
+               file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
+                   "a multiple of %" SIZE_T_FORMAT "u",
+                   dbname, map->len, sizeof(struct magic));
+               return -1;
+       }
+       map->magic[0] = CAST(struct magic *, map->p) + 1;
+       nentries = 0;
+       for (i = 0; i < MAGIC_SETS; i++) {
+               if (needsbyteswap)
+                       map->nmagic[i] = swap4(ptr[i + 2]);
+               else
+                       map->nmagic[i] = ptr[i + 2];
+               if (i != MAGIC_SETS - 1)
+                       map->magic[i + 1] = map->magic[i] + map->nmagic[i];
+               nentries += map->nmagic[i];
+       }
+       if (entries != nentries + 1) {
+               file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
+                   dbname, entries, nentries + 1);
+               return -1;
+       }
+       if (needsbyteswap)
+               for (i = 0; i < MAGIC_SETS; i++)
+                       byteswap(map->magic[i], map->nmagic[i]);
+       return 0;
+}
+
+/*
+ * handle an mmaped file.
+ */
+private int
+apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
+{
+       static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
+       static const size_t m = sizeof(**map->magic);
+       int fd = -1;
+       size_t len;
+       char *dbname;
+       int rv = -1;
+       uint32_t i;
+       union {
+               struct magic m;
+               uint32_t h[2 + MAGIC_SETS];
+       } hdr;
+
+       dbname = mkdbname(ms, fn, 1);
+
+       if (dbname == NULL)
+               goto out;
+
+       if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
+       {
+               file_error(ms, errno, "cannot open `%s'", dbname);
+               goto out;
+       }
+       memset(&hdr, 0, sizeof(hdr));
+       hdr.h[0] = MAGICNO;
+       hdr.h[1] = VERSIONNO;
+       memcpy(hdr.h + 2, map->nmagic, nm);
+
+       if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) {
+               file_error(ms, errno, "error writing `%s'", dbname);
+               goto out2;
+       }
+
+       for (i = 0; i < MAGIC_SETS; i++) {
+               len = m * map->nmagic[i];
+               if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) {
+                       file_error(ms, errno, "error writing `%s'", dbname);
+                       goto out2;
+               }
+       }
+
+       rv = 0;
+out2:
+       if (fd != -1)
+               (void)close(fd);
+out:
+       apprentice_unmap(map);
+       free(dbname);
+       return rv;
+}
+
+private const char ext[] = ".mgc";
+/*
+ * make a dbname
+ */
+private char *
+mkdbname(struct magic_set *ms, const char *fn, int strip)
+{
+       const char *p, *q;
+       char *buf;
+
+       if (strip) {
+               if ((p = strrchr(fn, '/')) != NULL)
+                       fn = ++p;
+       }
+
+       for (q = fn; *q; q++)
+               continue;
+       /* Look for .mgc */
+       for (p = ext + sizeof(ext) - 1; p >= ext && q >= fn; p--, q--)
+               if (*p != *q)
+                       break;
+
+       /* Did not find .mgc, restore q */
+       if (p >= ext)
+               while (*q)
+                       q++;
+
+       q++;
+       /* Compatibility with old code that looked in .mime */
+       if (ms->flags & MAGIC_MIME) {
+               if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext)
+                   < 0)
+                       return NULL;
+               if (access(buf, R_OK) != -1) {
+                       ms->flags &= MAGIC_MIME_TYPE;
+                       return buf;
+               }
+               free(buf);
+       }
+       if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0)
+               return NULL;
+
+       /* Compatibility with old code that looked in .mime */
+       if (strstr(fn, ".mime") != NULL)
+               ms->flags &= MAGIC_MIME_TYPE;
+       return buf;
+}
+
+/*
+ * Byteswap an mmap'ed file if needed
+ */
+private void
+byteswap(struct magic *magic, uint32_t nmagic)
+{
+       uint32_t i;
+       for (i = 0; i < nmagic; i++)
+               bs1(&magic[i]);
+}
+
+/*
+ * swap a short
+ */
+private uint16_t
+swap2(uint16_t sv)
+{
+       uint16_t rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
+       d[0] = s[1];
+       d[1] = s[0];
+       return rv;
+}
+
+/*
+ * swap an int
+ */
+private uint32_t
+swap4(uint32_t sv)
+{
+       uint32_t rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
+       d[0] = s[3];
+       d[1] = s[2];
+       d[2] = s[1];
+       d[3] = s[0];
+       return rv;
+}
+
+/*
+ * swap a quad
+ */
+private uint64_t
+swap8(uint64_t sv)
+{
+       uint64_t rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
+#if 0
+       d[0] = s[3];
+       d[1] = s[2];
+       d[2] = s[1];
+       d[3] = s[0];
+       d[4] = s[7];
+       d[5] = s[6];
+       d[6] = s[5];
+       d[7] = s[4];
+#else
+       d[0] = s[7];
+       d[1] = s[6];
+       d[2] = s[5];
+       d[3] = s[4];
+       d[4] = s[3];
+       d[5] = s[2];
+       d[6] = s[1];
+       d[7] = s[0];
+#endif
+       return rv;
+}
+
+/*
+ * byteswap a single magic entry
+ */
+private void
+bs1(struct magic *m)
+{
+       m->cont_level = swap2(m->cont_level);
+       m->offset = swap4(CAST(uint32_t, m->offset));
+       m->in_offset = swap4(CAST(uint32_t, m->in_offset));
+       m->lineno = swap4(CAST(uint32_t, m->lineno));
+       if (IS_STRING(m->type)) {
+               m->str_range = swap4(m->str_range);
+               m->str_flags = swap4(m->str_flags);
+       }
+       else {
+               m->value.q = swap8(m->value.q);
+               m->num_mask = swap8(m->num_mask);
+       }
+}
+
+protected size_t
+file_pstring_length_size(const struct magic *m)
+{
+       switch (m->str_flags & PSTRING_LEN) {
+       case PSTRING_1_LE:
+               return 1;
+       case PSTRING_2_LE:
+       case PSTRING_2_BE:
+               return 2;
+       case PSTRING_4_LE:
+       case PSTRING_4_BE:
+               return 4;
+       default:
+               abort();        /* Impossible */
+               return 1;
+       }
+}
+protected size_t
+file_pstring_get_length(const struct magic *m, const char *ss)
+{
+       size_t len = 0;
+       const unsigned char *s = RCAST(const unsigned char *, ss);
+       unsigned int s3, s2, s1, s0;
+
+       switch (m->str_flags & PSTRING_LEN) {
+       case PSTRING_1_LE:
+               len = *s;
+               break;
+       case PSTRING_2_LE:
+               s0 = s[0];
+               s1 = s[1];
+               len = (s1 << 8) | s0;
+               break;
+       case PSTRING_2_BE:
+               s0 = s[0];
+               s1 = s[1];
+               len = (s0 << 8) | s1;
+               break;
+       case PSTRING_4_LE:
+               s0 = s[0];
+               s1 = s[1];
+               s2 = s[2];
+               s3 = s[3];
+               len = (s3 << 24) | (s2 << 16) | (s1 << 8) | s0;
+               break;
+       case PSTRING_4_BE:
+               s0 = s[0];
+               s1 = s[1];
+               s2 = s[2];
+               s3 = s[3];
+               len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3;
+               break;
+       default:
+               abort();        /* Impossible */
+       }
+
+       if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF)
+               len -= file_pstring_length_size(m);
+
+       return len;
+}
+
+protected int
+file_magicfind(struct magic_set *ms, const char *name, struct mlist *v)
+{
+       uint32_t i, j;
+       struct mlist *mlist, *ml;
+
+       mlist = ms->mlist[1];
+
+       for (ml = mlist->next; ml != mlist; ml = ml->next) {
+               struct magic *ma = ml->magic;
+               uint32_t nma = ml->nmagic;
+               for (i = 0; i < nma; i++) {
+                       if (ma[i].type != FILE_NAME)
+                               continue;
+                       if (strcmp(ma[i].value.s, name) == 0) {
+                               v->magic = &ma[i];
+                               for (j = i + 1; j < nma; j++)
+                                   if (ma[j].cont_level == 0)
+                                           break;
+                               v->nmagic = j - i;
+                               return 0;
+                       }
+               }
+       }
+       return -1;
+}
diff --git a/src/apptype.c b/src/apptype.c
new file mode 100644 (file)
index 0000000..1bb33e4
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Adapted from: apptype.c, Written by Eberhard Mattes and put into the
+ * public domain
+ *
+ * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
+ * searches.
+ *
+ * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com"
+ * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes
+ * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very
+ * bug ridden) Win Emacs as "OS/2 executable".
+ *
+ * 3. apptype() uses the filename if given, otherwise a tmp file is created with
+ * the contents of buf. If buf is not the complete file, apptype can
+ * incorrectly identify the exe type. The "-z" option of "file" is the reason
+ * for this ugly code.
+ */
+
+/*
+ * amai: Darrel Hankerson did the changes described here.
+ *
+ * It remains to check the validity of comments (2.) since it's referred to an
+ * "old" OS/2 version.
+ *
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: apptype.c,v 1.14 2018/09/09 20:33:28 christos Exp $")
+#endif /* lint */
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __EMX__
+#include <io.h>
+#define INCL_DOSSESMGR
+#define INCL_DOSERRORS
+#define INCL_DOSFILEMGR
+#include <os2.h>
+typedef ULONG   APPTYPE;
+
+protected int
+file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf,
+    size_t nb)
+{
+       APPTYPE         rc, type;
+       char            path[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR],
+                       fname[_MAX_FNAME], ext[_MAX_EXT];
+       char           *filename;
+       FILE           *fp;
+
+       if (fn)
+               filename = strdup(fn);
+       else if ((filename = tempnam("./", "tmp")) == NULL) {
+               file_error(ms, errno, "cannot create tempnam");
+               return -1;
+       }
+       /* qualify the filename to prevent extraneous searches */
+       _splitpath(filename, drive, dir, fname, ext);
+       (void)sprintf(path, "%s%s%s%s", drive,
+               (*dir == '\0') ? "./" : dir,
+               fname,
+               (*ext == '\0') ? "." : ext);
+
+       if (fn == NULL) {
+               if ((fp = fopen(path, "wb")) == NULL) {
+                       file_error(ms, errno, "cannot open tmp file `%s'", path);
+                       return -1;
+               }
+               if (fwrite(buf, 1, nb, fp) != nb) {
+                       file_error(ms, errno, "cannot write tmp file `%s'",
+                           path);
+                       (void)fclose(fp);
+                       return -1;
+               }
+               (void)fclose(fp);
+       }
+       rc = DosQueryAppType((unsigned char *)path, &type);
+
+       if (fn == NULL) {
+               unlink(path);
+               free(filename);
+       }
+#if 0
+       if (rc == ERROR_INVALID_EXE_SIGNATURE)
+               printf("%s: not an executable file\n", fname);
+       else if (rc == ERROR_FILE_NOT_FOUND)
+               printf("%s: not found\n", fname);
+       else if (rc == ERROR_ACCESS_DENIED)
+               printf("%s: access denied\n", fname);
+       else if (rc != 0)
+               printf("%s: error code = %lu\n", fname, rc);
+       else
+#else
+
+       /*
+        * for our purpose here it's sufficient to just ignore the error and
+        * return w/o success (=0)
+        */
+
+       if (rc)
+               return (0);
+
+#endif
+
+       if (type & FAPPTYP_32BIT)
+               if (file_printf(ms, "32-bit ") == -1)
+                       return -1;
+       if (type & FAPPTYP_PHYSDRV) {
+               if (file_printf(ms, "physical device driver") == -1)
+                       return -1;
+       } else if (type & FAPPTYP_VIRTDRV) {
+               if (file_printf(ms, "virtual device driver") == -1)
+                       return -1;
+       } else if (type & FAPPTYP_DLL) {
+               if (type & FAPPTYP_PROTDLL)
+                       if (file_printf(ms, "protected ") == -1)
+                               return -1;
+               if (file_printf(ms, "DLL") == -1)
+                       return -1;
+       } else if (type & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT)) {
+               if (file_printf(ms, "Windows executable") == -1)
+                       return -1;
+       } else if (type & FAPPTYP_DOS) {
+               /*
+                * The API routine is partially broken on filenames ending
+                * ".com".
+                */
+               if (stricmp(ext, ".com") == 0)
+                       if (strncmp((const char *)buf, "MZ", 2))
+                               return (0);
+               if (file_printf(ms, "DOS executable") == -1)
+                       return -1;
+               /* ---------------------------------------- */
+               /* Might learn more from the magic(4) entry */
+               if (file_printf(ms, ", magic(4)-> ") == -1)
+                       return -1;
+               return (0);
+               /* ---------------------------------------- */
+       } else if (type & FAPPTYP_BOUND) {
+               if (file_printf(ms, "bound executable") == -1)
+                       return -1;
+       } else if ((type & 7) == FAPPTYP_WINDOWAPI) {
+               if (file_printf(ms, "PM executable") == -1)
+                       return -1;
+       } else if (file_printf(ms, "OS/2 executable") == -1)
+               return -1;
+
+       switch (type & (FAPPTYP_NOTWINDOWCOMPAT |
+                       FAPPTYP_WINDOWCOMPAT |
+                       FAPPTYP_WINDOWAPI)) {
+       case FAPPTYP_NOTWINDOWCOMPAT:
+               if (file_printf(ms, " [NOTWINDOWCOMPAT]") == -1)
+                       return -1;
+               break;
+       case FAPPTYP_WINDOWCOMPAT:
+               if (file_printf(ms, " [WINDOWCOMPAT]") == -1)
+                       return -1;
+               break;
+       case FAPPTYP_WINDOWAPI:
+               if (file_printf(ms, " [WINDOWAPI]") == -1)
+                       return -1;
+               break;
+       }
+       return 1;
+}
+#endif
diff --git a/src/ascmagic.c b/src/ascmagic.c
new file mode 100644 (file)
index 0000000..624ac90
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * ASCII magic -- try to detect text encoding.
+ *
+ * Extensively modified by Eric Fischer <enf@pobox.com> in July, 2000,
+ * to handle character codes other than ASCII on a unified basis.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.104 2019/05/07 02:27:11 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <string.h>
+#include <memory.h>
+#include <ctype.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#define MAXLINELEN 300 /* longest sane line length */
+#define ISSPC(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n' \
+                 || (x) == 0x85 || (x) == '\f')
+
+private unsigned char *encode_utf8(unsigned char *, size_t, unichar *, size_t);
+private size_t trim_nuls(const unsigned char *, size_t);
+
+/*
+ * Undo the NUL-termination kindly provided by process()
+ * but leave at least one byte to look at
+ */
+private size_t
+trim_nuls(const unsigned char *buf, size_t nbytes)
+{
+       while (nbytes > 1 && buf[nbytes - 1] == '\0')
+               nbytes--;
+
+       return nbytes;
+}
+
+protected int
+file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
+{
+       unichar *ubuf = NULL;
+       size_t ulen = 0;
+       int rv = 1;
+       struct buffer bb;
+
+       const char *code = NULL;
+       const char *code_mime = NULL;
+       const char *type = NULL;
+
+       bb = *b;
+       bb.flen = trim_nuls(CAST(const unsigned char *, b->fbuf), b->flen);
+       /*
+        * Avoid trimming at an odd byte if the original buffer was evenly
+        * sized; this avoids losing the last character on UTF-16 LE text
+        */
+       if ((bb.flen & 1) && !(b->flen & 1))
+               bb.flen++;
+
+       /* If file doesn't look like any sort of text, give up. */
+       if (file_encoding(ms, &bb, &ubuf, &ulen, &code, &code_mime,
+           &type) == 0)
+               rv = 0;
+        else
+               rv = file_ascmagic_with_encoding(ms, &bb,
+                   ubuf, ulen, code, type, text);
+
+       free(ubuf);
+
+       return rv;
+}
+
+protected int
+file_ascmagic_with_encoding(struct magic_set *ms,
+    const struct buffer *b, unichar *ubuf, size_t ulen, const char *code,
+    const char *type, int text)
+{
+       struct buffer bb;
+       const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
+       size_t nbytes = b->flen;
+       unsigned char *utf8_buf = NULL, *utf8_end;
+       size_t mlen, i, len;
+       int rv = -1;
+       int mime = ms->flags & MAGIC_MIME;
+       int need_separator = 0;
+
+       const char *subtype = NULL;
+       const char *subtype_mime = NULL;
+
+       int has_escapes = 0;
+       int has_backspace = 0;
+       int seen_cr = 0;
+
+       int n_crlf = 0;
+       int n_lf = 0;
+       int n_cr = 0;
+       int n_nel = 0;
+       int executable = 0;
+
+       size_t last_line_end = CAST(size_t, -1);
+       int has_long_lines = 0;
+
+       nbytes = trim_nuls(buf, nbytes);
+
+       /* If we have fewer than 2 bytes, give up. */
+       if (nbytes <= 1) {
+               rv = 0;
+               goto done;
+       }
+
+       if (ulen > 0 && (ms->flags & MAGIC_NO_CHECK_SOFT) == 0) {
+               /* Convert ubuf to UTF-8 and try text soft magic */
+               /* malloc size is a conservative overestimate; could be
+                  improved, or at least realloced after conversion. */
+               mlen = ulen * 6;
+               if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
+                       file_oomem(ms, mlen);
+                       goto done;
+               }
+               if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))
+                   == NULL)
+                       goto done;
+               buffer_init(&bb, b->fd, &b->st, utf8_buf,
+                   CAST(size_t, utf8_end - utf8_buf));
+
+               if ((rv = file_softmagic(ms, &bb, NULL, NULL,
+                   TEXTTEST, text)) == 0)
+                       rv = -1;
+               else
+                       need_separator = 1;
+               buffer_fini(&bb);
+               if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) {
+                       rv = rv == -1 ? 0 : 1;
+                       goto done;
+               }
+       }
+       if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)))
+               return 0;
+
+       /* Now try to discover other details about the file. */
+       for (i = 0; i < ulen; i++) {
+               if (ubuf[i] == '\n') {
+                       if (seen_cr)
+                               n_crlf++;
+                       else
+                               n_lf++;
+                       last_line_end = i;
+               } else if (seen_cr)
+                       n_cr++;
+
+               seen_cr = (ubuf[i] == '\r');
+               if (seen_cr)
+                       last_line_end = i;
+
+               if (ubuf[i] == 0x85) { /* X3.64/ECMA-43 "next line" character */
+                       n_nel++;
+                       last_line_end = i;
+               }
+
+               /* If this line is _longer_ than MAXLINELEN, remember it. */
+               if (i > last_line_end + MAXLINELEN)
+                       has_long_lines = 1;
+
+               if (ubuf[i] == '\033')
+                       has_escapes = 1;
+               if (ubuf[i] == '\b')
+                       has_backspace = 1;
+       }
+
+       /* Beware, if the data has been truncated, the final CR could have
+          been followed by a LF.  If we have ms->bytes_max bytes, it indicates
+          that the data might have been truncated, probably even before
+          this function was called. */
+       if (seen_cr && nbytes < ms->bytes_max)
+               n_cr++;
+
+       if (strcmp(type, "binary") == 0) {
+               rv = 0;
+               goto done;
+       }
+       len = file_printedlen(ms);
+       if (mime) {
+               if ((mime & MAGIC_MIME_TYPE) != 0) {
+                       if (len) {
+                               /*
+                                * Softmagic printed something, we
+                                * are either done, or we need a separator
+                                */
+                               if ((ms->flags & MAGIC_CONTINUE) == 0) {
+                                       rv = 1;
+                                       goto done;
+                               }
+                               if (need_separator && file_separator(ms) == -1)
+                                       goto done;
+                       }
+                       if (subtype_mime) {
+                               if (file_printf(ms, "%s", subtype_mime) == -1)
+                                       goto done;
+                       } else {
+                               if (file_printf(ms, "text/plain") == -1)
+                                       goto done;
+                       }
+               }
+       } else {
+               if (len) {
+                       switch (file_replace(ms, " text$", ", ")) {
+                       case 0:
+                               switch (file_replace(ms, " text executable$",
+                                   ", ")) {
+                               case 0:
+                                       if (file_printf(ms, ", ") == -1)
+                                               goto done;
+                                       break;
+                               case -1:
+                                       goto done;
+                               default:
+                                       executable = 1;
+                                       break;
+                               }
+                               break;
+                       case -1:
+                               goto done;
+                       default:
+                               break;
+                       }
+               }
+
+               if (file_printf(ms, "%s", code) == -1)
+                       goto done;
+
+               if (subtype) {
+                       if (file_printf(ms, " %s", subtype) == -1)
+                               goto done;
+               }
+
+               if (file_printf(ms, " %s", type) == -1)
+                       goto done;
+
+               if (executable)
+                       if (file_printf(ms, " executable") == -1)
+                               goto done;
+
+               if (has_long_lines)
+                       if (file_printf(ms, ", with very long lines") == -1)
+                               goto done;
+
+               /*
+                * Only report line terminators if we find one other than LF,
+                * or if we find none at all.
+                */
+               if ((n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) ||
+                   (n_crlf != 0 || n_cr != 0 || n_nel != 0)) {
+                       if (file_printf(ms, ", with") == -1)
+                               goto done;
+
+                       if (n_crlf == 0 && n_cr == 0 && n_nel == 0 && n_lf == 0) {
+                               if (file_printf(ms, " no") == -1)
+                                       goto done;
+                       } else {
+                               if (n_crlf) {
+                                       if (file_printf(ms, " CRLF") == -1)
+                                               goto done;
+                                       if (n_cr || n_lf || n_nel)
+                                               if (file_printf(ms, ",") == -1)
+                                                       goto done;
+                               }
+                               if (n_cr) {
+                                       if (file_printf(ms, " CR") == -1)
+                                               goto done;
+                                       if (n_lf || n_nel)
+                                               if (file_printf(ms, ",") == -1)
+                                                       goto done;
+                               }
+                               if (n_lf) {
+                                       if (file_printf(ms, " LF") == -1)
+                                               goto done;
+                                       if (n_nel)
+                                               if (file_printf(ms, ",") == -1)
+                                                       goto done;
+                               }
+                               if (n_nel)
+                                       if (file_printf(ms, " NEL") == -1)
+                                               goto done;
+                       }
+
+                       if (file_printf(ms, " line terminators") == -1)
+                               goto done;
+               }
+
+               if (has_escapes)
+                       if (file_printf(ms, ", with escape sequences") == -1)
+                               goto done;
+               if (has_backspace)
+                       if (file_printf(ms, ", with overstriking") == -1)
+                               goto done;
+       }
+       rv = 1;
+done:
+       free(utf8_buf);
+
+       return rv;
+}
+
+/*
+ * Encode Unicode string as UTF-8, returning pointer to character
+ * after end of string, or NULL if an invalid character is found.
+ */
+private unsigned char *
+encode_utf8(unsigned char *buf, size_t len, unichar *ubuf, size_t ulen)
+{
+       size_t i;
+       unsigned char *end = buf + len;
+
+       for (i = 0; i < ulen; i++) {
+               if (ubuf[i] <= 0x7f) {
+                       if (end - buf < 1)
+                               return NULL;
+                       *buf++ = CAST(unsigned char, ubuf[i]);
+               } else if (ubuf[i] <= 0x7ff) {
+                       if (end - buf < 2)
+                               return NULL;
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 6) + 0xc0);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
+               } else if (ubuf[i] <= 0xffff) {
+                       if (end - buf < 3)
+                               return NULL;
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 12) + 0xe0);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
+               } else if (ubuf[i] <= 0x1fffff) {
+                       if (end - buf < 4)
+                               return NULL;
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 18) + 0xf0);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >>  6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
+               } else if (ubuf[i] <= 0x3ffffff) {
+                       if (end - buf < 5)
+                               return NULL;
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 24) + 0xf8);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >>  6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
+               } else if (ubuf[i] <= 0x7fffffff) {
+                       if (end - buf < 6)
+                               return NULL;
+                       *buf++ = CAST(unsigned char, (ubuf[i] >> 30) + 0xfc);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 24) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, ((ubuf[i] >>  6) & 0x3f) + 0x80);
+                       *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
+               } else /* Invalid character */
+                       return NULL;
+       }
+
+       return buf;
+}
diff --git a/src/asctime_r.c b/src/asctime_r.c
new file mode 100644 (file)
index 0000000..876fae6
--- /dev/null
@@ -0,0 +1,19 @@
+/*     $File$  */
+
+#include "file.h"
+#ifndef        lint
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.84 2011/12/08 12:38:24 rrt Exp $")
+#endif /* lint */
+#include <time.h>
+#include <string.h>
+
+/* asctime_r is not thread-safe anyway */
+char *
+asctime_r(const struct tm *t, char *dst)
+{
+       char *p = asctime(t);
+       if (p == NULL)
+               return NULL;
+       memcpy(dst, p, 26);
+       return dst;
+}
diff --git a/src/asprintf.c b/src/asprintf.c
new file mode 100644 (file)
index 0000000..2d14e80
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: asprintf.c,v 1.5 2018/09/09 20:33:28 christos Exp $")
+#endif
+
+int asprintf(char **ptr, const char *fmt, ...)
+{
+  va_list vargs;
+  int retval;
+
+  va_start(vargs, fmt);
+  retval = vasprintf(ptr, fmt, vargs);
+  va_end(vargs);
+
+  return retval;
+}
diff --git a/src/buffer.c b/src/buffer.c
new file mode 100644 (file)
index 0000000..6d8967d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) Christos Zoulas 2017.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: buffer.c,v 1.6 2019/05/07 02:27:11 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+void
+buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data,
+    size_t len)
+{
+       b->fd = fd;
+       if (st)
+               memcpy(&b->st, st, sizeof(b->st));
+       else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
+               memset(&b->st, 0, sizeof(b->st));
+       b->fbuf = data;
+       b->flen = len;
+       b->eoff = 0;
+       b->ebuf = NULL;
+       b->elen = 0;
+}
+
+void
+buffer_fini(struct buffer *b)
+{
+       free(b->ebuf);
+}
+
+int
+buffer_fill(const struct buffer *bb)
+{
+       struct buffer *b = CCAST(struct buffer *, bb);
+
+       if (b->elen != 0)
+               return b->elen == CAST(size_t, ~0) ? -1 : 0;
+
+       if (!S_ISREG(b->st.st_mode))
+               goto out;
+
+       b->elen =  CAST(size_t, b->st.st_size) < b->flen ?
+           CAST(size_t, b->st.st_size) : b->flen;
+       if ((b->ebuf = malloc(b->elen)) == NULL)
+               goto out;
+
+       b->eoff = b->st.st_size - b->elen;
+       if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
+               free(b->ebuf);
+               goto out;
+       }
+
+       return 0;
+out:
+       b->elen = CAST(size_t, ~0);
+       return -1;
+}
diff --git a/src/cdf.c b/src/cdf.c
new file mode 100644 (file)
index 0000000..556a3ff
--- /dev/null
+++ b/src/cdf.c
@@ -0,0 +1,1642 @@
+/*-
+ * Copyright (c) 2008 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Parse Composite Document Files, the format used in Microsoft Office
+ * document files before they switched to zipped XML.
+ * Info from: http://sc.openoffice.org/compdocfileformat.pdf
+ *
+ * N.B. This is the "Composite Document File" format, and not the
+ * "Compound Document Format", nor the "Channel Definition Format".
+ */
+
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: cdf.c,v 1.114 2019/02/20 02:35:27 christos Exp $")
+#endif
+
+#include <assert.h>
+#ifdef CDF_DEBUG
+#include <err.h>
+#endif
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#include <limits.h>
+
+#ifndef EFTYPE
+#define EFTYPE EINVAL
+#endif
+
+#include "cdf.h"
+
+#ifdef CDF_DEBUG
+#define DPRINTF(a) printf a, fflush(stdout)
+#else
+#define DPRINTF(a)
+#endif
+
+static union {
+       char s[4];
+       uint32_t u;
+} cdf_bo;
+
+#define NEED_SWAP      (cdf_bo.u == CAST(uint32_t, 0x01020304))
+
+#define CDF_TOLE8(x)   \
+    (CAST(uint64_t, NEED_SWAP ? _cdf_tole8(x) : CAST(uint64_t, x)))
+#define CDF_TOLE4(x)   \
+    (CAST(uint32_t, NEED_SWAP ? _cdf_tole4(x) : CAST(uint32_t, x)))
+#define CDF_TOLE2(x)   \
+    (CAST(uint16_t, NEED_SWAP ? _cdf_tole2(x) : CAST(uint16_t, x)))
+#define CDF_TOLE(x)    (/*CONSTCOND*/sizeof(x) == 2 ? \
+                           CDF_TOLE2(CAST(uint16_t, x)) : \
+                       (/*CONSTCOND*/sizeof(x) == 4 ? \
+                           CDF_TOLE4(CAST(uint32_t, x)) : \
+                           CDF_TOLE8(CAST(uint64_t, x))))
+#define CDF_GETUINT32(x, y)    cdf_getuint32(x, y)
+
+#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
+#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
+#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
+
+
+/*ARGSUSED*/
+static void *
+cdf_malloc(const char *file __attribute__((__unused__)),
+    size_t line __attribute__((__unused__)), size_t n)
+{
+       DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
+           file, line, __func__, n));
+       return malloc(n);
+}
+
+/*ARGSUSED*/
+static void *
+cdf_realloc(const char *file __attribute__((__unused__)),
+    size_t line __attribute__((__unused__)), void *p, size_t n)
+{
+       DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
+           file, line, __func__, n));
+       return realloc(p, n);
+}
+
+/*ARGSUSED*/
+static void *
+cdf_calloc(const char *file __attribute__((__unused__)),
+    size_t line __attribute__((__unused__)), size_t n, size_t u)
+{
+       DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %"
+           SIZE_T_FORMAT "u\n", file, line, __func__, n, u));
+       return calloc(n, u);
+}
+
+/*
+ * swap a short
+ */
+static uint16_t
+_cdf_tole2(uint16_t sv)
+{
+       uint16_t rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
+       d[0] = s[1];
+       d[1] = s[0];
+       return rv;
+}
+
+/*
+ * swap an int
+ */
+static uint32_t
+_cdf_tole4(uint32_t sv)
+{
+       uint32_t rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
+       d[0] = s[3];
+       d[1] = s[2];
+       d[2] = s[1];
+       d[3] = s[0];
+       return rv;
+}
+
+/*
+ * swap a quad
+ */
+static uint64_t
+_cdf_tole8(uint64_t sv)
+{
+       uint64_t rv;
+       uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+       uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
+       d[0] = s[7];
+       d[1] = s[6];
+       d[2] = s[5];
+       d[3] = s[4];
+       d[4] = s[3];
+       d[5] = s[2];
+       d[6] = s[1];
+       d[7] = s[0];
+       return rv;
+}
+
+/*
+ * grab a uint32_t from a possibly unaligned address, and return it in
+ * the native host order.
+ */
+static uint32_t
+cdf_getuint32(const uint8_t *p, size_t offs)
+{
+       uint32_t rv;
+       (void)memcpy(&rv, p + offs * sizeof(uint32_t), sizeof(rv));
+       return CDF_TOLE4(rv);
+}
+
+#define CDF_UNPACK(a)  \
+    (void)memcpy(&(a), &buf[len], sizeof(a)), len += sizeof(a)
+#define CDF_UNPACKA(a) \
+    (void)memcpy((a), &buf[len], sizeof(a)), len += sizeof(a)
+
+uint16_t
+cdf_tole2(uint16_t sv)
+{
+       return CDF_TOLE2(sv);
+}
+
+uint32_t
+cdf_tole4(uint32_t sv)
+{
+       return CDF_TOLE4(sv);
+}
+
+uint64_t
+cdf_tole8(uint64_t sv)
+{
+       return CDF_TOLE8(sv);
+}
+
+void
+cdf_swap_header(cdf_header_t *h)
+{
+       size_t i;
+
+       h->h_magic = CDF_TOLE8(h->h_magic);
+       h->h_uuid[0] = CDF_TOLE8(h->h_uuid[0]);
+       h->h_uuid[1] = CDF_TOLE8(h->h_uuid[1]);
+       h->h_revision = CDF_TOLE2(h->h_revision);
+       h->h_version = CDF_TOLE2(h->h_version);
+       h->h_byte_order = CDF_TOLE2(h->h_byte_order);
+       h->h_sec_size_p2 = CDF_TOLE2(h->h_sec_size_p2);
+       h->h_short_sec_size_p2 = CDF_TOLE2(h->h_short_sec_size_p2);
+       h->h_num_sectors_in_sat = CDF_TOLE4(h->h_num_sectors_in_sat);
+       h->h_secid_first_directory = CDF_TOLE4(h->h_secid_first_directory);
+       h->h_min_size_standard_stream =
+           CDF_TOLE4(h->h_min_size_standard_stream);
+       h->h_secid_first_sector_in_short_sat =
+           CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_short_sat));
+       h->h_num_sectors_in_short_sat =
+           CDF_TOLE4(h->h_num_sectors_in_short_sat);
+       h->h_secid_first_sector_in_master_sat =
+           CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_master_sat));
+       h->h_num_sectors_in_master_sat =
+           CDF_TOLE4(h->h_num_sectors_in_master_sat);
+       for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+               h->h_master_sat[i] =
+                   CDF_TOLE4(CAST(uint32_t, h->h_master_sat[i]));
+       }
+}
+
+void
+cdf_unpack_header(cdf_header_t *h, char *buf)
+{
+       size_t i;
+       size_t len = 0;
+
+       CDF_UNPACK(h->h_magic);
+       CDF_UNPACKA(h->h_uuid);
+       CDF_UNPACK(h->h_revision);
+       CDF_UNPACK(h->h_version);
+       CDF_UNPACK(h->h_byte_order);
+       CDF_UNPACK(h->h_sec_size_p2);
+       CDF_UNPACK(h->h_short_sec_size_p2);
+       CDF_UNPACKA(h->h_unused0);
+       CDF_UNPACK(h->h_num_sectors_in_sat);
+       CDF_UNPACK(h->h_secid_first_directory);
+       CDF_UNPACKA(h->h_unused1);
+       CDF_UNPACK(h->h_min_size_standard_stream);
+       CDF_UNPACK(h->h_secid_first_sector_in_short_sat);
+       CDF_UNPACK(h->h_num_sectors_in_short_sat);
+       CDF_UNPACK(h->h_secid_first_sector_in_master_sat);
+       CDF_UNPACK(h->h_num_sectors_in_master_sat);
+       for (i = 0; i < __arraycount(h->h_master_sat); i++)
+               CDF_UNPACK(h->h_master_sat[i]);
+}
+
+void
+cdf_swap_dir(cdf_directory_t *d)
+{
+       d->d_namelen = CDF_TOLE2(d->d_namelen);
+       d->d_left_child = CDF_TOLE4(CAST(uint32_t, d->d_left_child));
+       d->d_right_child = CDF_TOLE4(CAST(uint32_t, d->d_right_child));
+       d->d_storage = CDF_TOLE4(CAST(uint32_t, d->d_storage));
+       d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]);
+       d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]);
+       d->d_flags = CDF_TOLE4(d->d_flags);
+       d->d_created = CDF_TOLE8(CAST(uint64_t, d->d_created));
+       d->d_modified = CDF_TOLE8(CAST(uint64_t, d->d_modified));
+       d->d_stream_first_sector = CDF_TOLE4(
+           CAST(uint32_t, d->d_stream_first_sector));
+       d->d_size = CDF_TOLE4(d->d_size);
+}
+
+void
+cdf_swap_class(cdf_classid_t *d)
+{
+       d->cl_dword = CDF_TOLE4(d->cl_dword);
+       d->cl_word[0] = CDF_TOLE2(d->cl_word[0]);
+       d->cl_word[1] = CDF_TOLE2(d->cl_word[1]);
+}
+
+void
+cdf_unpack_dir(cdf_directory_t *d, char *buf)
+{
+       size_t len = 0;
+
+       CDF_UNPACKA(d->d_name);
+       CDF_UNPACK(d->d_namelen);
+       CDF_UNPACK(d->d_type);
+       CDF_UNPACK(d->d_color);
+       CDF_UNPACK(d->d_left_child);
+       CDF_UNPACK(d->d_right_child);
+       CDF_UNPACK(d->d_storage);
+       CDF_UNPACKA(d->d_storage_uuid);
+       CDF_UNPACK(d->d_flags);
+       CDF_UNPACK(d->d_created);
+       CDF_UNPACK(d->d_modified);
+       CDF_UNPACK(d->d_stream_first_sector);
+       CDF_UNPACK(d->d_size);
+       CDF_UNPACK(d->d_unused0);
+}
+
+int
+cdf_zero_stream(cdf_stream_t *scn)
+{
+       scn->sst_len = 0;
+       scn->sst_dirlen = 0;
+       scn->sst_ss = 0;
+       free(scn->sst_tab);
+       scn->sst_tab = NULL;
+       return -1;
+}
+
+static size_t
+cdf_check_stream(const cdf_stream_t *sst, const cdf_header_t *h)
+{
+       size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ?
+           CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
+       assert(ss == sst->sst_ss);
+       return sst->sst_ss;
+}
+
+static int
+cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
+    const void *p, size_t tail, int line)
+{
+       const char *b = RCAST(const char *, sst->sst_tab);
+       const char *e = RCAST(const char *, p) + tail;
+       size_t ss = cdf_check_stream(sst, h);
+       /*LINTED*/(void)&line;
+       if (e >= b && CAST(size_t, e - b) <= ss * sst->sst_len)
+               return 0;
+       DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u"
+           " > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
+           SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b),
+           ss * sst->sst_len, ss, sst->sst_len));
+       errno = EFTYPE;
+       return -1;
+}
+
+static ssize_t
+cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
+{
+       size_t siz = CAST(size_t, off + len);
+
+       if (CAST(off_t, off + len) != CAST(off_t, siz))
+               goto out;
+
+       if (info->i_buf != NULL && info->i_len >= siz) {
+               (void)memcpy(buf, &info->i_buf[off], len);
+               return CAST(ssize_t, len);
+       }
+
+       if (info->i_fd == -1)
+               goto out;
+
+       if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len))
+               return -1;
+
+       return CAST(ssize_t, len);
+out:
+       errno = EINVAL;
+       return -1;
+}
+
+int
+cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
+{
+       char buf[512];
+
+       (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
+       if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1)
+               return -1;
+       cdf_unpack_header(h, buf);
+       cdf_swap_header(h);
+       if (h->h_magic != CDF_MAGIC) {
+               DPRINTF(("Bad magic %#" INT64_T_FORMAT "x != %#"
+                   INT64_T_FORMAT "x\n",
+                   (unsigned long long)h->h_magic,
+                   (unsigned long long)CDF_MAGIC));
+               goto out;
+       }
+       if (h->h_sec_size_p2 > 20) {
+               DPRINTF(("Bad sector size %hu\n", h->h_sec_size_p2));
+               goto out;
+       }
+       if (h->h_short_sec_size_p2 > 20) {
+               DPRINTF(("Bad short sector size %hu\n",
+                   h->h_short_sec_size_p2));
+               goto out;
+       }
+       return 0;
+out:
+       errno = EFTYPE;
+       return -1;
+}
+
+
+ssize_t
+cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
+    const cdf_header_t *h, cdf_secid_t id)
+{
+       size_t ss = CDF_SEC_SIZE(h);
+       size_t pos = CDF_SEC_POS(h, id);
+       assert(ss == len);
+       return cdf_read(info, CAST(off_t, pos), RCAST(char *, buf) + offs, len);
+}
+
+ssize_t
+cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
+    size_t len, const cdf_header_t *h, cdf_secid_t id)
+{
+       size_t ss = CDF_SHORT_SEC_SIZE(h);
+       size_t pos = CDF_SHORT_SEC_POS(h, id);
+       assert(ss == len);
+       if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) {
+               DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %"
+                   SIZE_T_FORMAT "u\n",
+                   pos + len, CDF_SEC_SIZE(h) * sst->sst_len));
+               goto out;
+       }
+       (void)memcpy(RCAST(char *, buf) + offs,
+           RCAST(const char *, sst->sst_tab) + pos, len);
+       return len;
+out:
+       errno = EFTYPE;
+       return -1;
+}
+
+/*
+ * Read the sector allocation table.
+ */
+int
+cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
+{
+       size_t i, j, k;
+       size_t ss = CDF_SEC_SIZE(h);
+       cdf_secid_t *msa, mid, sec;
+       size_t nsatpersec = (ss / sizeof(mid)) - 1;
+
+       for (i = 0; i < __arraycount(h->h_master_sat); i++)
+               if (h->h_master_sat[i] == CDF_SECID_FREE)
+                       break;
+
+#define CDF_SEC_LIMIT (UINT32_MAX / (64 * ss))
+       if ((nsatpersec > 0 &&
+           h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) ||
+           i > CDF_SEC_LIMIT) {
+               DPRINTF(("Number of sectors in master SAT too big %u %"
+                   SIZE_T_FORMAT "u\n", h->h_num_sectors_in_master_sat, i));
+               errno = EFTYPE;
+               return -1;
+       }
+
+       sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i;
+       DPRINTF(("sat_len = %" SIZE_T_FORMAT "u ss = %" SIZE_T_FORMAT "u\n",
+           sat->sat_len, ss));
+       if ((sat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(sat->sat_len, ss)))
+           == NULL)
+               return -1;
+
+       for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+               if (h->h_master_sat[i] < 0)
+                       break;
+               if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
+                   h->h_master_sat[i]) != CAST(ssize_t, ss)) {
+                       DPRINTF(("Reading sector %d", h->h_master_sat[i]));
+                       goto out1;
+               }
+       }
+
+       if ((msa = CAST(cdf_secid_t *, CDF_CALLOC(1, ss))) == NULL)
+               goto out1;
+
+       mid = h->h_secid_first_sector_in_master_sat;
+       for (j = 0; j < h->h_num_sectors_in_master_sat; j++) {
+               if (mid < 0)
+                       goto out;
+               if (j >= CDF_LOOP_LIMIT) {
+                       DPRINTF(("Reading master sector loop limit"));
+                       goto out3;
+               }
+               if (cdf_read_sector(info, msa, 0, ss, h, mid) !=
+                   CAST(ssize_t, ss)) {
+                       DPRINTF(("Reading master sector %d", mid));
+                       goto out2;
+               }
+               for (k = 0; k < nsatpersec; k++, i++) {
+                       sec = CDF_TOLE4(CAST(uint32_t, msa[k]));
+                       if (sec < 0)
+                               goto out;
+                       if (i >= sat->sat_len) {
+                           DPRINTF(("Out of bounds reading MSA %"
+                               SIZE_T_FORMAT "u >= %" SIZE_T_FORMAT "u",
+                               i, sat->sat_len));
+                           goto out3;
+                       }
+                       if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
+                           sec) != CAST(ssize_t, ss)) {
+                               DPRINTF(("Reading sector %d",
+                                   CDF_TOLE4(msa[k])));
+                               goto out2;
+                       }
+               }
+               mid = CDF_TOLE4(CAST(uint32_t, msa[nsatpersec]));
+       }
+out:
+       sat->sat_len = i;
+       free(msa);
+       return 0;
+out3:
+       errno = EFTYPE;
+out2:
+       free(msa);
+out1:
+       free(sat->sat_tab);
+       return -1;
+}
+
+size_t
+cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
+{
+       size_t i, j;
+       cdf_secid_t maxsector = CAST(cdf_secid_t, (sat->sat_len * size)
+           / sizeof(maxsector));
+
+       DPRINTF(("Chain:"));
+       if (sid == CDF_SECID_END_OF_CHAIN) {
+               /* 0-length chain. */
+               DPRINTF((" empty\n"));
+               return 0;
+       }
+
+       for (j = i = 0; sid >= 0; i++, j++) {
+               DPRINTF((" %d", sid));
+               if (j >= CDF_LOOP_LIMIT) {
+                       DPRINTF(("Counting chain loop limit"));
+                       goto out;
+               }
+               if (sid >= maxsector) {
+                       DPRINTF(("Sector %d >= %d\n", sid, maxsector));
+                       goto out;
+               }
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
+       }
+       if (i == 0) {
+               DPRINTF((" none, sid: %d\n", sid));
+               goto out;
+
+       }
+       DPRINTF(("\n"));
+       return i;
+out:
+       errno = EFTYPE;
+       return CAST(size_t, -1);
+}
+
+int
+cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, cdf_secid_t sid, size_t len, cdf_stream_t *scn)
+{
+       size_t ss = CDF_SEC_SIZE(h), i, j;
+       ssize_t nr;
+       scn->sst_tab = NULL;
+       scn->sst_len = cdf_count_chain(sat, sid, ss);
+       scn->sst_dirlen = MAX(h->h_min_size_standard_stream, len);
+       scn->sst_ss = ss;
+
+       if (sid == CDF_SECID_END_OF_CHAIN || len == 0)
+               return cdf_zero_stream(scn);
+
+       if (scn->sst_len == CAST(size_t, -1))
+               goto out;
+
+       scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
+       if (scn->sst_tab == NULL)
+               return cdf_zero_stream(scn);
+
+       for (j = i = 0; sid >= 0; i++, j++) {
+               if (j >= CDF_LOOP_LIMIT) {
+                       DPRINTF(("Read long sector chain loop limit"));
+                       goto out;
+               }
+               if (i >= scn->sst_len) {
+                       DPRINTF(("Out of bounds reading long sector chain "
+                           "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", i,
+                           scn->sst_len));
+                       goto out;
+               }
+               if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
+                   sid)) != CAST(ssize_t, ss)) {
+                       if (i == scn->sst_len - 1 && nr > 0) {
+                               /* Last sector might be truncated */
+                               return 0;
+                       }
+                       DPRINTF(("Reading long sector chain %d", sid));
+                       goto out;
+               }
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
+       }
+       return 0;
+out:
+       errno = EFTYPE;
+       return cdf_zero_stream(scn);
+}
+
+int
+cdf_read_short_sector_chain(const cdf_header_t *h,
+    const cdf_sat_t *ssat, const cdf_stream_t *sst,
+    cdf_secid_t sid, size_t len, cdf_stream_t *scn)
+{
+       size_t ss = CDF_SHORT_SEC_SIZE(h), i, j;
+       scn->sst_tab = NULL;
+       scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h));
+       scn->sst_dirlen = len;
+       scn->sst_ss = ss;
+
+       if (scn->sst_len == CAST(size_t, -1))
+               goto out;
+
+       scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
+       if (scn->sst_tab == NULL)
+               return cdf_zero_stream(scn);
+
+       for (j = i = 0; sid >= 0; i++, j++) {
+               if (j >= CDF_LOOP_LIMIT) {
+                       DPRINTF(("Read short sector chain loop limit"));
+                       goto out;
+               }
+               if (i >= scn->sst_len) {
+                       DPRINTF(("Out of bounds reading short sector chain "
+                           "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n",
+                           i, scn->sst_len));
+                       goto out;
+               }
+               if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
+                   sid) != CAST(ssize_t, ss)) {
+                       DPRINTF(("Reading short sector chain %d", sid));
+                       goto out;
+               }
+               sid = CDF_TOLE4(CAST(uint32_t, ssat->sat_tab[sid]));
+       }
+       return 0;
+out:
+       errno = EFTYPE;
+       return cdf_zero_stream(scn);
+}
+
+int
+cdf_read_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
+    cdf_secid_t sid, size_t len, cdf_stream_t *scn)
+{
+
+       if (len < h->h_min_size_standard_stream && sst->sst_tab != NULL)
+               return cdf_read_short_sector_chain(h, ssat, sst, sid, len,
+                   scn);
+       else
+               return cdf_read_long_sector_chain(info, h, sat, sid, len, scn);
+}
+
+int
+cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, cdf_dir_t *dir)
+{
+       size_t i, j;
+       size_t ss = CDF_SEC_SIZE(h), ns, nd;
+       char *buf;
+       cdf_secid_t sid = h->h_secid_first_directory;
+
+       ns = cdf_count_chain(sat, sid, ss);
+       if (ns == CAST(size_t, -1))
+               return -1;
+
+       nd = ss / CDF_DIRECTORY_SIZE;
+
+       dir->dir_len = ns * nd;
+       dir->dir_tab = CAST(cdf_directory_t *,
+           CDF_CALLOC(dir->dir_len, sizeof(dir->dir_tab[0])));
+       if (dir->dir_tab == NULL)
+               return -1;
+
+       if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) {
+               free(dir->dir_tab);
+               return -1;
+       }
+
+       for (j = i = 0; i < ns; i++, j++) {
+               if (j >= CDF_LOOP_LIMIT) {
+                       DPRINTF(("Read dir loop limit"));
+                       goto out;
+               }
+               if (cdf_read_sector(info, buf, 0, ss, h, sid) !=
+                   CAST(ssize_t, ss)) {
+                       DPRINTF(("Reading directory sector %d", sid));
+                       goto out;
+               }
+               for (j = 0; j < nd; j++) {
+                       cdf_unpack_dir(&dir->dir_tab[i * nd + j],
+                           &buf[j * CDF_DIRECTORY_SIZE]);
+               }
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
+       }
+       if (NEED_SWAP)
+               for (i = 0; i < dir->dir_len; i++)
+                       cdf_swap_dir(&dir->dir_tab[i]);
+       free(buf);
+       return 0;
+out:
+       free(dir->dir_tab);
+       free(buf);
+       errno = EFTYPE;
+       return -1;
+}
+
+
+int
+cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, cdf_sat_t *ssat)
+{
+       size_t i, j;
+       size_t ss = CDF_SEC_SIZE(h);
+       cdf_secid_t sid = h->h_secid_first_sector_in_short_sat;
+
+       ssat->sat_tab = NULL;
+       ssat->sat_len = cdf_count_chain(sat, sid, ss);
+       if (ssat->sat_len == CAST(size_t, -1))
+               goto out;
+
+       ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss));
+       if (ssat->sat_tab == NULL)
+               goto out1;
+
+       for (j = i = 0; sid >= 0; i++, j++) {
+               if (j >= CDF_LOOP_LIMIT) {
+                       DPRINTF(("Read short sat sector loop limit"));
+                       goto out;
+               }
+               if (i >= ssat->sat_len) {
+                       DPRINTF(("Out of bounds reading short sector chain "
+                           "%" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", i,
+                           ssat->sat_len));
+                       goto out;
+               }
+               if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
+                   CAST(ssize_t, ss)) {
+                       DPRINTF(("Reading short sat sector %d", sid));
+                       goto out1;
+               }
+               sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
+       }
+       return 0;
+out:
+       errno = EFTYPE;
+out1:
+       free(ssat->sat_tab);
+       return -1;
+}
+
+int
+cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn,
+    const cdf_directory_t **root)
+{
+       size_t i;
+       const cdf_directory_t *d;
+
+       *root = NULL;
+       for (i = 0; i < dir->dir_len; i++)
+               if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE)
+                       break;
+
+       /* If the it is not there, just fake it; some docs don't have it */
+       if (i == dir->dir_len) {
+               DPRINTF(("Cannot find root storage dir\n"));
+               goto out;
+       }
+       d = &dir->dir_tab[i];
+       *root = d;
+
+       /* If the it is not there, just fake it; some docs don't have it */
+       if (d->d_stream_first_sector < 0) {
+               DPRINTF(("No first secror in dir\n"));
+               goto out;
+       }
+
+       return cdf_read_long_sector_chain(info, h, sat,
+           d->d_stream_first_sector, d->d_size, scn);
+out:
+       scn->sst_tab = NULL;
+       (void)cdf_zero_stream(scn);
+       return 0;
+}
+
+static int
+cdf_namecmp(const char *d, const uint16_t *s, size_t l)
+{
+       for (; l--; d++, s++)
+               if (*d != CDF_TOLE2(*s))
+                       return CAST(unsigned char, *d) - CDF_TOLE2(*s);
+       return 0;
+}
+
+int
+cdf_read_doc_summary_info(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
+    const cdf_dir_t *dir, cdf_stream_t *scn)
+{
+       return cdf_read_user_stream(info, h, sat, ssat, sst, dir,
+           "\05DocumentSummaryInformation", scn);
+}
+
+int
+cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
+    const cdf_dir_t *dir, cdf_stream_t *scn)
+{
+       return cdf_read_user_stream(info, h, sat, ssat, sst, dir,
+           "\05SummaryInformation", scn);
+}
+
+int
+cdf_read_user_stream(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
+    const cdf_dir_t *dir, const char *name, cdf_stream_t *scn)
+{
+       const cdf_directory_t *d;
+       int i = cdf_find_stream(dir, name, CDF_DIR_TYPE_USER_STREAM);
+
+       if (i <= 0) {
+               memset(scn, 0, sizeof(*scn));
+               return -1;
+       }
+
+       d = &dir->dir_tab[i - 1];
+       return cdf_read_sector_chain(info, h, sat, ssat, sst,
+           d->d_stream_first_sector, d->d_size, scn);
+}
+
+int
+cdf_find_stream(const cdf_dir_t *dir, const char *name, int type)
+{
+       size_t i, name_len = strlen(name) + 1;
+
+       for (i = dir->dir_len; i > 0; i--)
+               if (dir->dir_tab[i - 1].d_type == type &&
+                   cdf_namecmp(name, dir->dir_tab[i - 1].d_name, name_len)
+                   == 0)
+                       break;
+       if (i > 0)
+               return CAST(int, i);
+
+       DPRINTF(("Cannot find type %d `%s'\n", type, name));
+       errno = ESRCH;
+       return 0;
+}
+
+#define CDF_SHLEN_LIMIT (UINT32_MAX / 64)
+#define CDF_PROP_LIMIT (UINT32_MAX / (64 * sizeof(cdf_property_info_t)))
+
+static const void *
+cdf_offset(const void *p, size_t l)
+{
+       return CAST(const void *, CAST(const uint8_t *, p) + l);
+}
+
+static const uint8_t *
+cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
+    const uint8_t *p, const uint8_t *e, size_t i)
+{
+       size_t tail = (i << 1) + 1;
+       size_t ofs;
+       const uint8_t *q;
+
+       if (p >= e) {
+               DPRINTF(("Past end %p < %p\n", e, p));
+               return NULL;
+       }
+       if (cdf_check_stream_offset(sst, h, p, (tail + 1) * sizeof(uint32_t),
+           __LINE__) == -1)
+               return NULL;
+       ofs = CDF_GETUINT32(p, tail);
+       q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
+           ofs - 2 * sizeof(uint32_t)));
+
+       if (q < p) {
+               DPRINTF(("Wrapped around %p < %p\n", q, p));
+               return NULL;
+       }
+
+       if (q >= e) {
+               DPRINTF(("Ran off the end %p >= %p\n", q, e));
+               return NULL;
+       }
+       return q;
+}
+
+static cdf_property_info_t *
+cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr)
+{
+       cdf_property_info_t *inp;
+       size_t newcount = *maxcount + incr;
+
+       if (newcount > CDF_PROP_LIMIT) {
+               DPRINTF(("exceeded property limit %" SIZE_T_FORMAT "u > %"
+                   SIZE_T_FORMAT "u\n", newcount, CDF_PROP_LIMIT));
+               goto out;
+       }
+       inp = CAST(cdf_property_info_t *,
+           CDF_REALLOC(*info, newcount * sizeof(*inp)));
+       if (inp == NULL)
+               goto out;
+
+       *info = inp;
+       *maxcount = newcount;
+       return inp;
+out:
+       free(*info);
+       *maxcount = 0;
+       *info = NULL;
+       return NULL;
+}
+
+static int
+cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e,
+    size_t len)
+{
+       if (inp->pi_type & CDF_VECTOR)
+               return 0;
+
+       if (CAST(size_t, CAST(const char *, e) - CAST(const char *, p)) < len)
+               return 0;
+
+       (void)memcpy(&inp->pi_val, p, len);
+
+       switch (len) {
+       case 2:
+               inp->pi_u16 = CDF_TOLE2(inp->pi_u16);
+               break;
+       case 4:
+               inp->pi_u32 = CDF_TOLE4(inp->pi_u32);
+               break;
+       case 8:
+               inp->pi_u64 = CDF_TOLE8(inp->pi_u64);
+               break;
+       default:
+               abort();
+       }
+       return 1;
+}
+
+int
+cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
+    uint32_t offs, cdf_property_info_t **info, size_t *count, size_t *maxcount)
+{
+       const cdf_section_header_t *shp;
+       cdf_section_header_t sh;
+       const uint8_t *p, *q, *e;
+       size_t i, o4, nelements, j, slen, left;
+       cdf_property_info_t *inp;
+
+       if (offs > UINT32_MAX / 4) {
+               errno = EFTYPE;
+               goto out;
+       }
+       shp = CAST(const cdf_section_header_t *,
+           cdf_offset(sst->sst_tab, offs));
+       if (cdf_check_stream_offset(sst, h, shp, sizeof(*shp), __LINE__) == -1)
+               goto out;
+       sh.sh_len = CDF_TOLE4(shp->sh_len);
+       if (sh.sh_len > CDF_SHLEN_LIMIT) {
+               errno = EFTYPE;
+               goto out;
+       }
+
+       if (cdf_check_stream_offset(sst, h, shp, sh.sh_len, __LINE__) == -1)
+               goto out;
+
+       sh.sh_properties = CDF_TOLE4(shp->sh_properties);
+       DPRINTF(("section len: %u properties %u\n", sh.sh_len,
+           sh.sh_properties));
+       if (sh.sh_properties > CDF_PROP_LIMIT)
+               goto out;
+       inp = cdf_grow_info(info, maxcount, sh.sh_properties);
+       if (inp == NULL)
+               goto out;
+       inp += *count;
+       *count += sh.sh_properties;
+       p = CAST(const uint8_t *, cdf_offset(sst->sst_tab, offs + sizeof(sh)));
+       e = CAST(const uint8_t *, cdf_offset(shp, sh.sh_len));
+       if (p >= e || cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
+               goto out;
+
+       for (i = 0; i < sh.sh_properties; i++) {
+               if ((q = cdf_get_property_info_pos(sst, h, p, e, i)) == NULL)
+                       goto out;
+               inp[i].pi_id = CDF_GETUINT32(p, i << 1);
+               left = CAST(size_t, e - q);
+               if (left < sizeof(uint32_t)) {
+                       DPRINTF(("short info (no type)_\n"));
+                       goto out;
+               }
+               inp[i].pi_type = CDF_GETUINT32(q, 0);
+               DPRINTF(("%" SIZE_T_FORMAT "u) id=%#x type=%#x offs=%#tx,%#x\n",
+                   i, inp[i].pi_id, inp[i].pi_type, q - p, offs));
+               if (inp[i].pi_type & CDF_VECTOR) {
+                       if (left < sizeof(uint32_t) * 2) {
+                               DPRINTF(("missing CDF_VECTOR length\n"));
+                               goto out;
+                       }
+                       nelements = CDF_GETUINT32(q, 1);
+                       if (nelements == 0) {
+                               DPRINTF(("CDF_VECTOR with nelements == 0\n"));
+                               goto out;
+                       }
+                       slen = 2;
+               } else {
+                       nelements = 1;
+                       slen = 1;
+               }
+               o4 = slen * sizeof(uint32_t);
+               if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
+                       goto unknown;
+               switch (inp[i].pi_type & CDF_TYPEMASK) {
+               case CDF_NULL:
+               case CDF_EMPTY:
+                       break;
+               case CDF_SIGNED16:
+                       if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int16_t)))
+                               goto unknown;
+                       break;
+               case CDF_SIGNED32:
+               case CDF_BOOL:
+               case CDF_UNSIGNED32:
+               case CDF_FLOAT:
+                       if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int32_t)))
+                               goto unknown;
+                       break;
+               case CDF_SIGNED64:
+               case CDF_UNSIGNED64:
+               case CDF_DOUBLE:
+               case CDF_FILETIME:
+                       if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int64_t)))
+                               goto unknown;
+                       break;
+               case CDF_LENGTH32_STRING:
+               case CDF_LENGTH32_WSTRING:
+                       if (nelements > 1) {
+                               size_t nelem = inp - *info;
+                               inp = cdf_grow_info(info, maxcount, nelements);
+                               if (inp == NULL)
+                                       goto out;
+                               inp += nelem;
+                       }
+                       DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
+                           nelements));
+                       for (j = 0; j < nelements && i < sh.sh_properties;
+                           j++, i++)
+                       {
+                               uint32_t l;
+
+                               if (o4 + sizeof(uint32_t) > left)
+                                       goto out;
+
+                               l = CDF_GETUINT32(q, slen);
+                               o4 += sizeof(uint32_t);
+                               if (o4 + l > left)
+                                       goto out;
+
+                               inp[i].pi_str.s_len = l;
+                               inp[i].pi_str.s_buf = CAST(const char *,
+                                   CAST(const void *, &q[o4]));
+
+                               DPRINTF(("o=%" SIZE_T_FORMAT "u l=%d(%"
+                                   SIZE_T_FORMAT "u), t=%" SIZE_T_FORMAT
+                                   "u s=%s\n", o4, l, CDF_ROUND(l, sizeof(l)),
+                                   left, inp[i].pi_str.s_buf));
+
+                               if (l & 1)
+                                       l++;
+
+                               slen += l >> 1;
+                               o4 = slen * sizeof(uint32_t);
+                       }
+                       i--;
+                       break;
+               case CDF_CLIPBOARD:
+                       if (inp[i].pi_type & CDF_VECTOR)
+                               goto unknown;
+                       break;
+               default:
+               unknown:
+                       memset(&inp[i].pi_val, 0, sizeof(inp[i].pi_val));
+                       DPRINTF(("Don't know how to deal with %#x\n",
+                           inp[i].pi_type));
+                       break;
+               }
+       }
+       return 0;
+out:
+       free(*info);
+       *info = NULL;
+       *count = 0;
+       *maxcount = 0;
+       errno = EFTYPE;
+       return -1;
+}
+
+int
+cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
+    cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count)
+{
+       size_t maxcount;
+       const cdf_summary_info_header_t *si =
+           CAST(const cdf_summary_info_header_t *, sst->sst_tab);
+       const cdf_section_declaration_t *sd =
+           CAST(const cdf_section_declaration_t *, RCAST(const void *,
+           RCAST(const char *, sst->sst_tab)
+           + CDF_SECTION_DECLARATION_OFFSET));
+
+       if (cdf_check_stream_offset(sst, h, si, sizeof(*si), __LINE__) == -1 ||
+           cdf_check_stream_offset(sst, h, sd, sizeof(*sd), __LINE__) == -1)
+               return -1;
+       ssi->si_byte_order = CDF_TOLE2(si->si_byte_order);
+       ssi->si_os_version = CDF_TOLE2(si->si_os_version);
+       ssi->si_os = CDF_TOLE2(si->si_os);
+       ssi->si_class = si->si_class;
+       cdf_swap_class(&ssi->si_class);
+       ssi->si_count = CDF_TOLE4(si->si_count);
+       *count = 0;
+       maxcount = 0;
+       *info = NULL;
+       if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info,
+           count, &maxcount) == -1)
+               return -1;
+       return 0;
+}
+
+
+#define extract_catalog_field(t, f, l) \
+    if (b + l + sizeof(cep->f) > eb) { \
+           cep->ce_namlen = 0; \
+           break; \
+    } \
+    memcpy(&cep->f, b + (l), sizeof(cep->f)); \
+    ce[i].f = CAST(t, CDF_TOLE(cep->f))
+
+int
+cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst,
+    cdf_catalog_t **cat)
+{
+       size_t ss = cdf_check_stream(sst, h);
+       const char *b = CAST(const char *, sst->sst_tab);
+       const char *nb, *eb = b + ss * sst->sst_len;
+       size_t nr, i, j, k;
+       cdf_catalog_entry_t *ce;
+       uint16_t reclen;
+       const uint16_t *np;
+
+       for (nr = 0;; nr++) {
+               memcpy(&reclen, b, sizeof(reclen));
+               reclen = CDF_TOLE2(reclen);
+               if (reclen == 0)
+                       break;
+               b += reclen;
+               if (b > eb)
+                   break;
+       }
+       if (nr == 0)
+               return -1;
+       nr--;
+       *cat = CAST(cdf_catalog_t *,
+           CDF_MALLOC(sizeof(cdf_catalog_t) + nr * sizeof(*ce)));
+       if (*cat == NULL)
+               return -1;
+       ce = (*cat)->cat_e;
+       memset(ce, 0, nr * sizeof(*ce));
+       b = CAST(const char *, sst->sst_tab);
+       for (j = i = 0; i < nr; b += reclen) {
+               cdf_catalog_entry_t *cep = &ce[j];
+               uint16_t rlen;
+
+               extract_catalog_field(uint16_t, ce_namlen, 0);
+               extract_catalog_field(uint16_t, ce_num, 4);
+               extract_catalog_field(uint64_t, ce_timestamp, 8);
+               reclen = cep->ce_namlen;
+
+               if (reclen < 14) {
+                       cep->ce_namlen = 0;
+                       continue;
+               }
+
+               cep->ce_namlen = __arraycount(cep->ce_name) - 1;
+               rlen = reclen - 14;
+               if (cep->ce_namlen > rlen)
+                       cep->ce_namlen = rlen;
+
+               np = CAST(const uint16_t *, CAST(const void *, (b + 16)));
+               nb = CAST(const char *, CAST(const void *,
+                   (np + cep->ce_namlen)));
+               if (nb > eb) {
+                       cep->ce_namlen = 0;
+                       break;
+               }
+
+               for (k = 0; k < cep->ce_namlen; k++)
+                       cep->ce_name[k] = np[k]; /* XXX: CDF_TOLE2? */
+               cep->ce_name[cep->ce_namlen] = 0;
+               j = i;
+               i++;
+       }
+       (*cat)->cat_num = j;
+       return 0;
+}
+
+int
+cdf_print_classid(char *buf, size_t buflen, const cdf_classid_t *id)
+{
+       return snprintf(buf, buflen, "%.8x-%.4x-%.4x-%.2x%.2x-"
+           "%.2x%.2x%.2x%.2x%.2x%.2x", id->cl_dword, id->cl_word[0],
+           id->cl_word[1], id->cl_two[0], id->cl_two[1], id->cl_six[0],
+           id->cl_six[1], id->cl_six[2], id->cl_six[3], id->cl_six[4],
+           id->cl_six[5]);
+}
+
+static const struct {
+       uint32_t v;
+       const char *n;
+} vn[] = {
+       { CDF_PROPERTY_CODE_PAGE, "Code page" },
+       { CDF_PROPERTY_TITLE, "Title" },
+       { CDF_PROPERTY_SUBJECT, "Subject" },
+       { CDF_PROPERTY_AUTHOR, "Author" },
+       { CDF_PROPERTY_KEYWORDS, "Keywords" },
+       { CDF_PROPERTY_COMMENTS, "Comments" },
+       { CDF_PROPERTY_TEMPLATE, "Template" },
+       { CDF_PROPERTY_LAST_SAVED_BY, "Last Saved By" },
+       { CDF_PROPERTY_REVISION_NUMBER, "Revision Number" },
+       { CDF_PROPERTY_TOTAL_EDITING_TIME, "Total Editing Time" },
+       { CDF_PROPERTY_LAST_PRINTED, "Last Printed" },
+       { CDF_PROPERTY_CREATE_TIME, "Create Time/Date" },
+       { CDF_PROPERTY_LAST_SAVED_TIME, "Last Saved Time/Date" },
+       { CDF_PROPERTY_NUMBER_OF_PAGES, "Number of Pages" },
+       { CDF_PROPERTY_NUMBER_OF_WORDS, "Number of Words" },
+       { CDF_PROPERTY_NUMBER_OF_CHARACTERS, "Number of Characters" },
+       { CDF_PROPERTY_THUMBNAIL, "Thumbnail" },
+       { CDF_PROPERTY_NAME_OF_APPLICATION, "Name of Creating Application" },
+       { CDF_PROPERTY_SECURITY, "Security" },
+       { CDF_PROPERTY_LOCALE_ID, "Locale ID" },
+};
+
+int
+cdf_print_property_name(char *buf, size_t bufsiz, uint32_t p)
+{
+       size_t i;
+
+       for (i = 0; i < __arraycount(vn); i++)
+               if (vn[i].v == p)
+                       return snprintf(buf, bufsiz, "%s", vn[i].n);
+       return snprintf(buf, bufsiz, "%#x", p);
+}
+
+int
+cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
+{
+       int len = 0;
+       int days, hours, mins, secs;
+
+       ts /= CDF_TIME_PREC;
+       secs = CAST(int, ts % 60);
+       ts /= 60;
+       mins = CAST(int, ts % 60);
+       ts /= 60;
+       hours = CAST(int, ts % 24);
+       ts /= 24;
+       days = CAST(int, ts);
+
+       if (days) {
+               len += snprintf(buf + len, bufsiz - len, "%dd+", days);
+               if (CAST(size_t, len) >= bufsiz)
+                       return len;
+       }
+
+       if (days || hours) {
+               len += snprintf(buf + len, bufsiz - len, "%.2d:", hours);
+               if (CAST(size_t, len) >= bufsiz)
+                       return len;
+       }
+
+       len += snprintf(buf + len, bufsiz - len, "%.2d:", mins);
+       if (CAST(size_t, len) >= bufsiz)
+               return len;
+
+       len += snprintf(buf + len, bufsiz - len, "%.2d", secs);
+       return len;
+}
+
+char *
+cdf_u16tos8(char *buf, size_t len, const uint16_t *p)
+{
+       size_t i;
+       for (i = 0; i < len && p[i]; i++)
+               buf[i] = CAST(char, p[i]);
+       buf[i] = '\0';
+       return buf;
+}
+
+#ifdef CDF_DEBUG
+void
+cdf_dump_header(const cdf_header_t *h)
+{
+       size_t i;
+
+#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b)
+#define DUMP2(a, b) (void)fprintf(stderr, "%40.40s = " a " (" a ")\n", # b, \
+    h->h_ ## b, 1 << h->h_ ## b)
+       DUMP("%d", revision);
+       DUMP("%d", version);
+       DUMP("%#x", byte_order);
+       DUMP2("%d", sec_size_p2);
+       DUMP2("%d", short_sec_size_p2);
+       DUMP("%d", num_sectors_in_sat);
+       DUMP("%d", secid_first_directory);
+       DUMP("%d", min_size_standard_stream);
+       DUMP("%d", secid_first_sector_in_short_sat);
+       DUMP("%d", num_sectors_in_short_sat);
+       DUMP("%d", secid_first_sector_in_master_sat);
+       DUMP("%d", num_sectors_in_master_sat);
+       for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+               if (h->h_master_sat[i] == CDF_SECID_FREE)
+                       break;
+               (void)fprintf(stderr, "%35.35s[%.3" SIZE_T_FORMAT "u] = %d\n",
+                   "master_sat", i, h->h_master_sat[i]);
+       }
+}
+
+void
+cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size)
+{
+       size_t i, j, s = size / sizeof(cdf_secid_t);
+
+       for (i = 0; i < sat->sat_len; i++) {
+               (void)fprintf(stderr, "%s[%" SIZE_T_FORMAT "u]:\n%.6"
+                   SIZE_T_FORMAT "u: ", prefix, i, i * s);
+               for (j = 0; j < s; j++) {
+                       (void)fprintf(stderr, "%5d, ",
+                           CDF_TOLE4(sat->sat_tab[s * i + j]));
+                       if ((j + 1) % 10 == 0)
+                               (void)fprintf(stderr, "\n%.6" SIZE_T_FORMAT
+                                   "u: ", i * s + j + 1);
+               }
+               (void)fprintf(stderr, "\n");
+       }
+}
+
+void
+cdf_dump(const void *v, size_t len)
+{
+       size_t i, j;
+       const unsigned char *p = v;
+       char abuf[16];
+
+       (void)fprintf(stderr, "%.4x: ", 0);
+       for (i = 0, j = 0; i < len; i++, p++) {
+               (void)fprintf(stderr, "%.2x ", *p);
+               abuf[j++] = isprint(*p) ? *p : '.';
+               if (j == 16) {
+                       j = 0;
+                       abuf[15] = '\0';
+                       (void)fprintf(stderr, "%s\n%.4" SIZE_T_FORMAT "x: ",
+                           abuf, i + 1);
+               }
+       }
+       (void)fprintf(stderr, "\n");
+}
+
+void
+cdf_dump_stream(const cdf_stream_t *sst)
+{
+       size_t ss = sst->sst_ss;
+       cdf_dump(sst->sst_tab, ss * sst->sst_len);
+}
+
+void
+cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h,
+    const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst,
+    const cdf_dir_t *dir)
+{
+       size_t i, j;
+       cdf_directory_t *d;
+       char name[__arraycount(d->d_name)];
+       cdf_stream_t scn;
+       struct timespec ts;
+
+       static const char *types[] = { "empty", "user storage",
+           "user stream", "lockbytes", "property", "root storage" };
+
+       for (i = 0; i < dir->dir_len; i++) {
+               char buf[26];
+               d = &dir->dir_tab[i];
+               for (j = 0; j < sizeof(name); j++)
+                       name[j] = (char)CDF_TOLE2(d->d_name[j]);
+               (void)fprintf(stderr, "Directory %" SIZE_T_FORMAT "u: %s\n",
+                   i, name);
+               if (d->d_type < __arraycount(types))
+                       (void)fprintf(stderr, "Type: %s\n", types[d->d_type]);
+               else
+                       (void)fprintf(stderr, "Type: %d\n", d->d_type);
+               (void)fprintf(stderr, "Color: %s\n",
+                   d->d_color ? "black" : "red");
+               (void)fprintf(stderr, "Left child: %d\n", d->d_left_child);
+               (void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
+               (void)fprintf(stderr, "Flags: %#x\n", d->d_flags);
+               cdf_timestamp_to_timespec(&ts, d->d_created);
+               (void)fprintf(stderr, "Created %s", cdf_ctime(&ts.tv_sec, buf));
+               cdf_timestamp_to_timespec(&ts, d->d_modified);
+               (void)fprintf(stderr, "Modified %s",
+                   cdf_ctime(&ts.tv_sec, buf));
+               (void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector);
+               (void)fprintf(stderr, "Size %d\n", d->d_size);
+               switch (d->d_type) {
+               case CDF_DIR_TYPE_USER_STORAGE:
+                       (void)fprintf(stderr, "Storage: %d\n", d->d_storage);
+                       break;
+               case CDF_DIR_TYPE_USER_STREAM:
+                       if (sst == NULL)
+                               break;
+                       if (cdf_read_sector_chain(info, h, sat, ssat, sst,
+                           d->d_stream_first_sector, d->d_size, &scn) == -1) {
+                               warn("Can't read stream for %s at %d len %d",
+                                   name, d->d_stream_first_sector, d->d_size);
+                               break;
+                       }
+                       cdf_dump_stream(&scn);
+                       free(scn.sst_tab);
+                       break;
+               default:
+                       break;
+               }
+
+       }
+}
+
+void
+cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
+{
+       cdf_timestamp_t tp;
+       struct timespec ts;
+       char buf[64];
+       size_t i, j;
+
+       for (i = 0; i < count; i++) {
+               cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
+               (void)fprintf(stderr, "%" SIZE_T_FORMAT "u) %s: ", i, buf);
+               switch (info[i].pi_type) {
+               case CDF_NULL:
+                       break;
+               case CDF_SIGNED16:
+                       (void)fprintf(stderr, "signed 16 [%hd]\n",
+                           info[i].pi_s16);
+                       break;
+               case CDF_SIGNED32:
+                       (void)fprintf(stderr, "signed 32 [%d]\n",
+                           info[i].pi_s32);
+                       break;
+               case CDF_UNSIGNED32:
+                       (void)fprintf(stderr, "unsigned 32 [%u]\n",
+                           info[i].pi_u32);
+                       break;
+               case CDF_FLOAT:
+                       (void)fprintf(stderr, "float [%g]\n",
+                           info[i].pi_f);
+                       break;
+               case CDF_DOUBLE:
+                       (void)fprintf(stderr, "double [%g]\n",
+                           info[i].pi_d);
+                       break;
+               case CDF_LENGTH32_STRING:
+                       (void)fprintf(stderr, "string %u [%.*s]\n",
+                           info[i].pi_str.s_len,
+                           info[i].pi_str.s_len, info[i].pi_str.s_buf);
+                       break;
+               case CDF_LENGTH32_WSTRING:
+                       (void)fprintf(stderr, "string %u [",
+                           info[i].pi_str.s_len);
+                       for (j = 0; j < info[i].pi_str.s_len - 1; j++)
+                           (void)fputc(info[i].pi_str.s_buf[j << 1], stderr);
+                       (void)fprintf(stderr, "]\n");
+                       break;
+               case CDF_FILETIME:
+                       tp = info[i].pi_tp;
+                       if (tp < 1000000000000000LL) {
+                               cdf_print_elapsed_time(buf, sizeof(buf), tp);
+                               (void)fprintf(stderr, "timestamp %s\n", buf);
+                       } else {
+                               char tbuf[26];
+                               cdf_timestamp_to_timespec(&ts, tp);
+                               (void)fprintf(stderr, "timestamp %s",
+                                   cdf_ctime(&ts.tv_sec, tbuf));
+                       }
+                       break;
+               case CDF_CLIPBOARD:
+                       (void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32);
+                       break;
+               default:
+                       DPRINTF(("Don't know how to deal with %#x\n",
+                           info[i].pi_type));
+                       break;
+               }
+       }
+}
+
+
+void
+cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
+{
+       char buf[128];
+       cdf_summary_info_header_t ssi;
+       cdf_property_info_t *info;
+       size_t count;
+
+       (void)&h;
+       if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1)
+               return;
+       (void)fprintf(stderr, "Endian: %#x\n", ssi.si_byte_order);
+       (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
+           ssi.si_os_version >> 8);
+       (void)fprintf(stderr, "Os %d\n", ssi.si_os);
+       cdf_print_classid(buf, sizeof(buf), &ssi.si_class);
+       (void)fprintf(stderr, "Class %s\n", buf);
+       (void)fprintf(stderr, "Count %d\n", ssi.si_count);
+       cdf_dump_property_info(info, count);
+       free(info);
+}
+
+
+void
+cdf_dump_catalog(const cdf_header_t *h, const cdf_stream_t *sst)
+{
+       cdf_catalog_t *cat;
+       cdf_unpack_catalog(h, sst, &cat);
+       const cdf_catalog_entry_t *ce = cat->cat_e;
+       struct timespec ts;
+       char tbuf[64], sbuf[256];
+       size_t i;
+
+       printf("Catalog:\n");
+       for (i = 0; i < cat->cat_num; i++) {
+               cdf_timestamp_to_timespec(&ts, ce[i].ce_timestamp);
+               printf("\t%d %s %s", ce[i].ce_num,
+                   cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name),
+                   cdf_ctime(&ts.tv_sec, tbuf));
+       }
+       free(cat);
+}
+
+#endif
+
+#ifdef TEST
+int
+main(int argc, char *argv[])
+{
+       int i;
+       cdf_header_t h;
+       cdf_sat_t sat, ssat;
+       cdf_stream_t sst, scn;
+       cdf_dir_t dir;
+       cdf_info_t info;
+       const cdf_directory_t *root;
+#ifdef __linux__
+#define getprogname() __progname
+       extern char *__progname;
+#endif
+       if (argc < 2) {
+               (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
+               return -1;
+       }
+
+       info.i_buf = NULL;
+       info.i_len = 0;
+       for (i = 1; i < argc; i++) {
+               if ((info.i_fd = open(argv[1], O_RDONLY)) == -1)
+                       err(EXIT_FAILURE, "Cannot open `%s'", argv[1]);
+
+               if (cdf_read_header(&info, &h) == -1)
+                       err(EXIT_FAILURE, "Cannot read header");
+#ifdef CDF_DEBUG
+               cdf_dump_header(&h);
+#endif
+
+               if (cdf_read_sat(&info, &h, &sat) == -1)
+                       err(EXIT_FAILURE, "Cannot read sat");
+#ifdef CDF_DEBUG
+               cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
+#endif
+
+               if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1)
+                       err(EXIT_FAILURE, "Cannot read ssat");
+#ifdef CDF_DEBUG
+               cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
+#endif
+
+               if (cdf_read_dir(&info, &h, &sat, &dir) == -1)
+                       err(EXIT_FAILURE, "Cannot read dir");
+
+               if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst, &root)
+                   == -1)
+                       err(EXIT_FAILURE, "Cannot read short stream");
+#ifdef CDF_DEBUG
+               cdf_dump_stream(&sst);
+#endif
+
+#ifdef CDF_DEBUG
+               cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
+#endif
+
+
+               if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
+                   &scn) == -1)
+                       warn("Cannot read summary info");
+#ifdef CDF_DEBUG
+               else
+                       cdf_dump_summary_info(&h, &scn);
+#endif
+               if (cdf_read_user_stream(&info, &h, &sat, &ssat, &sst,
+                   &dir, "Catalog", &scn) == -1)
+                       warn("Cannot read catalog");
+#ifdef CDF_DEBUG
+               else
+                       cdf_dump_catalog(&h, &scn);
+#endif
+
+               (void)close(info.i_fd);
+       }
+
+       return 0;
+}
+#endif
diff --git a/src/cdf.h b/src/cdf.h
new file mode 100644 (file)
index 0000000..2f7e554
--- /dev/null
+++ b/src/cdf.h
@@ -0,0 +1,352 @@
+/*-
+ * Copyright (c) 2008 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Parse Composite Document Files, the format used in Microsoft Office
+ * document files before they switched to zipped XML.
+ * Info from: http://sc.openoffice.org/compdocfileformat.pdf
+ *
+ * N.B. This is the "Composite Document File" format, and not the
+ * "Compound Document Format", nor the "Channel Definition Format".
+ */
+
+#ifndef _H_CDF_
+#define _H_CDF_
+
+#ifdef WIN32
+#include <winsock2.h>
+#define timespec timeval
+#define tv_nsec tv_usec
+#endif
+#ifdef __DJGPP__
+#define timespec timeval
+#define tv_nsec tv_usec
+#endif
+
+typedef int32_t cdf_secid_t;
+
+#define CDF_LOOP_LIMIT                                 10000
+
+#define CDF_SECID_NULL                                 0
+#define CDF_SECID_FREE                                 -1
+#define CDF_SECID_END_OF_CHAIN                         -2
+#define CDF_SECID_SECTOR_ALLOCATION_TABLE              -3
+#define CDF_SECID_MASTER_SECTOR_ALLOCATION_TABLE       -4
+
+typedef struct {
+       uint64_t        h_magic;
+#define CDF_MAGIC      0xE11AB1A1E011CFD0LL
+       uint64_t        h_uuid[2];
+       uint16_t        h_revision;
+       uint16_t        h_version;
+       uint16_t        h_byte_order;
+       uint16_t        h_sec_size_p2;
+       uint16_t        h_short_sec_size_p2;
+       uint8_t         h_unused0[10];
+       uint32_t        h_num_sectors_in_sat;
+       uint32_t        h_secid_first_directory;
+       uint8_t         h_unused1[4];
+       uint32_t        h_min_size_standard_stream;
+       cdf_secid_t     h_secid_first_sector_in_short_sat;
+       uint32_t        h_num_sectors_in_short_sat;
+       cdf_secid_t     h_secid_first_sector_in_master_sat;
+       uint32_t        h_num_sectors_in_master_sat;
+       cdf_secid_t     h_master_sat[436/4];
+} cdf_header_t;
+
+#define CDF_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_sec_size_p2)
+#define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h))
+#define CDF_SHORT_SEC_SIZE(h)  CAST(size_t, 1 << (h)->h_short_sec_size_p2)
+#define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h))
+
+typedef int32_t cdf_dirid_t;
+#define CDF_DIRID_NULL -1
+
+typedef int64_t cdf_timestamp_t;
+#define CDF_BASE_YEAR  1601
+#define CDF_TIME_PREC  10000000
+
+typedef struct {
+       uint16_t        d_name[32];
+       uint16_t        d_namelen;
+       uint8_t         d_type;
+#define CDF_DIR_TYPE_EMPTY             0
+#define CDF_DIR_TYPE_USER_STORAGE      1
+#define CDF_DIR_TYPE_USER_STREAM       2
+#define CDF_DIR_TYPE_LOCKBYTES         3
+#define CDF_DIR_TYPE_PROPERTY          4
+#define CDF_DIR_TYPE_ROOT_STORAGE      5
+       uint8_t         d_color;
+#define CDF_DIR_COLOR_READ     0
+#define CDF_DIR_COLOR_BLACK    1
+       cdf_dirid_t     d_left_child;
+       cdf_dirid_t     d_right_child;
+       cdf_dirid_t     d_storage;
+       uint64_t        d_storage_uuid[2];
+       uint32_t        d_flags;
+       cdf_timestamp_t d_created;
+       cdf_timestamp_t d_modified;
+       cdf_secid_t     d_stream_first_sector;
+       uint32_t        d_size;
+       uint32_t        d_unused0;
+} cdf_directory_t;
+
+#define CDF_DIRECTORY_SIZE     128
+
+typedef struct {
+       cdf_secid_t *sat_tab;
+       size_t sat_len;
+} cdf_sat_t;
+
+typedef struct {
+       cdf_directory_t *dir_tab;
+       size_t dir_len;
+} cdf_dir_t;
+
+typedef struct {
+       void *sst_tab;
+       size_t sst_len;         /* Number of sectors */
+       size_t sst_dirlen;      /* Directory sector size */
+       size_t sst_ss;          /* Sector size */
+} cdf_stream_t;
+
+typedef struct {
+       uint32_t        cl_dword;
+       uint16_t        cl_word[2];
+       uint8_t         cl_two[2];
+       uint8_t         cl_six[6];
+} cdf_classid_t;
+
+typedef struct {
+       uint16_t        si_byte_order;
+       uint16_t        si_zero;
+       uint16_t        si_os_version;
+       uint16_t        si_os;
+       cdf_classid_t   si_class;
+       uint32_t        si_count;
+} cdf_summary_info_header_t;
+
+#define CDF_SECTION_DECLARATION_OFFSET 0x1c
+
+typedef struct {
+       cdf_classid_t   sd_class;
+       uint32_t        sd_offset;
+} cdf_section_declaration_t;
+
+typedef struct {
+       uint32_t        sh_len;
+       uint32_t        sh_properties;
+} cdf_section_header_t;
+
+typedef struct {
+       uint32_t        pi_id;
+       uint32_t        pi_type;
+       union {
+               uint16_t        _pi_u16;
+               int16_t         _pi_s16;
+               uint32_t        _pi_u32;
+               int32_t         _pi_s32;
+               uint64_t        _pi_u64;
+               int64_t         _pi_s64;
+               cdf_timestamp_t _pi_tp;
+               float           _pi_f;
+               double          _pi_d;
+               struct {
+                       uint32_t s_len;
+                       const char *s_buf;
+               } _pi_str;
+       } pi_val;
+#define pi_u64 pi_val._pi_u64
+#define pi_s64 pi_val._pi_s64
+#define pi_u32 pi_val._pi_u32
+#define pi_s32 pi_val._pi_s32
+#define pi_u16 pi_val._pi_u16
+#define pi_s16 pi_val._pi_s16
+#define pi_f   pi_val._pi_f
+#define pi_d   pi_val._pi_d
+#define pi_tp  pi_val._pi_tp
+#define pi_str pi_val._pi_str
+} cdf_property_info_t;
+
+#define CDF_ROUND(val, by)     (((val) + (by) - 1) & ~((by) - 1))
+
+/* Variant type definitions */
+#define CDF_EMPTY              0x00000000
+#define CDF_NULL               0x00000001
+#define CDF_SIGNED16           0x00000002
+#define CDF_SIGNED32           0x00000003
+#define CDF_FLOAT              0x00000004
+#define CDF_DOUBLE             0x00000005
+#define CDF_CY                 0x00000006
+#define CDF_DATE               0x00000007
+#define CDF_BSTR               0x00000008
+#define CDF_DISPATCH           0x00000009
+#define CDF_ERROR              0x0000000a
+#define CDF_BOOL               0x0000000b
+#define CDF_VARIANT            0x0000000c
+#define CDF_UNKNOWN            0x0000000d
+#define CDF_DECIMAL            0x0000000e
+#define CDF_SIGNED8            0x00000010
+#define CDF_UNSIGNED8          0x00000011
+#define CDF_UNSIGNED16         0x00000012
+#define CDF_UNSIGNED32         0x00000013
+#define CDF_SIGNED64           0x00000014
+#define CDF_UNSIGNED64         0x00000015
+#define CDF_INT                        0x00000016
+#define CDF_UINT               0x00000017
+#define CDF_VOID               0x00000018
+#define CDF_HRESULT            0x00000019
+#define CDF_PTR                        0x0000001a
+#define CDF_SAFEARRAY          0x0000001b
+#define CDF_CARRAY             0x0000001c
+#define CDF_USERDEFINED                0x0000001d
+#define CDF_LENGTH32_STRING    0x0000001e
+#define CDF_LENGTH32_WSTRING   0x0000001f
+#define CDF_FILETIME           0x00000040
+#define CDF_BLOB               0x00000041
+#define CDF_STREAM             0x00000042
+#define CDF_STORAGE            0x00000043
+#define CDF_STREAMED_OBJECT    0x00000044
+#define CDF_STORED_OBJECT      0x00000045
+#define CDF_BLOB_OBJECT                0x00000046
+#define CDF_CLIPBOARD          0x00000047
+#define CDF_CLSID              0x00000048
+#define CDF_VECTOR             0x00001000
+#define CDF_ARRAY              0x00002000
+#define CDF_BYREF              0x00004000
+#define CDF_RESERVED           0x00008000
+#define CDF_ILLEGAL            0x0000ffff
+#define CDF_ILLEGALMASKED      0x00000fff
+#define CDF_TYPEMASK           0x00000fff
+
+#define CDF_PROPERTY_CODE_PAGE                 0x00000001
+#define CDF_PROPERTY_TITLE                     0x00000002
+#define CDF_PROPERTY_SUBJECT                   0x00000003
+#define CDF_PROPERTY_AUTHOR                    0x00000004
+#define CDF_PROPERTY_KEYWORDS                  0x00000005
+#define CDF_PROPERTY_COMMENTS                  0x00000006
+#define CDF_PROPERTY_TEMPLATE                  0x00000007
+#define CDF_PROPERTY_LAST_SAVED_BY             0x00000008
+#define CDF_PROPERTY_REVISION_NUMBER           0x00000009
+#define CDF_PROPERTY_TOTAL_EDITING_TIME                0x0000000a
+#define CDF_PROPERTY_LAST_PRINTED              0X0000000b
+#define CDF_PROPERTY_CREATE_TIME               0x0000000c
+#define CDF_PROPERTY_LAST_SAVED_TIME           0x0000000d
+#define CDF_PROPERTY_NUMBER_OF_PAGES           0x0000000e
+#define CDF_PROPERTY_NUMBER_OF_WORDS           0x0000000f
+#define CDF_PROPERTY_NUMBER_OF_CHARACTERS      0x00000010
+#define CDF_PROPERTY_THUMBNAIL                 0x00000011
+#define CDF_PROPERTY_NAME_OF_APPLICATION       0x00000012
+#define CDF_PROPERTY_SECURITY                  0x00000013
+#define CDF_PROPERTY_LOCALE_ID                 0x80000000
+
+typedef struct {
+       int i_fd;
+       const unsigned char *i_buf;
+       size_t i_len;
+} cdf_info_t;
+
+
+typedef struct {
+       uint16_t ce_namlen;
+       uint32_t ce_num;
+       uint64_t ce_timestamp;
+       uint16_t ce_name[256];
+} cdf_catalog_entry_t;
+
+typedef struct {
+       size_t cat_num;
+       cdf_catalog_entry_t cat_e[1];
+} cdf_catalog_t;
+
+struct timespec;
+int cdf_timestamp_to_timespec(struct timespec *, cdf_timestamp_t);
+int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *);
+int cdf_read_header(const cdf_info_t *, cdf_header_t *);
+void cdf_swap_header(cdf_header_t *);
+void cdf_unpack_header(cdf_header_t *, char *);
+void cdf_swap_dir(cdf_directory_t *);
+void cdf_unpack_dir(cdf_directory_t *, char *);
+void cdf_swap_class(cdf_classid_t *);
+ssize_t cdf_read_sector(const cdf_info_t *, void *, size_t, size_t,
+    const cdf_header_t *, cdf_secid_t);
+ssize_t cdf_read_short_sector(const cdf_stream_t *, void *, size_t, size_t,
+    const cdf_header_t *, cdf_secid_t);
+int cdf_read_sat(const cdf_info_t *, cdf_header_t *, cdf_sat_t *);
+size_t cdf_count_chain(const cdf_sat_t *, cdf_secid_t, size_t);
+int cdf_read_long_sector_chain(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, cdf_secid_t, size_t, cdf_stream_t *);
+int cdf_read_short_sector_chain(const cdf_header_t *, const cdf_sat_t *,
+    const cdf_stream_t *, cdf_secid_t, size_t, cdf_stream_t *);
+int cdf_read_sector_chain(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, cdf_secid_t,
+    size_t, cdf_stream_t *);
+int cdf_read_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
+    cdf_dir_t *);
+int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
+    cdf_sat_t *);
+int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *,
+    const cdf_directory_t **);
+int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t,
+    cdf_property_info_t **, size_t *, size_t *);
+int cdf_read_user_stream(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
+    const cdf_dir_t *, const char *, cdf_stream_t *);
+int cdf_find_stream(const cdf_dir_t *, const char *, int);
+int cdf_zero_stream(cdf_stream_t *);
+int cdf_read_doc_summary_info(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
+    const cdf_dir_t *, cdf_stream_t *);
+int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *,
+    const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
+    const cdf_dir_t *, cdf_stream_t *);
+int cdf_unpack_summary_info(const cdf_stream_t *, const cdf_header_t *,
+    cdf_summary_info_header_t *, cdf_property_info_t **, size_t *);
+int cdf_unpack_catalog(const cdf_header_t *, const cdf_stream_t *,
+    cdf_catalog_t **);
+int cdf_print_classid(char *, size_t, const cdf_classid_t *);
+int cdf_print_property_name(char *, size_t, uint32_t);
+int cdf_print_elapsed_time(char *, size_t, cdf_timestamp_t);
+uint16_t cdf_tole2(uint16_t);
+uint32_t cdf_tole4(uint32_t);
+uint64_t cdf_tole8(uint64_t);
+char *cdf_ctime(const time_t *, char *);
+char *cdf_u16tos8(char *, size_t, const uint16_t *);
+
+#ifdef CDF_DEBUG
+void cdf_dump_header(const cdf_header_t *);
+void cdf_dump_sat(const char *, const cdf_sat_t *, size_t);
+void cdf_dump(const void *, size_t);
+void cdf_dump_stream(const cdf_stream_t *);
+void cdf_dump_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
+    const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *);
+void cdf_dump_property_info(const cdf_property_info_t *, size_t);
+void cdf_dump_summary_info(const cdf_header_t *, const cdf_stream_t *);
+void cdf_dump_catalog(const cdf_header_t *, const cdf_stream_t *);
+#endif
+
+
+#endif /* _H_CDF_ */
diff --git a/src/cdf.mk b/src/cdf.mk
new file mode 100644 (file)
index 0000000..681616a
--- /dev/null
@@ -0,0 +1,3 @@
+CFLAGS+=-DTEST -DCDF_DEBUG -g -DHAVE_CONFIG_H -I..
+cdf: cdf.o cdf_time.o
+       ${CC} ${CFLAGS} -o $@ $>
diff --git a/src/cdf_time.c b/src/cdf_time.c
new file mode 100644 (file)
index 0000000..e4eea4c
--- /dev/null
@@ -0,0 +1,198 @@
+/*-
+ * Copyright (c) 2008 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: cdf_time.c,v 1.19 2019/03/12 20:43:05 christos Exp $")
+#endif
+
+#include <time.h>
+#ifdef TEST
+#include <err.h>
+#endif
+#include <string.h>
+
+#include "cdf.h"
+
+#define isleap(y) ((((y) % 4) == 0) && \
+    ((((y) % 100) != 0) || (((y) % 400) == 0)))
+
+static const int mdays[] = {
+    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * Return the number of days between jan 01 1601 and jan 01 of year.
+ */
+static int
+cdf_getdays(int year)
+{
+       int days = 0;
+       int y;
+
+       for (y = CDF_BASE_YEAR; y < year; y++)
+               days += isleap(y) + 365;
+
+       return days;
+}
+
+/*
+ * Return the day within the month
+ */
+static int
+cdf_getday(int year, int days)
+{
+       size_t m;
+
+       for (m = 0; m < __arraycount(mdays); m++) {
+               int sub = mdays[m] + (m == 1 && isleap(year));
+               if (days < sub)
+                       return days;
+               days -= sub;
+       }
+       return days;
+}
+
+/*
+ * Return the 0...11 month number.
+ */
+static int
+cdf_getmonth(int year, int days)
+{
+       size_t m;
+
+       for (m = 0; m < __arraycount(mdays); m++) {
+               days -= mdays[m];
+               if (m == 1 && isleap(year))
+                       days--;
+               if (days <= 0)
+                       return CAST(int, m);
+       }
+       return CAST(int, m);
+}
+
+int
+cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
+{
+       struct tm tm;
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+       static char UTC[] = "UTC";
+#endif
+       int rdays;
+
+       /* Unit is 100's of nanoseconds */
+       ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
+
+       t /= CDF_TIME_PREC;
+       tm.tm_sec = CAST(int, t % 60);
+       t /= 60;
+
+       tm.tm_min = CAST(int, t % 60);
+       t /= 60;
+
+       tm.tm_hour = CAST(int, t % 24);
+       t /= 24;
+
+       /* XXX: Approx */
+       tm.tm_year = CAST(int, CDF_BASE_YEAR + (t / 365));
+
+       rdays = cdf_getdays(tm.tm_year);
+       t -= rdays - 1;
+       tm.tm_mday = cdf_getday(tm.tm_year, CAST(int, t));
+       tm.tm_mon = cdf_getmonth(tm.tm_year, CAST(int, t));
+       tm.tm_wday = 0;
+       tm.tm_yday = 0;
+       tm.tm_isdst = 0;
+#ifdef HAVE_STRUCT_TM_TM_GMTOFF
+       tm.tm_gmtoff = 0;
+#endif
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+       tm.tm_zone = UTC;
+#endif
+       tm.tm_year -= 1900;
+       ts->tv_sec = mktime(&tm);
+       if (ts->tv_sec == -1) {
+               errno = EINVAL;
+               return -1;
+       }
+       return 0;
+}
+
+int
+/*ARGSUSED*/
+cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
+{
+#ifndef __lint__
+       (void)&t;
+       (void)&ts;
+#endif
+#ifdef notyet
+       struct tm tm;
+       if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
+       *t = (ts->ts_nsec / 100) * CDF_TIME_PREC;
+       *t = tm.tm_sec;
+       *t += tm.tm_min * 60;
+       *t += tm.tm_hour * 60 * 60;
+       *t += tm.tm_mday * 60 * 60 * 24;
+#endif
+       return 0;
+}
+
+char *
+cdf_ctime(const time_t *sec, char *buf)
+{
+       char *ptr = ctime_r(sec, buf);
+       if (ptr != NULL)
+               return buf;
+       (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
+           CAST(long long, *sec));
+       return buf;
+}
+
+
+#ifdef TEST_TIME
+int
+main(int argc, char *argv[])
+{
+       struct timespec ts;
+       char buf[25];
+       static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
+       static const char *ref = "Sat Apr 23 01:30:00 1977";
+       char *p, *q;
+
+       cdf_timestamp_to_timespec(&ts, tst);
+       p = cdf_ctime(&ts.tv_sec, buf);
+       if ((q = strchr(p, '\n')) != NULL)
+               *q = '\0';
+       if (strcmp(ref, p) != 0)
+               errx(1, "Error date %s != %s\n", ref, p);
+       return 0;
+}
+#endif
diff --git a/src/compress.c b/src/compress.c
new file mode 100644 (file)
index 0000000..95e42a2
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * compress routines:
+ *     zmagic() - returns 0 if not recognized, uncompresses and prints
+ *                information if recognized
+ *     uncompress(method, old, n, newch) - uncompress old into new,
+ *                                         using method, return sizeof new
+ */
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: compress.c,v 1.121 2019/05/07 02:27:11 christos Exp $")
+#endif
+
+#include "magic.h"
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <signal.h>
+#ifndef HAVE_SIG_T
+typedef void (*sig_t)(int);
+#endif /* HAVE_SIG_T */
+#if !defined(__MINGW32__) && !defined(WIN32)
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
+#define BUILTIN_DECOMPRESS
+#include <zlib.h>
+#endif
+
+#if defined(HAVE_BZLIB_H)
+#define BUILTIN_BZLIB
+#include <bzlib.h>
+#endif
+
+#ifdef DEBUG
+int tty = -1;
+#define DPRINTF(...)   do { \
+       if (tty == -1) \
+               tty = open("/dev/tty", O_RDWR); \
+       if (tty == -1) \
+               abort(); \
+       dprintf(tty, __VA_ARGS__); \
+} while (/*CONSTCOND*/0)
+#else
+#define DPRINTF(...)
+#endif
+
+#ifdef ZLIBSUPPORT
+/*
+ * The following python code is not really used because ZLIBSUPPORT is only
+ * defined if we have a built-in zlib, and the built-in zlib handles that.
+ * That is not true for android where we have zlib.h and not -lz.
+ */
+static const char zlibcode[] =
+    "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
+
+static const char *zlib_args[] = { "python", "-c", zlibcode, NULL };
+
+static int
+zlibcmp(const unsigned char *buf)
+{
+       unsigned short x = 1;
+       unsigned char *s = CAST(unsigned char *, CAST(void *, &x));
+
+       if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
+               return 0;
+       if (s[0] != 1)  /* endianness test */
+               x = buf[0] | (buf[1] << 8);
+       else
+               x = buf[1] | (buf[0] << 8);
+       if (x % 31)
+               return 0;
+       return 1;
+}
+#endif
+
+#define gzip_flags "-cd"
+#define lrzip_flags "-do"
+#define lzip_flags gzip_flags
+
+static const char *gzip_args[] = {
+       "gzip", gzip_flags, NULL
+};
+static const char *uncompress_args[] = {
+       "uncompress", "-c", NULL
+};
+static const char *bzip2_args[] = {
+       "bzip2", "-cd", NULL
+};
+static const char *lzip_args[] = {
+       "lzip", lzip_flags, NULL
+};
+static const char *xz_args[] = {
+       "xz", "-cd", NULL
+};
+static const char *lrzip_args[] = {
+       "lrzip", lrzip_flags, NULL
+};
+static const char *lz4_args[] = {
+       "lz4", "-cd", NULL
+};
+static const char *zstd_args[] = {
+       "zstd", "-cd", NULL
+};
+
+#define        do_zlib         NULL
+#define        do_bzlib        NULL
+
+private const struct {
+       const void *magic;
+       size_t maglen;
+       const char **argv;
+       void *unused;
+} compr[] = {
+       { "\037\235",   2, gzip_args, NULL },           /* compressed */
+       /* Uncompress can get stuck; so use gzip first if we have it
+        * Idea from Damien Clark, thanks! */
+       { "\037\235",   2, uncompress_args, NULL },     /* compressed */
+       { "\037\213",   2, gzip_args, do_zlib },        /* gzipped */
+       { "\037\236",   2, gzip_args, NULL },           /* frozen */
+       { "\037\240",   2, gzip_args, NULL },           /* SCO LZH */
+       /* the standard pack utilities do not accept standard input */
+       { "\037\036",   2, gzip_args, NULL },           /* packed */
+       { "PK\3\4",     4, gzip_args, NULL },           /* pkzipped, */
+       /* ...only first file examined */
+       { "BZh",        3, bzip2_args, do_bzlib },      /* bzip2-ed */
+       { "LZIP",       4, lzip_args, NULL },           /* lzip-ed */
+       { "\3757zXZ\0", 6, xz_args, NULL },             /* XZ Utils */
+       { "LRZI",       4, lrzip_args, NULL },  /* LRZIP */
+       { "\004\"M\030",4, lz4_args, NULL },            /* LZ4 */
+       { "\x28\xB5\x2F\xFD", 4, zstd_args, NULL },     /* zstd */
+#ifdef ZLIBSUPPORT
+       { RCAST(const void *, zlibcmp), 0, zlib_args, NULL },   /* zlib */
+#endif
+};
+
+#define OKDATA         0
+#define NODATA 1
+#define ERRDATA        2
+
+private ssize_t swrite(int, const void *, size_t);
+#if HAVE_FORK
+private size_t ncompr = __arraycount(compr);
+private int uncompressbuf(int, size_t, size_t, const unsigned char *,
+    unsigned char **, size_t *);
+#ifdef BUILTIN_DECOMPRESS
+private int uncompresszlib(const unsigned char *, unsigned char **, size_t,
+    size_t *, int);
+private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
+    size_t *);
+#endif
+#ifdef BUILTIN_BZLIB
+private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
+    size_t *, int);
+#endif
+
+static int makeerror(unsigned char **, size_t *, const char *, ...)
+    __attribute__((__format__(__printf__, 3, 4)));
+private const char *methodname(size_t);
+
+private int
+format_decompression_error(struct magic_set *ms, size_t i, unsigned char *buf)
+{
+       unsigned char *p;
+       int mime = ms->flags & MAGIC_MIME;
+
+       if (!mime)
+               return file_printf(ms, "ERROR:[%s: %s]", methodname(i), buf);
+
+       for (p = buf; *p; p++)
+               if (!isalnum(*p))
+                       *p = '-';
+
+       return file_printf(ms, "application/x-decompression-error-%s-%s",
+           methodname(i), buf);
+}
+
+protected int
+file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
+{
+       unsigned char *newbuf = NULL;
+       size_t i, nsz;
+       char *rbuf;
+       file_pushbuf_t *pb;
+       int urv, prv, rv = 0;
+       int mime = ms->flags & MAGIC_MIME;
+       int fd = b->fd;
+       const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
+       size_t nbytes = b->flen;
+       int sa_saved = 0;
+       struct sigaction sig_act;
+
+       if ((ms->flags & MAGIC_COMPRESS) == 0)
+               return 0;
+
+       for (i = 0; i < ncompr; i++) {
+               int zm;
+               if (nbytes < compr[i].maglen)
+                       continue;
+#ifdef ZLIBSUPPORT
+               if (compr[i].maglen == 0)
+                       zm = (RCAST(int (*)(const unsigned char *),
+                           CCAST(void *, compr[i].magic)))(buf);
+               else
+#endif
+                       zm = memcmp(buf, compr[i].magic, compr[i].maglen) == 0;
+
+               if (!zm)
+                       continue;
+
+               /* Prevent SIGPIPE death if child dies unexpectedly */
+               if (!sa_saved) {
+                       //We can use sig_act for both new and old, but
+                       struct sigaction new_act;
+                       memset(&new_act, 0, sizeof(new_act));
+                       new_act.sa_handler = SIG_IGN;
+                       sa_saved = sigaction(SIGPIPE, &new_act, &sig_act) != -1;
+               }
+
+               nsz = nbytes;
+               urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz);
+               DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv,
+                   (char *)newbuf, nsz);
+               switch (urv) {
+               case OKDATA:
+               case ERRDATA:
+                       ms->flags &= ~MAGIC_COMPRESS;
+                       if (urv == ERRDATA)
+                               prv = format_decompression_error(ms, i, newbuf);
+                       else
+                               prv = file_buffer(ms, -1, NULL, name, newbuf, nsz);
+                       if (prv == -1)
+                               goto error;
+                       rv = 1;
+                       if ((ms->flags & MAGIC_COMPRESS_TRANSP) != 0)
+                               goto out;
+                       if (mime != MAGIC_MIME && mime != 0)
+                               goto out;
+                       if ((file_printf(ms,
+                           mime ? " compressed-encoding=" : " (")) == -1)
+                               goto error;
+                       if ((pb = file_push_buffer(ms)) == NULL)
+                               goto error;
+                       /*
+                        * XXX: If file_buffer fails here, we overwrite
+                        * the compressed text. FIXME.
+                        */
+                       if (file_buffer(ms, -1, NULL, NULL, buf, nbytes) == -1) {
+                               if (file_pop_buffer(ms, pb) != NULL)
+                                       abort();
+                               goto error;
+                       }
+                       if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
+                               if (file_printf(ms, "%s", rbuf) == -1) {
+                                       free(rbuf);
+                                       goto error;
+                               }
+                               free(rbuf);
+                       }
+                       if (!mime && file_printf(ms, ")") == -1)
+                               goto error;
+                       /*FALLTHROUGH*/
+               case NODATA:
+                       break;
+               default:
+                       abort();
+                       /*NOTREACHED*/
+               error:
+                       rv = -1;
+                       break;
+               }
+       }
+out:
+       DPRINTF("rv = %d\n", rv);
+
+       if (sa_saved && sig_act.sa_handler != SIG_IGN)
+               (void)sigaction(SIGPIPE, &sig_act, NULL);
+
+       free(newbuf);
+       ms->flags |= MAGIC_COMPRESS;
+       DPRINTF("Zmagic returns %d\n", rv);
+       return rv;
+}
+#endif
+/*
+ * `safe' write for sockets and pipes.
+ */
+private ssize_t
+swrite(int fd, const void *buf, size_t n)
+{
+       ssize_t rv;
+       size_t rn = n;
+
+       do
+               switch (rv = write(fd, buf, n)) {
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+                       return -1;
+               default:
+                       n -= rv;
+                       buf = CAST(const char *, buf) + rv;
+                       break;
+               }
+       while (n > 0);
+       return rn;
+}
+
+
+/*
+ * `safe' read for sockets and pipes.
+ */
+protected ssize_t
+sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
+{
+       ssize_t rv;
+#ifdef FIONREAD
+       int t = 0;
+#endif
+       size_t rn = n;
+
+       if (fd == STDIN_FILENO)
+               goto nocheck;
+
+#ifdef FIONREAD
+       if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1 || t == 0)) {
+#ifdef FD_ZERO
+               ssize_t cnt;
+               for (cnt = 0;; cnt++) {
+                       fd_set check;
+                       struct timeval tout = {0, 100 * 1000};
+                       int selrv;
+
+                       FD_ZERO(&check);
+                       FD_SET(fd, &check);
+
+                       /*
+                        * Avoid soft deadlock: do not read if there
+                        * is nothing to read from sockets and pipes.
+                        */
+                       selrv = select(fd + 1, &check, NULL, NULL, &tout);
+                       if (selrv == -1) {
+                               if (errno == EINTR || errno == EAGAIN)
+                                       continue;
+                       } else if (selrv == 0 && cnt >= 5) {
+                               return 0;
+                       } else
+                               break;
+               }
+#endif
+               (void)ioctl(fd, FIONREAD, &t);
+       }
+
+       if (t > 0 && CAST(size_t, t) < n) {
+               n = t;
+               rn = n;
+       }
+#endif
+
+nocheck:
+       do
+               switch ((rv = read(fd, buf, n))) {
+               case -1:
+                       if (errno == EINTR)
+                               continue;
+                       return -1;
+               case 0:
+                       return rn - n;
+               default:
+                       n -= rv;
+                       buf = CAST(char *, CCAST(void *, buf)) + rv;
+                       break;
+               }
+       while (n > 0);
+       return rn;
+}
+
+protected int
+file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
+    size_t nbytes)
+{
+       char buf[4096];
+       ssize_t r;
+       int tfd;
+
+       (void)strlcpy(buf, "/tmp/file.XXXXXX", sizeof buf);
+#ifndef HAVE_MKSTEMP
+       {
+               char *ptr = mktemp(buf);
+               tfd = open(ptr, O_RDWR|O_TRUNC|O_EXCL|O_CREAT, 0600);
+               r = errno;
+               (void)unlink(ptr);
+               errno = r;
+       }
+#else
+       {
+               int te;
+               mode_t ou = umask(0);
+               tfd = mkstemp(buf);
+               (void)umask(ou);
+               te = errno;
+               (void)unlink(buf);
+               errno = te;
+       }
+#endif
+       if (tfd == -1) {
+               file_error(ms, errno,
+                   "cannot create temporary file for pipe copy");
+               return -1;
+       }
+
+       if (swrite(tfd, startbuf, nbytes) != CAST(ssize_t, nbytes))
+               r = 1;
+       else {
+               while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
+                       if (swrite(tfd, buf, CAST(size_t, r)) != r)
+                               break;
+       }
+
+       switch (r) {
+       case -1:
+               file_error(ms, errno, "error copying from pipe to temp file");
+               return -1;
+       case 0:
+               break;
+       default:
+               file_error(ms, errno, "error while writing to temp file");
+               return -1;
+       }
+
+       /*
+        * We duplicate the file descriptor, because fclose on a
+        * tmpfile will delete the file, but any open descriptors
+        * can still access the phantom inode.
+        */
+       if ((fd = dup2(tfd, fd)) == -1) {
+               file_error(ms, errno, "could not dup descriptor for temp file");
+               return -1;
+       }
+       (void)close(tfd);
+       if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) {
+               file_badseek(ms);
+               return -1;
+       }
+       return fd;
+}
+#if HAVE_FORK
+#ifdef BUILTIN_DECOMPRESS
+
+#define FHCRC          (1 << 1)
+#define FEXTRA         (1 << 2)
+#define FNAME          (1 << 3)
+#define FCOMMENT       (1 << 4)
+
+
+private int
+uncompressgzipped(const unsigned char *old, unsigned char **newch,
+    size_t bytes_max, size_t *n)
+{
+       unsigned char flg = old[3];
+       size_t data_start = 10;
+
+       if (flg & FEXTRA) {
+               if (data_start + 1 >= *n)
+                       goto err;
+               data_start += 2 + old[data_start] + old[data_start + 1] * 256;
+       }
+       if (flg & FNAME) {
+               while(data_start < *n && old[data_start])
+                       data_start++;
+               data_start++;
+       }
+       if (flg & FCOMMENT) {
+               while(data_start < *n && old[data_start])
+                       data_start++;
+               data_start++;
+       }
+       if (flg & FHCRC)
+               data_start += 2;
+
+       if (data_start >= *n)
+               goto err;
+
+       *n -= data_start;
+       old += data_start;
+       return uncompresszlib(old, newch, bytes_max, n, 0);
+err:
+       return makeerror(newch, n, "File too short");
+}
+
+private int
+uncompresszlib(const unsigned char *old, unsigned char **newch,
+    size_t bytes_max, size_t *n, int zlib)
+{
+       int rc;
+       z_stream z;
+
+       if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
+               return makeerror(newch, n, "No buffer, %s", strerror(errno));
+
+       z.next_in = CCAST(Bytef *, old);
+       z.avail_in = CAST(uint32_t, *n);
+       z.next_out = *newch;
+       z.avail_out = CAST(unsigned int, bytes_max);
+       z.zalloc = Z_NULL;
+       z.zfree = Z_NULL;
+       z.opaque = Z_NULL;
+
+       /* LINTED bug in header macro */
+       rc = zlib ? inflateInit(&z) : inflateInit2(&z, -15);
+       if (rc != Z_OK)
+               goto err;
+
+       rc = inflate(&z, Z_SYNC_FLUSH);
+       if (rc != Z_OK && rc != Z_STREAM_END)
+               goto err;
+
+       *n = CAST(size_t, z.total_out);
+       rc = inflateEnd(&z);
+       if (rc != Z_OK)
+               goto err;
+
+       /* let's keep the nul-terminate tradition */
+       (*newch)[*n] = '\0';
+
+       return OKDATA;
+err:
+       strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max);
+       *n = strlen(RCAST(char *, *newch));
+       return ERRDATA;
+}
+#endif
+
+static int
+makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
+{
+       char *msg;
+       va_list ap;
+       int rv;
+
+       va_start(ap, fmt);
+       rv = vasprintf(&msg, fmt, ap);
+       va_end(ap);
+       if (rv < 0) {
+               *buf = NULL;
+               *len = 0;
+               return NODATA;
+       }
+       *buf = RCAST(unsigned char *, msg);
+       *len = strlen(msg);
+       return ERRDATA;
+}
+
+static void
+closefd(int *fd, size_t i)
+{
+       if (fd[i] == -1)
+               return;
+       (void) close(fd[i]);
+       fd[i] = -1;
+}
+
+static void
+closep(int *fd)
+{
+       size_t i;
+       for (i = 0; i < 2; i++)
+               closefd(fd, i);
+}
+
+static int
+copydesc(int i, int fd)
+{
+       if (fd == i)
+               return 0; /* "no dup was necessary" */
+       if (dup2(fd, i) == -1) {
+               DPRINTF("dup(%d, %d) failed (%s)\n", fd, i, strerror(errno));
+               exit(1);
+       }
+       return 1;
+}
+
+static pid_t
+writechild(int fd, const void *old, size_t n)
+{
+       pid_t pid;
+
+       /*
+        * fork again, to avoid blocking because both
+        * pipes filled
+        */
+       pid = fork();
+       if (pid == -1) {
+               DPRINTF("Fork failed (%s)\n", strerror(errno));
+               exit(1);
+       }
+       if (pid == 0) {
+               /* child */
+               if (swrite(fd, old, n) != CAST(ssize_t, n)) {
+                       DPRINTF("Write failed (%s)\n", strerror(errno));
+                       exit(1);
+               }
+               exit(0);
+       }
+       /* parent */
+       return pid;
+}
+
+static ssize_t
+filter_error(unsigned char *ubuf, ssize_t n)
+{
+       char *p;
+       char *buf;
+
+       ubuf[n] = '\0';
+       buf = RCAST(char *, ubuf);
+       while (isspace(CAST(unsigned char, *buf)))
+               buf++;
+       DPRINTF("Filter error[[[%s]]]\n", buf);
+       if ((p = strchr(CAST(char *, buf), '\n')) != NULL)
+               *p = '\0';
+       if ((p = strchr(CAST(char *, buf), ';')) != NULL)
+               *p = '\0';
+       if ((p = strrchr(CAST(char *, buf), ':')) != NULL) {
+               ++p;
+               while (isspace(CAST(unsigned char, *p)))
+                       p++;
+               n = strlen(p);
+               memmove(ubuf, p, CAST(size_t, n + 1));
+       }
+       DPRINTF("Filter error after[[[%s]]]\n", (char *)ubuf);
+       if (islower(*ubuf))
+               *ubuf = toupper(*ubuf);
+       return n;
+}
+
+private const char *
+methodname(size_t method)
+{
+#ifdef BUILTIN_DECOMPRESS
+        /* FIXME: This doesn't cope with bzip2 */
+       if (method == 2 || compr[method].maglen == 0)
+           return "zlib";
+#endif
+       return compr[method].argv[0];
+}
+
+private int
+uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
+    unsigned char **newch, size_t* n)
+{
+       int fdp[3][2];
+       int status, rv, w;
+       pid_t pid;
+       pid_t writepid = -1;
+       size_t i;
+       ssize_t r;
+
+#ifdef BUILTIN_DECOMPRESS
+        /* FIXME: This doesn't cope with bzip2 */
+       if (method == 2)
+               return uncompressgzipped(old, newch, bytes_max, n);
+       if (compr[method].maglen == 0)
+               return uncompresszlib(old, newch, bytes_max, n, 1);
+#endif
+       (void)fflush(stdout);
+       (void)fflush(stderr);
+
+       for (i = 0; i < __arraycount(fdp); i++)
+               fdp[i][0] = fdp[i][1] = -1;
+
+       if ((fd == -1 && pipe(fdp[STDIN_FILENO]) == -1) ||
+           pipe(fdp[STDOUT_FILENO]) == -1 || pipe(fdp[STDERR_FILENO]) == -1) {
+               closep(fdp[STDIN_FILENO]);
+               closep(fdp[STDOUT_FILENO]);
+               return makeerror(newch, n, "Cannot create pipe, %s",
+                   strerror(errno));
+       }
+
+       /* For processes with large mapped virtual sizes, vfork
+        * may be _much_ faster (10-100 times) than fork.
+        */
+       pid = vfork();
+       if (pid == -1) {
+               return makeerror(newch, n, "Cannot vfork, %s",
+                   strerror(errno));
+       }
+       if (pid == 0) {
+               /* child */
+               /* Note: we are after vfork, do not modify memory
+                * in a way which confuses parent. In particular,
+                * do not modify fdp[i][j].
+                */
+               if (fd != -1) {
+                       (void) lseek(fd, CAST(off_t, 0), SEEK_SET);
+                       if (copydesc(STDIN_FILENO, fd))
+                               (void) close(fd);
+               } else {
+                       if (copydesc(STDIN_FILENO, fdp[STDIN_FILENO][0]))
+                               (void) close(fdp[STDIN_FILENO][0]);
+                       if (fdp[STDIN_FILENO][1] > 2)
+                               (void) close(fdp[STDIN_FILENO][1]);
+               }
+///FIXME: if one of the fdp[i][j] is 0 or 1, this can bomb spectacularly
+               if (copydesc(STDOUT_FILENO, fdp[STDOUT_FILENO][1]))
+                       (void) close(fdp[STDOUT_FILENO][1]);
+               if (fdp[STDOUT_FILENO][0] > 2)
+                       (void) close(fdp[STDOUT_FILENO][0]);
+
+               if (copydesc(STDERR_FILENO, fdp[STDERR_FILENO][1]))
+                       (void) close(fdp[STDERR_FILENO][1]);
+               if (fdp[STDERR_FILENO][0] > 2)
+                       (void) close(fdp[STDERR_FILENO][0]);
+
+               (void)execvp(compr[method].argv[0],
+                   RCAST(char *const *, RCAST(intptr_t, compr[method].argv)));
+               dprintf(STDERR_FILENO, "exec `%s' failed, %s",
+                   compr[method].argv[0], strerror(errno));
+               _exit(1); /* _exit(), not exit(), because of vfork */
+       }
+       /* parent */
+       /* Close write sides of child stdout/err pipes */
+       for (i = 1; i < __arraycount(fdp); i++)
+               closefd(fdp[i], 1);
+       /* Write the buffer data to child stdin, if we don't have fd */
+       if (fd == -1) {
+               closefd(fdp[STDIN_FILENO], 0);
+               writepid = writechild(fdp[STDIN_FILENO][1], old, *n);
+               closefd(fdp[STDIN_FILENO], 1);
+       }
+
+       *newch = CAST(unsigned char *, malloc(bytes_max + 1));
+       if (*newch == NULL) {
+               rv = makeerror(newch, n, "No buffer, %s",
+                   strerror(errno));
+               goto err;
+       }
+       rv = OKDATA;
+       r = sread(fdp[STDOUT_FILENO][0], *newch, bytes_max, 0);
+       if (r <= 0) {
+               DPRINTF("Read stdout failed %d (%s)\n", fdp[STDOUT_FILENO][0],
+                   r != -1 ? strerror(errno) : "no data");
+
+               rv = ERRDATA;
+               if (r == 0 &&
+                   (r = sread(fdp[STDERR_FILENO][0], *newch, bytes_max, 0)) > 0)
+               {
+                       r = filter_error(*newch, r);
+                       goto ok;
+               }
+               free(*newch);
+               if  (r == 0)
+                       rv = makeerror(newch, n, "Read failed, %s",
+                           strerror(errno));
+               else
+                       rv = makeerror(newch, n, "No data");
+               goto err;
+       }
+ok:
+       *n = r;
+       /* NUL terminate, as every buffer is handled here. */
+       (*newch)[*n] = '\0';
+err:
+       closefd(fdp[STDIN_FILENO], 1);
+       closefd(fdp[STDOUT_FILENO], 0);
+       closefd(fdp[STDERR_FILENO], 0);
+
+       w = waitpid(pid, &status, 0);
+wait_err:
+       if (w == -1) {
+               free(*newch);
+               rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
+               DPRINTF("Child wait return %#x\n", status);
+       } else if (!WIFEXITED(status)) {
+               DPRINTF("Child not exited (%#x)\n", status);
+       } else if (WEXITSTATUS(status) != 0) {
+               DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status));
+       }
+       if (writepid > 0) {
+               /* _After_ we know decompressor has exited, our input writer
+                * definitely will exit now (at worst, writing fails in it,
+                * since output fd is closed now on the reading size).
+                */
+               w = waitpid(writepid, &status, 0);
+               writepid = -1;
+               goto wait_err;
+       }
+
+       closefd(fdp[STDIN_FILENO], 0); //why? it is already closed here!
+       DPRINTF("Returning %p n=%" SIZE_T_FORMAT "u rv=%d\n", *newch, *n, rv);
+
+       return rv;
+}
+#endif
diff --git a/src/ctime_r.c b/src/ctime_r.c
new file mode 100644 (file)
index 0000000..eff9f07
--- /dev/null
@@ -0,0 +1,19 @@
+/*     $File$  */
+
+#include "file.h"
+#ifndef        lint
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.84 2011/12/08 12:38:24 rrt Exp $")
+#endif /* lint */
+#include <time.h>
+#include <string.h>
+
+/* ctime_r is not thread-safe anyway */
+char *
+ctime_r(const time_t *t, char *dst)
+{
+       char *p = ctime(t);
+       if (p == NULL)
+               return NULL;
+       memcpy(dst, p, 26);
+       return dst;
+}
diff --git a/src/der.c b/src/der.c
new file mode 100644 (file)
index 0000000..8867c56
--- /dev/null
+++ b/src/der.c
@@ -0,0 +1,409 @@
+/*-
+ * Copyright (c) 2016 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * DER (Distinguished Encoding Rules) Parser
+ *
+ * Sources:
+ * https://en.wikipedia.org/wiki/X.690
+ * http://fm4dd.com/openssl/certexamples.htm
+ * http://blog.engelke.com/2014/10/17/parsing-ber-and-der-encoded-asn-1-objects/
+ */
+#ifndef TEST_DER
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
+#endif
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef TEST_DER
+#include "magic.h"
+#include "der.h"
+#else
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <err.h>
+#endif
+
+#define DER_BAD        CAST(uint32_t, -1)
+
+#define DER_CLASS_UNIVERSAL    0
+#define        DER_CLASS_APPLICATION   1
+#define        DER_CLASS_CONTEXT       2
+#define        DER_CLASS_PRIVATE       3
+#ifdef DEBUG_DER
+static const char der_class[] = "UACP";
+#endif
+
+#define DER_TYPE_PRIMITIVE     0
+#define DER_TYPE_CONSTRUCTED   1
+#ifdef DEBUG_DER
+static const char der_type[] = "PC";
+#endif
+
+#define        DER_TAG_EOC                     0x00
+#define        DER_TAG_BOOLEAN                 0x01
+#define        DER_TAG_INTEGER                 0x02
+#define        DER_TAG_BIT STRING              0x03
+#define        DER_TAG_OCTET_STRING            0x04
+#define        DER_TAG_NULL                    0x05
+#define        DER_TAG_OBJECT_IDENTIFIER       0x06
+#define        DER_TAG_OBJECT_DESCRIPTOR       0x07
+#define        DER_TAG_EXTERNAL                0x08
+#define        DER_TAG_REAL                    0x09
+#define        DER_TAG_ENUMERATED              0x0a
+#define        DER_TAG_EMBEDDED_PDV            0x0b
+#define        DER_TAG_UTF8_STRING             0x0c
+#define        DER_TAG_RELATIVE_OID            0x0d
+#define DER_TAG_RESERVED_1             0x0e
+#define DER_TAG_RESERVED_2             0x0f
+#define        DER_TAG_SEQUENCE                0x10
+#define        DER_TAG_SET                     0x11
+#define        DER_TAG_NUMERIC_STRING          0x12
+#define        DER_TAG_PRINTABLE_STRING        0x13
+#define        DER_TAG_T61_STRING              0x14
+#define        DER_TAG_VIDEOTEX_STRING         0x15
+#define        DER_TAG_IA5_STRING              0x16
+#define        DER_TAG_UTCTIME                 0x17
+#define        DER_TAG_GENERALIZED_TIME        0x18
+#define        DER_TAG_GRAPHIC_STRING          0x19
+#define        DER_TAG_VISIBLE_STRING          0x1a
+#define        DER_TAG_GENERAL_STRING          0x1b
+#define        DER_TAG_UNIVERSAL_STRING        0x1c
+#define        DER_TAG_CHARACTER_STRING        0x1d
+#define        DER_TAG_BMP_STRING              0x1e
+#define        DER_TAG_LONG                    0x1f
+
+static const char *der__tag[] = {
+       "eoc", "bool", "int", "bit_str", "octet_str",
+       "null", "obj_id", "obj_desc", "ext", "real",
+       "enum", "embed", "utf8_str", "oid", "res1",
+       "res2", "seq", "set", "num_str", "prt_str",
+       "t61_str", "vid_str", "ia5_str", "utc_time",
+       "gen_time", "gr_str", "vis_str", "gen_str",
+       "char_str", "bmp_str", "long"
+};
+
+#ifdef DEBUG_DER
+#define DPRINTF(a) printf a
+#else
+#define DPRINTF(a)
+#endif
+
+#ifdef TEST_DER
+static uint8_t
+getclass(uint8_t c)
+{
+       return c >> 6;
+}
+
+static uint8_t
+gettype(uint8_t c)
+{
+       return (c >> 5) & 1;
+}
+#endif
+
+static uint32_t
+gettag(const uint8_t *c, size_t *p, size_t l)
+{
+       uint32_t tag;
+
+       if (*p >= l)
+               return DER_BAD;
+
+       tag = c[(*p)++] & 0x1f;
+
+       if (tag != 0x1f)
+               return tag;
+
+       if (*p >= l)
+               return DER_BAD;
+
+       while (c[*p] >= 0x80) {
+               tag = tag * 128 + c[(*p)++] - 0x80;
+               if (*p >= l)
+                       return DER_BAD;
+       }
+       return tag;
+}
+
+/*
+ * Read the length of a DER tag from the input.
+ *
+ * `c` is the input, `p` is an output parameter that specifies how much of the
+ * input we consumed, and `l` is the maximum input length.
+ *
+ * Returns the length, or DER_BAD if the end of the input is reached or the
+ * length exceeds the remaining input.
+ */
+static uint32_t
+getlength(const uint8_t *c, size_t *p, size_t l)
+{
+       uint8_t digits, i;
+       size_t len;
+       int is_onebyte_result;
+
+       if (*p >= l)
+               return DER_BAD;
+
+       /*
+        * Digits can either be 0b0 followed by the result, or 0b1
+        * followed by the number of digits of the result. In either case,
+        * we verify that we can read so many bytes from the input.
+        */
+       is_onebyte_result = (c[*p] & 0x80) == 0;
+       digits = c[(*p)++] & 0x7f;
+       if (*p + digits >= l)
+               return DER_BAD;
+
+       if (is_onebyte_result)
+               return digits;
+
+       /*
+        * Decode len. We've already verified that we're allowed to read
+        * `digits` bytes.
+        */
+       len = 0;
+       for (i = 0; i < digits; i++)
+               len = (len << 8) | c[(*p)++];
+
+       if (len > UINT32_MAX - *p || *p + len >= l)
+               return DER_BAD;
+       return CAST(uint32_t, len);
+}
+
+static const char *
+der_tag(char *buf, size_t len, uint32_t tag)
+{
+       if (tag < DER_TAG_LONG)
+               strlcpy(buf, der__tag[tag], len);
+       else
+               snprintf(buf, len, "%#x", tag);
+       return buf;
+}
+
+#ifndef TEST_DER
+static int
+der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
+{
+       const uint8_t *d = CAST(const uint8_t *, q);
+       switch (tag) {
+       case DER_TAG_PRINTABLE_STRING:
+       case DER_TAG_UTF8_STRING:
+       case DER_TAG_IA5_STRING:
+       case DER_TAG_UTCTIME:
+               return snprintf(buf, blen, "%.*s", len, RCAST(const char *, q));
+       default:
+               break;
+       }
+
+       for (uint32_t i = 0; i < len; i++) {
+               uint32_t z = i << 1;
+               if (z < blen - 2)
+                       snprintf(buf + z, blen - z, "%.2x", d[i]);
+       }
+       return len * 2;
+}
+
+int32_t
+der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
+{
+       const uint8_t *b = RCAST(const uint8_t *, ms->search.s);
+       size_t offs = 0, len = ms->search.s_len ? ms->search.s_len : nbytes;
+
+       if (gettag(b, &offs, len) == DER_BAD)
+               return -1;
+       DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
+           offs, m->offset));
+
+       uint32_t tlen = getlength(b, &offs, len);
+       if (tlen == DER_BAD)
+               return -1;
+       DPRINTF(("%s2: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
+           offs, tlen));
+
+       offs += ms->offset + m->offset;
+       DPRINTF(("cont_level = %d\n", m->cont_level));
+#ifdef DEBUG_DER
+       for (size_t i = 0; i < m->cont_level; i++)
+               printf("cont_level[%" SIZE_T_FORMAT "u] = %u\n", i,
+                   ms->c.li[i].off);
+#endif
+       if (m->cont_level != 0) {
+               if (offs + tlen > nbytes)
+                       return -1;
+               ms->c.li[m->cont_level - 1].off = CAST(int, offs + tlen);
+               DPRINTF(("cont_level[%u] = %u\n", m->cont_level - 1,
+                   ms->c.li[m->cont_level - 1].off));
+       }
+       return CAST(int32_t, offs);
+}
+
+int
+der_cmp(struct magic_set *ms, struct magic *m)
+{
+       const uint8_t *b = RCAST(const uint8_t *, ms->search.s);
+       const char *s = m->value.s;
+       size_t offs = 0, len = ms->search.s_len;
+       uint32_t tag, tlen;
+       char buf[128];
+
+       tag = gettag(b, &offs, len);
+       if (tag == DER_BAD)
+               return -1;
+
+       tlen = getlength(b, &offs, len);
+       if (tlen == DER_BAD)
+               return -1;
+
+       der_tag(buf, sizeof(buf), tag);
+       if ((ms->flags & MAGIC_DEBUG) != 0)
+               fprintf(stderr, "%s: tag %p got=%s exp=%s\n", __func__, b,
+                   buf, s);
+       size_t slen = strlen(buf);
+
+       if (strncmp(buf, s, slen) != 0)
+               return 0;
+
+       s += slen;
+
+again:
+       switch (*s) {
+       case '\0':
+               return 1;
+       case '=':
+               s++;
+               goto val;
+       default:
+               if (!isdigit(CAST(unsigned char, *s)))
+                       return 0;
+
+               slen = 0;
+               do
+                       slen = slen * 10 + *s - '0';
+               while (isdigit(CAST(unsigned char, *++s)));
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       fprintf(stderr, "%s: len %" SIZE_T_FORMAT "u %u\n",
+                           __func__, slen, tlen);
+               if (tlen != slen)
+                       return 0;
+               goto again;
+       }
+val:
+       DPRINTF(("%s: before data %" SIZE_T_FORMAT "u %u\n", __func__, offs,
+           tlen));
+       der_data(buf, sizeof(buf), tag, b + offs, tlen);
+       if ((ms->flags & MAGIC_DEBUG) != 0)
+               fprintf(stderr, "%s: data %s %s\n", __func__, buf, s);
+       if (strcmp(buf, s) != 0 && strcmp("x", s) != 0)
+               return 0;
+       strlcpy(ms->ms_value.s, buf, sizeof(ms->ms_value.s));
+       return 1;
+}
+#endif
+
+#ifdef TEST_DER
+static void
+printtag(uint32_t tag, const void *q, uint32_t len)
+{
+       const uint8_t *d = q;
+       switch (tag) {
+       case DER_TAG_PRINTABLE_STRING:
+       case DER_TAG_UTF8_STRING:
+               printf("%.*s\n", len, (const char *)q);
+               return;
+       default:
+               break;
+       }
+
+       for (uint32_t i = 0; i < len; i++)
+               printf("%.2x", d[i]);
+       printf("\n");
+}
+
+static void
+printdata(size_t level, const void *v, size_t x, size_t l)
+{
+       const uint8_t *p = v, *ep = p + l;
+       size_t ox;
+       char buf[128];
+
+       while (p + x < ep) {
+               const uint8_t *q;
+               uint8_t c = getclass(p[x]);
+               uint8_t t = gettype(p[x]);
+               ox = x;
+               if (x != 0)
+               printf("%.2x %.2x %.2x\n", p[x - 1], p[x], p[x + 1]);
+               uint32_t tag = gettag(p, &x, ep - p + x);
+               if (p + x >= ep)
+                       break;
+               uint32_t len = getlength(p, &x, ep - p + x);
+
+               printf("%" SIZE_T_FORMAT "u %" SIZE_T_FORMAT "u-%"
+                   SIZE_T_FORMAT "u %c,%c,%s,%u:", level, ox, x,
+                   der_class[c], der_type[t],
+                   der_tag(buf, sizeof(buf), tag), len);
+               q = p + x;
+               if (p + len > ep)
+                       errx(EXIT_FAILURE, "corrupt der");
+               printtag(tag, q, len);
+               if (t != DER_TYPE_PRIMITIVE)
+                       printdata(level + 1, p, x, len + x);
+               x += len;
+       }
+}
+
+int
+main(int argc, char *argv[])
+{
+       int fd;
+       struct stat st;
+       size_t l;
+       void *p;
+
+       if ((fd = open(argv[1], O_RDONLY)) == -1)
+               err(EXIT_FAILURE, "open `%s'", argv[1]);
+       if (fstat(fd, &st) == -1)
+               err(EXIT_FAILURE, "stat `%s'", argv[1]);
+       l = (size_t)st.st_size;
+       if ((p = mmap(NULL, l, PROT_READ, MAP_FILE, fd, 0)) == MAP_FAILED)
+               err(EXIT_FAILURE, "mmap `%s'", argv[1]);
+
+       printdata(0, p, 0, l);
+       munmap(p, l);
+       return 0;
+}
+#endif
diff --git a/src/der.h b/src/der.h
new file mode 100644 (file)
index 0000000..3333239
--- /dev/null
+++ b/src/der.h
@@ -0,0 +1,28 @@
+/*-
+ * Copyright (c) 2016 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+extern int der_offs(struct magic_set *, struct magic *, size_t);
+extern int der_cmp(struct magic_set *, struct magic *);
diff --git a/src/dprintf.c b/src/dprintf.c
new file mode 100644 (file)
index 0000000..027a64f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: dprintf.c,v 1.2 2018/09/09 20:33:28 christos Exp $")
+#endif /* lint */
+
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+int
+dprintf(int fd, const char *fmt, ...)
+{
+       va_list ap;
+       /* Simpler than using vasprintf() here, since we never need more */
+       char buf[1024];
+       int len;
+
+       va_start(ap, fmt);
+       len = vsnprintf(buf, sizeof(buf), fmt, ap);
+       va_end(ap);
+
+       if ((size_t)len >= sizeof(buf))
+               return -1;
+
+       if (write(fd, buf, (size_t)len) != len)
+               return -1;
+
+       return len;
+}
diff --git a/src/elfclass.h b/src/elfclass.h
new file mode 100644 (file)
index 0000000..936d8dc
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) Christos Zoulas 2008.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+       if (nbytes <= sizeof(elfhdr))
+               return 0;
+
+       u.l = 1;
+       (void)memcpy(&elfhdr, buf, sizeof elfhdr);
+       swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
+
+       type = elf_getu16(swap, elfhdr.e_type);
+       notecount = ms->elf_notes_max;
+       switch (type) {
+#ifdef ELFCORE
+       case ET_CORE:
+               phnum = elf_getu16(swap, elfhdr.e_phnum);
+               if (phnum > ms->elf_phnum_max)
+                       return toomany(ms, "program headers", phnum);
+               flags |= FLAGS_IS_CORE;
+               if (dophn_core(ms, clazz, swap, fd,
+                   CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
+                   CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
+                   fsize, &flags, &notecount) == -1)
+                       return -1;
+               break;
+#endif
+       case ET_EXEC:
+       case ET_DYN:
+               phnum = elf_getu16(swap, elfhdr.e_phnum);
+               if (phnum > ms->elf_phnum_max)
+                       return toomany(ms, "program", phnum);
+               shnum = elf_getu16(swap, elfhdr.e_shnum);
+               if (shnum > ms->elf_shnum_max)
+                       return toomany(ms, "section", shnum);
+               if (dophn_exec(ms, clazz, swap, fd,
+                   CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
+                   CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
+                   fsize, shnum, &flags, &notecount) == -1)
+                       return -1;
+               /*FALLTHROUGH*/
+       case ET_REL:
+               shnum = elf_getu16(swap, elfhdr.e_shnum);
+               if (shnum > ms->elf_shnum_max)
+                       return toomany(ms, "section headers", shnum);
+               if (doshn(ms, clazz, swap, fd,
+                   CAST(off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
+                   CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)),
+                   fsize, elf_getu16(swap, elfhdr.e_machine),
+                   CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)),
+                   &flags, &notecount) == -1)
+                       return -1;
+               break;
+
+       default:
+               break;
+       }
+       if (notecount == 0)
+               return toomany(ms, "notes", ms->elf_notes_max);
+       return 1;
diff --git a/src/encoding.c b/src/encoding.c
new file mode 100644 (file)
index 0000000..76244f8
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Encoding -- determine the character encoding of a text file.
+ *
+ * Joerg Wunsch <joerg@freebsd.org> wrote the original support for 8-bit
+ * international characters.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: encoding.c,v 1.20 2019/04/15 16:48:41 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+
+private int looks_ascii(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *,
+    size_t *);
+private int looks_utf7(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_ucs32(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_extended(const unsigned char *, size_t, unichar *, size_t *);
+private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
+
+#ifdef DEBUG_ENCODING
+#define DPRINTF(a) printf a
+#else
+#define DPRINTF(a)
+#endif
+
+/*
+ * Try to determine whether text is in some character code we can
+ * identify.  Each of these tests, if it succeeds, will leave
+ * the text converted into one-unichar-per-character Unicode in
+ * ubuf, and the number of characters converted in ulen.
+ */
+protected int
+file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
+    size_t *ulen, const char **code, const char **code_mime, const char **type)
+{
+       const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
+       size_t nbytes = b->flen;
+       size_t mlen;
+       int rv = 1, ucs_type;
+       unsigned char *nbuf = NULL;
+       unichar *udefbuf;
+       size_t udeflen;
+
+       if (ubuf == NULL)
+               ubuf = &udefbuf;
+       if (ulen == NULL)
+               ulen = &udeflen;
+
+       *type = "text";
+       *ulen = 0;
+       *code = "unknown";
+       *code_mime = "binary";
+
+       mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
+       if ((*ubuf = CAST(unichar *, calloc(CAST(size_t, 1), mlen))) == NULL) {
+               file_oomem(ms, mlen);
+               goto done;
+       }
+       mlen = (nbytes + 1) * sizeof(nbuf[0]);
+       if ((nbuf = CAST(unsigned char *,
+           calloc(CAST(size_t, 1), mlen))) == NULL) {
+               file_oomem(ms, mlen);
+               goto done;
+       }
+
+       if (looks_ascii(buf, nbytes, *ubuf, ulen)) {
+               if (looks_utf7(buf, nbytes, *ubuf, ulen) > 0) {
+                       DPRINTF(("utf-7 %" SIZE_T_FORMAT "u\n", *ulen));
+                       *code = "UTF-7 Unicode";
+                       *code_mime = "utf-7";
+               } else {
+                       DPRINTF(("ascii %" SIZE_T_FORMAT "u\n", *ulen));
+                       *code = "ASCII";
+                       *code_mime = "us-ascii";
+               }
+       } else if (looks_utf8_with_BOM(buf, nbytes, *ubuf, ulen) > 0) {
+               DPRINTF(("utf8/bom %" SIZE_T_FORMAT "u\n", *ulen));
+               *code = "UTF-8 Unicode (with BOM)";
+               *code_mime = "utf-8";
+       } else if (file_looks_utf8(buf, nbytes, *ubuf, ulen) > 1) {
+               DPRINTF(("utf8 %" SIZE_T_FORMAT "u\n", *ulen));
+               *code = "UTF-8 Unicode";
+               *code_mime = "utf-8";
+       } else if ((ucs_type = looks_ucs32(buf, nbytes, *ubuf, ulen)) != 0) {
+               if (ucs_type == 1) {
+                       *code = "Little-endian UTF-32 Unicode";
+                       *code_mime = "utf-32le";
+               } else {
+                       *code = "Big-endian UTF-32 Unicode";
+                       *code_mime = "utf-32be";
+               }
+               DPRINTF(("ucs32 %" SIZE_T_FORMAT "u\n", *ulen));
+       } else if ((ucs_type = looks_ucs16(buf, nbytes, *ubuf, ulen)) != 0) {
+               if (ucs_type == 1) {
+                       *code = "Little-endian UTF-16 Unicode";
+                       *code_mime = "utf-16le";
+               } else {
+                       *code = "Big-endian UTF-16 Unicode";
+                       *code_mime = "utf-16be";
+               }
+               DPRINTF(("ucs16 %" SIZE_T_FORMAT "u\n", *ulen));
+       } else if (looks_latin1(buf, nbytes, *ubuf, ulen)) {
+               DPRINTF(("latin1 %" SIZE_T_FORMAT "u\n", *ulen));
+               *code = "ISO-8859";
+               *code_mime = "iso-8859-1";
+       } else if (looks_extended(buf, nbytes, *ubuf, ulen)) {
+               DPRINTF(("extended %" SIZE_T_FORMAT "u\n", *ulen));
+               *code = "Non-ISO extended-ASCII";
+               *code_mime = "unknown-8bit";
+       } else {
+               from_ebcdic(buf, nbytes, nbuf);
+
+               if (looks_ascii(nbuf, nbytes, *ubuf, ulen)) {
+                       DPRINTF(("ebcdic %" SIZE_T_FORMAT "u\n", *ulen));
+                       *code = "EBCDIC";
+                       *code_mime = "ebcdic";
+               } else if (looks_latin1(nbuf, nbytes, *ubuf, ulen)) {
+                       DPRINTF(("ebcdic/international %" SIZE_T_FORMAT "u\n",
+                           *ulen));
+                       *code = "International EBCDIC";
+                       *code_mime = "ebcdic";
+               } else { /* Doesn't look like text at all */
+                       DPRINTF(("binary\n"));
+                       rv = 0;
+                       *type = "binary";
+               }
+       }
+
+ done:
+       free(nbuf);
+       if (ubuf == &udefbuf)
+               free(udefbuf);
+
+       return rv;
+}
+
+/*
+ * This table reflects a particular philosophy about what constitutes
+ * "text," and there is room for disagreement about it.
+ *
+ * Version 3.31 of the file command considered a file to be ASCII if
+ * each of its characters was approved by either the isascii() or
+ * isalpha() function.  On most systems, this would mean that any
+ * file consisting only of characters in the range 0x00 ... 0x7F
+ * would be called ASCII text, but many systems might reasonably
+ * consider some characters outside this range to be alphabetic,
+ * so the file command would call such characters ASCII.  It might
+ * have been more accurate to call this "considered textual on the
+ * local system" than "ASCII."
+ *
+ * It considered a file to be "International language text" if each
+ * of its characters was either an ASCII printing character (according
+ * to the real ASCII standard, not the above test), a character in
+ * the range 0x80 ... 0xFF, or one of the following control characters:
+ * backspace, tab, line feed, vertical tab, form feed, carriage return,
+ * escape.  No attempt was made to determine the language in which files
+ * of this type were written.
+ *
+ *
+ * The table below considers a file to be ASCII if all of its characters
+ * are either ASCII printing characters (again, according to the X3.4
+ * standard, not isascii()) or any of the following controls: bell,
+ * backspace, tab, line feed, form feed, carriage return, esc, nextline.
+ *
+ * I include bell because some programs (particularly shell scripts)
+ * use it literally, even though it is rare in normal text.  I exclude
+ * vertical tab because it never seems to be used in real text.  I also
+ * include, with hesitation, the X3.64/ECMA-43 control nextline (0x85),
+ * because that's what the dd EBCDIC->ASCII table maps the EBCDIC newline
+ * character to.  It might be more appropriate to include it in the 8859
+ * set instead of the ASCII set, but it's got to be included in *something*
+ * we recognize or EBCDIC files aren't going to be considered textual.
+ * Some old Unix source files use SO/SI (^N/^O) to shift between Greek
+ * and Latin characters, so these should possibly be allowed.  But they
+ * make a real mess on VT100-style displays if they're not paired properly,
+ * so we are probably better off not calling them text.
+ *
+ * A file is considered to be ISO-8859 text if its characters are all
+ * either ASCII, according to the above definition, or printing characters
+ * from the ISO-8859 8-bit extension, characters 0xA0 ... 0xFF.
+ *
+ * Finally, a file is considered to be international text from some other
+ * character code if its characters are all either ISO-8859 (according to
+ * the above definition) or characters in the range 0x80 ... 0x9F, which
+ * ISO-8859 considers to be control characters but the IBM PC and Macintosh
+ * consider to be printing characters.
+ */
+
+#define F 0   /* character never appears in text */
+#define T 1   /* character appears in plain ASCII text */
+#define I 2   /* character appears in ISO-8859 text */
+#define X 3   /* character appears in non-ISO extended ASCII (Mac, IBM PC) */
+
+private char text_chars[256] = {
+       /*                  BEL BS HT LF VT FF CR    */
+       F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F,  /* 0x0X */
+       /*                              ESC          */
+       F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F,  /* 0x1X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x2X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x3X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x4X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x5X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,  /* 0x6X */
+       T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F,  /* 0x7X */
+       /*            NEL                            */
+       X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X,  /* 0x8X */
+       X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,  /* 0x9X */
+       I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,  /* 0xaX */
+       I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,  /* 0xbX */
+       I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,  /* 0xcX */
+       I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,  /* 0xdX */
+       I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,  /* 0xeX */
+       I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I   /* 0xfX */
+};
+
+private int
+looks_ascii(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+    size_t *ulen)
+{
+       size_t i;
+
+       *ulen = 0;
+
+       for (i = 0; i < nbytes; i++) {
+               int t = text_chars[buf[i]];
+
+               if (t != T)
+                       return 0;
+
+               ubuf[(*ulen)++] = buf[i];
+       }
+
+       return 1;
+}
+
+private int
+looks_latin1(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
+{
+       size_t i;
+
+       *ulen = 0;
+
+       for (i = 0; i < nbytes; i++) {
+               int t = text_chars[buf[i]];
+
+               if (t != T && t != I)
+                       return 0;
+
+               ubuf[(*ulen)++] = buf[i];
+       }
+
+       return 1;
+}
+
+private int
+looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+    size_t *ulen)
+{
+       size_t i;
+
+       *ulen = 0;
+
+       for (i = 0; i < nbytes; i++) {
+               int t = text_chars[buf[i]];
+
+               if (t != T && t != I && t != X)
+                       return 0;
+
+               ubuf[(*ulen)++] = buf[i];
+       }
+
+       return 1;
+}
+
+/*
+ * Decide whether some text looks like UTF-8. Returns:
+ *
+ *     -1: invalid UTF-8
+ *      0: uses odd control characters, so doesn't look like text
+ *      1: 7-bit text
+ *      2: definitely UTF-8 text (valid high-bit set bytes)
+ *
+ * If ubuf is non-NULL on entry, text is decoded into ubuf, *ulen;
+ * ubuf must be big enough!
+ */
+protected int
+file_looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
+{
+       size_t i;
+       int n;
+       unichar c;
+       int gotone = 0, ctrl = 0;
+
+       if (ubuf)
+               *ulen = 0;
+
+       for (i = 0; i < nbytes; i++) {
+               if ((buf[i] & 0x80) == 0) {        /* 0xxxxxxx is plain ASCII */
+                       /*
+                        * Even if the whole file is valid UTF-8 sequences,
+                        * still reject it if it uses weird control characters.
+                        */
+
+                       if (text_chars[buf[i]] != T)
+                               ctrl = 1;
+
+                       if (ubuf)
+                               ubuf[(*ulen)++] = buf[i];
+               } else if ((buf[i] & 0x40) == 0) { /* 10xxxxxx never 1st byte */
+                       return -1;
+               } else {                           /* 11xxxxxx begins UTF-8 */
+                       int following;
+
+                       if ((buf[i] & 0x20) == 0) {             /* 110xxxxx */
+                               c = buf[i] & 0x1f;
+                               following = 1;
+                       } else if ((buf[i] & 0x10) == 0) {      /* 1110xxxx */
+                               c = buf[i] & 0x0f;
+                               following = 2;
+                       } else if ((buf[i] & 0x08) == 0) {      /* 11110xxx */
+                               c = buf[i] & 0x07;
+                               following = 3;
+                       } else if ((buf[i] & 0x04) == 0) {      /* 111110xx */
+                               c = buf[i] & 0x03;
+                               following = 4;
+                       } else if ((buf[i] & 0x02) == 0) {      /* 1111110x */
+                               c = buf[i] & 0x01;
+                               following = 5;
+                       } else
+                               return -1;
+
+                       for (n = 0; n < following; n++) {
+                               i++;
+                               if (i >= nbytes)
+                                       goto done;
+
+                               if ((buf[i] & 0x80) == 0 || (buf[i] & 0x40))
+                                       return -1;
+
+                               c = (c << 6) + (buf[i] & 0x3f);
+                       }
+
+                       if (ubuf)
+                               ubuf[(*ulen)++] = c;
+                       gotone = 1;
+               }
+       }
+done:
+       return ctrl ? 0 : (gotone ? 2 : 1);
+}
+
+/*
+ * Decide whether some text looks like UTF-8 with BOM. If there is no
+ * BOM, return -1; otherwise return the result of looks_utf8 on the
+ * rest of the text.
+ */
+private int
+looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+    size_t *ulen)
+{
+       if (nbytes > 3 && buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
+               return file_looks_utf8(buf + 3, nbytes - 3, ubuf, ulen);
+       else
+               return -1;
+}
+
+private int
+looks_utf7(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
+{
+       if (nbytes > 4 && buf[0] == '+' && buf[1] == '/' && buf[2] == 'v')
+               switch (buf[3]) {
+               case '8':
+               case '9':
+               case '+':
+               case '/':
+                       if (ubuf)
+                               *ulen = 0;
+                       return 1;
+               default:
+                       return -1;
+               }
+       else
+               return -1;
+}
+
+private int
+looks_ucs16(const unsigned char *bf, size_t nbytes, unichar *ubf,
+    size_t *ulen)
+{
+       int bigend;
+       size_t i;
+
+       if (nbytes < 2)
+               return 0;
+
+       if (bf[0] == 0xff && bf[1] == 0xfe)
+               bigend = 0;
+       else if (bf[0] == 0xfe && bf[1] == 0xff)
+               bigend = 1;
+       else
+               return 0;
+
+       *ulen = 0;
+
+       for (i = 2; i + 1 < nbytes; i += 2) {
+               /* XXX fix to properly handle chars > 65536 */
+
+               if (bigend)
+                       ubf[(*ulen)++] = bf[i + 1]
+                           | (CAST(unichar, bf[i]) << 8);
+               else
+                       ubf[(*ulen)++] = bf[i]
+                           | (CAST(unichar, bf[i + 1]) << 8);
+
+               if (ubf[*ulen - 1] == 0xfffe)
+                       return 0;
+               if (ubf[*ulen - 1] < 128 &&
+                   text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
+                       return 0;
+       }
+
+       return 1 + bigend;
+}
+
+private int
+looks_ucs32(const unsigned char *bf, size_t nbytes, unichar *ubf,
+    size_t *ulen)
+{
+       int bigend;
+       size_t i;
+
+       if (nbytes < 4)
+               return 0;
+
+       if (bf[0] == 0xff && bf[1] == 0xfe && bf[2] == 0 && bf[3] == 0)
+               bigend = 0;
+       else if (bf[0] == 0 && bf[1] == 0 && bf[2] == 0xfe && bf[3] == 0xff)
+               bigend = 1;
+       else
+               return 0;
+
+       *ulen = 0;
+
+       for (i = 4; i + 3 < nbytes; i += 4) {
+               /* XXX fix to properly handle chars > 65536 */
+
+               if (bigend)
+                       ubf[(*ulen)++] = CAST(unichar, bf[i + 3])
+                           | (CAST(unichar, bf[i + 2]) << 8)
+                           | (CAST(unichar, bf[i + 1]) << 16)
+                           | (CAST(unichar, bf[i]) << 24);
+               else
+                       ubf[(*ulen)++] = CAST(unichar, bf[i + 0])
+                           | (CAST(unichar, bf[i + 1]) << 8) 
+                           | (CAST(unichar, bf[i + 2]) << 16)
+                           | (CAST(unichar, bf[i + 3]) << 24);
+
+               if (ubf[*ulen - 1] == 0xfffe)
+                       return 0;
+               if (ubf[*ulen - 1] < 128 &&
+                   text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
+                       return 0;
+       }
+
+       return 1 + bigend;
+}
+#undef F
+#undef T
+#undef I
+#undef X
+
+/*
+ * This table maps each EBCDIC character to an (8-bit extended) ASCII
+ * character, as specified in the rationale for the dd(1) command in
+ * draft 11.2 (September, 1991) of the POSIX P1003.2 standard.
+ *
+ * Unfortunately it does not seem to correspond exactly to any of the
+ * five variants of EBCDIC documented in IBM's _Enterprise Systems
+ * Architecture/390: Principles of Operation_, SA22-7201-06, Seventh
+ * Edition, July, 1999, pp. I-1 - I-4.
+ *
+ * Fortunately, though, all versions of EBCDIC, including this one, agree
+ * on most of the printing characters that also appear in (7-bit) ASCII.
+ * Of these, only '|', '!', '~', '^', '[', and ']' are in question at all.
+ *
+ * Fortunately too, there is general agreement that codes 0x00 through
+ * 0x3F represent control characters, 0x41 a nonbreaking space, and the
+ * remainder printing characters.
+ *
+ * This is sufficient to allow us to identify EBCDIC text and to distinguish
+ * between old-style and internationalized examples of text.
+ */
+
+private unsigned char ebcdic_to_ascii[] = {
+  0,   1,   2,   3, 156,   9, 134, 127, 151, 141, 142,  11,  12,  13,  14,  15,
+ 16,  17,  18,  19, 157, 133,   8, 135,  24,  25, 146, 143,  28,  29,  30,  31,
+128, 129, 130, 131, 132,  10,  23,  27, 136, 137, 138, 139, 140,   5,   6,   7,
+144, 145,  22, 147, 148, 149, 150,   4, 152, 153, 154, 155,  20,  21, 158,  26,
+' ', 160, 161, 162, 163, 164, 165, 166, 167, 168, 213, '.', '<', '(', '+', '|',
+'&', 169, 170, 171, 172, 173, 174, 175, 176, 177, '!', '$', '*', ')', ';', '~',
+'-', '/', 178, 179, 180, 181, 182, 183, 184, 185, 203, ',', '%', '_', '>', '?',
+186, 187, 188, 189, 190, 191, 192, 193, 194, '`', ':', '#', '@', '\'','=', '"',
+195, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 196, 197, 198, 199, 200, 201,
+202, 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', '^', 204, 205, 206, 207, 208,
+209, 229, 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 210, 211, 212, '[', 214, 215,
+216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, ']', 230, 231,
+'{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 232, 233, 234, 235, 236, 237,
+'}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 238, 239, 240, 241, 242, 243,
+'\\',159, 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 244, 245, 246, 247, 248, 249,
+'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 250, 251, 252, 253, 254, 255
+};
+
+#ifdef notdef
+/*
+ * The following EBCDIC-to-ASCII table may relate more closely to reality,
+ * or at least to modern reality.  It comes from
+ *
+ *   http://ftp.s390.ibm.com/products/oe/bpxqp9.html
+ *
+ * and maps the characters of EBCDIC code page 1047 (the code used for
+ * Unix-derived software on IBM's 390 systems) to the corresponding
+ * characters from ISO 8859-1.
+ *
+ * If this table is used instead of the above one, some of the special
+ * cases for the NEL character can be taken out of the code.
+ */
+
+private unsigned char ebcdic_1047_to_8859[] = {
+0x00,0x01,0x02,0x03,0x9C,0x09,0x86,0x7F,0x97,0x8D,0x8E,0x0B,0x0C,0x0D,0x0E,0x0F,
+0x10,0x11,0x12,0x13,0x9D,0x0A,0x08,0x87,0x18,0x19,0x92,0x8F,0x1C,0x1D,0x1E,0x1F,
+0x80,0x81,0x82,0x83,0x84,0x85,0x17,0x1B,0x88,0x89,0x8A,0x8B,0x8C,0x05,0x06,0x07,
+0x90,0x91,0x16,0x93,0x94,0x95,0x96,0x04,0x98,0x99,0x9A,0x9B,0x14,0x15,0x9E,0x1A,
+0x20,0xA0,0xE2,0xE4,0xE0,0xE1,0xE3,0xE5,0xE7,0xF1,0xA2,0x2E,0x3C,0x28,0x2B,0x7C,
+0x26,0xE9,0xEA,0xEB,0xE8,0xED,0xEE,0xEF,0xEC,0xDF,0x21,0x24,0x2A,0x29,0x3B,0x5E,
+0x2D,0x2F,0xC2,0xC4,0xC0,0xC1,0xC3,0xC5,0xC7,0xD1,0xA6,0x2C,0x25,0x5F,0x3E,0x3F,
+0xF8,0xC9,0xCA,0xCB,0xC8,0xCD,0xCE,0xCF,0xCC,0x60,0x3A,0x23,0x40,0x27,0x3D,0x22,
+0xD8,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0xAB,0xBB,0xF0,0xFD,0xFE,0xB1,
+0xB0,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0xAA,0xBA,0xE6,0xB8,0xC6,0xA4,
+0xB5,0x7E,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0xA1,0xBF,0xD0,0x5B,0xDE,0xAE,
+0xAC,0xA3,0xA5,0xB7,0xA9,0xA7,0xB6,0xBC,0xBD,0xBE,0xDD,0xA8,0xAF,0x5D,0xB4,0xD7,
+0x7B,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0xAD,0xF4,0xF6,0xF2,0xF3,0xF5,
+0x7D,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0xB9,0xFB,0xFC,0xF9,0xFA,0xFF,
+0x5C,0xF7,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0xB2,0xD4,0xD6,0xD2,0xD3,0xD5,
+0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xB3,0xDB,0xDC,0xD9,0xDA,0x9F
+};
+#endif
+
+/*
+ * Copy buf[0 ... nbytes-1] into out[], translating EBCDIC to ASCII.
+ */
+private void
+from_ebcdic(const unsigned char *buf, size_t nbytes, unsigned char *out)
+{
+       size_t i;
+
+       for (i = 0; i < nbytes; i++) {
+               out[i] = ebcdic_to_ascii[buf[i]];
+       }
+}
diff --git a/src/file.c b/src/file.c
new file mode 100644 (file)
index 0000000..5b60b95
--- /dev/null
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * file - find type of a file or files - main program.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: file.c,v 1.181 2019/03/28 20:54:03 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef RESTORE_TIME
+# if (__COHERENT__ >= 0x420)
+#  include <sys/utime.h>
+# else
+#  ifdef USE_UTIMES
+#   include <sys/time.h>
+#  else
+#   include <utime.h>
+#  endif
+# endif
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>    /* for read() */
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
+# include <getopt.h>
+# ifndef HAVE_GETOPT_LONG
+int getopt_long(int, char * const *, const char *,
+    const struct option *, int *);
+# endif
+# else
+#  include "mygetopt.h"
+#endif
+
+#ifdef S_IFLNK
+# define IFLNK_h "h"
+# define IFLNK_L "L"
+#else
+# define IFLNK_h ""
+# define IFLNK_L ""
+#endif
+
+#ifdef HAVE_LIBSECCOMP
+# define SECCOMP_S "S"
+#else
+# define SECCOMP_S ""
+#endif
+
+#define FILE_FLAGS     "bcCdE" IFLNK_h "ik" IFLNK_L "lNnprs" SECCOMP_S "vzZ0"
+#define OPTSTRING      "bcCde:Ef:F:hiklLm:nNpP:rsSvzZ0"
+
+# define USAGE  \
+    "Usage: %s [-" FILE_FLAGS "] [--apple] [--extension] [--mime-encoding]\n" \
+    "            [--mime-type] [-e <testname>] [-F <separator>] " \
+    " [-f <namefile>]\n" \
+    "            [-m <magicfiles>] [-P <parameter=value>] <file> ...\n" \
+    "       %s -C [-m <magicfiles>]\n" \
+    "       %s [--help]\n"
+
+private int            /* Global command-line options          */
+       bflag = 0,      /* brief output format                  */
+       nopad = 0,      /* Don't pad output                     */
+       nobuffer = 0,   /* Do not buffer stdout                 */
+       nulsep = 0;     /* Append '\0' to the separator         */
+
+private const char *separator = ":";   /* Default field separator      */
+private const struct option long_options[] = {
+#define OPT_HELP               1
+#define OPT_APPLE              2
+#define OPT_EXTENSIONS         3
+#define OPT_MIME_TYPE          4
+#define OPT_MIME_ENCODING      5
+#define OPT(shortname, longname, opt, def, doc)      \
+    {longname, opt, NULL, shortname},
+#define OPT_LONGONLY(longname, opt, def, doc, id)        \
+    {longname, opt, NULL, id},
+#include "file_opts.h"
+#undef OPT
+#undef OPT_LONGONLY
+    {0, 0, NULL, 0}
+    };
+
+private const struct {
+       const char *name;
+       int value;
+} nv[] = {
+       { "apptype",    MAGIC_NO_CHECK_APPTYPE },
+       { "ascii",      MAGIC_NO_CHECK_ASCII },
+       { "cdf",        MAGIC_NO_CHECK_CDF },
+       { "compress",   MAGIC_NO_CHECK_COMPRESS },
+       { "elf",        MAGIC_NO_CHECK_ELF },
+       { "encoding",   MAGIC_NO_CHECK_ENCODING },
+       { "soft",       MAGIC_NO_CHECK_SOFT },
+       { "tar",        MAGIC_NO_CHECK_TAR },
+       { "json",       MAGIC_NO_CHECK_JSON },
+       { "text",       MAGIC_NO_CHECK_TEXT },  /* synonym for ascii */
+       { "tokens",     MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */
+};
+
+private struct {
+       const char *name;
+       int tag;
+       size_t value;
+       int set;
+} pm[] = {
+       { "indir",      MAGIC_PARAM_INDIR_MAX, 0, 0 },
+       { "name",       MAGIC_PARAM_NAME_MAX, 0, 0 },
+       { "elf_phnum",  MAGIC_PARAM_ELF_PHNUM_MAX, 0, 0 },
+       { "elf_shnum",  MAGIC_PARAM_ELF_SHNUM_MAX, 0, 0 },
+       { "elf_notes",  MAGIC_PARAM_ELF_NOTES_MAX, 0, 0 },
+       { "regex",      MAGIC_PARAM_REGEX_MAX, 0, 0 },
+       { "bytes",      MAGIC_PARAM_BYTES_MAX, 0, 0 },
+};
+
+private int posixly;
+
+#ifdef __dead
+__dead
+#endif
+private void usage(void);
+private void docprint(const char *, int);
+#ifdef __dead
+__dead
+#endif
+private void help(void);
+
+private int unwrap(struct magic_set *, const char *);
+private int process(struct magic_set *ms, const char *, int);
+private struct magic_set *load(const char *, int);
+private void setparam(const char *);
+private void applyparam(magic_t);
+
+
+/*
+ * main - parse arguments and handle options
+ */
+int
+main(int argc, char *argv[])
+{
+       int c;
+       size_t i;
+       int action = 0, didsomefiles = 0, errflg = 0;
+       int flags = 0, e = 0;
+#ifdef HAVE_LIBSECCOMP
+       int sandbox = 1;
+#endif
+       struct magic_set *magic = NULL;
+       int longindex;
+       const char *magicfile = NULL;           /* where the magic is   */
+       char *progname;
+
+       /* makes islower etc work for other langs */
+       (void)setlocale(LC_CTYPE, "");
+
+#ifdef __EMX__
+       /* sh-like wildcard expansion! Shouldn't hurt at least ... */
+       _wildcard(&argc, &argv);
+#endif
+
+       if ((progname = strrchr(argv[0], '/')) != NULL)
+               progname++;
+       else
+               progname = argv[0];
+
+       file_setprogname(progname);
+
+
+#ifdef S_IFLNK
+       posixly = getenv("POSIXLY_CORRECT") != NULL;
+       flags |=  posixly ? MAGIC_SYMLINK : 0;
+#endif
+       while ((c = getopt_long(argc, argv, OPTSTRING, long_options,
+           &longindex)) != -1)
+               switch (c) {
+               case OPT_HELP:
+                       help();
+                       break;
+               case OPT_APPLE:
+                       flags |= MAGIC_APPLE;
+                       break;
+               case OPT_EXTENSIONS:
+                       flags |= MAGIC_EXTENSION;
+                       break;
+               case OPT_MIME_TYPE:
+                       flags |= MAGIC_MIME_TYPE;
+                       break;
+               case OPT_MIME_ENCODING:
+                       flags |= MAGIC_MIME_ENCODING;
+                       break;
+               case '0':
+                       nulsep++;
+                       break;
+               case 'b':
+                       bflag++;
+                       break;
+               case 'c':
+                       action = FILE_CHECK;
+                       break;
+               case 'C':
+                       action = FILE_COMPILE;
+                       break;
+               case 'd':
+                       flags |= MAGIC_DEBUG|MAGIC_CHECK;
+                       break;
+               case 'E':
+                       flags |= MAGIC_ERROR;
+                       break;
+               case 'e':
+                       for (i = 0; i < __arraycount(nv); i++)
+                               if (strcmp(nv[i].name, optarg) == 0)
+                                       break;
+
+                       if (i == __arraycount(nv))
+                               errflg++;
+                       else
+                               flags |= nv[i].value;
+                       break;
+
+               case 'f':
+                       if(action)
+                               usage();
+                       if (magic == NULL)
+                               if ((magic = load(magicfile, flags)) == NULL)
+                                       return 1;
+                       applyparam(magic);
+                       e |= unwrap(magic, optarg);
+                       ++didsomefiles;
+                       break;
+               case 'F':
+                       separator = optarg;
+                       break;
+               case 'i':
+                       flags |= MAGIC_MIME;
+                       break;
+               case 'k':
+                       flags |= MAGIC_CONTINUE;
+                       break;
+               case 'l':
+                       action = FILE_LIST;
+                       break;
+               case 'm':
+                       magicfile = optarg;
+                       break;
+               case 'n':
+                       ++nobuffer;
+                       break;
+               case 'N':
+                       ++nopad;
+                       break;
+#if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
+               case 'p':
+                       flags |= MAGIC_PRESERVE_ATIME;
+                       break;
+#endif
+               case 'P':
+                       setparam(optarg);
+                       break;
+               case 'r':
+                       flags |= MAGIC_RAW;
+                       break;
+               case 's':
+                       flags |= MAGIC_DEVICES;
+                       break;
+#ifdef HAVE_LIBSECCOMP
+               case 'S':
+                       sandbox = 0;
+                       break;
+#endif
+               case 'v':
+                       if (magicfile == NULL)
+                               magicfile = magic_getpath(magicfile, action);
+                       (void)fprintf(stdout, "%s-%s\n", file_getprogname(),
+                           VERSION);
+                       (void)fprintf(stdout, "magic file from %s\n",
+                           magicfile);
+                       return 0;
+               case 'z':
+                       flags |= MAGIC_COMPRESS;
+                       break;
+
+               case 'Z':
+                       flags |= MAGIC_COMPRESS|MAGIC_COMPRESS_TRANSP;
+                       break;
+#ifdef S_IFLNK
+               case 'L':
+                       flags |= MAGIC_SYMLINK;
+                       break;
+               case 'h':
+                       flags &= ~MAGIC_SYMLINK;
+                       break;
+#endif
+               case '?':
+               default:
+                       errflg++;
+                       break;
+               }
+
+       if (errflg) {
+               usage();
+       }
+       if (e)
+               return e;
+
+#ifdef HAVE_LIBSECCOMP
+#if 0
+       if (sandbox && enable_sandbox_basic() == -1)
+#else
+       if (sandbox && enable_sandbox_full() == -1)
+#endif
+               file_err(EXIT_FAILURE, "SECCOMP initialisation failed");
+#endif /* HAVE_LIBSECCOMP */
+
+       if (MAGIC_VERSION != magic_version())
+               file_warnx("Compiled magic version [%d] "
+                   "does not match with shared library magic version [%d]\n",
+                   MAGIC_VERSION, magic_version());
+
+       switch(action) {
+       case FILE_CHECK:
+       case FILE_COMPILE:
+       case FILE_LIST:
+               /*
+                * Don't try to check/compile ~/.magic unless we explicitly
+                * ask for it.
+                */
+               magic = magic_open(flags|MAGIC_CHECK);
+               if (magic == NULL) {
+                       file_warn("Can't create magic");
+                       return 1;
+               }
+
+
+               switch(action) {
+               case FILE_CHECK:
+                       c = magic_check(magic, magicfile);
+                       break;
+               case FILE_COMPILE:
+                       c = magic_compile(magic, magicfile);
+                       break;
+               case FILE_LIST:
+                       c = magic_list(magic, magicfile);
+                       break;
+               default:
+                       abort();
+               }
+               if (c == -1) {
+                       file_warnx("%s", magic_error(magic));
+                       e = 1;
+                       goto out;
+               }
+               goto out;
+       default:
+               if (magic == NULL)
+                       if ((magic = load(magicfile, flags)) == NULL)
+                               return 1;
+               applyparam(magic);
+       }
+
+       if (optind == argc) {
+               if (!didsomefiles)
+                       usage();
+       }
+       else {
+               size_t j, wid, nw;
+               for (wid = 0, j = CAST(size_t, optind); j < CAST(size_t, argc);
+                   j++) {
+                       nw = file_mbswidth(argv[j]);
+                       if (nw > wid)
+                               wid = nw;
+               }
+               /*
+                * If bflag is only set twice, set it depending on
+                * number of files [this is undocumented, and subject to change]
+                */
+               if (bflag == 2) {
+                       bflag = optind >= argc - 1;
+               }
+               for (; optind < argc; optind++)
+                       e |= process(magic, argv[optind], wid);
+       }
+
+out:
+       if (magic)
+               magic_close(magic);
+       return e;
+}
+
+private void
+applyparam(magic_t magic)
+{
+       size_t i;
+
+       for (i = 0; i < __arraycount(pm); i++) {
+               if (!pm[i].set)
+                       continue;
+               if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1)
+                       file_err(EXIT_FAILURE, "Can't set %s", pm[i].name);
+       }
+}
+
+private void
+setparam(const char *p)
+{
+       size_t i;
+       char *s;
+
+       if ((s = strchr(p, '=')) == NULL)
+               goto badparm;
+
+       for (i = 0; i < __arraycount(pm); i++) {
+               if (strncmp(p, pm[i].name, s - p) != 0)
+                       continue;
+               pm[i].value = atoi(s + 1);
+               pm[i].set = 1;
+               return;
+       }
+badparm:
+       file_errx(EXIT_FAILURE, "Unknown param %s", p);
+}
+
+private struct magic_set *
+/*ARGSUSED*/
+load(const char *magicfile, int flags)
+{
+       struct magic_set *magic = magic_open(flags);
+       const char *e;
+
+       if (magic == NULL) {
+               file_warn("Can't create magic");
+               return NULL;
+       }
+       if (magic_load(magic, magicfile) == -1) {
+               file_warn("%s", magic_error(magic));
+               magic_close(magic);
+               return NULL;
+       }
+       if ((e = magic_error(magic)) != NULL)
+               file_warn("%s", e);
+       return magic;
+}
+
+/*
+ * unwrap -- read a file of filenames, do each one.
+ */
+private int
+unwrap(struct magic_set *ms, const char *fn)
+{
+       FILE *f;
+       ssize_t len;
+       char *line = NULL;
+       size_t llen = 0;
+       int wid = 0, cwid;
+       int e = 0;
+
+       if (strcmp("-", fn) == 0) {
+               f = stdin;
+               wid = 1;
+       } else {
+               if ((f = fopen(fn, "r")) == NULL) {
+                       file_warn("Cannot open `%s'", fn);
+                       return 1;
+               }
+
+               while ((len = getline(&line, &llen, f)) > 0) {
+                       if (line[len - 1] == '\n')
+                               line[len - 1] = '\0';
+                       cwid = file_mbswidth(line);
+                       if (cwid > wid)
+                               wid = cwid;
+               }
+
+               rewind(f);
+       }
+
+       while ((len = getline(&line, &llen, f)) > 0) {
+               if (line[len - 1] == '\n')
+                       line[len - 1] = '\0';
+               e |= process(ms, line, wid);
+               if(nobuffer)
+                       (void)fflush(stdout);
+       }
+
+       free(line);
+       (void)fclose(f);
+       return e;
+}
+
+/*
+ * Called for each input file on the command line (or in a list of files)
+ */
+private int
+process(struct magic_set *ms, const char *inname, int wid)
+{
+       const char *type, c = nulsep > 1 ? '\0' : '\n';
+       int std_in = strcmp(inname, "-") == 0;
+
+       if (wid > 0 && !bflag) {
+               (void)printf("%s", std_in ? "/dev/stdin" : inname);
+               if (nulsep)
+                       (void)putc('\0', stdout);
+               if (nulsep < 2) {
+                       (void)printf("%s", separator);
+                       (void)printf("%*s ", CAST(int, nopad ? 0
+                           : (wid - file_mbswidth(inname))), "");
+               }
+       }
+
+       type = magic_file(ms, std_in ? NULL : inname);
+
+       if (type == NULL) {
+               (void)printf("ERROR: %s%c", magic_error(ms), c);
+               return 1;
+       } else {
+               (void)printf("%s%c", type, c);
+               return 0;
+       }
+}
+
+protected size_t
+file_mbswidth(const char *s)
+{
+#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
+       size_t bytesconsumed, old_n, n, width = 0;
+       mbstate_t state;
+       wchar_t nextchar;
+       (void)memset(&state, 0, sizeof(mbstate_t));
+       old_n = n = strlen(s);
+
+       while (n > 0) {
+               bytesconsumed = mbrtowc(&nextchar, s, n, &state);
+               if (bytesconsumed == CAST(size_t, -1) ||
+                   bytesconsumed == CAST(size_t, -2)) {
+                       /* Something went wrong, return something reasonable */
+                       return old_n;
+               }
+               if (s[0] == '\n') {
+                       /*
+                        * do what strlen() would do, so that caller
+                        * is always right
+                        */
+                       width++;
+               } else {
+                       int w = wcwidth(nextchar);
+                       if (w > 0)
+                               width += w;
+               }
+
+               s += bytesconsumed, n -= bytesconsumed;
+       }
+       return width;
+#else
+       return strlen(s);
+#endif
+}
+
+private void
+usage(void)
+{
+       const char *pn = file_getprogname();
+       (void)fprintf(stderr, USAGE, pn, pn, pn);
+       exit(EXIT_FAILURE);
+}
+
+private void
+defprint(int def)
+{
+       if (!def)
+               return;
+       if (((def & 1) && posixly) || ((def & 2) && !posixly))
+               fprintf(stdout, " (default)");
+       fputc('\n', stdout);
+}
+
+private void
+docprint(const char *opts, int def)
+{
+       size_t i;
+       int comma;
+       char *sp, *p;
+
+       p = strstr(opts, "%o");
+       if (p == NULL) {
+               fprintf(stdout, "%s", opts);
+               defprint(def);
+               return;
+       }
+
+       for (sp = p - 1; sp > opts && *sp == ' '; sp--)
+               continue;
+
+       fprintf(stdout, "%.*s", CAST(int, p - opts), opts);
+
+       comma = 0;
+       for (i = 0; i < __arraycount(nv); i++) {
+               fprintf(stdout, "%s%s", comma++ ? ", " : "", nv[i].name);
+               if (i && i % 5 == 0 && i != __arraycount(nv) - 1) {
+                       fprintf(stdout, ",\n%*s", CAST(int, p - sp - 1), "");
+                       comma = 0;
+               }
+       }
+
+       fprintf(stdout, "%s", opts + (p - opts) + 2);
+}
+
+private void
+help(void)
+{
+       (void)fputs(
+"Usage: file [OPTION...] [FILE...]\n"
+"Determine type of FILEs.\n"
+"\n", stdout);
+#define OPT(shortname, longname, opt, def, doc)      \
+       fprintf(stdout, "  -%c, --" longname, shortname), \
+       docprint(doc, def);
+#define OPT_LONGONLY(longname, opt, def, doc, id)        \
+       fprintf(stdout, "      --" longname),   \
+       docprint(doc, def);
+#include "file_opts.h"
+#undef OPT
+#undef OPT_LONGONLY
+       fprintf(stdout, "\nReport bugs to https://bugs.astron.com/\n");
+       exit(EXIT_SUCCESS);
+}
+
+private const char *file_progname;
+
+protected void
+file_setprogname(const char *progname)
+{
+       file_progname = progname;
+}
+
+protected const char *
+file_getprogname(void)
+{
+       return file_progname;
+}
+
+protected void
+file_err(int e, const char *fmt, ...)
+{
+       va_list ap;
+       int se = errno;
+
+       va_start(ap, fmt);
+       fprintf(stderr, "%s: ", file_progname);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, " (%s)\n", strerror(se));
+       exit(e);
+}
+
+protected void
+file_errx(int e, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       fprintf(stderr, "%s: ", file_progname);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "\n");
+       exit(e);
+}
+
+protected void
+file_warn(const char *fmt, ...)
+{
+       va_list ap;
+       int se = errno;
+
+       va_start(ap, fmt);
+       fprintf(stderr, "%s: ", file_progname);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, " (%s)\n", strerror(se));
+       errno = se;
+}
+
+protected void
+file_warnx(const char *fmt, ...)
+{
+       va_list ap;
+       int se = errno;
+
+       va_start(ap, fmt);
+       fprintf(stderr, "%s: ", file_progname);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "\n");
+       errno = se;
+}
diff --git a/src/file.h b/src/file.h
new file mode 100644 (file)
index 0000000..69a586a
--- /dev/null
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * file.h - definitions for file(1) program
+ * @(#)$File: file.h,v 1.206 2019/05/07 02:27:11 christos Exp $
+ */
+
+#ifndef __file_h__
+#define __file_h__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef HAVE_STDINT_H
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#ifdef WIN32
+  #ifdef _WIN64
+    #define SIZE_T_FORMAT "I64"
+  #else
+    #define SIZE_T_FORMAT ""
+  #endif
+  #define INT64_T_FORMAT "I64"
+  #define INTMAX_T_FORMAT "I64"
+#else
+  #define SIZE_T_FORMAT "z"
+  #define INT64_T_FORMAT "ll"
+  #define INTMAX_T_FORMAT "j"
+#endif
+#include <stdint.h>
+#endif
+
+#include <stdio.h>     /* Include that here, to make sure __P gets defined */
+#include <errno.h>
+#include <fcntl.h>     /* For open and flags */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <regex.h>
+#include <time.h>
+#include <sys/types.h>
+#ifndef WIN32
+#include <sys/param.h>
+#endif
+/* Do this here and now, because struct stat gets re-defined on solaris */
+#include <sys/stat.h>
+#include <stdarg.h>
+
+#define ENABLE_CONDITIONALS
+
+#ifndef MAGIC
+#define MAGIC "/etc/magic"
+#endif
+
+#if defined(__EMX__) || defined (WIN32)
+#define PATHSEP        ';'
+#else
+#define PATHSEP        ':'
+#endif
+
+#define private static
+
+#if HAVE_VISIBILITY && !defined(WIN32)
+#define public  __attribute__ ((__visibility__("default")))
+#ifndef protected
+#define protected __attribute__ ((__visibility__("hidden")))
+#endif
+#else
+#define public
+#ifndef protected
+#define protected
+#endif
+#endif
+
+#ifndef __arraycount
+#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+#ifndef __GNUC_PREREQ__
+#ifdef __GNUC__
+#define        __GNUC_PREREQ__(x, y)                                           \
+       ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||                  \
+        (__GNUC__ > (x)))
+#else
+#define        __GNUC_PREREQ__(x, y)   0
+#endif
+#endif
+
+#ifndef __GNUC__
+#ifndef __attribute__
+#define __attribute__(a)
+#endif
+#endif
+
+#ifndef MIN
+#define        MIN(a,b)        (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define        MAX(a,b)        (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef FILE_BYTES_MAX
+# define FILE_BYTES_MAX (1024 * 1024)  /* how much of the file to look at */
+#endif
+#define MAXMAGIS 8192          /* max entries in any one magic file
+                                  or directory */
+#define MAXDESC        64              /* max len of text description/MIME type */
+#define MAXMIME        80              /* max len of text MIME type */
+#define MAXstring 96           /* max len of "string" types */
+
+#define MAGICNO                0xF11E041C
+#define VERSIONNO      14
+#define FILE_MAGICSIZE 344
+
+#define        FILE_LOAD       0
+#define FILE_CHECK     1
+#define FILE_COMPILE   2
+#define FILE_LIST      3
+
+struct buffer {
+       int fd;
+       struct stat st;
+       const void *fbuf;
+       size_t flen;
+       off_t eoff;
+       void *ebuf;
+       size_t elen;
+};
+
+union VALUETYPE {
+       uint8_t b;
+       uint16_t h;
+       uint32_t l;
+       uint64_t q;
+       uint8_t hs[2];  /* 2 bytes of a fixed-endian "short" */
+       uint8_t hl[4];  /* 4 bytes of a fixed-endian "long" */
+       uint8_t hq[8];  /* 8 bytes of a fixed-endian "quad" */
+       char s[MAXstring];      /* the search string or regex pattern */
+       unsigned char us[MAXstring];
+       float f;
+       double d;
+};
+
+struct magic {
+       /* Word 1 */
+       uint16_t cont_level;    /* level of ">" */
+       uint8_t flag;
+#define INDIR          0x01    /* if '(...)' appears */
+#define OFFADD         0x02    /* if '>&' or '>...(&' appears */
+#define INDIROFFADD    0x04    /* if '>&(' appears */
+#define UNSIGNED       0x08    /* comparison is unsigned */
+#define NOSPACE                0x10    /* suppress space character before output */
+#define BINTEST                0x20    /* test is for a binary type (set only
+                                  for top-level tests) */
+#define TEXTTEST       0x40    /* for passing to file_softmagic */
+
+       uint8_t factor;
+
+       /* Word 2 */
+       uint8_t reln;           /* relation (0=eq, '>'=gt, etc) */
+       uint8_t vallen;         /* length of string value, if any */
+       uint8_t type;           /* comparison type (FILE_*) */
+       uint8_t in_type;        /* type of indirection */
+#define                        FILE_INVALID    0
+#define                        FILE_BYTE       1
+#define                                FILE_SHORT      2
+#define                                FILE_DEFAULT    3
+#define                                FILE_LONG       4
+#define                                FILE_STRING     5
+#define                                FILE_DATE       6
+#define                                FILE_BESHORT    7
+#define                                FILE_BELONG     8
+#define                                FILE_BEDATE     9
+#define                                FILE_LESHORT    10
+#define                                FILE_LELONG     11
+#define                                FILE_LEDATE     12
+#define                                FILE_PSTRING    13
+#define                                FILE_LDATE      14
+#define                                FILE_BELDATE    15
+#define                                FILE_LELDATE    16
+#define                                FILE_REGEX      17
+#define                                FILE_BESTRING16 18
+#define                                FILE_LESTRING16 19
+#define                                FILE_SEARCH     20
+#define                                FILE_MEDATE     21
+#define                                FILE_MELDATE    22
+#define                                FILE_MELONG     23
+#define                                FILE_QUAD       24
+#define                                FILE_LEQUAD     25
+#define                                FILE_BEQUAD     26
+#define                                FILE_QDATE      27
+#define                                FILE_LEQDATE    28
+#define                                FILE_BEQDATE    29
+#define                                FILE_QLDATE     30
+#define                                FILE_LEQLDATE   31
+#define                                FILE_BEQLDATE   32
+#define                                FILE_FLOAT      33
+#define                                FILE_BEFLOAT    34
+#define                                FILE_LEFLOAT    35
+#define                                FILE_DOUBLE     36
+#define                                FILE_BEDOUBLE   37
+#define                                FILE_LEDOUBLE   38
+#define                                FILE_BEID3      39
+#define                                FILE_LEID3      40
+#define                                FILE_INDIRECT   41
+#define                                FILE_QWDATE     42
+#define                                FILE_LEQWDATE   43
+#define                                FILE_BEQWDATE   44
+#define                                FILE_NAME       45
+#define                                FILE_USE        46
+#define                                FILE_CLEAR      47
+#define                                FILE_DER        48
+#define                                FILE_NAMES_SIZE 49 /* size of array to contain all names */
+
+#define IS_STRING(t) \
+       ((t) == FILE_STRING || \
+        (t) == FILE_PSTRING || \
+        (t) == FILE_BESTRING16 || \
+        (t) == FILE_LESTRING16 || \
+        (t) == FILE_REGEX || \
+        (t) == FILE_SEARCH || \
+        (t) == FILE_INDIRECT || \
+        (t) == FILE_NAME || \
+        (t) == FILE_USE)
+
+#define FILE_FMT_NONE 0
+#define FILE_FMT_NUM  1 /* "cduxXi" */
+#define FILE_FMT_STR  2 /* "s" */
+#define FILE_FMT_QUAD 3 /* "ll" */
+#define FILE_FMT_FLOAT 4 /* "eEfFgG" */
+#define FILE_FMT_DOUBLE 5 /* "eEfFgG" */
+
+       /* Word 3 */
+       uint8_t in_op;          /* operator for indirection */
+       uint8_t mask_op;        /* operator for mask */
+#ifdef ENABLE_CONDITIONALS
+       uint8_t cond;           /* conditional type */
+#else
+       uint8_t dummy;
+#endif
+       uint8_t factor_op;
+#define                FILE_FACTOR_OP_PLUS     '+'
+#define                FILE_FACTOR_OP_MINUS    '-'
+#define                FILE_FACTOR_OP_TIMES    '*'
+#define                FILE_FACTOR_OP_DIV      '/'
+#define                FILE_FACTOR_OP_NONE     '\0'
+
+#define                                FILE_OPS        "&|^+-*/%"
+#define                                FILE_OPAND      0
+#define                                FILE_OPOR       1
+#define                                FILE_OPXOR      2
+#define                                FILE_OPADD      3
+#define                                FILE_OPMINUS    4
+#define                                FILE_OPMULTIPLY 5
+#define                                FILE_OPDIVIDE   6
+#define                                FILE_OPMODULO   7
+#define                                FILE_OPS_MASK   0x07 /* mask for above ops */
+#define                                FILE_UNUSED_1   0x08
+#define                                FILE_UNUSED_2   0x10
+#define                                FILE_OPSIGNED   0x20
+#define                                FILE_OPINVERSE  0x40
+#define                                FILE_OPINDIRECT 0x80
+
+#ifdef ENABLE_CONDITIONALS
+#define                                COND_NONE       0
+#define                                COND_IF         1
+#define                                COND_ELIF       2
+#define                                COND_ELSE       3
+#endif /* ENABLE_CONDITIONALS */
+
+       /* Word 4 */
+       int32_t offset;         /* offset to magic number */
+       /* Word 5 */
+       int32_t in_offset;      /* offset from indirection */
+       /* Word 6 */
+       uint32_t lineno;        /* line number in magic file */
+       /* Word 7,8 */
+       union {
+               uint64_t _mask; /* for use with numeric and date types */
+               struct {
+                       uint32_t _count;        /* repeat/line count */
+                       uint32_t _flags;        /* modifier flags */
+               } _s;           /* for use with string types */
+       } _u;
+#define num_mask _u._mask
+#define str_range _u._s._count
+#define str_flags _u._s._flags
+       /* Words 9-24 */
+       union VALUETYPE value;  /* either number or string */
+       /* Words 25-40 */
+       char desc[MAXDESC];     /* description */
+       /* Words 41-60 */
+       char mimetype[MAXMIME]; /* MIME type */
+       /* Words 61-62 */
+       char apple[8];          /* APPLE CREATOR/TYPE */
+       /* Words 63-78 */
+       char ext[64];           /* Popular extensions */
+};
+
+#define BIT(A)   (1 << (A))
+#define STRING_COMPACT_WHITESPACE              BIT(0)
+#define STRING_COMPACT_OPTIONAL_WHITESPACE     BIT(1)
+#define STRING_IGNORE_LOWERCASE                        BIT(2)
+#define STRING_IGNORE_UPPERCASE                        BIT(3)
+#define REGEX_OFFSET_START                     BIT(4)
+#define STRING_TEXTTEST                                BIT(5)
+#define STRING_BINTEST                         BIT(6)
+#define PSTRING_1_BE                           BIT(7)
+#define PSTRING_1_LE                           BIT(7)
+#define PSTRING_2_BE                           BIT(8)
+#define PSTRING_2_LE                           BIT(9)
+#define PSTRING_4_BE                           BIT(10)
+#define PSTRING_4_LE                           BIT(11)
+#define REGEX_LINE_COUNT                       BIT(11)
+#define PSTRING_LEN    \
+    (PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE)
+#define PSTRING_LENGTH_INCLUDES_ITSELF         BIT(12)
+#define        STRING_TRIM                             BIT(13)
+#define CHAR_COMPACT_WHITESPACE                        'W'
+#define CHAR_COMPACT_OPTIONAL_WHITESPACE       'w'
+#define CHAR_IGNORE_LOWERCASE                  'c'
+#define CHAR_IGNORE_UPPERCASE                  'C'
+#define CHAR_REGEX_OFFSET_START                        's'
+#define CHAR_TEXTTEST                          't'
+#define        CHAR_TRIM                               'T'
+#define CHAR_BINTEST                           'b'
+#define CHAR_PSTRING_1_BE                      'B'
+#define CHAR_PSTRING_1_LE                      'B'
+#define CHAR_PSTRING_2_BE                      'H'
+#define CHAR_PSTRING_2_LE                      'h'
+#define CHAR_PSTRING_4_BE                      'L'
+#define CHAR_PSTRING_4_LE                      'l'
+#define CHAR_PSTRING_LENGTH_INCLUDES_ITSELF     'J'
+#define STRING_IGNORE_CASE             (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
+#define STRING_DEFAULT_RANGE           100
+
+#define        INDIRECT_RELATIVE                       BIT(0)
+#define        CHAR_INDIRECT_RELATIVE                  'r'
+
+/* list of magic entries */
+struct mlist {
+       struct magic *magic;            /* array of magic entries */
+       uint32_t nmagic;                /* number of entries in array */
+       void *map;                      /* internal resources used by entry */
+       struct mlist *next, *prev;
+};
+
+#ifdef __cplusplus
+#define CAST(T, b)     static_cast<T>(b)
+#define RCAST(T, b)    reinterpret_cast<T>(b)
+#define CCAST(T, b)    const_cast<T>(b)
+#else
+#define CAST(T, b)     ((T)(b))
+#define RCAST(T, b)    ((T)(uintptr_t)(b))
+#define CCAST(T, b)    ((T)(uintptr_t)(b))
+#endif
+
+struct level_info {
+       int32_t off;
+       int got_match;
+#ifdef ENABLE_CONDITIONALS
+       int last_match;
+       int last_cond;  /* used for error checking by parse() */
+#endif
+};
+
+#define MAGIC_SETS     2
+
+struct magic_set {
+       struct mlist *mlist[MAGIC_SETS];        /* list of regular entries */
+       struct cont {
+               size_t len;
+               struct level_info *li;
+       } c;
+       struct out {
+               char *buf;              /* Accumulation buffer */
+               char *pbuf;             /* Printable buffer */
+       } o;
+       uint32_t offset;                /* a copy of m->offset while we */
+                                       /* are working on the magic entry */
+       uint32_t eoffset;               /* offset from end of file */
+       int error;
+       int flags;                      /* Control magic tests. */
+       int event_flags;                /* Note things that happened. */
+#define                EVENT_HAD_ERR           0x01
+       const char *file;
+       size_t line;                    /* current magic line number */
+       mode_t mode;                    /* copy of current stat mode */
+
+       /* data for searches */
+       struct {
+               const char *s;          /* start of search in original source */
+               size_t s_len;           /* length of search region */
+               size_t offset;          /* starting offset in source: XXX - should this be off_t? */
+               size_t rm_len;          /* match length */
+       } search;
+
+       /* FIXME: Make the string dynamically allocated so that e.g.
+          strings matched in files can be longer than MAXstring */
+       union VALUETYPE ms_value;       /* either number or string */
+       uint16_t indir_max;
+       uint16_t name_max;
+       uint16_t elf_shnum_max;
+       uint16_t elf_phnum_max;
+       uint16_t elf_notes_max;
+       uint16_t regex_max;
+       size_t bytes_max;               /* number of bytes to read from file */
+#define        FILE_INDIR_MAX                  50
+#define        FILE_NAME_MAX                   30
+#define        FILE_ELF_SHNUM_MAX              32768
+#define        FILE_ELF_PHNUM_MAX              2048
+#define        FILE_ELF_NOTES_MAX              256
+#define        FILE_REGEX_MAX                  8192
+};
+
+/* Type for Unicode characters */
+typedef unsigned long unichar;
+
+struct stat;
+#define FILE_T_LOCAL   1
+#define FILE_T_WINDOWS 2
+protected const char *file_fmttime(uint64_t, int, char *);
+protected struct magic_set *file_ms_alloc(int);
+protected void file_ms_free(struct magic_set *);
+protected int file_default(struct magic_set *, size_t);
+protected int file_buffer(struct magic_set *, int, struct stat *, const char *,
+    const void *, size_t);
+protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
+protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
+protected int file_vprintf(struct magic_set *, const char *, va_list)
+    __attribute__((__format__(__printf__, 2, 0)));
+protected int file_separator(struct magic_set *);
+protected size_t file_printedlen(const struct magic_set *);
+protected int file_replace(struct magic_set *, const char *, const char *);
+protected int file_printf(struct magic_set *, const char *, ...)
+    __attribute__((__format__(__printf__, 2, 3)));
+protected int file_reset(struct magic_set *, int);
+protected int file_tryelf(struct magic_set *, const struct buffer *);
+protected int file_trycdf(struct magic_set *, const struct buffer *);
+#if HAVE_FORK
+protected int file_zmagic(struct magic_set *, const struct buffer *,
+    const char *);
+#endif
+protected int file_ascmagic(struct magic_set *, const struct buffer *,
+    int);
+protected int file_ascmagic_with_encoding(struct magic_set *,
+    const struct buffer *, unichar *, size_t, const char *, const char *, int);
+protected int file_encoding(struct magic_set *, const struct buffer *,
+    unichar **, size_t *, const char **, const char **, const char **);
+protected int file_is_json(struct magic_set *, const struct buffer *);
+protected int file_is_tar(struct magic_set *, const struct buffer *);
+protected int file_softmagic(struct magic_set *, const struct buffer *,
+    uint16_t *, uint16_t *, int, int);
+protected int file_apprentice(struct magic_set *, const char *, int);
+protected int buffer_apprentice(struct magic_set *, struct magic **,
+    size_t *, size_t);
+protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
+protected uint64_t file_signextend(struct magic_set *, struct magic *,
+    uint64_t);
+protected void file_badread(struct magic_set *);
+protected void file_badseek(struct magic_set *);
+protected void file_oomem(struct magic_set *, size_t);
+protected void file_error(struct magic_set *, int, const char *, ...)
+    __attribute__((__format__(__printf__, 3, 4)));
+protected void file_magerror(struct magic_set *, const char *, ...)
+    __attribute__((__format__(__printf__, 2, 3)));
+protected void file_magwarn(struct magic_set *, const char *, ...)
+    __attribute__((__format__(__printf__, 2, 3)));
+protected void file_mdump(struct magic *);
+protected void file_showstr(FILE *, const char *, size_t);
+protected size_t file_mbswidth(const char *);
+protected const char *file_getbuffer(struct magic_set *);
+protected ssize_t sread(int, void *, size_t, int);
+protected int file_check_mem(struct magic_set *, unsigned int);
+protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
+    size_t *);
+protected size_t file_pstring_length_size(const struct magic *);
+protected size_t file_pstring_get_length(const struct magic *, const char *);
+protected char * file_printable(char *, size_t, const char *, size_t);
+#ifdef __EMX__
+protected int file_os2_apptype(struct magic_set *, const char *, const void *,
+    size_t);
+#endif /* __EMX__ */
+
+protected void buffer_init(struct buffer *, int, const struct stat *,
+    const void *, size_t);
+protected void buffer_fini(struct buffer *);
+protected int buffer_fill(const struct buffer *);
+
+#include <locale.h>
+#if defined(HAVE_XLOCALE_H)
+#include <xlocale.h>
+#endif
+
+typedef struct {
+       const char *pat;
+#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
+#define USE_C_LOCALE
+       locale_t old_lc_ctype;
+       locale_t c_lc_ctype;
+#else
+       char *old_lc_ctype;
+#endif
+       int rc;
+       regex_t rx;
+} file_regex_t;
+
+protected int file_regcomp(file_regex_t *, const char *, int);
+protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
+    int);
+protected void file_regfree(file_regex_t *);
+protected void file_regerror(file_regex_t *, int, struct magic_set *);
+
+typedef struct {
+       char *buf;
+       uint32_t offset;
+} file_pushbuf_t;
+
+protected file_pushbuf_t *file_push_buffer(struct magic_set *);
+protected char  *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
+
+#ifndef COMPILE_ONLY
+extern const char *file_names[];
+extern const size_t file_nnames;
+#endif
+
+#ifndef HAVE_PREAD
+ssize_t pread(int, void *, size_t, off_t);
+#endif
+#ifndef HAVE_VASPRINTF
+int vasprintf(char **, const char *, va_list);
+#endif
+#ifndef HAVE_ASPRINTF
+int asprintf(char **, const char *, ...);
+#endif
+#ifndef HAVE_DPRINTF
+int dprintf(int, const char *, ...);
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *, const char *, size_t);
+#endif
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *, const char *, size_t);
+#endif
+#ifndef HAVE_STRCASESTR
+char *strcasestr(const char *, const char *);
+#endif
+#ifndef HAVE_GETLINE
+ssize_t getline(char **, size_t *, FILE *);
+ssize_t getdelim(char **, size_t *, int, FILE *);
+#endif
+#ifndef HAVE_CTIME_R
+char   *ctime_r(const time_t *, char *);
+#endif
+#ifndef HAVE_ASCTIME_R
+char   *asctime_r(const struct tm *, char *);
+#endif
+#ifndef HAVE_GMTIME_R
+struct tm *gmtime_r(const time_t *, struct tm *);
+#endif
+#ifndef HAVE_LOCALTIME_R
+struct tm *localtime_r(const time_t *, struct tm *);
+#endif
+#ifndef HAVE_FMTCHECK
+const char *fmtcheck(const char *, const char *)
+     __attribute__((__format_arg__(2)));
+#endif
+
+#ifdef HAVE_LIBSECCOMP
+// basic filter
+// this mode should not interfere with normal operations
+// only some dangerous syscalls are blacklisted
+int enable_sandbox_basic(void);
+
+// enhanced filter
+// this mode allows only the necessary syscalls used during normal operation
+// extensive testing required !!!
+int enable_sandbox_full(void);
+#endif
+
+protected const char *file_getprogname(void);
+protected void file_setprogname(const char *);
+protected void file_err(int, const char *, ...)
+    __attribute__((__format__(__printf__, 2, 3), __noreturn__));
+protected void file_errx(int, const char *, ...)
+    __attribute__((__format__(__printf__, 2, 3), __noreturn__));
+protected void file_warn(const char *, ...)
+    __attribute__((__format__(__printf__, 1, 2)));
+protected void file_warnx(const char *, ...)
+    __attribute__((__format__(__printf__, 1, 2)));
+
+#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
+#define QUICK
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY       0
+#endif
+#ifndef O_NONBLOCK
+#define O_NONBLOCK     0
+#endif
+
+#ifndef __cplusplus
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define FILE_RCSID(id) \
+static const char rcsid[] __attribute__((__used__)) = id;
+#else
+#define FILE_RCSID(id) \
+static const char *rcsid(const char *p) { \
+       return rcsid(p = id); \
+}
+#endif
+#else
+#define FILE_RCSID(id)
+#endif
+#ifndef __RCSID
+#define __RCSID(a)
+#endif
+
+#endif /* __file_h__ */
diff --git a/src/file_opts.h b/src/file_opts.h
new file mode 100644 (file)
index 0000000..02611cc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Table of command-line options
+ *
+ * The first column specifies the short name, if any, or 0 if none.
+ * The second column specifies the long name.
+ * The third column specifies whether it takes a parameter.
+ * The fourth column is the documentation.
+ *
+ * N.B. The long options' order must correspond to the code in file.c,
+ * and OPTSTRING must be kept up-to-date with the short options.
+ * Pay particular attention to the numbers of long-only options in the
+ * switch statement!
+ */
+
+OPT_LONGONLY("help", 0, 0, "                 display this help and exit\n", OPT_HELP)
+OPT('v', "version", 0, 0, "              output version information and exit\n")
+OPT('m', "magic-file", 1, 0, " LIST      use LIST as a colon-separated list of magic\n"
+    "                               number files\n")
+OPT('z', "uncompress", 0, 0, "           try to look inside compressed files\n")
+OPT('Z', "uncompress-noreport", 0, 0, "  only print the contents of compressed files\n")
+OPT('b', "brief", 0, 0, "                do not prepend filenames to output lines\n")
+OPT('c', "checking-printout", 0, 0, "    print the parsed form of the magic file, use in\n"
+    "                               conjunction with -m to debug a new magic file\n"
+    "                               before installing it\n")
+OPT('e', "exclude", 1, 0, " TEST         exclude TEST from the list of test to be\n"
+    "                               performed for file. Valid tests are:\n"
+    "                               %o\n")
+OPT('f', "files-from", 1, 0, " FILE      read the filenames to be examined from FILE\n")
+OPT('F', "separator", 1, 0, " STRING     use string as separator instead of `:'\n")
+OPT('i', "mime", 0, 0, "                 output MIME type strings (--mime-type and\n"
+    "                               --mime-encoding)\n")
+OPT_LONGONLY("apple", 0, 0, "                output the Apple CREATOR/TYPE\n", OPT_APPLE)
+OPT_LONGONLY("extension", 0, 0, "            output a slash-separated list of extensions\n", OPT_EXTENSIONS)
+OPT_LONGONLY("mime-type", 0, 0, "            output the MIME type\n", OPT_MIME_TYPE)
+OPT_LONGONLY("mime-encoding", 0, 0, "        output the MIME encoding\n", OPT_MIME_ENCODING)
+OPT('k', "keep-going", 0, 0, "           don't stop at the first match\n")
+OPT('l', "list", 0, 0, "                 list magic strength\n")
+#ifdef S_IFLNK
+OPT('L', "dereference", 0, 1, "          follow symlinks")
+OPT('h', "no-dereference", 0, 2, "       don't follow symlinks")
+#endif
+OPT('n', "no-buffer", 0, 0, "            do not buffer output\n")
+OPT('N', "no-pad", 0, 0, "               do not pad output\n")
+OPT('0', "print0", 0, 0, "               terminate filenames with ASCII NUL\n")
+#if defined(HAVE_UTIME) || defined(HAVE_UTIMES)
+OPT('p', "preserve-date", 0, 0, "        preserve access times on files\n")
+#endif
+OPT('P', "parameter", 1, 0, "            set file engine parameter limits\n"
+    "                               indir        15 recursion limit for indirection\n"
+    "                               name         30 use limit for name/use magic\n"
+    "                               elf_notes   256 max ELF notes processed\n"
+    "                               elf_phnum   128 max ELF prog sections processed\n"
+    "                               elf_shnum 32768 max ELF sections processed\n")
+OPT('r', "raw", 0, 0, "                  don't translate unprintable chars to \\ooo\n")
+OPT('s', "special-files", 0, 0, "        treat special (block/char devices) files as\n"
+    "                             ordinary ones\n")
+#ifdef HAVE_LIBSECCOMP
+OPT('S', "no-sandbox", 0, 0, "           disable system call sandboxing\n")
+#endif
+OPT('C', "compile", 0, 0, "              compile file specified by -m\n")
+OPT('d', "debug", 0, 0, "                print debugging messages\n")
diff --git a/src/fmtcheck.c b/src/fmtcheck.c
new file mode 100644 (file)
index 0000000..fcad436
--- /dev/null
@@ -0,0 +1,251 @@
+/*     $NetBSD: fmtcheck.c,v 1.8 2008/04/28 20:22:59 martin Exp $      */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Allen Briggs.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "file.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+enum __e_fmtcheck_types {
+       FMTCHECK_START,
+       FMTCHECK_SHORT,
+       FMTCHECK_INT,
+       FMTCHECK_LONG,
+       FMTCHECK_QUAD,
+       FMTCHECK_SHORTPOINTER,
+       FMTCHECK_INTPOINTER,
+       FMTCHECK_LONGPOINTER,
+       FMTCHECK_QUADPOINTER,
+       FMTCHECK_DOUBLE,
+       FMTCHECK_LONGDOUBLE,
+       FMTCHECK_STRING,
+       FMTCHECK_WIDTH,
+       FMTCHECK_PRECISION,
+       FMTCHECK_DONE,
+       FMTCHECK_UNKNOWN
+};
+typedef enum __e_fmtcheck_types EFT;
+
+#define RETURN(pf,f,r) do { \
+                       *(pf) = (f); \
+                       return r; \
+                      } /*NOTREACHED*/ /*CONSTCOND*/ while (0)
+
+static EFT
+get_next_format_from_precision(const char **pf)
+{
+       int             sh, lg, quad, longdouble;
+       const char      *f;
+
+       sh = lg = quad = longdouble = 0;
+
+       f = *pf;
+       switch (*f) {
+       case 'h':
+               f++;
+               sh = 1;
+               break;
+       case 'l':
+               f++;
+               if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (*f == 'l') {
+                       f++;
+                       quad = 1;
+               } else {
+                       lg = 1;
+               }
+               break;
+       case 'q':
+               f++;
+               quad = 1;
+               break;
+       case 'L':
+               f++;
+               longdouble = 1;
+               break;
+#ifdef WIN32
+       case 'I':
+               f++;
+               if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (*f == '3' && f[1] == '2') {
+                       f += 2;
+               } else if (*f == '6' && f[1] == '4') {
+                       f += 2;
+                       quad = 1;
+               }
+#ifdef _WIN64
+               else {
+                       quad = 1;
+               }
+#endif
+               break;
+#endif
+       default:
+               break;
+       }
+       if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+       if (strchr("diouxX", *f)) {
+               if (longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (lg)
+                       RETURN(pf,f,FMTCHECK_LONG);
+               if (quad)
+                       RETURN(pf,f,FMTCHECK_QUAD);
+               RETURN(pf,f,FMTCHECK_INT);
+       }
+       if (*f == 'n') {
+               if (longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (sh)
+                       RETURN(pf,f,FMTCHECK_SHORTPOINTER);
+               if (lg)
+                       RETURN(pf,f,FMTCHECK_LONGPOINTER);
+               if (quad)
+                       RETURN(pf,f,FMTCHECK_QUADPOINTER);
+               RETURN(pf,f,FMTCHECK_INTPOINTER);
+       }
+       if (strchr("DOU", *f)) {
+               if (sh + lg + quad + longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_LONG);
+       }
+       if (strchr("eEfg", *f)) {
+               if (longdouble)
+                       RETURN(pf,f,FMTCHECK_LONGDOUBLE);
+               if (sh + lg + quad)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_DOUBLE);
+       }
+       if (*f == 'c') {
+               if (sh + lg + quad + longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_INT);
+       }
+       if (*f == 's') {
+               if (sh + lg + quad + longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_STRING);
+       }
+       if (*f == 'p') {
+               if (sh + lg + quad + longdouble)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               RETURN(pf,f,FMTCHECK_LONG);
+       }
+       RETURN(pf,f,FMTCHECK_UNKNOWN);
+       /*NOTREACHED*/
+}
+
+static EFT
+get_next_format_from_width(const char **pf)
+{
+       const char      *f;
+
+       f = *pf;
+       if (*f == '.') {
+               f++;
+               if (*f == '*') {
+                       RETURN(pf,f,FMTCHECK_PRECISION);
+               }
+               /* eat any precision (empty is allowed) */
+               while (isdigit((unsigned char)*f)) f++;
+               if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
+       }
+       RETURN(pf,f,get_next_format_from_precision(pf));
+       /*NOTREACHED*/
+}
+
+static EFT
+get_next_format(const char **pf, EFT eft)
+{
+       int             infmt;
+       const char      *f;
+
+       if (eft == FMTCHECK_WIDTH) {
+               (*pf)++;
+               return get_next_format_from_width(pf);
+       } else if (eft == FMTCHECK_PRECISION) {
+               (*pf)++;
+               return get_next_format_from_precision(pf);
+       }
+
+       f = *pf;
+       infmt = 0;
+       while (!infmt) {
+               f = strchr(f, '%');
+               if (f == NULL)
+                       RETURN(pf,f,FMTCHECK_DONE);
+               f++;
+               if (!*f)
+                       RETURN(pf,f,FMTCHECK_UNKNOWN);
+               if (*f != '%')
+                       infmt = 1;
+               else
+                       f++;
+       }
+
+       /* Eat any of the flags */
+       while (*f && (strchr("#0- +", *f)))
+               f++;
+
+       if (*f == '*') {
+               RETURN(pf,f,FMTCHECK_WIDTH);
+       }
+       /* eat any width */
+       while (isdigit((unsigned char)*f)) f++;
+       if (!*f) {
+               RETURN(pf,f,FMTCHECK_UNKNOWN);
+       }
+
+       RETURN(pf,f,get_next_format_from_width(pf));
+       /*NOTREACHED*/
+}
+
+const char *
+fmtcheck(const char *f1, const char *f2)
+{
+       const char      *f1p, *f2p;
+       EFT             f1t, f2t;
+
+       if (!f1) return f2;
+
+       f1p = f1;
+       f1t = FMTCHECK_START;
+       f2p = f2;
+       f2t = FMTCHECK_START;
+       while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) {
+               if (f1t == FMTCHECK_UNKNOWN)
+                       return f2;
+               f2t = get_next_format(&f2p, f2t);
+               if (f1t != f2t)
+                       return f2;
+       }
+       return f1;
+}
diff --git a/src/fsmagic.c b/src/fsmagic.c
new file mode 100644 (file)
index 0000000..25c4f81
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * fsmagic - magic based on filesystem info - directory, special files, etc.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.80 2019/04/23 18:59:27 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+/* Since major is a function on SVR4, we cannot use `ifndef major'.  */
+#ifdef MAJOR_IN_MKDEV
+# include <sys/mkdev.h>
+# define HAVE_MAJOR
+#endif
+#ifdef HAVE_SYS_SYSMACROS_H
+# include <sys/sysmacros.h>
+#endif
+#ifdef MAJOR_IN_SYSMACROS
+# define HAVE_MAJOR
+#endif
+#if defined(major) && !defined(HAVE_MAJOR)
+/* Might be defined in sys/types.h.  */
+# define HAVE_MAJOR
+#endif
+#ifdef WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#ifndef HAVE_MAJOR
+# define major(dev)  (((dev) >> 8) & 0xff)
+# define minor(dev)  ((dev) & 0xff)
+#endif
+#undef HAVE_MAJOR
+#ifdef S_IFLNK
+private int
+bad_link(struct magic_set *ms, int err, char *buf)
+{
+       int mime = ms->flags & MAGIC_MIME;
+       if ((mime & MAGIC_MIME_TYPE) &&
+           file_printf(ms, "inode/symlink")
+           == -1)
+               return -1;
+       else if (!mime) {
+               if (ms->flags & MAGIC_ERROR) {
+                       file_error(ms, err,
+                                  "broken symbolic link to %s", buf);
+                       return -1;
+               }
+               if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
+                       return -1;
+       }
+       return 1;
+}
+#endif
+private int
+handle_mime(struct magic_set *ms, int mime, const char *str)
+{
+       if ((mime & MAGIC_MIME_TYPE)) {
+               if (file_printf(ms, "inode/%s", str) == -1)
+                       return -1;
+               if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms,
+                   "; charset=") == -1)
+                       return -1;
+       }
+       if ((mime & MAGIC_MIME_ENCODING) && file_printf(ms, "binary") == -1)
+               return -1;
+       return 0;
+}
+
+protected int
+file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
+{
+       int ret, did = 0;
+       int mime = ms->flags & MAGIC_MIME;
+       int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
+#ifdef S_IFLNK
+       char buf[BUFSIZ+4];
+       ssize_t nch;
+       struct stat tstatbuf;
+#endif
+
+       if (fn == NULL)
+               return 0;
+
+#define COMMA  (did++ ? ", " : "")
+       /*
+        * Fstat is cheaper but fails for files you don't have read perms on.
+        * On 4.2BSD and similar systems, use lstat() to identify symlinks.
+        */
+#ifdef S_IFLNK
+       if ((ms->flags & MAGIC_SYMLINK) == 0)
+               ret = lstat(fn, sb);
+       else
+#endif
+       ret = stat(fn, sb);     /* don't merge into if; see "ret =" above */
+
+#ifdef WIN32
+       {
+               HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
+                   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
+                   NULL);
+               if (hFile != INVALID_HANDLE_VALUE) {
+                       /*
+                        * Stat failed, but we can still open it - assume it's
+                        * a block device, if nothing else.
+                        */
+                       if (ret) {
+                               sb->st_mode = S_IFBLK;
+                               ret = 0;
+                       }
+                       switch (GetFileType(hFile)) {
+                       case FILE_TYPE_CHAR:
+                               sb->st_mode |= S_IFCHR;
+                               sb->st_mode &= ~S_IFREG;
+                               break;
+                       case FILE_TYPE_PIPE:
+                               sb->st_mode |= S_IFIFO;
+                               sb->st_mode &= ~S_IFREG;
+                               break;
+                       }
+                       CloseHandle(hFile);
+               }
+       }
+#endif
+
+       if (ret) {
+               if (ms->flags & MAGIC_ERROR) {
+                       file_error(ms, errno, "cannot stat `%s'", fn);
+                       return -1;
+               }
+               if (file_printf(ms, "cannot open `%s' (%s)",
+                   fn, strerror(errno)) == -1)
+                       return -1;
+               return 0;
+       }
+
+       ret = 1;
+       if (!mime && !silent) {
+#ifdef S_ISUID
+               if (sb->st_mode & S_ISUID)
+                       if (file_printf(ms, "%ssetuid", COMMA) == -1)
+                               return -1;
+#endif
+#ifdef S_ISGID
+               if (sb->st_mode & S_ISGID)
+                       if (file_printf(ms, "%ssetgid", COMMA) == -1)
+                               return -1;
+#endif
+#ifdef S_ISVTX
+               if (sb->st_mode & S_ISVTX)
+                       if (file_printf(ms, "%ssticky", COMMA) == -1)
+                               return -1;
+#endif
+       }
+
+       switch (sb->st_mode & S_IFMT) {
+       case S_IFDIR:
+               if (mime) {
+                       if (handle_mime(ms, mime, "directory") == -1)
+                               return -1;
+               } else if (silent) {
+               } else if (file_printf(ms, "%sdirectory", COMMA) == -1)
+                       return -1;
+               break;
+#ifdef S_IFCHR
+       case S_IFCHR:
+               /*
+                * If -s has been specified, treat character special files
+                * like ordinary files.  Otherwise, just report that they
+                * are block special files and go on to the next file.
+                */
+               if ((ms->flags & MAGIC_DEVICES) != 0) {
+                       ret = 0;
+                       break;
+               }
+               if (mime) {
+                       if (handle_mime(ms, mime, "chardevice") == -1)
+                               return -1;
+               } else if (silent) {
+               } else {
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+# ifdef dv_unit
+                       if (file_printf(ms, "%scharacter special (%d/%d/%d)",
+                           COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
+                                       dv_subunit(sb->st_rdev)) == -1)
+                               return -1;
+# else
+                       if (file_printf(ms, "%scharacter special (%ld/%ld)",
+                           COMMA, (long)major(sb->st_rdev),
+                           (long)minor(sb->st_rdev)) == -1)
+                               return -1;
+# endif
+#else
+                       if (file_printf(ms, "%scharacter special", COMMA) == -1)
+                               return -1;
+#endif
+               }
+               break;
+#endif
+#ifdef S_IFBLK
+       case S_IFBLK:
+               /*
+                * If -s has been specified, treat block special files
+                * like ordinary files.  Otherwise, just report that they
+                * are block special files and go on to the next file.
+                */
+               if ((ms->flags & MAGIC_DEVICES) != 0) {
+                       ret = 0;
+                       break;
+               }
+               if (mime) {
+                       if (handle_mime(ms, mime, "blockdevice") == -1)
+                               return -1;
+               } else if (silent) {
+               } else {
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+# ifdef dv_unit
+                       if (file_printf(ms, "%sblock special (%d/%d/%d)",
+                           COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
+                           dv_subunit(sb->st_rdev)) == -1)
+                               return -1;
+# else
+                       if (file_printf(ms, "%sblock special (%ld/%ld)",
+                           COMMA, (long)major(sb->st_rdev),
+                           (long)minor(sb->st_rdev)) == -1)
+                               return -1;
+# endif
+#else
+                       if (file_printf(ms, "%sblock special", COMMA) == -1)
+                               return -1;
+#endif
+               }
+               break;
+#endif
+       /* TODO add code to handle V7 MUX and Blit MUX files */
+#ifdef S_IFIFO
+       case S_IFIFO:
+               if((ms->flags & MAGIC_DEVICES) != 0)
+                       break;
+               if (mime) {
+                       if (handle_mime(ms, mime, "fifo") == -1)
+                               return -1;
+               } else if (silent) {
+               } else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
+                       return -1;
+               break;
+#endif
+#ifdef S_IFDOOR
+       case S_IFDOOR:
+               if (mime) {
+                       if (handle_mime(ms, mime, "door") == -1)
+                               return -1;
+               } else if (silent) {
+               } else if (file_printf(ms, "%sdoor", COMMA) == -1)
+                       return -1;
+               break;
+#endif
+#ifdef S_IFLNK
+       case S_IFLNK:
+               if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
+                       if (ms->flags & MAGIC_ERROR) {
+                           file_error(ms, errno, "unreadable symlink `%s'",
+                               fn);
+                           return -1;
+                       }
+                       if (mime) {
+                               if (handle_mime(ms, mime, "symlink") == -1)
+                                       return -1;
+                       } else if (silent) {
+                       } else if (file_printf(ms,
+                           "%sunreadable symlink `%s' (%s)", COMMA, fn,
+                           strerror(errno)) == -1)
+                               return -1;
+                       break;
+               }
+               buf[nch] = '\0';        /* readlink(2) does not do this */
+
+               /* If broken symlink, say so and quit early. */
+#ifdef __linux__
+               /*
+                * linux procfs/devfs makes symlinks like pipe:[3515864880]
+                * that we can't stat their readlink output, so stat the
+                * original filename instead.
+                */
+               if (stat(fn, &tstatbuf) < 0)
+                       return bad_link(ms, errno, buf);
+#else
+               if (*buf == '/') {
+                       if (stat(buf, &tstatbuf) < 0)
+                               return bad_link(ms, errno, buf);
+               } else {
+                       char *tmp;
+                       char buf2[BUFSIZ+BUFSIZ+4];
+
+                       if ((tmp = strrchr(fn,  '/')) == NULL) {
+                               tmp = buf; /* in current directory anyway */
+                       } else {
+                               if (tmp - fn + 1 > BUFSIZ) {
+                                       if (ms->flags & MAGIC_ERROR) {
+                                               file_error(ms, 0,
+                                                   "path too long: `%s'", buf);
+                                               return -1;
+                                       }
+                                       if (mime) {
+                                               if (handle_mime(ms, mime,
+                                                   "x-path-too-long") == -1)
+                                                       return -1;
+                                       } else if (silent) {
+                                       } else if (file_printf(ms,
+                                           "%spath too long: `%s'", COMMA,
+                                           fn) == -1)
+                                               return -1;
+                                       break;
+                               }
+                               /* take dir part */
+                               (void)strlcpy(buf2, fn, sizeof buf2);
+                               buf2[tmp - fn + 1] = '\0';
+                               /* plus (rel) link */
+                               (void)strlcat(buf2, buf, sizeof buf2);
+                               tmp = buf2;
+                       }
+                       if (stat(tmp, &tstatbuf) < 0)
+                               return bad_link(ms, errno, buf);
+               }
+#endif
+
+               /* Otherwise, handle it. */
+               if ((ms->flags & MAGIC_SYMLINK) != 0) {
+                       const char *p;
+                       ms->flags &= MAGIC_SYMLINK;
+                       p = magic_file(ms, buf);
+                       ms->flags |= MAGIC_SYMLINK;
+                       if (p == NULL)
+                               return -1;
+               } else { /* just print what it points to */
+                       if (mime) {
+                               if (handle_mime(ms, mime, "symlink") == -1)
+                                       return -1;
+                       } else if (silent) {
+                       } else if (file_printf(ms, "%ssymbolic link to %s",
+                           COMMA, buf) == -1)
+                               return -1;
+               }
+               break;
+#endif
+#ifdef S_IFSOCK
+#ifndef __COHERENT__
+       case S_IFSOCK:
+               if (mime) {
+                       if (handle_mime(ms, mime, "socket") == -1)
+                               return -1;
+               } else if (silent) {
+               } else if (file_printf(ms, "%ssocket", COMMA) == -1)
+                       return -1;
+               break;
+#endif
+#endif
+       case S_IFREG:
+               /*
+                * regular file, check next possibility
+                *
+                * If stat() tells us the file has zero length, report here that
+                * the file is empty, so we can skip all the work of opening and
+                * reading the file.
+                * But if the -s option has been given, we skip this
+                * optimization, since on some systems, stat() reports zero
+                * size for raw disk partitions. (If the block special device
+                * really has zero length, the fact that it is empty will be
+                * detected and reported correctly when we read the file.)
+                */
+               if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
+                       if (mime) {
+                               if (handle_mime(ms, mime, "x-empty") == -1)
+                                       return -1;
+                       } else if (silent) {
+                       } else if (file_printf(ms, "%sempty", COMMA) == -1)
+                               return -1;
+                       break;
+               }
+               ret = 0;
+               break;
+
+       default:
+               file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
+               return -1;
+               /*NOTREACHED*/
+       }
+
+       if (!silent && !mime && did && ret == 0) {
+           if (file_printf(ms, " ") == -1)
+                   return -1;
+       }
+       return ret;
+}
diff --git a/src/funcs.c b/src/funcs.c
new file mode 100644 (file)
index 0000000..23e7f32
--- /dev/null
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: funcs.c,v 1.104 2019/05/07 02:27:11 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <assert.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#if defined(HAVE_WCHAR_H)
+#include <wchar.h>
+#endif
+#if defined(HAVE_WCTYPE_H)
+#include <wctype.h>
+#endif
+#include <limits.h>
+
+#ifndef SIZE_MAX
+#define SIZE_MAX       ((size_t)~0)
+#endif
+
+/*
+ * Like printf, only we append to a buffer.
+ */
+protected int
+file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
+{
+       int len;
+       char *buf, *newstr;
+
+       if (ms->event_flags & EVENT_HAD_ERR)
+               return 0;
+       len = vasprintf(&buf, fmt, ap);
+       if (len < 0)
+               goto out;
+
+       if (ms->o.buf != NULL) {
+               len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
+               free(buf);
+               if (len < 0)
+                       goto out;
+               free(ms->o.buf);
+               buf = newstr;
+       }
+       ms->o.buf = buf;
+       return 0;
+out:
+       fprintf(stderr, "vasprintf failed (%s)", strerror(errno));
+       return -1;
+}
+
+protected int
+file_printf(struct magic_set *ms, const char *fmt, ...)
+{
+       int rv;
+       va_list ap;
+
+       va_start(ap, fmt);
+       rv = file_vprintf(ms, fmt, ap);
+       va_end(ap);
+       return rv;
+}
+
+/*
+ * error - print best error message possible
+ */
+/*VARARGS*/
+__attribute__((__format__(__printf__, 3, 0)))
+private void
+file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
+    size_t lineno)
+{
+       /* Only the first error is ok */
+       if (ms->event_flags & EVENT_HAD_ERR)
+               return;
+       if (lineno != 0) {
+               free(ms->o.buf);
+               ms->o.buf = NULL;
+               (void)file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
+       }
+       if (ms->o.buf && *ms->o.buf)
+               (void)file_printf(ms, " ");
+       (void)file_vprintf(ms, f, va);
+       if (error > 0)
+               (void)file_printf(ms, " (%s)", strerror(error));
+       ms->event_flags |= EVENT_HAD_ERR;
+       ms->error = error;
+}
+
+/*VARARGS*/
+protected void
+file_error(struct magic_set *ms, int error, const char *f, ...)
+{
+       va_list va;
+       va_start(va, f);
+       file_error_core(ms, error, f, va, 0);
+       va_end(va);
+}
+
+/*
+ * Print an error with magic line number.
+ */
+/*VARARGS*/
+protected void
+file_magerror(struct magic_set *ms, const char *f, ...)
+{
+       va_list va;
+       va_start(va, f);
+       file_error_core(ms, 0, f, va, ms->line);
+       va_end(va);
+}
+
+protected void
+file_oomem(struct magic_set *ms, size_t len)
+{
+       file_error(ms, errno, "cannot allocate %" SIZE_T_FORMAT "u bytes",
+           len);
+}
+
+protected void
+file_badseek(struct magic_set *ms)
+{
+       file_error(ms, errno, "error seeking");
+}
+
+protected void
+file_badread(struct magic_set *ms)
+{
+       file_error(ms, errno, "error reading");
+}
+
+#ifndef COMPILE_ONLY
+
+protected int
+file_separator(struct magic_set *ms)
+{
+       return file_printf(ms, "\n- ");
+}
+
+static int
+checkdone(struct magic_set *ms, int *rv)
+{
+       if ((ms->flags & MAGIC_CONTINUE) == 0)
+               return 1;
+       if (file_separator(ms) == -1)
+               *rv = -1;
+       return 0;
+}
+
+protected int
+file_default(struct magic_set *ms, size_t nb)
+{
+       if (ms->flags & MAGIC_MIME) {
+               if ((ms->flags & MAGIC_MIME_TYPE) &&
+                   file_printf(ms, "application/%s",
+                       nb ? "octet-stream" : "x-empty") == -1)
+                       return -1;
+               return 1;
+       }
+       if (ms->flags & MAGIC_APPLE) {
+               if (file_printf(ms, "UNKNUNKN") == -1)
+                       return -1;
+               return 1;
+       }
+       if (ms->flags & MAGIC_EXTENSION) {
+               if (file_printf(ms, "???") == -1)
+                       return -1;
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * The magic detection functions return:
+ *      1: found
+ *      0: not found
+ *     -1: error
+ */
+/*ARGSUSED*/
+protected int
+file_buffer(struct magic_set *ms, int fd, struct stat *st,
+    const char *inname __attribute__ ((__unused__)),
+    const void *buf, size_t nb)
+{
+       int m = 0, rv = 0, looks_text = 0;
+       const char *code = NULL;
+       const char *code_mime = "binary";
+       const char *def = "data";
+       const char *ftype = NULL;
+       char *rbuf = NULL;
+       struct buffer b;
+
+       buffer_init(&b, fd, st, buf, nb);
+       ms->mode = b.st.st_mode;
+
+       if (nb == 0) {
+               def = "empty";
+               goto simple;
+       } else if (nb == 1) {
+               def = "very short file (no magic)";
+               goto simple;
+       }
+
+       if ((ms->flags & MAGIC_NO_CHECK_ENCODING) == 0) {
+               looks_text = file_encoding(ms, &b, NULL, 0,
+                   &code, &code_mime, &ftype);
+       }
+
+#ifdef __EMX__
+       if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
+               m = file_os2_apptype(ms, inname, &b);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try os2_apptype %d]\n", m);
+               switch (m) {
+               case -1:
+                       return -1;
+               case 0:
+                       break;
+               default:
+                       return 1;
+               }
+       }
+#endif
+#if HAVE_FORK
+       /* try compression stuff */
+       if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
+               m = file_zmagic(ms, &b, inname);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try zmagic %d]\n", m);
+               if (m) {
+                       goto done_encoding;
+               }
+       }
+#endif
+       /* Check if we have a tar file */
+       if ((ms->flags & MAGIC_NO_CHECK_TAR) == 0) {
+               m = file_is_tar(ms, &b);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try tar %d]\n", m);
+               if (m) {
+                       if (checkdone(ms, &rv))
+                               goto done;
+               }
+       }
+
+       /* Check if we have a JSON file */
+       if ((ms->flags & MAGIC_NO_CHECK_JSON) == 0) {
+               m = file_is_json(ms, &b);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try json %d]\n", m);
+               if (m) {
+                       if (checkdone(ms, &rv))
+                               goto done;
+               }
+       }
+
+       /* Check if we have a CDF file */
+       if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
+               m = file_trycdf(ms, &b);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try cdf %d]\n", m);
+               if (m) {
+                       if (checkdone(ms, &rv))
+                               goto done;
+               }
+       }
+#ifdef BUILTIN_ELF
+       if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && nb > 5 && fd != -1) {
+               file_pushbuf_t *pb;
+               /*
+                * We matched something in the file, so this
+                * *might* be an ELF file, and the file is at
+                * least 5 bytes long, so if it's an ELF file
+                * it has at least one byte past the ELF magic
+                * number - try extracting information from the
+                * ELF headers that cannot easily be  extracted
+                * with rules in the magic file. We we don't
+                * print the information yet.
+                */
+               if ((pb = file_push_buffer(ms)) == NULL)
+                       return -1;
+
+               rv = file_tryelf(ms, &b);
+               rbuf = file_pop_buffer(ms, pb);
+               if (rv == -1) {
+                       free(rbuf);
+                       rbuf = NULL;
+               }
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try elf %d]\n", m);
+       }
+#endif
+
+       /* try soft magic tests */
+       if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) {
+               m = file_softmagic(ms, &b, NULL, NULL, BINTEST, looks_text);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try softmagic %d]\n", m);
+               if (m == 1 && rbuf) {
+                       if (file_printf(ms, "%s", rbuf) == -1)
+                               goto done;
+               }
+               if (m) {
+                       if (checkdone(ms, &rv))
+                               goto done;
+               }
+       }
+
+       /* try text properties */
+       if ((ms->flags & MAGIC_NO_CHECK_TEXT) == 0) {
+
+               m = file_ascmagic(ms, &b, looks_text);
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void)fprintf(stderr, "[try ascmagic %d]\n", m);
+               if (m) {
+                       goto done;
+               }
+       }
+
+simple:
+       /* give up */
+       if (m == 0) {
+               m = 1;
+               rv = file_default(ms, nb);
+               if (rv == 0)
+                       if (file_printf(ms, "%s", def) == -1)
+                               rv = -1;
+       }
+ done:
+       if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {
+               if (ms->flags & MAGIC_MIME_TYPE)
+                       if (file_printf(ms, "; charset=") == -1)
+                               rv = -1;
+               if (file_printf(ms, "%s", code_mime) == -1)
+                       rv = -1;
+       }
+#if HAVE_FORK
+ done_encoding:
+#endif
+       free(rbuf);
+       buffer_fini(&b);
+       if (rv)
+               return rv;
+
+       return m;
+}
+#endif
+
+protected int
+file_reset(struct magic_set *ms, int checkloaded)
+{
+       if (checkloaded && ms->mlist[0] == NULL) {
+               file_error(ms, 0, "no magic files loaded");
+               return -1;
+       }
+       if (ms->o.buf) {
+               free(ms->o.buf);
+               ms->o.buf = NULL;
+       }
+       if (ms->o.pbuf) {
+               free(ms->o.pbuf);
+               ms->o.pbuf = NULL;
+       }
+       ms->event_flags &= ~EVENT_HAD_ERR;
+       ms->error = -1;
+       return 0;
+}
+
+#define OCTALIFY(n, o) \
+       /*LINTED*/ \
+       (void)(*(n)++ = '\\', \
+       *(n)++ = ((CAST(uint32_t, *(o)) >> 6) & 3) + '0', \
+       *(n)++ = ((CAST(uint32_t, *(o)) >> 3) & 7) + '0', \
+       *(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \
+       (o)++)
+
+protected const char *
+file_getbuffer(struct magic_set *ms)
+{
+       char *pbuf, *op, *np;
+       size_t psize, len;
+
+       if (ms->event_flags & EVENT_HAD_ERR)
+               return NULL;
+
+       if (ms->flags & MAGIC_RAW)
+               return ms->o.buf;
+
+       if (ms->o.buf == NULL)
+               return NULL;
+
+       /* * 4 is for octal representation, + 1 is for NUL */
+       len = strlen(ms->o.buf);
+       if (len > (SIZE_MAX - 1) / 4) {
+               file_oomem(ms, len);
+               return NULL;
+       }
+       psize = len * 4 + 1;
+       if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
+               file_oomem(ms, psize);
+               return NULL;
+       }
+       ms->o.pbuf = pbuf;
+
+#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
+       {
+               mbstate_t state;
+               wchar_t nextchar;
+               int mb_conv = 1;
+               size_t bytesconsumed;
+               char *eop;
+               (void)memset(&state, 0, sizeof(mbstate_t));
+
+               np = ms->o.pbuf;
+               op = ms->o.buf;
+               eop = op + len;
+
+               while (op < eop) {
+                       bytesconsumed = mbrtowc(&nextchar, op,
+                           CAST(size_t, eop - op), &state);
+                       if (bytesconsumed == CAST(size_t, -1) ||
+                           bytesconsumed == CAST(size_t, -2)) {
+                               mb_conv = 0;
+                               break;
+                       }
+
+                       if (iswprint(nextchar)) {
+                               (void)memcpy(np, op, bytesconsumed);
+                               op += bytesconsumed;
+                               np += bytesconsumed;
+                       } else {
+                               while (bytesconsumed-- > 0)
+                                       OCTALIFY(np, op);
+                       }
+               }
+               *np = '\0';
+
+               /* Parsing succeeded as a multi-byte sequence */
+               if (mb_conv != 0)
+                       return ms->o.pbuf;
+       }
+#endif
+
+       for (np = ms->o.pbuf, op = ms->o.buf; *op;) {
+               if (isprint(CAST(unsigned char, *op))) {
+                       *np++ = *op++;
+               } else {
+                       OCTALIFY(np, op);
+               }
+       }
+       *np = '\0';
+       return ms->o.pbuf;
+}
+
+protected int
+file_check_mem(struct magic_set *ms, unsigned int level)
+{
+       size_t len;
+
+       if (level >= ms->c.len) {
+               len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
+               ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
+                   malloc(len) :
+                   realloc(ms->c.li, len));
+               if (ms->c.li == NULL) {
+                       file_oomem(ms, len);
+                       return -1;
+               }
+       }
+       ms->c.li[level].got_match = 0;
+#ifdef ENABLE_CONDITIONALS
+       ms->c.li[level].last_match = 0;
+       ms->c.li[level].last_cond = COND_NONE;
+#endif /* ENABLE_CONDITIONALS */
+       return 0;
+}
+
+protected size_t
+file_printedlen(const struct magic_set *ms)
+{
+       return ms->o.buf == NULL ? 0 : strlen(ms->o.buf);
+}
+
+protected int
+file_replace(struct magic_set *ms, const char *pat, const char *rep)
+{
+       file_regex_t rx;
+       int rc, rv = -1;
+
+       rc = file_regcomp(&rx, pat, REG_EXTENDED);
+       if (rc) {
+               file_regerror(&rx, rc, ms);
+       } else {
+               regmatch_t rm;
+               int nm = 0;
+               while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
+                       ms->o.buf[rm.rm_so] = '\0';
+                       if (file_printf(ms, "%s%s", rep,
+                           rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
+                               goto out;
+                       nm++;
+               }
+               rv = nm;
+       }
+out:
+       file_regfree(&rx);
+       return rv;
+}
+
+protected int
+file_regcomp(file_regex_t *rx, const char *pat, int flags)
+{
+#ifdef USE_C_LOCALE
+       rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
+       assert(rx->c_lc_ctype != NULL);
+       rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
+       assert(rx->old_lc_ctype != NULL);
+#else
+       rx->old_lc_ctype = setlocale(LC_CTYPE, "C");
+#endif
+       rx->pat = pat;
+
+       return rx->rc = regcomp(&rx->rx, pat, flags);
+}
+
+protected int
+file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
+    regmatch_t* pmatch, int eflags)
+{
+       assert(rx->rc == 0);
+       /* XXX: force initialization because glibc does not always do this */
+       memset(pmatch, 0, nmatch * sizeof(*pmatch));
+       return regexec(&rx->rx, str, nmatch, pmatch, eflags);
+}
+
+protected void
+file_regfree(file_regex_t *rx)
+{
+       if (rx->rc == 0)
+               regfree(&rx->rx);
+#ifdef USE_C_LOCALE
+       (void)uselocale(rx->old_lc_ctype);
+       freelocale(rx->c_lc_ctype);
+#else
+       (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
+#endif
+}
+
+protected void
+file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
+{
+       char errmsg[512];
+
+       (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg));
+       file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
+           errmsg);
+}
+
+protected file_pushbuf_t *
+file_push_buffer(struct magic_set *ms)
+{
+       file_pushbuf_t *pb;
+
+       if (ms->event_flags & EVENT_HAD_ERR)
+               return NULL;
+
+       if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
+               return NULL;
+
+       pb->buf = ms->o.buf;
+       pb->offset = ms->offset;
+
+       ms->o.buf = NULL;
+       ms->offset = 0;
+
+       return pb;
+}
+
+protected char *
+file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
+{
+       char *rbuf;
+
+       if (ms->event_flags & EVENT_HAD_ERR) {
+               free(pb->buf);
+               free(pb);
+               return NULL;
+       }
+
+       rbuf = ms->o.buf;
+
+       ms->o.buf = pb->buf;
+       ms->offset = pb->offset;
+
+       free(pb);
+       return rbuf;
+}
+
+/*
+ * convert string to ascii printable format.
+ */
+protected char *
+file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
+{
+       char *ptr, *eptr = buf + bufsiz - 1;
+       const unsigned char *s = RCAST(const unsigned char *, str);
+       const unsigned char *es = s + slen;
+
+       for (ptr = buf;  ptr < eptr && s < es && *s; s++) {
+               if (isprint(*s)) {
+                       *ptr++ = *s;
+                       continue;
+               }
+               if (ptr >= eptr - 3)
+                       break;
+               *ptr++ = '\\';
+               *ptr++ = ((CAST(unsigned int, *s) >> 6) & 7) + '0';
+               *ptr++ = ((CAST(unsigned int, *s) >> 3) & 7) + '0';
+               *ptr++ = ((CAST(unsigned int, *s) >> 0) & 7) + '0';
+       }
+       *ptr = '\0';
+       return buf;
+}
diff --git a/src/getline.c b/src/getline.c
new file mode 100644 (file)
index 0000000..b00de01
--- /dev/null
@@ -0,0 +1,104 @@
+/*     $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $     */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "file.h"
+#if !HAVE_GETLINE
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+public ssize_t
+getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
+{
+       char *ptr, *eptr;
+
+
+       if (*buf == NULL || *bufsiz == 0) {
+               *bufsiz = BUFSIZ;
+               if ((*buf = malloc(*bufsiz)) == NULL)
+                       return -1;
+       }
+
+       for (ptr = *buf, eptr = *buf + *bufsiz;;) {
+               int c = fgetc(fp);
+               if (c == -1) {
+                       if (feof(fp)) {
+                               ssize_t diff = (ssize_t)(ptr - *buf);
+                               if (diff != 0) {
+                                       *ptr = '\0';
+                                       return diff;
+                               }
+                       }
+                       return -1;
+               }
+               *ptr++ = c;
+               if (c == delimiter) {
+                       *ptr = '\0';
+                       return ptr - *buf;
+               }
+               if (ptr + 2 >= eptr) {
+                       char *nbuf;
+                       size_t nbufsiz = *bufsiz * 2;
+                       ssize_t d = ptr - *buf;
+                       if ((nbuf = realloc(*buf, nbufsiz)) == NULL)
+                               return -1;
+                       *buf = nbuf;
+                       *bufsiz = nbufsiz;
+                       eptr = nbuf + nbufsiz;
+                       ptr = nbuf + d;
+               }
+       }
+}
+
+public ssize_t
+getline(char **buf, size_t *bufsiz, FILE *fp)
+{
+       return getdelim(buf, bufsiz, '\n', fp);
+}
+
+#endif
+
+#ifdef TEST
+int
+main(int argc, char *argv[])
+{
+       char *p = NULL;
+       ssize_t len;
+       size_t n = 0;
+
+       while ((len = getline(&p, &n, stdin)) != -1)
+               (void)printf("%" SIZE_T_FORMAT "d %s", len, p);
+       free(p);
+       return 0;
+}
+#endif
diff --git a/src/getopt_long.c b/src/getopt_long.c
new file mode 100644 (file)
index 0000000..43c4245
--- /dev/null
@@ -0,0 +1,498 @@
+/*     $NetBSD: getopt_long.c,v 1.21.4.1 2008/01/09 01:34:14 matt Exp $        */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: getopt_long.c,v 1.7 2018/09/09 20:33:28 christos Exp $")
+#endif /* lint */
+
+#include <assert.h>
+#ifdef HAVE_ERR_H
+#include <err.h>
+#else
+#define warnx printf
+#endif
+#include <errno.h>
+#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
+#include <getopt.h>
+#else
+#include "mygetopt.h"
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#define REPLACE_GETOPT
+
+#ifndef _DIAGASSERT
+#define _DIAGASSERT assert
+#endif
+
+#ifdef REPLACE_GETOPT
+#ifdef __weak_alias
+__weak_alias(getopt,_getopt)
+#endif
+int    opterr = 1;             /* if error message should be printed */
+int    optind = 1;             /* index into parent argv vector */
+int    optopt = '?';           /* character checked for validity */
+int    optreset;               /* reset getopt */
+char    *optarg;               /* argument associated with option */
+#elif HAVE_NBTOOL_CONFIG_H && !HAVE_DECL_OPTRESET
+static int optreset;
+#endif
+
+#ifdef __weak_alias
+__weak_alias(getopt_long,_getopt_long)
+#endif
+
+#define IGNORE_FIRST   (*options == '-' || *options == '+')
+#define PRINT_ERROR    ((opterr) && ((*options != ':') \
+                                     || (IGNORE_FIRST && options[1] != ':')))
+#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
+#define PERMUTE         (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
+/* XXX: GNU ignores PC if *options == '-' */
+#define IN_ORDER        (!IS_POSIXLY_CORRECT && *options == '-')
+
+/* return values */
+#define        BADCH   (int)'?'
+#define        BADARG          ((IGNORE_FIRST && options[1] == ':') \
+                        || (*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define        EMSG    ""
+
+static int getopt_internal(int, char **, const char *);
+static int gcd(int, int);
+static void permute_args(int, int, int, char **);
+
+static const char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1;   /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(a, b)
+       int a;
+       int b;
+{
+       int c;
+
+       c = a % b;
+       while (c != 0) {
+               a = b;
+               b = c;
+               c = a % b;
+       }
+
+       return b;
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(panonopt_start, panonopt_end, opt_end, nargv)
+       int panonopt_start;
+       int panonopt_end;
+       int opt_end;
+       char **nargv;
+{
+       int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+       char *swap;
+
+       _DIAGASSERT(nargv != NULL);
+
+       /*
+        * compute lengths of blocks and number and size of cycles
+        */
+       nnonopts = panonopt_end - panonopt_start;
+       nopts = opt_end - panonopt_end;
+       ncycle = gcd(nnonopts, nopts);
+       cyclelen = (opt_end - panonopt_start) / ncycle;
+
+       for (i = 0; i < ncycle; i++) {
+               cstart = panonopt_end+i;
+               pos = cstart;
+               for (j = 0; j < cyclelen; j++) {
+                       if (pos >= panonopt_end)
+                               pos -= nnonopts;
+                       else
+                               pos += nopts;
+                       swap = nargv[pos];
+                       nargv[pos] = nargv[cstart];
+                       nargv[cstart] = swap;
+               }
+       }
+}
+
+/*
+ * getopt_internal --
+ *     Parse argc/argv argument vector.  Called by user level routines.
+ *  Returns -2 if -- is found (can be long option or end of options marker).
+ */
+static int
+getopt_internal(nargc, nargv, options)
+       int nargc;
+       char **nargv;
+       const char *options;
+{
+       char *oli;                              /* option letter list index */
+       int optchar;
+
+       _DIAGASSERT(nargv != NULL);
+       _DIAGASSERT(options != NULL);
+
+       optarg = NULL;
+
+       /*
+        * XXX Some programs (like rsyncd) expect to be able to
+        * XXX re-initialize optind to 0 and have getopt_long(3)
+        * XXX properly function again.  Work around this braindamage.
+        */
+       if (optind == 0)
+               optind = 1;
+
+       if (optreset)
+               nonopt_start = nonopt_end = -1;
+start:
+       if (optreset || !*place) {              /* update scanning pointer */
+               optreset = 0;
+               if (optind >= nargc) {          /* end of argument vector */
+                       place = EMSG;
+                       if (nonopt_end != -1) {
+                               /* do permutation, if we have to */
+                               permute_args(nonopt_start, nonopt_end,
+                                   optind, nargv);
+                               optind -= nonopt_end - nonopt_start;
+                       }
+                       else if (nonopt_start != -1) {
+                               /*
+                                * If we skipped non-options, set optind
+                                * to the first of them.
+                                */
+                               optind = nonopt_start;
+                       }
+                       nonopt_start = nonopt_end = -1;
+                       return -1;
+               }
+               if ((*(place = nargv[optind]) != '-')
+                   || (place[1] == '\0')) {    /* found non-option */
+                       place = EMSG;
+                       if (IN_ORDER) {
+                               /*
+                                * GNU extension:
+                                * return non-option as argument to option 1
+                                */
+                               optarg = nargv[optind++];
+                               return INORDER;
+                       }
+                       if (!PERMUTE) {
+                               /*
+                                * if no permutation wanted, stop parsing
+                                * at first non-option
+                                */
+                               return -1;
+                       }
+                       /* do permutation */
+                       if (nonopt_start == -1)
+                               nonopt_start = optind;
+                       else if (nonopt_end != -1) {
+                               permute_args(nonopt_start, nonopt_end,
+                                   optind, nargv);
+                               nonopt_start = optind -
+                                   (nonopt_end - nonopt_start);
+                               nonopt_end = -1;
+                       }
+                       optind++;
+                       /* process next argument */
+                       goto start;
+               }
+               if (nonopt_start != -1 && nonopt_end == -1)
+                       nonopt_end = optind;
+               if (place[1] && *++place == '-') {      /* found "--" */
+                       place++;
+                       return -2;
+               }
+       }
+       if ((optchar = (int)*place++) == (int)':' ||
+           (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
+               /* option letter unknown or ':' */
+               if (!*place)
+                       ++optind;
+               if (PRINT_ERROR)
+                       warnx(illoptchar, optchar);
+               optopt = optchar;
+               return BADCH;
+       }
+       if (optchar == 'W' && oli[1] == ';') {          /* -W long-option */
+               /* XXX: what if no long options provided (called by getopt)? */
+               if (*place)
+                       return -2;
+
+               if (++optind >= nargc) {        /* no arg */
+                       place = EMSG;
+                       if (PRINT_ERROR)
+                               warnx(recargchar, optchar);
+                       optopt = optchar;
+                       return BADARG;
+               } else                          /* white space */
+                       place = nargv[optind];
+               /*
+                * Handle -W arg the same as --arg (which causes getopt to
+                * stop parsing).
+                */
+               return -2;
+       }
+       if (*++oli != ':') {                    /* doesn't take argument */
+               if (!*place)
+                       ++optind;
+       } else {                                /* takes (optional) argument */
+               optarg = NULL;
+               if (*place)                     /* no white space */
+                       optarg = (char *)place;
+               /* XXX: disable test for :: if PC? (GNU doesn't) */
+               else if (oli[1] != ':') {       /* arg not optional */
+                       if (++optind >= nargc) {        /* no arg */
+                               place = EMSG;
+                               if (PRINT_ERROR)
+                                       warnx(recargchar, optchar);
+                               optopt = optchar;
+                               return BADARG;
+                       } else
+                               optarg = nargv[optind];
+               }
+               place = EMSG;
+               ++optind;
+       }
+       /* dump back option letter */
+       return optchar;
+}
+
+#ifdef REPLACE_GETOPT
+/*
+ * getopt --
+ *     Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the real getopt]
+ */
+int
+getopt(nargc, nargv, options)
+       int nargc;
+       char * const *nargv;
+       const char *options;
+{
+       int retval;
+
+       _DIAGASSERT(nargv != NULL);
+       _DIAGASSERT(options != NULL);
+
+       retval = getopt_internal(nargc, (char **)nargv, options);
+       if (retval == -2) {
+               ++optind;
+               /*
+                * We found an option (--), so if we skipped non-options,
+                * we have to permute.
+                */
+               if (nonopt_end != -1) {
+                       permute_args(nonopt_start, nonopt_end, optind,
+                                    (char **)nargv);
+                       optind -= nonopt_end - nonopt_start;
+               }
+               nonopt_start = nonopt_end = -1;
+               retval = -1;
+       }
+       return retval;
+}
+#endif
+
+/*
+ * getopt_long --
+ *     Parse argc/argv argument vector.
+ */
+int
+getopt_long(nargc, nargv, options, long_options, idx)
+       int nargc;
+       char * const *nargv;
+       const char *options;
+       const struct option *long_options;
+       int *idx;
+{
+       int retval;
+
+#define IDENTICAL_INTERPRETATION(_x, _y)                               \
+       (long_options[(_x)].has_arg == long_options[(_y)].has_arg &&    \
+        long_options[(_x)].flag == long_options[(_y)].flag &&          \
+        long_options[(_x)].val == long_options[(_y)].val)
+
+       _DIAGASSERT(nargv != NULL);
+       _DIAGASSERT(options != NULL);
+       _DIAGASSERT(long_options != NULL);
+       /* idx may be NULL */
+
+       retval = getopt_internal(nargc, (char **)nargv, options);
+       if (retval == -2) {
+               char *current_argv, *has_equal;
+               size_t current_argv_len;
+               int i, ambiguous, match;
+
+               current_argv = (char *)place;
+               match = -1;
+               ambiguous = 0;
+
+               optind++;
+               place = EMSG;
+
+               if (*current_argv == '\0') {            /* found "--" */
+                       /*
+                        * We found an option (--), so if we skipped
+                        * non-options, we have to permute.
+                        */
+                       if (nonopt_end != -1) {
+                               permute_args(nonopt_start, nonopt_end,
+                                            optind, (char **)nargv);
+                               optind -= nonopt_end - nonopt_start;
+                       }
+                       nonopt_start = nonopt_end = -1;
+                       return -1;
+               }
+               if ((has_equal = strchr(current_argv, '=')) != NULL) {
+                       /* argument found (--option=arg) */
+                       current_argv_len = has_equal - current_argv;
+                       has_equal++;
+               } else
+                       current_argv_len = strlen(current_argv);
+
+               for (i = 0; long_options[i].name; i++) {
+                       /* find matching long option */
+                       if (strncmp(current_argv, long_options[i].name,
+                           current_argv_len))
+                               continue;
+
+                       if (strlen(long_options[i].name) ==
+                           (unsigned)current_argv_len) {
+                               /* exact match */
+                               match = i;
+                               ambiguous = 0;
+                               break;
+                       }
+                       if (match == -1)                /* partial match */
+                               match = i;
+                       else if (!IDENTICAL_INTERPRETATION(i, match))
+                               ambiguous = 1;
+               }
+               if (ambiguous) {
+                       /* ambiguous abbreviation */
+                       if (PRINT_ERROR)
+                               warnx(ambig, (int)current_argv_len,
+                                    current_argv);
+                       optopt = 0;
+                       return BADCH;
+               }
+               if (match != -1) {                      /* option found */
+                       if (long_options[match].has_arg == no_argument
+                           && has_equal) {
+                               if (PRINT_ERROR)
+                                       warnx(noarg, (int)current_argv_len,
+                                            current_argv);
+                               /*
+                                * XXX: GNU sets optopt to val regardless of
+                                * flag
+                                */
+                               if (long_options[match].flag == NULL)
+                                       optopt = long_options[match].val;
+                               else
+                                       optopt = 0;
+                               return BADARG;
+                       }
+                       if (long_options[match].has_arg == required_argument ||
+                           long_options[match].has_arg == optional_argument) {
+                               if (has_equal)
+                                       optarg = has_equal;
+                               else if (long_options[match].has_arg ==
+                                   required_argument) {
+                                       /*
+                                        * optional argument doesn't use
+                                        * next nargv
+                                        */
+                                       optarg = nargv[optind++];
+                               }
+                       }
+                       if ((long_options[match].has_arg == required_argument)
+                           && (optarg == NULL)) {
+                               /*
+                                * Missing argument; leading ':'
+                                * indicates no error should be generated
+                                */
+                               if (PRINT_ERROR)
+                                       warnx(recargstring, current_argv);
+                               /*
+                                * XXX: GNU sets optopt to val regardless
+                                * of flag
+                                */
+                               if (long_options[match].flag == NULL)
+                                       optopt = long_options[match].val;
+                               else
+                                       optopt = 0;
+                               --optind;
+                               return BADARG;
+                       }
+               } else {                        /* unknown option */
+                       if (PRINT_ERROR)
+                               warnx(illoptstring, current_argv);
+                       optopt = 0;
+                       return BADCH;
+               }
+               if (long_options[match].flag) {
+                       *long_options[match].flag = long_options[match].val;
+                       retval = 0;
+               } else
+                       retval = long_options[match].val;
+               if (idx)
+                       *idx = match;
+       }
+       return retval;
+#undef IDENTICAL_INTERPRETATION
+}
diff --git a/src/gmtime_r.c b/src/gmtime_r.c
new file mode 100644 (file)
index 0000000..7e27ed6
--- /dev/null
@@ -0,0 +1,19 @@
+/*     $File: gmtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $      */
+
+#include "file.h"
+#ifndef        lint
+FILE_RCSID("@(#)$File: gmtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $")
+#endif /* lint */
+#include <time.h>
+#include <string.h>
+
+/* asctime_r is not thread-safe anyway */
+struct tm *
+gmtime_r(const time_t *t, struct tm *tm)
+{
+       struct tm *tmp = gmtime(t);
+       if (tmp == NULL)
+               return NULL;
+       memcpy(tm, tmp, sizeof(*tm));
+       return tmp;
+}
diff --git a/src/is_json.c b/src/is_json.c
new file mode 100644 (file)
index 0000000..206ec37
--- /dev/null
@@ -0,0 +1,462 @@
+/*-
+ * Copyright (c) 2018 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Parse JSON object serialization format (RFC-7159)
+ */
+
+#ifndef TEST
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: is_json.c,v 1.13 2019/03/02 01:08:10 christos Exp $")
+#endif
+
+#include <string.h>
+#include "magic.h"
+#endif
+
+#ifdef DEBUG
+#include <stdio.h>
+#define DPRINTF(a, b, c)       \
+    printf("%s [%.2x/%c] %.20s\n", (a), *(b), *(b), (const char *)(c))
+#else
+#define DPRINTF(a, b, c)       do { } while (/*CONSTCOND*/0)
+#endif
+
+#define JSON_ARRAY     0
+#define JSON_CONSTANT  1
+#define JSON_NUMBER    2
+#define JSON_OBJECT    3
+#define JSON_STRING    4
+#define JSON_ARRAYN    5
+#define JSON_MAX       6
+
+/*
+ * if JSON_COUNT != 0:
+ *     count all the objects, require that we have the whole data file
+ * otherwise:
+ *     stop if we find an object or an array
+ */
+#ifndef JSON_COUNT
+#define JSON_COUNT 0
+#endif
+
+static int json_parse(const unsigned char **, const unsigned char *, size_t *,
+       size_t);
+
+static int
+json_isspace(const unsigned char uc)
+{
+       switch (uc) {
+       case ' ':
+       case '\n':
+       case '\r':
+       case '\t':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int
+json_isdigit(unsigned char uc)
+{
+       switch (uc) {
+       case '0': case '1': case '2': case '3': case '4':
+       case '5': case '6': case '7': case '8': case '9':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int
+json_isxdigit(unsigned char uc)
+{
+       if (json_isdigit(uc))
+               return 1;
+       switch (uc) {
+       case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+       case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static const unsigned char *
+json_skip_space(const unsigned char *uc, const unsigned char *ue)
+{
+       while (uc < ue && json_isspace(*uc))
+               uc++;
+       return uc;
+}
+
+static int
+json_parse_string(const unsigned char **ucp, const unsigned char *ue)
+{
+       const unsigned char *uc = *ucp;
+       size_t i;
+
+       DPRINTF("Parse string: ", uc, *ucp);
+       while (uc < ue) {
+               switch (*uc++) {
+               case '\0':
+                       goto out;
+               case '\\':
+                       if (uc == ue)
+                               goto out;
+                       switch (*uc++) {
+                       case '\0':
+                               goto out;
+                       case '"':
+                       case '\\':
+                       case '/':
+                       case 'b':
+                       case 'f':
+                       case 'n':
+                       case 'r':
+                       case 't':
+                               continue;
+                       case 'u':
+                               if (ue - uc < 4) {
+                                       uc = ue;
+                                       goto out;
+                               }
+                               for (i = 0; i < 4; i++)
+                                       if (!json_isxdigit(*uc++))
+                                               goto out;
+                               continue;
+                       default:
+                               goto out;
+                       }
+               case '"':
+                       *ucp = uc;
+                       return 1;
+               default:
+                       continue;
+               }
+       }
+out:
+       DPRINTF("Bad string: ", uc, *ucp);
+       *ucp = uc;
+       return 0;
+}
+
+static int
+json_parse_array(const unsigned char **ucp, const unsigned char *ue,
+       size_t *st, size_t lvl)
+{
+       const unsigned char *uc = *ucp;
+       int more = 0;   /* Array has more than 1 element */
+
+       DPRINTF("Parse array: ", uc, *ucp);
+       while (uc < ue) {
+               if (!json_parse(&uc, ue, st, lvl + 1))
+                       goto out;
+               if (uc == ue)
+                       goto out;
+               switch (*uc) {
+               case ',':
+                       more++;
+                       uc++;
+                       continue;
+               case ']':
+                       if (more)
+                               st[JSON_ARRAYN]++;
+                       *ucp = uc + 1;
+                       return 1;
+               default:
+                       goto out;
+               }
+       }
+out:
+       DPRINTF("Bad array: ", uc,  *ucp);
+       *ucp = uc;
+       return 0;
+}
+
+static int
+json_parse_object(const unsigned char **ucp, const unsigned char *ue,
+       size_t *st, size_t lvl)
+{
+       const unsigned char *uc = *ucp;
+       DPRINTF("Parse object: ", uc, *ucp);
+       while (uc < ue) {
+               uc = json_skip_space(uc, ue);
+               if (uc == ue)
+                       goto out;
+               if (*uc++ != '"') {
+                       DPRINTF("not string", uc, *ucp);
+                       goto out;
+               }
+               DPRINTF("next field", uc, *ucp);
+               if (!json_parse_string(&uc, ue)) {
+                       DPRINTF("not string", uc, *ucp);
+                       goto out;
+               }
+               uc = json_skip_space(uc, ue);
+               if (uc == ue)
+                       goto out;
+               if (*uc++ != ':') {
+                       DPRINTF("not colon", uc, *ucp);
+                       goto out;
+               }
+               if (!json_parse(&uc, ue, st, lvl + 1)) {
+                       DPRINTF("not json", uc, *ucp);
+                       goto out;
+               }
+               if (uc == ue)
+                       goto out;
+               switch (*uc++) {
+               case ',':
+                       continue;
+               case '}': /* { */
+                       *ucp = uc;
+                       DPRINTF("Good object: ", uc, *ucp);
+                       return 1;
+               default:
+                       *ucp = uc - 1;
+                       DPRINTF("not more", uc, *ucp);
+                       goto out;
+               }
+       }
+out:
+       DPRINTF("Bad object: ", uc, *ucp);
+       *ucp = uc;
+       return 0;
+}
+
+static int
+json_parse_number(const unsigned char **ucp, const unsigned char *ue)
+{
+       const unsigned char *uc = *ucp;
+       int got = 0;
+
+       DPRINTF("Parse number: ", uc, *ucp);
+       if (uc == ue)
+               return 0;
+       if (*uc == '-')
+               uc++;
+
+       for (; uc < ue; uc++) {
+               if (!json_isdigit(*uc))
+                       break;
+               got = 1;
+       }
+       if (uc == ue)
+               goto out;
+       if (*uc == '.')
+               uc++;
+       for (; uc < ue; uc++) {
+               if (!json_isdigit(*uc))
+                       break;
+               got = 1;
+       }
+       if (uc == ue)
+               goto out;
+       if (got && (*uc == 'e' || *uc == 'E')) {
+               uc++;
+               got = 0;
+               if (uc == ue)
+                       goto out;
+               if (*uc == '+' || *uc == '-')
+                       uc++;
+               for (; uc < ue; uc++) {
+                       if (!json_isdigit(*uc))
+                               break;
+                       got = 1;
+               }
+       }
+out:
+       if (!got)
+               DPRINTF("Bad number: ", uc, *ucp);
+       else
+               DPRINTF("Good number: ", uc, *ucp);
+       *ucp = uc;
+       return got;
+}
+
+static int
+json_parse_const(const unsigned char **ucp, const unsigned char *ue,
+    const char *str, size_t len)
+{
+       const unsigned char *uc = *ucp;
+
+       DPRINTF("Parse const: ", uc, *ucp);
+       for (len--; uc < ue && --len;) {
+               if (*uc++ == *++str)
+                       continue;
+       }
+       if (len)
+               DPRINTF("Bad const: ", uc, *ucp);
+       *ucp = uc;
+       return len == 0;
+}
+
+static int
+json_parse(const unsigned char **ucp, const unsigned char *ue,
+    size_t *st, size_t lvl)
+{
+       const unsigned char *uc;
+       int rv = 0;
+       int t;
+
+       uc = json_skip_space(*ucp, ue);
+       if (uc == ue)
+               goto out;
+
+       // Avoid recursion
+       if (lvl > 20)
+               return 0;
+#if JSON_COUNT
+       /* bail quickly if not counting */
+       if (lvl > 1 && (st[JSON_OBJECT] || st[JSON_ARRAYN]))
+               return 1;
+#endif
+
+       DPRINTF("Parse general: ", uc, *ucp);
+       switch (*uc++) {
+       case '"':
+               rv = json_parse_string(&uc, ue);
+               t = JSON_STRING;
+               break;
+       case '[':
+               rv = json_parse_array(&uc, ue, st, lvl + 1);
+               t = JSON_ARRAY;
+               break;
+       case '{': /* '}' */
+               rv = json_parse_object(&uc, ue, st, lvl + 1);
+               t = JSON_OBJECT;
+               break;
+       case 't':
+               rv = json_parse_const(&uc, ue, "true", sizeof("true"));
+               t = JSON_CONSTANT;
+               break;
+       case 'f':
+               rv = json_parse_const(&uc, ue, "false", sizeof("false"));
+               t = JSON_CONSTANT;
+               break;
+       case 'n':
+               rv = json_parse_const(&uc, ue, "null", sizeof("null"));
+               t = JSON_CONSTANT;
+               break;
+       default:
+               --uc;
+               rv = json_parse_number(&uc, ue);
+               t = JSON_NUMBER;
+               break;
+       }
+       if (rv)
+               st[t]++;
+       uc = json_skip_space(uc, ue);
+out:
+       *ucp = uc;
+       DPRINTF("End general: ", uc, *ucp);
+       if (lvl == 0)
+               return rv && (st[JSON_ARRAYN] || st[JSON_OBJECT]);
+       return rv;
+}
+
+#ifndef TEST
+int
+file_is_json(struct magic_set *ms, const struct buffer *b)
+{
+       const unsigned char *uc = CAST(const unsigned char *, b->fbuf);
+       const unsigned char *ue = uc + b->flen;
+       size_t st[JSON_MAX];
+       int mime = ms->flags & MAGIC_MIME;
+
+
+       if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0)
+               return 0;
+
+       memset(st, 0, sizeof(st));
+
+       if (!json_parse(&uc, ue, st, 0))
+               return 0;
+
+       if (mime == MAGIC_MIME_ENCODING)
+               return 1;
+       if (mime) {
+               if (file_printf(ms, "application/json") == -1)
+                       return -1;
+               return 1;
+       }
+       if (file_printf(ms, "JSON data") == -1)
+               return -1;
+#if JSON_COUNT
+#define P(n) st[n], st[n] > 1 ? "s" : ""
+       if (file_printf(ms, " (%" SIZE_T_FORMAT "u object%s, %" SIZE_T_FORMAT
+           "u array%s, %" SIZE_T_FORMAT "u string%s, %" SIZE_T_FORMAT
+           "u constant%s, %" SIZE_T_FORMAT "u number%s, %" SIZE_T_FORMAT
+           "u >1array%s)",
+           P(JSON_OBJECT), P(JSON_ARRAY), P(JSON_STRING), P(JSON_CONSTANT),
+           P(JSON_NUMBER), P(JSON_ARRAYN))
+           == -1)
+               return -1;
+#endif
+       return 1;
+}
+
+#else
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <err.h>
+
+int
+main(int argc, char *argv[])
+{
+       int fd, rv;
+       struct stat st;
+       unsigned char *p;
+       size_t stats[JSON_MAX];
+
+       if ((fd = open(argv[1], O_RDONLY)) == -1)
+               err(EXIT_FAILURE, "Can't open `%s'", argv[1]);
+
+       if (fstat(fd, &st) == -1)
+               err(EXIT_FAILURE, "Can't stat `%s'", argv[1]);
+
+       if ((p = malloc(st.st_size)) == NULL)
+               err(EXIT_FAILURE, "Can't allocate %jd bytes",
+                   (intmax_t)st.st_size);
+       if (read(fd, p, st.st_size) != st.st_size)
+               err(EXIT_FAILURE, "Can't read %jd bytes",
+                   (intmax_t)st.st_size);
+       memset(stats, 0, sizeof(stats));
+       printf("is json %d\n", json_parse((const unsigned char **)&p,
+           p + st.st_size, stats, 0));
+       return 0;
+}
+#endif
diff --git a/src/is_tar.c b/src/is_tar.c
new file mode 100644 (file)
index 0000000..82b0805
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * is_tar() -- figure out whether file is a tar archive.
+ *
+ * Stolen (by the author!) from the public domain tar program:
+ * Public Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu).
+ *
+ * @(#)list.c 1.18 9/23/86 Public Domain - gnu
+ *
+ * Comments changed and some code/comments reformatted
+ * for file command by Ian Darwin.
+ */
+
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $")
+#endif
+
+#include "magic.h"
+#include <string.h>
+#include <ctype.h>
+#include "tar.h"
+
+#define        isodigit(c)     ( ((c) >= '0') && ((c) <= '7') )
+
+private int is_tar(const unsigned char *, size_t);
+private int from_oct(const char *, size_t);    /* Decode octal number */
+
+static const char tartype[][32] = {    /* should be equal to messages */
+       "tar archive",                  /* found in ../magic/Magdir/archive */
+       "POSIX tar archive",
+       "POSIX tar archive (GNU)",      /*  */
+};
+
+protected int
+file_is_tar(struct magic_set *ms, const struct buffer *b)
+{
+       const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
+       size_t nbytes = b->flen;
+       /*
+        * Do the tar test first, because if the first file in the tar
+        * archive starts with a dot, we can confuse it with an nroff file.
+        */
+       int tar;
+       int mime = ms->flags & MAGIC_MIME;
+
+       if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0)
+               return 0;
+
+       tar = is_tar(buf, nbytes);
+       if (tar < 1 || tar > 3)
+               return 0;
+
+       if (mime == MAGIC_MIME_ENCODING)
+               return 1;
+
+       if (file_printf(ms, "%s", mime ? "application/x-tar" :
+           tartype[tar - 1]) == -1)
+               return -1;
+
+       return 1;
+}
+
+/*
+ * Return
+ *     0 if the checksum is bad (i.e., probably not a tar archive),
+ *     1 for old UNIX tar file,
+ *     2 for Unix Std (POSIX) tar file,
+ *     3 for GNU tar file.
+ */
+private int
+is_tar(const unsigned char *buf, size_t nbytes)
+{
+       const union record *header = RCAST(const union record *,
+           RCAST(const void *, buf));
+       size_t i;
+       int sum, recsum;
+       const unsigned char *p, *ep;
+
+       if (nbytes < sizeof(*header))
+               return 0;
+
+       recsum = from_oct(header->header.chksum, sizeof(header->header.chksum));
+
+       sum = 0;
+       p = header->charptr;
+       ep = header->charptr + sizeof(*header);
+       while (p < ep)
+               sum += *p++;
+
+       /* Adjust checksum to count the "chksum" field as blanks. */
+       for (i = 0; i < sizeof(header->header.chksum); i++)
+               sum -= header->header.chksum[i];
+       sum += ' ' * sizeof(header->header.chksum);
+
+       if (sum != recsum)
+               return 0;       /* Not a tar archive */
+
+       if (strncmp(header->header.magic, GNUTMAGIC,
+           sizeof(header->header.magic)) == 0)
+               return 3;               /* GNU Unix Standard tar archive */
+
+       if (strncmp(header->header.magic, TMAGIC,
+           sizeof(header->header.magic)) == 0)
+               return 2;               /* Unix Standard tar archive */
+
+       return 1;                       /* Old fashioned tar archive */
+}
+
+
+/*
+ * Quick and dirty octal conversion.
+ *
+ * Result is -1 if the field is invalid (all blank, or non-octal).
+ */
+private int
+from_oct(const char *where, size_t digs)
+{
+       int     value;
+
+       if (digs == 0)
+               return -1;
+
+       while (isspace(CAST(unsigned char, *where))) {  /* Skip spaces */
+               where++;
+               if (digs-- == 0)
+                       return -1;              /* All blank field */
+       }
+       value = 0;
+       while (digs > 0 && isodigit(*where)) {  /* Scan til non-octal */
+               value = (value << 3) | (*where++ - '0');
+               digs--;
+       }
+
+       if (digs > 0 && *where && !isspace(CAST(unsigned char, *where)))
+               return -1;                      /* Ended on non-(space/NUL) */
+
+       return value;
+}
diff --git a/src/localtime_r.c b/src/localtime_r.c
new file mode 100644 (file)
index 0000000..35c3b40
--- /dev/null
@@ -0,0 +1,19 @@
+/*     $File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $   */
+
+#include "file.h"
+#ifndef        lint
+FILE_RCSID("@(#)$File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $")
+#endif /* lint */
+#include <time.h>
+#include <string.h>
+
+/* asctime_r is not thread-safe anyway */
+struct tm *
+localtime_r(const time_t *t, struct tm *tm)
+{
+       struct tm *tmp = localtime(t);
+       if (tmp == NULL)
+               return NULL;
+       memcpy(tm, tmp, sizeof(*tm));
+       return tmp;
+}
diff --git a/src/magic.c b/src/magic.c
new file mode 100644 (file)
index 0000000..da5baf1
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#include <shlwapi.h>
+#endif
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: magic.c,v 1.111 2019/05/07 02:27:11 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef QUICK
+#include <sys/mman.h>
+#endif
+#include <limits.h>    /* for PIPE_BUF */
+
+#if defined(HAVE_UTIMES)
+# include <sys/time.h>
+#elif defined(HAVE_UTIME)
+# if defined(HAVE_SYS_UTIME_H)
+#  include <sys/utime.h>
+# elif defined(HAVE_UTIME_H)
+#  include <utime.h>
+# endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>    /* for read() */
+#endif
+
+#ifndef PIPE_BUF
+/* Get the PIPE_BUF from pathconf */
+#ifdef _PC_PIPE_BUF
+#define PIPE_BUF pathconf(".", _PC_PIPE_BUF)
+#else
+#define PIPE_BUF 512
+#endif
+#endif
+
+private void close_and_restore(const struct magic_set *, const char *, int,
+    const struct stat *);
+private int unreadable_info(struct magic_set *, mode_t, const char *);
+private const char* get_default_magic(void);
+#ifndef COMPILE_ONLY
+private const char *file_or_fd(struct magic_set *, const char *, int);
+#endif
+
+#ifndef        STDIN_FILENO
+#define        STDIN_FILENO    0
+#endif
+
+#ifdef WIN32
+/* HINSTANCE of this shared library. Needed for get_default_magic() */
+static HINSTANCE _w32_dll_instance = NULL;
+
+static void
+_w32_append_path(char **hmagicpath, const char *fmt, ...)
+{
+       char *tmppath;
+        char *newpath;
+       va_list ap;
+
+       va_start(ap, fmt);
+       if (vasprintf(&tmppath, fmt, ap) < 0) {
+               va_end(ap);
+               return;
+       }
+       va_end(ap);
+
+       if (access(tmppath, R_OK) == -1)
+               goto out;
+
+       if (*hmagicpath == NULL) {
+               *hmagicpath = tmppath;
+               return;
+       }
+
+       if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0)
+               goto out;
+
+       free(*hmagicpath);
+       free(tmppath);
+       *hmagicpath = newpath;
+       return;
+out:
+       free(tmppath);
+}
+
+static void
+_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module)
+{
+       static const char *trypaths[] = {
+               "%s/share/misc/magic.mgc",
+               "%s/magic.mgc",
+       };
+       LPSTR dllpath;
+       size_t sp;
+
+       dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath));
+
+       if (!GetModuleFileNameA(module, dllpath, MAX_PATH))
+               goto out;
+
+       PathRemoveFileSpecA(dllpath);
+
+       if (module) {
+               char exepath[MAX_PATH];
+               GetModuleFileNameA(NULL, exepath, MAX_PATH);
+               PathRemoveFileSpecA(exepath);
+               if (stricmp(exepath, dllpath) == 0)
+                       goto out;
+       }
+
+       sp = strlen(dllpath);
+       if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) {
+               _w32_append_path(hmagicpath,
+                   "%s/../share/misc/magic.mgc", dllpath);
+               goto out;
+       }
+
+       for (sp = 0; sp < __arraycount(trypaths); sp++)
+               _w32_append_path(hmagicpath, trypaths[sp], dllpath);
+out:
+       free(dllpath);
+}
+
+/* Placate GCC by offering a sacrificial previous prototype */
+BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
+    LPVOID lpvReserved __attribute__((__unused__)))
+{
+       if (fdwReason == DLL_PROCESS_ATTACH)
+               _w32_dll_instance = hinstDLL;
+       return 1;
+}
+#endif
+
+private const char *
+get_default_magic(void)
+{
+       static const char hmagic[] = "/.magic/magic.mgc";
+       static char *default_magic;
+       char *home, *hmagicpath;
+
+#ifndef WIN32
+       struct stat st;
+
+       if (default_magic) {
+               free(default_magic);
+               default_magic = NULL;
+       }
+       if ((home = getenv("HOME")) == NULL)
+               return MAGIC;
+
+       if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
+               return MAGIC;
+       if (stat(hmagicpath, &st) == -1) {
+               free(hmagicpath);
+               if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
+                       return MAGIC;
+               if (stat(hmagicpath, &st) == -1)
+                       goto out;
+               if (S_ISDIR(st.st_mode)) {
+                       free(hmagicpath);
+                       if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
+                               return MAGIC;
+                       if (access(hmagicpath, R_OK) == -1)
+                               goto out;
+               }
+       }
+
+       if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
+               goto out;
+       free(hmagicpath);
+       return default_magic;
+out:
+       default_magic = NULL;
+       free(hmagicpath);
+       return MAGIC;
+#else
+       hmagicpath = NULL;
+
+       if (default_magic) {
+               free(default_magic);
+               default_magic = NULL;
+       }
+
+       /* First, try to get a magic file from user-application data */
+       if ((home = getenv("LOCALAPPDATA")) != NULL)
+               _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
+
+       /* Second, try to get a magic file from the user profile data */
+       if ((home = getenv("USERPROFILE")) != NULL)
+               _w32_append_path(&hmagicpath,
+                   "%s/Local Settings/Application Data%s", home, hmagic);
+
+       /* Third, try to get a magic file from Common Files */
+       if ((home = getenv("COMMONPROGRAMFILES")) != NULL)
+               _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
+
+       /* Fourth, try to get magic file relative to exe location */
+        _w32_get_magic_relative_to(&hmagicpath, NULL);
+
+       /* Fifth, try to get magic file relative to dll location */
+        _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance);
+
+       /* Avoid MAGIC constant - it likely points to a file within MSys tree */
+       default_magic = hmagicpath;
+       return default_magic;
+#endif
+}
+
+public const char *
+magic_getpath(const char *magicfile, int action)
+{
+       if (magicfile != NULL)
+               return magicfile;
+
+       magicfile = getenv("MAGIC");
+       if (magicfile != NULL)
+               return magicfile;
+
+       return action == FILE_LOAD ? get_default_magic() : MAGIC;
+}
+
+public struct magic_set *
+magic_open(int flags)
+{
+       return file_ms_alloc(flags);
+}
+
+private int
+unreadable_info(struct magic_set *ms, mode_t md, const char *file)
+{
+       if (file) {
+               /* We cannot open it, but we were able to stat it. */
+               if (access(file, W_OK) == 0)
+                       if (file_printf(ms, "writable, ") == -1)
+                               return -1;
+               if (access(file, X_OK) == 0)
+                       if (file_printf(ms, "executable, ") == -1)
+                               return -1;
+       }
+       if (S_ISREG(md))
+               if (file_printf(ms, "regular file, ") == -1)
+                       return -1;
+       if (file_printf(ms, "no read permission") == -1)
+               return -1;
+       return 0;
+}
+
+public void
+magic_close(struct magic_set *ms)
+{
+       if (ms == NULL)
+               return;
+       file_ms_free(ms);
+}
+
+/*
+ * load a magic file
+ */
+public int
+magic_load(struct magic_set *ms, const char *magicfile)
+{
+       if (ms == NULL)
+               return -1;
+       return file_apprentice(ms, magicfile, FILE_LOAD);
+}
+
+#ifndef COMPILE_ONLY
+/*
+ * Install a set of compiled magic buffers.
+ */
+public int
+magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
+    size_t nbufs)
+{
+       if (ms == NULL)
+               return -1;
+       return buffer_apprentice(ms, RCAST(struct magic **, bufs),
+           sizes, nbufs);
+}
+#endif
+
+public int
+magic_compile(struct magic_set *ms, const char *magicfile)
+{
+       if (ms == NULL)
+               return -1;
+       return file_apprentice(ms, magicfile, FILE_COMPILE);
+}
+
+public int
+magic_check(struct magic_set *ms, const char *magicfile)
+{
+       if (ms == NULL)
+               return -1;
+       return file_apprentice(ms, magicfile, FILE_CHECK);
+}
+
+public int
+magic_list(struct magic_set *ms, const char *magicfile)
+{
+       if (ms == NULL)
+               return -1;
+       return file_apprentice(ms, magicfile, FILE_LIST);
+}
+
+private void
+close_and_restore(const struct magic_set *ms, const char *name, int fd,
+    const struct stat *sb)
+{
+       if (fd == STDIN_FILENO || name == NULL)
+               return;
+       (void) close(fd);
+
+       if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
+               /*
+                * Try to restore access, modification times if read it.
+                * This is really *bad* because it will modify the status
+                * time of the file... And of course this will affect
+                * backup programs
+                */
+#ifdef HAVE_UTIMES
+               struct timeval  utsbuf[2];
+               (void)memset(utsbuf, 0, sizeof(utsbuf));
+               utsbuf[0].tv_sec = sb->st_atime;
+               utsbuf[1].tv_sec = sb->st_mtime;
+
+               (void) utimes(name, utsbuf); /* don't care if loses */
+#elif defined(HAVE_UTIME_H) || defined(HAVE_SYS_UTIME_H)
+               struct utimbuf  utbuf;
+
+               (void)memset(&utbuf, 0, sizeof(utbuf));
+               utbuf.actime = sb->st_atime;
+               utbuf.modtime = sb->st_mtime;
+               (void) utime(name, &utbuf); /* don't care if loses */
+#endif
+       }
+}
+
+#ifndef COMPILE_ONLY
+
+/*
+ * find type of descriptor
+ */
+public const char *
+magic_descriptor(struct magic_set *ms, int fd)
+{
+       if (ms == NULL)
+               return NULL;
+       return file_or_fd(ms, NULL, fd);
+}
+
+/*
+ * find type of named file
+ */
+public const char *
+magic_file(struct magic_set *ms, const char *inname)
+{
+       if (ms == NULL)
+               return NULL;
+       return file_or_fd(ms, inname, STDIN_FILENO);
+}
+
+private const char *
+file_or_fd(struct magic_set *ms, const char *inname, int fd)
+{
+       int     rv = -1;
+       unsigned char *buf;
+       struct stat     sb;
+       ssize_t nbytes = 0;     /* number of bytes read from a datafile */
+       int     ispipe = 0;
+       int     okstat = 0;
+       off_t   pos = CAST(off_t, -1);
+
+       if (file_reset(ms, 1) == -1)
+               goto out;
+
+       /*
+        * one extra for terminating '\0', and
+        * some overlapping space for matches near EOF
+        */
+#define SLOP (1 + sizeof(union VALUETYPE))
+       if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
+               return NULL;
+
+       switch (file_fsmagic(ms, inname, &sb)) {
+       case -1:                /* error */
+               goto done;
+       case 0:                 /* nothing found */
+               break;
+       default:                /* matched it and printed type */
+               rv = 0;
+               goto done;
+       }
+
+#ifdef WIN32
+       /* Place stdin in binary mode, so EOF (Ctrl+Z) doesn't stop early. */
+       if (fd == STDIN_FILENO)
+               _setmode(STDIN_FILENO, O_BINARY);
+#endif
+       if (inname != NULL) {
+               int flags = O_RDONLY|O_BINARY|O_NONBLOCK;
+               errno = 0;
+               if ((fd = open(inname, flags)) < 0) {
+                       okstat = stat(inname, &sb) == 0;
+                       if (okstat && S_ISFIFO(sb.st_mode))
+                               ispipe = 1;
+#ifdef WIN32
+                       /*
+                        * Can't stat, can't open.  It may have been opened in
+                        * fsmagic, so if the user doesn't have read permission,
+                        * allow it to say so; otherwise an error was probably
+                        * displayed in fsmagic.
+                        */
+                       if (!okstat && errno == EACCES) {
+                               sb.st_mode = S_IFBLK;
+                               okstat = 1;
+                       }
+#endif
+                       if (okstat &&
+                           unreadable_info(ms, sb.st_mode, inname) == -1)
+                               goto done;
+                       rv = 0;
+                       goto done;
+               }
+       }
+
+       if (fd != -1) {
+               if (!okstat)
+                       okstat = fstat(fd, &sb) == 0;
+               if (okstat && S_ISFIFO(sb.st_mode))
+                       ispipe = 1;
+               if (inname == NULL)
+                       pos = lseek(fd, CAST(off_t, 0), SEEK_CUR);
+       }
+
+       /*
+        * try looking at the first ms->bytes_max bytes
+        */
+       if (ispipe) {
+               if (fd != -1) {
+                       ssize_t r = 0;
+
+                       while ((r = sread(fd, RCAST(void *, &buf[nbytes]),
+                           CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) {
+                               nbytes += r;
+                               if (r < PIPE_BUF) break;
+                       }
+               }
+
+               if (nbytes == 0 && inname) {
+                       /* We can not read it, but we were able to stat it. */
+                       if (unreadable_info(ms, sb.st_mode, inname) == -1)
+                               goto done;
+                       rv = 0;
+                       goto done;
+               }
+
+       } else if (fd != -1) {
+               /* Windows refuses to read from a big console buffer. */
+               size_t howmany =
+#if defined(WIN32)
+                   _isatty(fd) ? 8 * 1024 :
+#endif
+                   ms->bytes_max;
+               if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) {
+                       if (inname == NULL && fd != STDIN_FILENO)
+                               file_error(ms, errno, "cannot read fd %d", fd);
+                       else
+                               file_error(ms, errno, "cannot read `%s'",
+                                   inname == NULL ? "/dev/stdin" : inname);
+                       goto done;
+               }
+       }
+
+       (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
+       if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, CAST(size_t, nbytes)) == -1)
+               goto done;
+       rv = 0;
+done:
+       free(buf);
+       if (fd != -1) {
+               if (pos != CAST(off_t, -1))
+                       (void)lseek(fd, pos, SEEK_SET);
+               close_and_restore(ms, inname, fd, &sb);
+       }
+out:
+       return rv == 0 ? file_getbuffer(ms) : NULL;
+}
+
+
+public const char *
+magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
+{
+       if (ms == NULL)
+               return NULL;
+       if (file_reset(ms, 1) == -1)
+               return NULL;
+       /*
+        * The main work is done here!
+        * We have the file name and/or the data buffer to be identified.
+        */
+       if (file_buffer(ms, -1, NULL, NULL, buf, nb) == -1) {
+               return NULL;
+       }
+       return file_getbuffer(ms);
+}
+#endif
+
+public const char *
+magic_error(struct magic_set *ms)
+{
+       if (ms == NULL)
+               return "Magic database is not open";
+       return (ms->event_flags & EVENT_HAD_ERR) ? ms->o.buf : NULL;
+}
+
+public int
+magic_errno(struct magic_set *ms)
+{
+       if (ms == NULL)
+               return EINVAL;
+       return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0;
+}
+
+public int
+magic_getflags(struct magic_set *ms)
+{
+       if (ms == NULL)
+               return -1;
+
+       return ms->flags;
+}
+
+public int
+magic_setflags(struct magic_set *ms, int flags)
+{
+       if (ms == NULL)
+               return -1;
+#if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
+       if (flags & MAGIC_PRESERVE_ATIME)
+               return -1;
+#endif
+       ms->flags = flags;
+       return 0;
+}
+
+public int
+magic_version(void)
+{
+       return MAGIC_VERSION;
+}
+
+public int
+magic_setparam(struct magic_set *ms, int param, const void *val)
+{
+       if (ms == NULL)
+               return -1;
+       switch (param) {
+       case MAGIC_PARAM_INDIR_MAX:
+               ms->indir_max = CAST(uint16_t, *CAST(const size_t *, val));
+               return 0;
+       case MAGIC_PARAM_NAME_MAX:
+               ms->name_max = CAST(uint16_t, *CAST(const size_t *, val));
+               return 0;
+       case MAGIC_PARAM_ELF_PHNUM_MAX:
+               ms->elf_phnum_max = CAST(uint16_t, *CAST(const size_t *, val));
+               return 0;
+       case MAGIC_PARAM_ELF_SHNUM_MAX:
+               ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val));
+               return 0;
+       case MAGIC_PARAM_ELF_NOTES_MAX:
+               ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val));
+               return 0;
+       case MAGIC_PARAM_REGEX_MAX:
+               ms->regex_max = CAST(uint16_t, *CAST(const size_t *, val));
+               return 0;
+       case MAGIC_PARAM_BYTES_MAX:
+               ms->bytes_max = *CAST(const size_t *, val);
+               return 0;
+       default:
+               errno = EINVAL;
+               return -1;
+       }
+}
+
+public int
+magic_getparam(struct magic_set *ms, int param, void *val)
+{
+       if (ms == NULL)
+               return -1;
+       switch (param) {
+       case MAGIC_PARAM_INDIR_MAX:
+               *CAST(size_t *, val) = ms->indir_max;
+               return 0;
+       case MAGIC_PARAM_NAME_MAX:
+               *CAST(size_t *, val) = ms->name_max;
+               return 0;
+       case MAGIC_PARAM_ELF_PHNUM_MAX:
+               *CAST(size_t *, val) = ms->elf_phnum_max;
+               return 0;
+       case MAGIC_PARAM_ELF_SHNUM_MAX:
+               *CAST(size_t *, val) = ms->elf_shnum_max;
+               return 0;
+       case MAGIC_PARAM_ELF_NOTES_MAX:
+               *CAST(size_t *, val) = ms->elf_notes_max;
+               return 0;
+       case MAGIC_PARAM_REGEX_MAX:
+               *CAST(size_t *, val) = ms->regex_max;
+               return 0;
+       case MAGIC_PARAM_BYTES_MAX:
+               *CAST(size_t *, val) = ms->bytes_max;
+               return 0;
+       default:
+               errno = EINVAL;
+               return -1;
+       }
+}
diff --git a/src/magic.h.in b/src/magic.h.in
new file mode 100644 (file)
index 0000000..0580fa2
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _MAGIC_H
+#define _MAGIC_H
+
+#include <sys/types.h>
+
+#define        MAGIC_NONE              0x0000000 /* No flags */
+#define        MAGIC_DEBUG             0x0000001 /* Turn on debugging */
+#define        MAGIC_SYMLINK           0x0000002 /* Follow symlinks */
+#define        MAGIC_COMPRESS          0x0000004 /* Check inside compressed files */
+#define        MAGIC_DEVICES           0x0000008 /* Look at the contents of devices */
+#define        MAGIC_MIME_TYPE         0x0000010 /* Return the MIME type */
+#define        MAGIC_CONTINUE          0x0000020 /* Return all matches */
+#define        MAGIC_CHECK             0x0000040 /* Print warnings to stderr */
+#define        MAGIC_PRESERVE_ATIME    0x0000080 /* Restore access time on exit */
+#define        MAGIC_RAW               0x0000100 /* Don't convert unprintable chars */
+#define        MAGIC_ERROR             0x0000200 /* Handle ENOENT etc as real errors */
+#define        MAGIC_MIME_ENCODING     0x0000400 /* Return the MIME encoding */
+#define MAGIC_MIME             (MAGIC_MIME_TYPE|MAGIC_MIME_ENCODING)
+#define        MAGIC_APPLE             0x0000800 /* Return the Apple creator/type */
+#define        MAGIC_EXTENSION         0x1000000 /* Return a /-separated list of
+                                          * extensions */
+#define MAGIC_COMPRESS_TRANSP  0x2000000 /* Check inside compressed files
+                                          * but not report compression */
+#define MAGIC_NODESC           (MAGIC_EXTENSION|MAGIC_MIME|MAGIC_APPLE)
+
+#define        MAGIC_NO_CHECK_COMPRESS 0x0001000 /* Don't check for compressed files */
+#define        MAGIC_NO_CHECK_TAR      0x0002000 /* Don't check for tar files */
+#define        MAGIC_NO_CHECK_SOFT     0x0004000 /* Don't check magic entries */
+#define        MAGIC_NO_CHECK_APPTYPE  0x0008000 /* Don't check application type */
+#define        MAGIC_NO_CHECK_ELF      0x0010000 /* Don't check for elf details */
+#define        MAGIC_NO_CHECK_TEXT     0x0020000 /* Don't check for text files */
+#define        MAGIC_NO_CHECK_CDF      0x0040000 /* Don't check for cdf files */
+#define        MAGIC_NO_CHECK_TOKENS   0x0100000 /* Don't check tokens */
+#define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */
+#define MAGIC_NO_CHECK_JSON    0x0400000 /* Don't check for JSON files */
+
+/* No built-in tests; only consult the magic file */
+#define MAGIC_NO_CHECK_BUILTIN ( \
+       MAGIC_NO_CHECK_COMPRESS | \
+       MAGIC_NO_CHECK_TAR      | \
+/*     MAGIC_NO_CHECK_SOFT     | */ \
+       MAGIC_NO_CHECK_APPTYPE  | \
+       MAGIC_NO_CHECK_ELF      | \
+       MAGIC_NO_CHECK_TEXT     | \
+       MAGIC_NO_CHECK_CDF      | \
+       MAGIC_NO_CHECK_TOKENS   | \
+       MAGIC_NO_CHECK_ENCODING | \
+       MAGIC_NO_CHECK_JSON     | \
+       0                         \
+)
+
+#define MAGIC_SNPRINTB "\177\020\
+b\0debug\0\
+b\1symlink\0\
+b\2compress\0\
+b\3devices\0\
+b\4mime_type\0\
+b\5continue\0\
+b\6check\0\
+b\7preserve_atime\0\
+b\10raw\0\
+b\11error\0\
+b\12mime_encoding\0\
+b\13apple\0\
+b\14no_check_compress\0\
+b\15no_check_tar\0\
+b\16no_check_soft\0\
+b\17no_check_sapptype\0\
+b\20no_check_elf\0\
+b\21no_check_text\0\
+b\22no_check_cdf\0\
+b\23no_check_reserved0\0\
+b\24no_check_tokens\0\
+b\25no_check_encoding\0\
+b\26no_check_json\0\
+b\27no_check_reserved2\0\
+b\30extension\0\
+b\31transp_compression\0\
+"
+
+/* Defined for backwards compatibility (renamed) */
+#define        MAGIC_NO_CHECK_ASCII    MAGIC_NO_CHECK_TEXT
+
+/* Defined for backwards compatibility; do nothing */
+#define        MAGIC_NO_CHECK_FORTRAN  0x000000 /* Don't check ascii/fortran */
+#define        MAGIC_NO_CHECK_TROFF    0x000000 /* Don't check ascii/troff */
+
+#define MAGIC_VERSION          X.YY    /* This implementation */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct magic_set *magic_t;
+magic_t magic_open(int);
+void magic_close(magic_t);
+
+const char *magic_getpath(const char *, int);
+const char *magic_file(magic_t, const char *);
+const char *magic_descriptor(magic_t, int);
+const char *magic_buffer(magic_t, const void *, size_t);
+
+const char *magic_error(magic_t);
+int magic_getflags(magic_t);
+int magic_setflags(magic_t, int);
+
+int magic_version(void);
+int magic_load(magic_t, const char *);
+int magic_load_buffers(magic_t, void **, size_t *, size_t);
+
+int magic_compile(magic_t, const char *);
+int magic_check(magic_t, const char *);
+int magic_list(magic_t, const char *);
+int magic_errno(magic_t);
+
+#define MAGIC_PARAM_INDIR_MAX          0
+#define MAGIC_PARAM_NAME_MAX           1
+#define MAGIC_PARAM_ELF_PHNUM_MAX      2
+#define MAGIC_PARAM_ELF_SHNUM_MAX      3
+#define MAGIC_PARAM_ELF_NOTES_MAX      4
+#define MAGIC_PARAM_REGEX_MAX          5
+#define        MAGIC_PARAM_BYTES_MAX           6
+
+int magic_setparam(magic_t, int, const void *);
+int magic_getparam(magic_t, int, void *);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* _MAGIC_H */
diff --git a/src/mygetopt.h b/src/mygetopt.h
new file mode 100644 (file)
index 0000000..d766762
--- /dev/null
@@ -0,0 +1,68 @@
+/*     $NetBSD: getopt.h,v 1.8 2007/11/06 19:21:18 christos Exp $      */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#include <unistd.h>
+
+/*
+ * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions
+ */
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+struct option {
+       /* name of long option */
+       const char *name;
+       /*
+        * one of no_argument, required_argument, and optional_argument:
+        * whether option takes an argument
+        */
+       int has_arg;
+       /* if not NULL, set *flag to val when option found */
+       int *flag;
+       /* if flag not NULL, value to set *flag to; else return value */
+       int val;
+};
+
+int getopt_long(int, char * const *, const char *,
+    const struct option *, int *);
+
+#endif /* !_GETOPT_H_ */
diff --git a/src/patchlevel.h b/src/patchlevel.h
new file mode 100644 (file)
index 0000000..8e50033
--- /dev/null
@@ -0,0 +1,361 @@
+#define        FILE_VERSION_MAJOR      5
+#define        patchlevel              6
+
+/*
+ * Patchlevel file for Ian Darwin's MAGIC command.
+ * $File: patchlevel.h,v 1.76 2011/01/17 16:40:41 christos Exp $
+ *
+ * $Log: patchlevel.h,v $
+ * Revision 1.77  2011/04/15 22:07:27  christos
+ * fix the patchlevel.
+ *
+ * Revision 1.76  2011/01/17 16:40:41  christos
+ * welcome to 5_05
+ *
+ * Revision 1.75  2010/01/22 21:08:13  christos
+ * welcome to 5.04
+ *
+ * Revision 1.74  2009/05/06 20:32:48  christos
+ * welcome to 5.03
+ *
+ * Revision 1.73  2009/05/04 15:15:13  christos
+ * 5.02...
+ *
+ * Revision 1.72  2009/04/30 21:20:15  christos
+ * 5.01 we are almost here.
+ *
+ * Revision 1.71  2009/01/21 19:09:42  christos
+ * file 5.0
+ *
+ * Revision 1.70  2008/08/30 10:01:01  christos
+ * file 4.26
+ *
+ * Revision 1.69  2008/07/02 15:27:05  christos
+ * welcome to 4.25
+ *
+ * Revision 1.68  2008/03/22 21:39:43  christos
+ * file 4.24
+ *
+ * Revision 1.67  2007/12/28 20:08:40  christos
+ * welcome to 4.23.
+ *
+ * Revision 1.66  2007/12/27 16:38:24  christos
+ * welcome to 4.22
+ *
+ * Revision 1.65  2007/05/24 17:22:27  christos
+ * Welcome to 4.21
+ *
+ * Revision 1.64  2007/03/01 22:14:55  christos
+ * welcome to 4.20
+ *
+ * Revision 1.63  2007/01/12 17:38:28  christos
+ * Use File id.
+ *
+ * Revision 1.62  2006/12/11 21:49:58  christos
+ * time for 4.19
+ *
+ * Revision 1.61  2006/10/31 21:18:09  christos
+ * bump
+ *
+ * Revision 1.60  2006/03/02 22:15:12  christos
+ * welcome to 4.17
+ *
+ * Revision 1.59  2005/10/17 17:15:21  christos
+ * welcome to 4.16
+ *
+ * Revision 1.58  2005/08/18 15:52:56  christos
+ * welcome to 4.15
+ *
+ * Revision 1.57  2005/06/25 15:52:14  christos
+ * Welcome to 4.14
+ *
+ * Revision 1.56  2005/02/09 19:25:13  christos
+ * Welcome to 4.13
+ *
+ * Revision 1.55  2004/11/24 18:57:47  christos
+ * Re-do the autoconf stuff once more; passes make dist now.
+ *
+ * Revision 1.54  2004/11/21 05:52:05  christos
+ * ready for 4.11
+ *
+ * Revision 1.53  2004/07/24 20:40:46  christos
+ * welcome to 4.10
+ *
+ * Revision 1.52  2004/04/07 00:32:25  christos
+ * welcome to 4.09
+ *
+ * Revision 1.51  2004/03/22 21:17:11  christos
+ * welcome to 4.08.
+ *
+ * Revision 1.50  2003/12/23 17:34:04  christos
+ * 4.07
+ *
+ * Revision 1.49  2003/10/15 02:08:27  christos
+ * welcome to 4.06
+ *
+ * Revision 1.48  2003/09/12 19:41:14  christos
+ * this is 4.04
+ *
+ * Revision 1.47  2003/05/23 21:38:21  christos
+ * welcome to 4.03
+ *
+ * Revision 1.46  2003/04/02 18:57:43  christos
+ * prepare for 4.02
+ *
+ * Revision 1.45  2003/03/26 15:37:25  christos
+ * - Pass lint
+ * - make NULL in magic_file mean stdin
+ * - Fix "-" argument to file to pass NULL to magic_file
+ * - avoid pointer casts by using memcpy
+ * - rename magic_buf -> magic_buffer
+ * - keep only the first error
+ * - manual page: new sentence, new line
+ * - fix typo in api function (magic_buf -> magic_buffer)
+ *
+ * Revision 1.44  2003/03/23 22:23:31  christos
+ * finish librarification.
+ *
+ * Revision 1.43  2003/03/23 21:16:26  christos
+ * update copyrights.
+ *
+ * Revision 1.42  2003/03/23 04:06:05  christos
+ * Library re-organization
+ *
+ * Revision 1.41  2003/02/27 20:53:45  christos
+ * - fix memory allocation problem (Jeff Johnson)
+ * - fix stack overflow corruption (David Endler)
+ * - fixes from NetBSD source (Antti Kantee)
+ * - magic fixes
+ *
+ * Revision 1.40  2003/02/08 18:33:53  christos
+ * - detect inttypes.h too (Dave Love <d.love@dl.ac.uk>)
+ * - eliminate unsigned char warnings (Petter Reinholdtsen <pere@hungry.com>)
+ * - better elf PT_NOTE handling (Nalin Dahyabhai <nalin@redhat.com>)
+ * - add options to format the output differently
+ * - much more magic.
+ *
+ * Revision 1.39  2002/07/03 18:57:52  christos
+ * - ansify/c99ize
+ * - more magic
+ * - better COMPILE_ONLY support.
+ * - new magic files.
+ * - fix solaris compilation problems.
+ *
+ * Revision 1.38  2002/05/16 18:45:56  christos
+ * - pt_note elf additions from NetBSD
+ * - EMX os specific changes (Alexander Mai)
+ * - stdint.h detection, acconfig.h fixes (Maciej W. Rozycki, Franz Korntner)
+ * - regex file additions (Kim Cromie)
+ * - getopt_long support and misc cleanups (Michael Piefel)
+ * - many magic fixes and additions
+ *
+ * Revision 1.37  2001/09/03 14:44:22  christos
+ * daylight/tm_isdst detection
+ * magic fixes
+ * don't eat the whole file if it has only nulls
+ *
+ * Revision 1.36  2001/07/22 21:04:15  christos
+ * - magic fixes
+ * - add new operators, pascal strings, UTC date printing, $HOME/.magic
+ *   [from "Tom N Harris" <telliamed@mac.com>]
+ *
+ * Revision 1.35  2001/04/24 14:40:25  christos
+ * - rename magic file sgi to mips and fix it
+ * - add support for building magic.mgc
+ * - portability fixes for mmap()
+ * - try gzip before uncompress, because uncompress sometimes hangs
+ * - be more conservative about pipe reads and writes
+ * - many magic fixes
+ *
+ * Revision 1.34  2001/03/12 05:05:57  christos
+ * - new compiled magic format
+ * - lots of magic additions
+ *
+ * Revision 1.33  2000/11/13 00:30:50  christos
+ * - wordperfect magic fix: freebsd pr 9388
+ * - more msdos fixes from freebsd pr's 20131 and 20812
+ * - sas and spss magic [Bruce Foster]
+ * - mkinstalldirs [John Fremlin]
+ * - sgi opengl fixes [Michael Pruett]
+ * - netbsd magic fixes [Ignatios Souvatzis]
+ * - audio additions [Michael Pruett]
+ * - fix problem with non ansi RCSID [Andreas Ley]
+ * - oggs magic [Felix von Leitner]
+ * - gmon magic [Eugen Dedu]
+ * - TNEF magic [Joomy]
+ * - netpbm magic and misc other image stuff [Bryan Henderson]
+ *
+ * Revision 1.32  2000/08/05 18:24:18  christos
+ * Correct indianness detection in elf (Charles Hannum)
+ * FreeBSD elf core support (Guy Harris)
+ * Use gzip in systems that don't have uncompress (Anthon van der Neut)
+ * Internationalization/EBCDIC support (Eric Fisher)
+ * Many many magic changes
+ *
+ * Revision 1.31  2000/05/14 17:58:36  christos
+ * - new magic for claris files
+ * - new magic for mathematica and maple files
+ * - new magic for msvc files
+ * - new -k flag to keep going matching all possible entries
+ * - add the word executable on #! magic files, and fix the usage of
+ *   the word script
+ * - lots of other magic fixes
+ * - fix typo test -> text
+ *
+ * Revision 1.30  2000/04/11 02:41:17  christos
+ * - add support for mime output (-i)
+ * - make sure we free memory in case realloc fails
+ * - magic fixes
+ *
+ * Revision 1.29  1999/11/28 20:02:29  christos
+ * new string/[Bcb] magic from anthon, and adjustments to the magic files to
+ * use it.
+ *
+ * Revision 1.28  1999/10/31 22:11:48  christos
+ * - add "char" type for compatibility with HP/UX
+ * - recognize HP/UX syntax &=n etc.
+ * - include errno.h for CYGWIN
+ * - conditionalize the S_IS* macros
+ * - revert the SHT_DYNSYM test that broke the linux stripped binaries test
+ * - lots of Magdir changes
+ *
+ * Revision 1.27  1999/02/14 17:21:41  christos
+ * Automake support and misc cleanups from Rainer Orth
+ * Enable reading character and block special files from Dale R. Worley
+ *
+ * Revision 1.26  1998/09/12 13:19:39  christos
+ * - add support for bi-endian indirect offsets (Richard Verhoeven)
+ * - add recognition for bcpl (Joseph Myers)
+ * - remove non magic files from Magdir to avoid difficulties building
+ *   on os2 where files are case independent
+ * - magic fixes.
+ *
+ * Revision 1.25  1998/06/27 14:04:04  christos
+ * OLF patch Guy Harris
+ * Recognize java/html (debian linux)
+ * Const poisoning (debian linux)
+ * More magic!
+ *
+ * Revision 1.24  1998/02/15 23:20:38  christos
+ * Autoconf patch: Felix von Leitner <leitner@math.fu-berlin.de>
+ * More magic fixes
+ * Elf64 fixes
+ *
+ * Revision 1.23  1997/11/05 16:03:37  christos
+ * - correct elf prps offset for SunOS-2.5.1 [guy@netapp.com]
+ * - handle 64 bit time_t's correctly [ewt@redhat.com]
+ * - new mime style magic [clarosse@netvista.net]
+ * - new TI calculator magic [rmcguire@freenet.columbus.oh.us]
+ * - new figlet fonts [obrien@freebsd.org]
+ * - new cisco magic, and elf fixes [jhawk@bbnplanet.com]
+ * - -b flag addition, and x86 filesystem magic [vax@linkhead.paranoia.com]
+ * - s/Mpeg/MPEG, header and elf typo fixes [guy@netapp.com]
+ * - Windows/NT registry files, audio code [guy@netapp.com]
+ * - libGrx graphics lib fonts [guy@netapp.com]
+ * - PNG fixes [guy@netapp.com]
+ * - more m$ document magic [guy@netapp.com]
+ * - PPD files [guy@netapp.com]
+ * - archive magic cleanup [guy@netapp.com]
+ * - linux kernel magic cleanup [guy@netapp.com]
+ * - lecter magic [guy@netapp.com]
+ * - vgetty magic [guy@netapp.com]
+ * - sniffer additions [guy@netapp.com]
+ *
+ * Revision 1.22  1997/01/15 17:23:24  christos
+ * - add support for elf core files: find the program name under SVR4 [Ken Pizzini]
+ * - print strings only up to the first carriage return [various]
+ * - freebsd international ascii support [J Wunsch]
+ * - magic fixes and additions [Guy Harris]
+ * - 64 bit fixes [Larry Schwimmer]
+ * - support for both utime and utimes, but don't restore file access times
+ *   by default [various]
+ * - \xXX only takes 2 hex digits, not 3.
+ * - re-implement support for core files [Guy Harris]
+ *
+ * Revision 1.21  1996/10/05 18:15:29  christos
+ * Segregate elf stuff and conditionally enable it with -DBUILTIN_ELF
+ * More magic fixes
+ *
+ * Revision 1.20  1996/06/22  22:15:52  christos
+ * - support relative offsets of the form >&
+ * - fix bug with truncating magic strings that contain \n
+ * - file -f - did not read from stdin as documented
+ * - support elf file parsing using our own elf support.
+ * - as always magdir fixes and additions.
+ *
+ * Revision 1.19  1995/10/27  23:14:46  christos
+ * Ability to parse colon separated list of magic files
+ * New LEGAL.NOTICE
+ * Various magic file changes
+ *
+ * Revision 1.18  1995/05/20  22:09:21  christos
+ * Passed incorrect argument to eatsize().
+ * Use %ld and %lx where appropriate.
+ * Remove unused variables
+ * ELF support for both big and little endian
+ * Fixes for small files again.
+ *
+ * Revision 1.17  1995/04/28  17:29:13  christos
+ * - Incorrect nroff detection fix from der Mouse
+ * - Lost and incorrect magic entries.
+ * - Added ELF stripped binary detection [in C; ugh]
+ * - Look for $MAGIC to find the magic file.
+ * - Eat trailing size specifications from numbers i.e. ignore 10L
+ * - More fixes for very short files
+ *
+ * Revision 1.16  1995/03/25  22:06:45  christos
+ * - use strtoul() where it exists.
+ * - fix sign-extend bug
+ * - try to detect tar archives before nroff files, otherwise
+ *   tar files where the first file starts with a . will not work
+ *
+ * Revision 1.15  1995/01/21  21:03:35  christos
+ * Added CSECTION for the file man page
+ * Added version flag -v
+ * Fixed bug with -f input flag (from iorio@violet.berkeley.edu)
+ * Lots of magic fixes and reorganization...
+ *
+ * Revision 1.14  1994/05/03  17:58:23  christos
+ * changes from mycroft@gnu.ai.mit.edu (Charles Hannum) for unsigned
+ *
+ * Revision 1.13  1994/01/21  01:27:01  christos
+ * Fixed null termination bug from Don Seeley at BSDI in ascmagic.c
+ *
+ * Revision 1.12  1993/10/27  20:59:05  christos
+ * Changed -z flag to understand gzip format too.
+ * Moved builtin compression detection to a table, and move
+ * the compress magic entry out of the source.
+ * Made printing of numbers unsigned, and added the mask to it.
+ * Changed the buffer size to 8k, because gzip will refuse to
+ * unzip just a few bytes.
+ *
+ * Revision 1.11  1993/09/24  18:49:06  christos
+ * Fixed small bug in softmagic.c introduced by
+ * copying the data to be examined out of the input
+ * buffer. Changed the Makefile to use sed to create
+ * the correct man pages.
+ *
+ * Revision 1.10  1993/09/23  21:56:23  christos
+ * Passed purify. Fixed indirections. Fixed byte order printing.
+ * Fixed segmentation faults caused by referencing past the end
+ * of the magic buffer. Fixed bus errors caused by referencing
+ * unaligned shorts or longs.
+ *
+ * Revision 1.9  1993/03/24  14:23:40  ian
+ * Batch of minor changes from several contributors.
+ *
+ * Revision 1.8  93/02/19  15:01:26  ian
+ * Numerous changes from Guy Harris too numerous to mention but including
+ * byte-order independance, fixing "old-style masking", etc. etc. A bugfix
+ * for broken symlinks from martin@@d255s004.zfe.siemens.de.
+ * 
+ * Revision 1.7  93/01/05  14:57:27  ian
+ * Couple of nits picked by Christos (again, thanks).
+ * 
+ * Revision 1.6  93/01/05  13:51:09  ian
+ * Lotsa work on the Magic directory.
+ * 
+ * Revision 1.5  92/09/14  14:54:51  ian
+ * Fix a tiny null-pointer bug in previous fix for tar archive + uncompress.
+ * 
+ */
diff --git a/src/pread.c b/src/pread.c
new file mode 100644 (file)
index 0000000..3ab52d1
--- /dev/null
@@ -0,0 +1,23 @@
+#include "file.h"
+#ifndef lint
+FILE_RCSID("@(#)$File: pread.c,v 1.2 2013/04/02 16:23:07 christos Exp $")
+#endif  /* lint */
+#include <fcntl.h>
+#include <unistd.h>
+
+ssize_t
+pread(int fd, void *buf, size_t len, off_t off) {
+       off_t old;
+       ssize_t rv;
+
+       if ((old = lseek(fd, off, SEEK_SET)) == -1)
+               return -1;
+
+       if ((rv = read(fd, buf, len)) == -1)
+               return -1;
+
+       if (lseek(fd, old, SEEK_SET) == -1)
+               return -1;
+
+       return rv;
+}
diff --git a/src/print.c b/src/print.c
new file mode 100644 (file)
index 0000000..391a7fb
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * print.c - debugging printout routines
+ */
+
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: print.c,v 1.85 2019/03/12 20:43:05 christos Exp $")
+#endif  /* lint */
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+
+#include "cdf.h"
+
+#ifndef COMPILE_ONLY
+protected void
+file_mdump(struct magic *m)
+{
+       static const char optyp[] = { FILE_OPS };
+       char tbuf[26];
+
+       (void) fprintf(stderr, "%u: %.*s %u", m->lineno,
+           (m->cont_level & 7) + 1, ">>>>>>>>", m->offset);
+
+       if (m->flag & INDIR) {
+               (void) fprintf(stderr, "(%s,",
+                   /* Note: type is unsigned */
+                   (m->in_type < file_nnames) ? file_names[m->in_type] :
+                   "*bad in_type*");
+               if (m->in_op & FILE_OPINVERSE)
+                       (void) fputc('~', stderr);
+               (void) fprintf(stderr, "%c%u),",
+                   (CAST(size_t, m->in_op & FILE_OPS_MASK) <
+                   __arraycount(optyp)) ?
+                   optyp[m->in_op & FILE_OPS_MASK] : '?', m->in_offset);
+       }
+       (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
+           /* Note: type is unsigned */
+           (m->type < file_nnames) ? file_names[m->type] : "*bad type");
+       if (m->mask_op & FILE_OPINVERSE)
+               (void) fputc('~', stderr);
+
+       if (IS_STRING(m->type)) {
+               if (m->str_flags) {
+                       (void) fputc('/', stderr);
+                       if (m->str_flags & STRING_COMPACT_WHITESPACE)
+                               (void) fputc(CHAR_COMPACT_WHITESPACE, stderr);
+                       if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE)
+                               (void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE,
+                                   stderr);
+                       if (m->str_flags & STRING_IGNORE_LOWERCASE)
+                               (void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
+                       if (m->str_flags & STRING_IGNORE_UPPERCASE)
+                               (void) fputc(CHAR_IGNORE_UPPERCASE, stderr);
+                       if (m->str_flags & REGEX_OFFSET_START)
+                               (void) fputc(CHAR_REGEX_OFFSET_START, stderr);
+                       if (m->str_flags & STRING_TEXTTEST)
+                               (void) fputc(CHAR_TEXTTEST, stderr);
+                       if (m->str_flags & STRING_BINTEST)
+                               (void) fputc(CHAR_BINTEST, stderr);
+                       if (m->str_flags & PSTRING_1_BE)
+                               (void) fputc(CHAR_PSTRING_1_BE, stderr);
+                       if (m->str_flags & PSTRING_2_BE)
+                               (void) fputc(CHAR_PSTRING_2_BE, stderr);
+                       if (m->str_flags & PSTRING_2_LE)
+                               (void) fputc(CHAR_PSTRING_2_LE, stderr);
+                       if (m->str_flags & PSTRING_4_BE)
+                               (void) fputc(CHAR_PSTRING_4_BE, stderr);
+                       if (m->str_flags & PSTRING_4_LE)
+                               (void) fputc(CHAR_PSTRING_4_LE, stderr);
+                       if (m->str_flags & PSTRING_LENGTH_INCLUDES_ITSELF)
+                               (void) fputc(
+                                   CHAR_PSTRING_LENGTH_INCLUDES_ITSELF,
+                                   stderr);
+               }
+               if (m->str_range)
+                       (void) fprintf(stderr, "/%u", m->str_range);
+       }
+       else {
+               if (CAST(size_t, m->mask_op & FILE_OPS_MASK) <
+                   __arraycount(optyp))
+                       (void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
+               else
+                       (void) fputc('?', stderr);
+
+               if (m->num_mask) {
+                       (void) fprintf(stderr, "%.8llx",
+                           CAST(unsigned long long, m->num_mask));
+               }
+       }
+       (void) fprintf(stderr, ",%c", m->reln);
+
+       if (m->reln != 'x') {
+               switch (m->type) {
+               case FILE_BYTE:
+               case FILE_SHORT:
+               case FILE_LONG:
+               case FILE_LESHORT:
+               case FILE_LELONG:
+               case FILE_MELONG:
+               case FILE_BESHORT:
+               case FILE_BELONG:
+               case FILE_INDIRECT:
+                       (void) fprintf(stderr, "%d", m->value.l);
+                       break;
+               case FILE_BEQUAD:
+               case FILE_LEQUAD:
+               case FILE_QUAD:
+                       (void) fprintf(stderr, "%" INT64_T_FORMAT "d",
+                           CAST(long long, m->value.q));
+                       break;
+               case FILE_PSTRING:
+               case FILE_STRING:
+               case FILE_REGEX:
+               case FILE_BESTRING16:
+               case FILE_LESTRING16:
+               case FILE_SEARCH:
+                       file_showstr(stderr, m->value.s,
+                           CAST(size_t, m->vallen));
+                       break;
+               case FILE_DATE:
+               case FILE_LEDATE:
+               case FILE_BEDATE:
+               case FILE_MEDATE:
+                       (void)fprintf(stderr, "%s,",
+                           file_fmttime(m->value.l, 0, tbuf));
+                       break;
+               case FILE_LDATE:
+               case FILE_LELDATE:
+               case FILE_BELDATE:
+               case FILE_MELDATE:
+                       (void)fprintf(stderr, "%s,",
+                           file_fmttime(m->value.l, FILE_T_LOCAL, tbuf));
+                       break;
+               case FILE_QDATE:
+               case FILE_LEQDATE:
+               case FILE_BEQDATE:
+                       (void)fprintf(stderr, "%s,",
+                           file_fmttime(m->value.q, 0, tbuf));
+                       break;
+               case FILE_QLDATE:
+               case FILE_LEQLDATE:
+               case FILE_BEQLDATE:
+                       (void)fprintf(stderr, "%s,",
+                           file_fmttime(m->value.q, FILE_T_LOCAL, tbuf));
+                       break;
+               case FILE_QWDATE:
+               case FILE_LEQWDATE:
+               case FILE_BEQWDATE:
+                       (void)fprintf(stderr, "%s,",
+                           file_fmttime(m->value.q, FILE_T_WINDOWS, tbuf));
+                       break;
+               case FILE_FLOAT:
+               case FILE_BEFLOAT:
+               case FILE_LEFLOAT:
+                       (void) fprintf(stderr, "%G", m->value.f);
+                       break;
+               case FILE_DOUBLE:
+               case FILE_BEDOUBLE:
+               case FILE_LEDOUBLE:
+                       (void) fprintf(stderr, "%G", m->value.d);
+                       break;
+               case FILE_DEFAULT:
+                       /* XXX - do anything here? */
+                       break;
+               case FILE_USE:
+               case FILE_NAME:
+               case FILE_DER:
+                       (void) fprintf(stderr, "'%s'", m->value.s);
+                       break;
+               default:
+                       (void) fprintf(stderr, "*bad type %d*", m->type);
+                       break;
+               }
+       }
+       (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
+}
+#endif
+
+/*VARARGS*/
+protected void
+file_magwarn(struct magic_set *ms, const char *f, ...)
+{
+       va_list va;
+
+       /* cuz we use stdout for most, stderr here */
+       (void) fflush(stdout);
+
+       if (ms->file)
+               (void) fprintf(stderr, "%s, %lu: ", ms->file,
+                   CAST(unsigned long, ms->line));
+       (void) fprintf(stderr, "Warning: ");
+       va_start(va, f);
+       (void) vfprintf(stderr, f, va);
+       va_end(va);
+       (void) fputc('\n', stderr);
+}
+
+protected const char *
+file_fmttime(uint64_t v, int flags, char *buf)
+{
+       char *pp;
+       time_t t;
+       struct tm *tm, tmz;
+
+       if (flags & FILE_T_WINDOWS) {
+               struct timespec ts;
+               cdf_timestamp_to_timespec(&ts, CAST(cdf_timestamp_t, v));
+               t = ts.tv_sec;
+       } else {
+               // XXX: perhaps detect and print something if overflow
+               // on 32 bit time_t?
+               t = CAST(time_t, v);
+       }
+
+       if (flags & FILE_T_LOCAL) {
+               tm = localtime_r(&t, &tmz);
+       } else {
+               tm = gmtime_r(&t, &tmz);
+       }
+       if (tm == NULL)
+               goto out;
+       pp = asctime_r(tm, buf);
+
+       if (pp == NULL)
+               goto out;
+       pp[strcspn(pp, "\n")] = '\0';
+       return pp;
+out:
+       return strcpy(buf, "*Invalid time*");
+}
diff --git a/src/readcdf.c b/src/readcdf.c
new file mode 100644 (file)
index 0000000..e6ea8e4
--- /dev/null
@@ -0,0 +1,676 @@
+/*-
+ * Copyright (c) 2008, 2016 Christos Zoulas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: readcdf.c,v 1.73 2019/03/12 20:43:05 christos Exp $")
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "cdf.h"
+#include "magic.h"
+
+#define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0)
+
+static const struct nv {
+       const char *pattern;
+       const char *mime;
+} app2mime[] =  {
+       { "Word",                       "msword",               },
+       { "Excel",                      "vnd.ms-excel",         },
+       { "Powerpoint",                 "vnd.ms-powerpoint",    },
+       { "Crystal Reports",            "x-rpt",                },
+       { "Advanced Installer",         "vnd.ms-msi",           },
+       { "InstallShield",              "vnd.ms-msi",           },
+       { "Microsoft Patch Compiler",   "vnd.ms-msi",           },
+       { "NAnt",                       "vnd.ms-msi",           },
+       { "Windows Installer",          "vnd.ms-msi",           },
+       { NULL,                         NULL,                   },
+}, name2mime[] = {
+       { "Book",                       "vnd.ms-excel",         },
+       { "Workbook",                   "vnd.ms-excel",         },
+       { "WordDocument",               "msword",               },
+       { "PowerPoint",                 "vnd.ms-powerpoint",    },
+       { "DigitalSignature",           "vnd.ms-msi",           },
+       { NULL,                         NULL,                   },
+}, name2desc[] = {
+       { "Book",                       "Microsoft Excel",      },
+       { "Workbook",                   "Microsoft Excel",      },
+       { "WordDocument",               "Microsoft Word",       },
+       { "PowerPoint",                 "Microsoft PowerPoint", },
+       { "DigitalSignature",           "Microsoft Installer",  },
+       { NULL,                         NULL,                   },
+};
+
+static const struct cv {
+       uint64_t clsid[2];
+       const char *mime;
+} clsid2mime[] = {
+       {
+               { 0x00000000000c1084ULL, 0x46000000000000c0ULL  },
+               "x-msi",
+       },
+       {       { 0,                     0                      },
+               NULL,
+       },
+}, clsid2desc[] = {
+       {
+               { 0x00000000000c1084ULL, 0x46000000000000c0ULL  },
+               "MSI Installer",
+       },
+       {       { 0,                     0                      },
+               NULL,
+       },
+};
+
+private const char *
+cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv)
+{
+       size_t i;
+       for (i = 0; cv[i].mime != NULL; i++) {
+               if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
+                       return cv[i].mime;
+       }
+#ifdef CDF_DEBUG
+       fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0],
+           clsid[1]);
+#endif
+       return NULL;
+}
+
+private const char *
+cdf_app_to_mime(const char *vbuf, const struct nv *nv)
+{
+       size_t i;
+       const char *rv = NULL;
+#ifdef USE_C_LOCALE
+       locale_t old_lc_ctype, c_lc_ctype;
+
+       c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
+       assert(c_lc_ctype != NULL);
+       old_lc_ctype = uselocale(c_lc_ctype);
+       assert(old_lc_ctype != NULL);
+#else
+       char *old_lc_ctype = setlocale(LC_CTYPE, "C");
+#endif
+       for (i = 0; nv[i].pattern != NULL; i++)
+               if (strcasestr(vbuf, nv[i].pattern) != NULL) {
+                       rv = nv[i].mime;
+                       break;
+               }
+#ifdef CDF_DEBUG
+       fprintf(stderr, "unknown app %s\n", vbuf);
+#endif
+#ifdef USE_C_LOCALE
+       (void)uselocale(old_lc_ctype);
+       freelocale(c_lc_ctype);
+#else
+       setlocale(LC_CTYPE, old_lc_ctype);
+#endif
+       return rv;
+}
+
+private int
+cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
+    size_t count, const cdf_directory_t *root_storage)
+{
+       size_t i;
+       cdf_timestamp_t tp;
+       struct timespec ts;
+       char buf[64];
+       const char *str = NULL;
+       const char *s, *e;
+       int len;
+
+       if (!NOTMIME(ms) && root_storage)
+               str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
+                   clsid2mime);
+
+       for (i = 0; i < count; i++) {
+               cdf_print_property_name(buf, sizeof(buf), info[i].pi_id);
+               switch (info[i].pi_type) {
+               case CDF_NULL:
+                       break;
+               case CDF_SIGNED16:
+                       if (NOTMIME(ms) && file_printf(ms, ", %s: %hd", buf,
+                           info[i].pi_s16) == -1)
+                               return -1;
+                       break;
+               case CDF_SIGNED32:
+                       if (NOTMIME(ms) && file_printf(ms, ", %s: %d", buf,
+                           info[i].pi_s32) == -1)
+                               return -1;
+                       break;
+               case CDF_UNSIGNED32:
+                       if (NOTMIME(ms) && file_printf(ms, ", %s: %u", buf,
+                           info[i].pi_u32) == -1)
+                               return -1;
+                       break;
+               case CDF_FLOAT:
+                       if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
+                           info[i].pi_f) == -1)
+                               return -1;
+                       break;
+               case CDF_DOUBLE:
+                       if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf,
+                           info[i].pi_d) == -1)
+                               return -1;
+                       break;
+               case CDF_LENGTH32_STRING:
+               case CDF_LENGTH32_WSTRING:
+                       len = info[i].pi_str.s_len;
+                       if (len > 1) {
+                               char vbuf[1024];
+                               size_t j, k = 1;
+
+                               if (info[i].pi_type == CDF_LENGTH32_WSTRING)
+                                   k++;
+                               s = info[i].pi_str.s_buf;
+                               e = info[i].pi_str.s_buf + len;
+                               for (j = 0; s < e && j < sizeof(vbuf)
+                                   && len--; s += k) {
+                                       if (*s == '\0')
+                                               break;
+                                       if (isprint(CAST(unsigned char, *s)))
+                                               vbuf[j++] = *s;
+                               }
+                               if (j == sizeof(vbuf))
+                                       --j;
+                               vbuf[j] = '\0';
+                               if (NOTMIME(ms)) {
+                                       if (vbuf[0]) {
+                                               if (file_printf(ms, ", %s: %s",
+                                                   buf, vbuf) == -1)
+                                                       return -1;
+                                       }
+                               } else if (str == NULL && info[i].pi_id ==
+                                   CDF_PROPERTY_NAME_OF_APPLICATION) {
+                                       str = cdf_app_to_mime(vbuf, app2mime);
+                               }
+                       }
+                       break;
+               case CDF_FILETIME:
+                       tp = info[i].pi_tp;
+                       if (tp != 0) {
+                               char tbuf[64];
+                               if (tp < 1000000000000000LL) {
+                                       cdf_print_elapsed_time(tbuf,
+                                           sizeof(tbuf), tp);
+                                       if (NOTMIME(ms) && file_printf(ms,
+                                           ", %s: %s", buf, tbuf) == -1)
+                                               return -1;
+                               } else {
+                                       char *c, *ec;
+                                       cdf_timestamp_to_timespec(&ts, tp);
+                                       c = cdf_ctime(&ts.tv_sec, tbuf);
+                                       if (c != NULL &&
+                                           (ec = strchr(c, '\n')) != NULL)
+                                               *ec = '\0';
+
+                                       if (NOTMIME(ms) && file_printf(ms,
+                                           ", %s: %s", buf, c) == -1)
+                                               return -1;
+                               }
+                       }
+                       break;
+               case CDF_CLIPBOARD:
+                       break;
+               default:
+                       return -1;
+               }
+       }
+       if (ms->flags & MAGIC_MIME_TYPE) {
+               if (str == NULL)
+                       return 0;
+               if (file_printf(ms, "application/%s", str) == -1)
+                       return -1;
+       }
+       return 1;
+}
+
+private int
+cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
+    const cdf_stream_t *sst)
+{
+       cdf_catalog_t *cat;
+       size_t i;
+       char buf[256];
+       cdf_catalog_entry_t *ce;
+
+       if (NOTMIME(ms)) {
+               if (file_printf(ms, "Microsoft Thumbs.db [") == -1)
+                       return -1;
+               if (cdf_unpack_catalog(h, sst, &cat) == -1)
+                       return -1;
+               ce = cat->cat_e;
+               /* skip first entry since it has a , or paren */
+               for (i = 1; i < cat->cat_num; i++)
+                       if (file_printf(ms, "%s%s",
+                           cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name),
+                           i == cat->cat_num - 1 ? "]" : ", ") == -1) {
+                               free(cat);
+                               return -1;
+                       }
+               free(cat);
+       } else if (ms->flags & MAGIC_MIME_TYPE) {
+               if (file_printf(ms, "application/CDFV2") == -1)
+                       return -1;
+       }
+       return 1;
+}
+
+private int
+cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
+    const cdf_stream_t *sst, const cdf_directory_t *root_storage)
+{
+       cdf_summary_info_header_t si;
+       cdf_property_info_t *info;
+       size_t count;
+       int m;
+
+       if (cdf_unpack_summary_info(sst, h, &si, &info, &count) == -1)
+               return -1;
+
+       if (NOTMIME(ms)) {
+               const char *str;
+
+               if (file_printf(ms, "Composite Document File V2 Document")
+                   == -1)
+                       return -1;
+
+               if (file_printf(ms, ", %s Endian",
+                   si.si_byte_order == 0xfffe ?  "Little" : "Big") == -1)
+                       return -2;
+               switch (si.si_os) {
+               case 2:
+                       if (file_printf(ms, ", Os: Windows, Version %d.%d",
+                           si.si_os_version & 0xff,
+                           CAST(uint32_t, si.si_os_version) >> 8) == -1)
+                               return -2;
+                       break;
+               case 1:
+                       if (file_printf(ms, ", Os: MacOS, Version %d.%d",
+                           CAST(uint32_t, si.si_os_version) >> 8,
+                           si.si_os_version & 0xff) == -1)
+                               return -2;
+                       break;
+               default:
+                       if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
+                           si.si_os_version & 0xff,
+                           CAST(uint32_t, si.si_os_version) >> 8) == -1)
+                               return -2;
+                       break;
+               }
+               if (root_storage) {
+                       str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
+                           clsid2desc);
+                       if (str) {
+                               if (file_printf(ms, ", %s", str) == -1)
+                                       return -2;
+                       }
+               }
+       }
+
+       m = cdf_file_property_info(ms, info, count, root_storage);
+       free(info);
+
+       return m == -1 ? -2 : m;
+}
+
+#ifdef notdef
+private char *
+format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
+       snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
+           PRIx64 "-%.12" PRIx64,
+           (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL,
+           (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL,
+           (uuid[0] >>  0) & (uint64_t)0x0000000000000ffffULL,
+           (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL,
+           (uuid[1] >>  0) & (uint64_t)0x0000fffffffffffffULL);
+       return buf;
+}
+#endif
+
+private int
+cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info,
+    const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat,
+    const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn)
+{
+       int i;
+
+       if ((i = cdf_read_user_stream(info, h, sat, ssat, sst,
+           dir, "Catalog", scn)) == -1)
+               return i;
+#ifdef CDF_DEBUG
+       cdf_dump_catalog(h, scn);
+#endif
+       if ((i = cdf_file_catalog(ms, h, scn)) == -1)
+               return -1;
+       return i;
+}
+
+private int
+cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
+    const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat,
+    const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn,
+    const cdf_directory_t *root_storage, const char **expn)
+{
+       int i;
+       const char *str = NULL;
+       cdf_directory_t *d;
+       char name[__arraycount(d->d_name)];
+       size_t j, k;
+
+#ifdef CDF_DEBUG
+       cdf_dump_summary_info(h, scn);
+#endif
+       if ((i = cdf_file_summary_info(ms, h, scn, root_storage)) < 0) {
+           *expn = "Can't expand summary_info";
+           return i;
+       }
+       if (i == 1)
+               return i;
+       for (j = 0; str == NULL && j < dir->dir_len; j++) {
+               d = &dir->dir_tab[j];
+               for (k = 0; k < sizeof(name); k++)
+                       name[k] = CAST(char, cdf_tole2(d->d_name[k]));
+               str = cdf_app_to_mime(name,
+                                     NOTMIME(ms) ? name2desc : name2mime);
+       }
+       if (NOTMIME(ms)) {
+               if (str != NULL) {
+                       if (file_printf(ms, "%s", str) == -1)
+                               return -1;
+                       i = 1;
+               }
+       } else if (ms->flags & MAGIC_MIME_TYPE) {
+               if (str == NULL)
+                       str = "vnd.ms-office";
+               if (file_printf(ms, "application/%s", str) == -1)
+                       return -1;
+               i = 1;
+       }
+       if (i <= 0) {
+               i = cdf_file_catalog_info(ms, info, h, sat, ssat, sst,
+                                         dir, scn);
+       }
+       return i;
+}
+
+private struct sinfo {
+       const char *name;
+       const char *mime;
+       const char *sections[5];
+       const int  types[5];
+} sectioninfo[] = {
+       { "Encrypted", "encrypted",
+               {
+                       "EncryptedPackage", "EncryptedSummary",
+                       NULL, NULL, NULL,
+               },
+               {
+                       CDF_DIR_TYPE_USER_STREAM,
+                       CDF_DIR_TYPE_USER_STREAM,
+                       0, 0, 0,
+
+               },
+       },
+       { "QuickBooks", "quickbooks",
+               {
+#if 0
+                       "TaxForms", "PDFTaxForms", "modulesInBackup",
+#endif
+                       "mfbu_header", NULL, NULL, NULL, NULL,
+               },
+               {
+#if 0
+                       CDF_DIR_TYPE_USER_STORAGE,
+                       CDF_DIR_TYPE_USER_STORAGE,
+                       CDF_DIR_TYPE_USER_STREAM,
+#endif
+                       CDF_DIR_TYPE_USER_STREAM,
+                       0, 0, 0, 0
+               },
+       },
+       { "Microsoft Excel", "vnd.ms-excel",
+               {
+                       "Book", "Workbook", NULL, NULL, NULL,
+               },
+               {
+                       CDF_DIR_TYPE_USER_STREAM,
+                       CDF_DIR_TYPE_USER_STREAM,
+                       0, 0, 0,
+               },
+       },
+       { "Microsoft Word", "msword",
+               {
+                       "WordDocument", NULL, NULL, NULL, NULL,
+               },
+               {
+                       CDF_DIR_TYPE_USER_STREAM,
+                       0, 0, 0, 0,
+               },
+       },
+       { "Microsoft PowerPoint", "vnd.ms-powerpoint",
+               {
+                       "PowerPoint", NULL, NULL, NULL, NULL,
+               },
+               {
+                       CDF_DIR_TYPE_USER_STREAM,
+                       0, 0, 0, 0,
+               },
+       },
+       { "Microsoft Outlook Message", "vnd.ms-outlook",
+               {
+                       "__properties_version1.0",
+                       "__recip_version1.0_#00000000",
+                       NULL, NULL, NULL,
+               },
+               {
+                       CDF_DIR_TYPE_USER_STREAM,
+                       CDF_DIR_TYPE_USER_STORAGE,
+                       0, 0, 0,
+               },
+       },
+};
+
+private int
+cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
+{
+       size_t sd, j;
+
+       for (sd = 0; sd < __arraycount(sectioninfo); sd++) {
+               const struct sinfo *si = &sectioninfo[sd];
+               for (j = 0; si->sections[j]; j++) {
+                       if (cdf_find_stream(dir, si->sections[j], si->types[j])
+                           > 0)
+                               break;
+#ifdef CDF_DEBUG
+                       fprintf(stderr, "Can't read %s\n", si->sections[j]);
+#endif
+               }
+               if (si->sections[j] == NULL)
+                       continue;
+               if (NOTMIME(ms)) {
+                       if (file_printf(ms, "CDFV2 %s", si->name) == -1)
+                               return -1;
+               } else if (ms->flags & MAGIC_MIME_TYPE) {
+                       if (file_printf(ms, "application/%s", si->mime) == -1)
+                               return -1;
+               }
+               return 1;
+       }
+       return -1;
+}
+
+protected int
+file_trycdf(struct magic_set *ms, const struct buffer *b)
+{
+       int fd = b->fd;
+       const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
+       size_t nbytes = b->flen;
+       cdf_info_t info;
+       cdf_header_t h;
+       cdf_sat_t sat, ssat;
+       cdf_stream_t sst, scn;
+       cdf_dir_t dir;
+       int i;
+       const char *expn = "";
+       const cdf_directory_t *root_storage;
+
+       scn.sst_tab = NULL;
+       info.i_fd = fd;
+       info.i_buf = buf;
+       info.i_len = nbytes;
+       if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
+               return 0;
+       if (cdf_read_header(&info, &h) == -1)
+               return 0;
+#ifdef CDF_DEBUG
+       cdf_dump_header(&h);
+#endif
+
+       if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
+               expn = "Can't read SAT";
+               goto out0;
+       }
+#ifdef CDF_DEBUG
+       cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
+#endif
+
+       if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) {
+               expn = "Can't read SSAT";
+               goto out1;
+       }
+#ifdef CDF_DEBUG
+       cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h));
+#endif
+
+       if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) {
+               expn = "Can't read directory";
+               goto out2;
+       }
+
+       if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst,
+           &root_storage)) == -1) {
+               expn = "Cannot read short stream";
+               goto out3;
+       }
+#ifdef CDF_DEBUG
+       cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir);
+#endif
+#ifdef notdef
+       if (root_storage) {
+               if (NOTMIME(ms)) {
+                       char clsbuf[128];
+                       if (file_printf(ms, "CLSID %s, ",
+                           format_clsid(clsbuf, sizeof(clsbuf),
+                           root_storage->d_storage_uuid)) == -1)
+                               return -1;
+               }
+       }
+#endif
+
+       if ((i = cdf_read_user_stream(&info, &h, &sat, &ssat, &sst, &dir,
+           "FileHeader", &scn)) != -1) {
+#define HWP5_SIGNATURE "HWP Document File"
+               if (scn.sst_len * scn.sst_ss >= sizeof(HWP5_SIGNATURE) - 1
+                   && memcmp(scn.sst_tab, HWP5_SIGNATURE,
+                   sizeof(HWP5_SIGNATURE) - 1) == 0) {
+                   if (NOTMIME(ms)) {
+                       if (file_printf(ms,
+                           "Hangul (Korean) Word Processor File 5.x") == -1)
+                           return -1;
+                   } else if (ms->flags & MAGIC_MIME_TYPE) {
+                       if (file_printf(ms, "application/x-hwp") == -1)
+                           return -1;
+                   }
+                   i = 1;
+                   goto out5;
+               } else {
+                   cdf_zero_stream(&scn);
+               }
+       }
+
+       if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
+           &scn)) == -1) {
+               if (errno != ESRCH) {
+                       expn = "Cannot read summary info";
+               }
+       } else {
+               i = cdf_check_summary_info(ms, &info, &h,
+                   &sat, &ssat, &sst, &dir, &scn, root_storage, &expn);
+               cdf_zero_stream(&scn);
+       }
+       if (i <= 0) {
+               if ((i = cdf_read_doc_summary_info(&info, &h, &sat, &ssat,
+                   &sst, &dir, &scn)) == -1) {
+                       if (errno != ESRCH) {
+                               expn = "Cannot read summary info";
+                       }
+               } else {
+                       i = cdf_check_summary_info(ms, &info, &h, &sat, &ssat,
+                           &sst, &dir, &scn, root_storage, &expn);
+               }
+       }
+       if (i <= 0) {
+               i = cdf_file_dir_info(ms, &dir);
+               if (i < 0)
+                       expn = "Cannot read section info";
+       }
+out5:
+       cdf_zero_stream(&scn);
+       cdf_zero_stream(&sst);
+out3:
+       free(dir.dir_tab);
+out2:
+       free(ssat.sat_tab);
+out1:
+       free(sat.sat_tab);
+out0:
+       /* If we handled it already, return */
+       if (i != -1)
+               return i;
+       /* Provide a default handler */
+       if (NOTMIME(ms)) {
+               if (file_printf(ms,
+                   "Composite Document File V2 Document") == -1)
+                       return -1;
+               if (*expn)
+                       if (file_printf(ms, ", %s", expn) == -1)
+                               return -1;
+       } else if (ms->flags & MAGIC_MIME_TYPE) {
+               if (file_printf(ms, "application/CDFV2") == -1)
+                       return -1;
+       }
+       return 1;
+}
diff --git a/src/readelf.c b/src/readelf.c
new file mode 100644 (file)
index 0000000..ef61d4c
--- /dev/null
@@ -0,0 +1,1810 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: readelf.c,v 1.165 2019/05/07 02:27:11 christos Exp $")
+#endif
+
+#ifdef BUILTIN_ELF
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "readelf.h"
+#include "magic.h"
+
+#ifdef ELFCORE
+private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
+    off_t, int *, uint16_t *);
+#endif
+private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
+    off_t, int, int *, uint16_t *);
+private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
+    off_t, int, int, int *, uint16_t *);
+private size_t donote(struct magic_set *, void *, size_t, size_t, int,
+    int, size_t, int *, uint16_t *, int, off_t, int, off_t);
+
+#define        ELF_ALIGN(a)    ((((a) + align - 1) / align) * align)
+
+#define isquote(c) (strchr("'\"`", (c)) != NULL)
+
+private uint16_t getu16(int, uint16_t);
+private uint32_t getu32(int, uint32_t);
+private uint64_t getu64(int, uint64_t);
+
+#define MAX_PHNUM      128
+#define        MAX_SHNUM       32768
+#define SIZE_UNKNOWN   CAST(off_t, -1)
+
+private int
+toomany(struct magic_set *ms, const char *name, uint16_t num)
+{
+       if (file_printf(ms, ", too many %s (%u)", name, num) == -1)
+               return -1;
+       return 1;
+}
+
+private uint16_t
+getu16(int swap, uint16_t value)
+{
+       union {
+               uint16_t ui;
+               char c[2];
+       } retval, tmpval;
+
+       if (swap) {
+               tmpval.ui = value;
+
+               retval.c[0] = tmpval.c[1];
+               retval.c[1] = tmpval.c[0];
+
+               return retval.ui;
+       } else
+               return value;
+}
+
+private uint32_t
+getu32(int swap, uint32_t value)
+{
+       union {
+               uint32_t ui;
+               char c[4];
+       } retval, tmpval;
+
+       if (swap) {
+               tmpval.ui = value;
+
+               retval.c[0] = tmpval.c[3];
+               retval.c[1] = tmpval.c[2];
+               retval.c[2] = tmpval.c[1];
+               retval.c[3] = tmpval.c[0];
+
+               return retval.ui;
+       } else
+               return value;
+}
+
+private uint64_t
+getu64(int swap, uint64_t value)
+{
+       union {
+               uint64_t ui;
+               char c[8];
+       } retval, tmpval;
+
+       if (swap) {
+               tmpval.ui = value;
+
+               retval.c[0] = tmpval.c[7];
+               retval.c[1] = tmpval.c[6];
+               retval.c[2] = tmpval.c[5];
+               retval.c[3] = tmpval.c[4];
+               retval.c[4] = tmpval.c[3];
+               retval.c[5] = tmpval.c[2];
+               retval.c[6] = tmpval.c[1];
+               retval.c[7] = tmpval.c[0];
+
+               return retval.ui;
+       } else
+               return value;
+}
+
+#define elf_getu16(swap, value) getu16(swap, value)
+#define elf_getu32(swap, value) getu32(swap, value)
+#define elf_getu64(swap, value) getu64(swap, value)
+
+#define xsh_addr       (clazz == ELFCLASS32                    \
+                        ? CAST(void *, &sh32)                  \
+                        : CAST(void *, &sh64))
+#define xsh_sizeof     (clazz == ELFCLASS32                    \
+                        ? sizeof(sh32)                         \
+                        : sizeof(sh64))
+#define xsh_size       CAST(size_t, (clazz == ELFCLASS32       \
+                        ? elf_getu32(swap, sh32.sh_size)       \
+                        : elf_getu64(swap, sh64.sh_size)))
+#define xsh_offset     CAST(off_t, (clazz == ELFCLASS32        \
+                        ? elf_getu32(swap, sh32.sh_offset)     \
+                        : elf_getu64(swap, sh64.sh_offset)))
+#define xsh_type       (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, sh32.sh_type)       \
+                        : elf_getu32(swap, sh64.sh_type))
+#define xsh_name       (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, sh32.sh_name)       \
+                        : elf_getu32(swap, sh64.sh_name))
+
+#define xph_addr       (clazz == ELFCLASS32                    \
+                        ? CAST(void *, &ph32)                  \
+                        : CAST(void *, &ph64))
+#define xph_sizeof     (clazz == ELFCLASS32                    \
+                        ? sizeof(ph32)                         \
+                        : sizeof(ph64))
+#define xph_type       (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, ph32.p_type)        \
+                        : elf_getu32(swap, ph64.p_type))
+#define xph_offset     CAST(off_t, (clazz == ELFCLASS32        \
+                        ? elf_getu32(swap, ph32.p_offset)      \
+                        : elf_getu64(swap, ph64.p_offset)))
+#define xph_align      CAST(size_t, (clazz == ELFCLASS32       \
+                        ? CAST(off_t, (ph32.p_align ?          \
+                           elf_getu32(swap, ph32.p_align) : 4))\
+                        : CAST(off_t, (ph64.p_align ?          \
+                           elf_getu64(swap, ph64.p_align) : 4))))
+#define xph_vaddr      CAST(size_t, (clazz == ELFCLASS32       \
+                        ? CAST(off_t, (ph32.p_vaddr ?          \
+                           elf_getu32(swap, ph32.p_vaddr) : 4))\
+                        : CAST(off_t, (ph64.p_vaddr ?          \
+                           elf_getu64(swap, ph64.p_vaddr) : 4))))
+#define xph_filesz     CAST(size_t, (clazz == ELFCLASS32       \
+                        ? elf_getu32(swap, ph32.p_filesz)      \
+                        : elf_getu64(swap, ph64.p_filesz)))
+#define xph_memsz      CAST(size_t, ((clazz == ELFCLASS32      \
+                        ? elf_getu32(swap, ph32.p_memsz)       \
+                        : elf_getu64(swap, ph64.p_memsz))))
+#define xnh_addr       (clazz == ELFCLASS32                    \
+                        ? CAST(void *, &nh32)                  \
+                        : CAST(void *, &nh64))
+#define xnh_sizeof     (clazz == ELFCLASS32                    \
+                        ? sizeof(nh32)                         \
+                        : sizeof(nh64))
+#define xnh_type       (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, nh32.n_type)        \
+                        : elf_getu32(swap, nh64.n_type))
+#define xnh_namesz     (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, nh32.n_namesz)      \
+                        : elf_getu32(swap, nh64.n_namesz))
+#define xnh_descsz     (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, nh32.n_descsz)      \
+                        : elf_getu32(swap, nh64.n_descsz))
+
+#define xdh_addr       (clazz == ELFCLASS32                    \
+                        ? CAST(void *, &dh32)                  \
+                        : CAST(void *, &dh64))
+#define xdh_sizeof     (clazz == ELFCLASS32                    \
+                        ? sizeof(dh32)                         \
+                        : sizeof(dh64))
+#define xdh_tag                (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, dh32.d_tag)         \
+                        : elf_getu64(swap, dh64.d_tag))
+#define xdh_val                (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, dh32.d_un.d_val)    \
+                        : elf_getu64(swap, dh64.d_un.d_val))
+
+#define xcap_addr      (clazz == ELFCLASS32                    \
+                        ? CAST(void *, &cap32)                 \
+                        : CAST(void *, &cap64))
+#define xcap_sizeof    (clazz == ELFCLASS32                    \
+                        ? sizeof(cap32)                        \
+                        : sizeof(cap64))
+#define xcap_tag       (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, cap32.c_tag)        \
+                        : elf_getu64(swap, cap64.c_tag))
+#define xcap_val       (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, cap32.c_un.c_val)   \
+                        : elf_getu64(swap, cap64.c_un.c_val))
+
+#define xauxv_addr     (clazz == ELFCLASS32                    \
+                        ? CAST(void *, &auxv32)                \
+                        : CAST(void *, &auxv64))
+#define xauxv_sizeof   (clazz == ELFCLASS32                    \
+                        ? sizeof(auxv32)                       \
+                        : sizeof(auxv64))
+#define xauxv_type     (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, auxv32.a_type)      \
+                        : elf_getu64(swap, auxv64.a_type))
+#define xauxv_val      (clazz == ELFCLASS32                    \
+                        ? elf_getu32(swap, auxv32.a_v)         \
+                        : elf_getu64(swap, auxv64.a_v))
+
+#define prpsoffsets(i) (clazz == ELFCLASS32                    \
+                        ? prpsoffsets32[i]                     \
+                        : prpsoffsets64[i])
+
+#ifdef ELFCORE
+/*
+ * Try larger offsets first to avoid false matches
+ * from earlier data that happen to look like strings.
+ */
+static const size_t    prpsoffsets32[] = {
+#ifdef USE_NT_PSINFO
+       104,            /* SunOS 5.x (command line) */
+       88,             /* SunOS 5.x (short name) */
+#endif /* USE_NT_PSINFO */
+
+       100,            /* SunOS 5.x (command line) */
+       84,             /* SunOS 5.x (short name) */
+
+       44,             /* Linux (command line) */
+       28,             /* Linux (short name) */
+
+       48,             /* Linux PowerPC (command line) */
+       32,             /* Linux PowerPC (short name) */
+
+       8,              /* FreeBSD */
+};
+
+static const size_t    prpsoffsets64[] = {
+#ifdef USE_NT_PSINFO
+       152,            /* SunOS 5.x (command line) */
+       136,            /* SunOS 5.x (short name) */
+#endif /* USE_NT_PSINFO */
+
+       136,            /* SunOS 5.x, 64-bit (command line) */
+       120,            /* SunOS 5.x, 64-bit (short name) */
+
+       56,             /* Linux (command line) */
+       40,             /* Linux (tested on core from 2.4.x, short name) */
+
+       16,             /* FreeBSD, 64-bit */
+};
+
+#define        NOFFSETS32      __arraycount(prpsoffsets32)
+#define NOFFSETS64     __arraycount(prpsoffsets64)
+
+#define NOFFSETS       (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
+
+/*
+ * Look through the program headers of an executable image, searching
+ * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE" or
+ * "FreeBSD"; if one is found, try looking in various places in its
+ * contents for a 16-character string containing only printable
+ * characters - if found, that string should be the name of the program
+ * that dropped core.  Note: right after that 16-character string is,
+ * at least in SunOS 5.x (and possibly other SVR4-flavored systems) and
+ * Linux, a longer string (80 characters, in 5.x, probably other
+ * SVR4-flavored systems, and Linux) containing the start of the
+ * command line for that program.
+ *
+ * SunOS 5.x core files contain two PT_NOTE sections, with the types
+ * NT_PRPSINFO (old) and NT_PSINFO (new).  These structs contain the
+ * same info about the command name and command line, so it probably
+ * isn't worthwhile to look for NT_PSINFO, but the offsets are provided
+ * above (see USE_NT_PSINFO), in case we ever decide to do so.  The
+ * NT_PRPSINFO and NT_PSINFO sections are always in order and adjacent;
+ * the SunOS 5.x file command relies on this (and prefers the latter).
+ *
+ * The signal number probably appears in a section of type NT_PRSTATUS,
+ * but that's also rather OS-dependent, in ways that are harder to
+ * dissect with heuristics, so I'm not bothering with the signal number.
+ * (I suppose the signal number could be of interest in situations where
+ * you don't have the binary of the program that dropped core; if you
+ * *do* have that binary, the debugger will probably tell you what
+ * signal it was.)
+ */
+
+#define        OS_STYLE_SVR4           0
+#define        OS_STYLE_FREEBSD        1
+#define        OS_STYLE_NETBSD         2
+
+private const char os_style_names[][8] = {
+       "SVR4",
+       "FreeBSD",
+       "NetBSD",
+};
+
+#define FLAGS_CORE_STYLE               0x0003
+
+#define FLAGS_DID_CORE                 0x0004
+#define FLAGS_DID_OS_NOTE              0x0008
+#define FLAGS_DID_BUILD_ID             0x0010
+#define FLAGS_DID_CORE_STYLE           0x0020
+#define FLAGS_DID_NETBSD_PAX           0x0040
+#define FLAGS_DID_NETBSD_MARCH         0x0080
+#define FLAGS_DID_NETBSD_CMODEL                0x0100
+#define FLAGS_DID_NETBSD_EMULATION     0x0200
+#define FLAGS_DID_NETBSD_UNKNOWN       0x0400
+#define FLAGS_IS_CORE                  0x0800
+#define FLAGS_DID_AUXV                 0x1000
+
+private int
+dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
+    int num, size_t size, off_t fsize, int *flags, uint16_t *notecount)
+{
+       Elf32_Phdr ph32;
+       Elf64_Phdr ph64;
+       size_t offset, len;
+       unsigned char nbuf[BUFSIZ];
+       ssize_t bufsize;
+       off_t ph_off = off;
+       int ph_num = num;
+
+       if (num == 0) {
+               if (file_printf(ms, ", no program header") == -1)
+                       return -1;
+               return 0;
+       }
+       if (size != xph_sizeof) {
+               if (file_printf(ms, ", corrupted program header size") == -1)
+                       return -1;
+               return 0;
+       }
+
+       /*
+        * Loop through all the program headers.
+        */
+       for ( ; num; num--) {
+               if (pread(fd, xph_addr, xph_sizeof, off) <
+                   CAST(ssize_t, xph_sizeof)) {
+                       file_badread(ms);
+                       return -1;
+               }
+               off += size;
+
+               if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
+                       /* Perhaps warn here */
+                       continue;
+               }
+
+               if (xph_type != PT_NOTE)
+                       continue;
+
+               /*
+                * This is a PT_NOTE section; loop through all the notes
+                * in the section.
+                */
+               len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf);
+               if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) {
+                       file_badread(ms);
+                       return -1;
+               }
+               offset = 0;
+               for (;;) {
+                       if (offset >= CAST(size_t, bufsize))
+                               break;
+                       offset = donote(ms, nbuf, offset, CAST(size_t, bufsize),
+                           clazz, swap, 4, flags, notecount, fd, ph_off,
+                           ph_num, fsize);
+                       if (offset == 0)
+                               break;
+
+               }
+       }
+       return 0;
+}
+#endif
+
+static int
+do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
+{
+       uint32_t desc;
+       memcpy(&desc, v, sizeof(desc));
+       desc = elf_getu32(swap, desc);
+
+       if (file_printf(ms, ", for NetBSD") == -1)
+               return -1;
+       /*
+        * The version number used to be stuck as 199905, and was thus
+        * basically content-free.  Newer versions of NetBSD have fixed
+        * this and now use the encoding of __NetBSD_Version__:
+        *
+        *      MMmmrrpp00
+        *
+        * M = major version
+        * m = minor version
+        * r = release ["",A-Z,Z[A-Z] but numeric]
+        * p = patchlevel
+        */
+       if (desc > 100000000U) {
+               uint32_t ver_patch = (desc / 100) % 100;
+               uint32_t ver_rel = (desc / 10000) % 100;
+               uint32_t ver_min = (desc / 1000000) % 100;
+               uint32_t ver_maj = desc / 100000000;
+
+               if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
+                       return -1;
+               if (ver_rel == 0 && ver_patch != 0) {
+                       if (file_printf(ms, ".%u", ver_patch) == -1)
+                               return -1;
+               } else if (ver_rel != 0) {
+                       while (ver_rel > 26) {
+                               if (file_printf(ms, "Z") == -1)
+                                       return -1;
+                               ver_rel -= 26;
+                       }
+                       if (file_printf(ms, "%c", 'A' + ver_rel - 1)
+                           == -1)
+                               return -1;
+               }
+       }
+       return 0;
+}
+
+static int
+do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
+{
+       uint32_t desc;
+
+       memcpy(&desc, v, sizeof(desc));
+       desc = elf_getu32(swap, desc);
+       if (file_printf(ms, ", for FreeBSD") == -1)
+               return -1;
+
+       /*
+        * Contents is __FreeBSD_version, whose relation to OS
+        * versions is defined by a huge table in the Porter's
+        * Handbook.  This is the general scheme:
+        *
+        * Releases:
+        *      Mmp000 (before 4.10)
+        *      Mmi0p0 (before 5.0)
+        *      Mmm0p0
+        *
+        * Development branches:
+        *      Mmpxxx (before 4.6)
+        *      Mmp1xx (before 4.10)
+        *      Mmi1xx (before 5.0)
+        *      M000xx (pre-M.0)
+        *      Mmm1xx
+        *
+        * M = major version
+        * m = minor version
+        * i = minor version increment (491000 -> 4.10)
+        * p = patchlevel
+        * x = revision
+        *
+        * The first release of FreeBSD to use ELF by default
+        * was version 3.0.
+        */
+       if (desc == 460002) {
+               if (file_printf(ms, " 4.6.2") == -1)
+                       return -1;
+       } else if (desc < 460100) {
+               if (file_printf(ms, " %d.%d", desc / 100000,
+                   desc / 10000 % 10) == -1)
+                       return -1;
+               if (desc / 1000 % 10 > 0)
+                       if (file_printf(ms, ".%d", desc / 1000 % 10) == -1)
+                               return -1;
+               if ((desc % 1000 > 0) || (desc % 100000 == 0))
+                       if (file_printf(ms, " (%d)", desc) == -1)
+                               return -1;
+       } else if (desc < 500000) {
+               if (file_printf(ms, " %d.%d", desc / 100000,
+                   desc / 10000 % 10 + desc / 1000 % 10) == -1)
+                       return -1;
+               if (desc / 100 % 10 > 0) {
+                       if (file_printf(ms, " (%d)", desc) == -1)
+                               return -1;
+               } else if (desc / 10 % 10 > 0) {
+                       if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
+                               return -1;
+               }
+       } else {
+               if (file_printf(ms, " %d.%d", desc / 100000,
+                   desc / 1000 % 100) == -1)
+                       return -1;
+               if ((desc / 100 % 10 > 0) ||
+                   (desc % 100000 / 100 == 0)) {
+                       if (file_printf(ms, " (%d)", desc) == -1)
+                               return -1;
+               } else if (desc / 10 % 10 > 0) {
+                       if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
+                               return -1;
+               }
+       }
+       return 0;
+}
+
+private int
+/*ARGSUSED*/
+do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags)
+{
+       if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "GNU") == 0 &&
+           type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) {
+               uint8_t desc[20];
+               const char *btype;
+               uint32_t i;
+               *flags |= FLAGS_DID_BUILD_ID;
+               switch (descsz) {
+               case 8:
+                   btype = "xxHash";
+                   break;
+               case 16:
+                   btype = "md5/uuid";
+                   break;
+               case 20:
+                   btype = "sha1";
+                   break;
+               default:
+                   btype = "unknown";
+                   break;
+               }
+               if (file_printf(ms, ", BuildID[%s]=", btype) == -1)
+                       return -1;
+               memcpy(desc, &nbuf[doff], descsz);
+               for (i = 0; i < descsz; i++)
+                   if (file_printf(ms, "%02x", desc[i]) == -1)
+                       return -1;
+               return 1;
+       }
+       if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "Go") == 0 &&
+           type == NT_GO_BUILD_ID && descsz < 128) {
+               if (file_printf(ms, ", Go BuildID=%.*s",
+                   CAST(int, descsz), RCAST(char *, &nbuf[doff])) == -1)
+                       return -1;
+               return 1;
+       }
+       return 0;
+}
+
+private int
+do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags)
+{
+       const char *name = RCAST(const char *, &nbuf[noff]);
+
+       if (namesz == 5 && strcmp(name, "SuSE") == 0 &&
+               type == NT_GNU_VERSION && descsz == 2) {
+               *flags |= FLAGS_DID_OS_NOTE;
+               if (file_printf(ms, ", for SuSE %d.%d", nbuf[doff],
+                   nbuf[doff + 1]) == -1)
+                   return -1;
+           return 1;
+       }
+
+       if (namesz == 4 && strcmp(name, "GNU") == 0 &&
+           type == NT_GNU_VERSION && descsz == 16) {
+               uint32_t desc[4];
+               memcpy(desc, &nbuf[doff], sizeof(desc));
+
+               *flags |= FLAGS_DID_OS_NOTE;
+               if (file_printf(ms, ", for GNU/") == -1)
+                       return -1;
+               switch (elf_getu32(swap, desc[0])) {
+               case GNU_OS_LINUX:
+                       if (file_printf(ms, "Linux") == -1)
+                               return -1;
+                       break;
+               case GNU_OS_HURD:
+                       if (file_printf(ms, "Hurd") == -1)
+                               return -1;
+                       break;
+               case GNU_OS_SOLARIS:
+                       if (file_printf(ms, "Solaris") == -1)
+                               return -1;
+                       break;
+               case GNU_OS_KFREEBSD:
+                       if (file_printf(ms, "kFreeBSD") == -1)
+                               return -1;
+                       break;
+               case GNU_OS_KNETBSD:
+                       if (file_printf(ms, "kNetBSD") == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, "<unknown>") == -1)
+                               return -1;
+               }
+               if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
+                   elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
+                       return -1;
+               return 1;
+       }
+
+       if (namesz == 7 && strcmp(name, "NetBSD") == 0) {
+               if (type == NT_NETBSD_VERSION && descsz == 4) {
+                       *flags |= FLAGS_DID_OS_NOTE;
+                       if (do_note_netbsd_version(ms, swap, &nbuf[doff]) == -1)
+                               return -1;
+                       return 1;
+               }
+       }
+
+       if (namesz == 8 && strcmp(name, "FreeBSD") == 0) {
+               if (type == NT_FREEBSD_VERSION && descsz == 4) {
+                       *flags |= FLAGS_DID_OS_NOTE;
+                       if (do_note_freebsd_version(ms, swap, &nbuf[doff])
+                           == -1)
+                               return -1;
+                       return 1;
+               }
+       }
+
+       if (namesz == 8 && strcmp(name, "OpenBSD") == 0 &&
+           type == NT_OPENBSD_VERSION && descsz == 4) {
+               *flags |= FLAGS_DID_OS_NOTE;
+               if (file_printf(ms, ", for OpenBSD") == -1)
+                       return -1;
+               /* Content of note is always 0 */
+               return 1;
+       }
+
+       if (namesz == 10 && strcmp(name, "DragonFly") == 0 &&
+           type == NT_DRAGONFLY_VERSION && descsz == 4) {
+               uint32_t desc;
+               *flags |= FLAGS_DID_OS_NOTE;
+               if (file_printf(ms, ", for DragonFly") == -1)
+                       return -1;
+               memcpy(&desc, &nbuf[doff], sizeof(desc));
+               desc = elf_getu32(swap, desc);
+               if (file_printf(ms, " %d.%d.%d", desc / 100000,
+                   desc / 10000 % 10, desc % 10000) == -1)
+                       return -1;
+               return 1;
+       }
+       return 0;
+}
+
+private int
+do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags)
+{
+       const char *name = RCAST(const char *, &nbuf[noff]);
+
+       if (namesz == 4 && strcmp(name, "PaX") == 0 &&
+           type == NT_NETBSD_PAX && descsz == 4) {
+               static const char *pax[] = {
+                   "+mprotect",
+                   "-mprotect",
+                   "+segvguard",
+                   "-segvguard",
+                   "+ASLR",
+                   "-ASLR",
+               };
+               uint32_t desc;
+               size_t i;
+               int did = 0;
+
+               *flags |= FLAGS_DID_NETBSD_PAX;
+               memcpy(&desc, &nbuf[doff], sizeof(desc));
+               desc = elf_getu32(swap, desc);
+
+               if (desc && file_printf(ms, ", PaX: ") == -1)
+                       return -1;
+
+               for (i = 0; i < __arraycount(pax); i++) {
+                       if (((1 << CAST(int, i)) & desc) == 0)
+                               continue;
+                       if (file_printf(ms, "%s%s", did++ ? "," : "",
+                           pax[i]) == -1)
+                               return -1;
+               }
+               return 1;
+       }
+       return 0;
+}
+
+private int
+do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz, uint32_t descsz,
+    size_t noff, size_t doff, int *flags, size_t size, int clazz)
+{
+#ifdef ELFCORE
+       const char *name = RCAST(const char *, &nbuf[noff]);
+
+       int os_style = -1;
+       /*
+        * Sigh.  The 2.0.36 kernel in Debian 2.1, at
+        * least, doesn't correctly implement name
+        * sections, in core dumps, as specified by
+        * the "Program Linking" section of "UNIX(R) System
+        * V Release 4 Programmer's Guide: ANSI C and
+        * Programming Support Tools", because my copy
+        * clearly says "The first 'namesz' bytes in 'name'
+        * contain a *null-terminated* [emphasis mine]
+        * character representation of the entry's owner
+        * or originator", but the 2.0.36 kernel code
+        * doesn't include the terminating null in the
+        * name....
+        */
+       if ((namesz == 4 && strncmp(name, "CORE", 4) == 0) ||
+           (namesz == 5 && strcmp(name, "CORE") == 0)) {
+               os_style = OS_STYLE_SVR4;
+       }
+
+       if ((namesz == 8 && strcmp(name, "FreeBSD") == 0)) {
+               os_style = OS_STYLE_FREEBSD;
+       }
+
+       if ((namesz >= 11 && strncmp(name, "NetBSD-CORE", 11)
+           == 0)) {
+               os_style = OS_STYLE_NETBSD;
+       }
+
+       if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
+               if (file_printf(ms, ", %s-style", os_style_names[os_style])
+                   == -1)
+                       return -1;
+               *flags |= FLAGS_DID_CORE_STYLE;
+               *flags |= os_style;
+       }
+
+       switch (os_style) {
+       case OS_STYLE_NETBSD:
+               if (type == NT_NETBSD_CORE_PROCINFO) {
+                       char sbuf[512];
+                       struct NetBSD_elfcore_procinfo pi;
+                       memset(&pi, 0, sizeof(pi));
+                       memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi)));
+
+                       if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
+                           "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
+                           file_printable(sbuf, sizeof(sbuf),
+                           RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)),
+                           elf_getu32(swap, CAST(uint32_t, pi.cpi_pid)),
+                           elf_getu32(swap, pi.cpi_euid),
+                           elf_getu32(swap, pi.cpi_egid),
+                           elf_getu32(swap, pi.cpi_nlwps),
+                           elf_getu32(swap, CAST(uint32_t, pi.cpi_siglwp)),
+                           elf_getu32(swap, pi.cpi_signo),
+                           elf_getu32(swap, pi.cpi_sigcode)) == -1)
+                               return -1;
+
+                       *flags |= FLAGS_DID_CORE;
+                       return 1;
+               }
+               break;
+
+       case OS_STYLE_FREEBSD:
+               if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
+                       size_t argoff, pidoff;
+
+                       if (clazz == ELFCLASS32)
+                               argoff = 4 + 4 + 17;
+                       else
+                               argoff = 4 + 4 + 8 + 17;
+                       if (file_printf(ms, ", from '%.80s'", nbuf + doff +
+                           argoff) == -1)
+                               return -1;
+                       pidoff = argoff + 81 + 2;
+                       if (doff + pidoff + 4 <= size) {
+                               if (file_printf(ms, ", pid=%u",
+                                   elf_getu32(swap, *RCAST(uint32_t *, (nbuf +
+                                   doff + pidoff)))) == -1)
+                                       return -1;
+                       }
+                       *flags |= FLAGS_DID_CORE;
+               }                           
+               break;
+
+       default:
+               if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
+                       size_t i, j;
+                       unsigned char c;
+                       /*
+                        * Extract the program name.  We assume
+                        * it to be 16 characters (that's what it
+                        * is in SunOS 5.x and Linux).
+                        *
+                        * Unfortunately, it's at a different offset
+                        * in various OSes, so try multiple offsets.
+                        * If the characters aren't all printable,
+                        * reject it.
+                        */
+                       for (i = 0; i < NOFFSETS; i++) {
+                               unsigned char *cname, *cp;
+                               size_t reloffset = prpsoffsets(i);
+                               size_t noffset = doff + reloffset;
+                               size_t k;
+                               for (j = 0; j < 16; j++, noffset++,
+                                   reloffset++) {
+                                       /*
+                                        * Make sure we're not past
+                                        * the end of the buffer; if
+                                        * we are, just give up.
+                                        */
+                                       if (noffset >= size)
+                                               goto tryanother;
+
+                                       /*
+                                        * Make sure we're not past
+                                        * the end of the contents;
+                                        * if we are, this obviously
+                                        * isn't the right offset.
+                                        */
+                                       if (reloffset >= descsz)
+                                               goto tryanother;
+
+                                       c = nbuf[noffset];
+                                       if (c == '\0') {
+                                               /*
+                                                * A '\0' at the
+                                                * beginning is
+                                                * obviously wrong.
+                                                * Any other '\0'
+                                                * means we're done.
+                                                */
+                                               if (j == 0)
+                                                       goto tryanother;
+                                               else
+                                                       break;
+                                       } else {
+                                               /*
+                                                * A nonprintable
+                                                * character is also
+                                                * wrong.
+                                                */
+                                               if (!isprint(c) || isquote(c))
+                                                       goto tryanother;
+                                       }
+                               }
+                               /*
+                                * Well, that worked.
+                                */
+
+                               /*
+                                * Try next offsets, in case this match is
+                                * in the middle of a string.
+                                */
+                               for (k = i + 1 ; k < NOFFSETS; k++) {
+                                       size_t no;
+                                       int adjust = 1;
+                                       if (prpsoffsets(k) >= prpsoffsets(i))
+                                               continue;
+                                       for (no = doff + prpsoffsets(k);
+                                            no < doff + prpsoffsets(i); no++)
+                                               adjust = adjust
+                                                        && isprint(nbuf[no]);
+                                       if (adjust)
+                                               i = k;
+                               }
+
+                               cname = CAST(unsigned char *,
+                                   &nbuf[doff + prpsoffsets(i)]);
+                               for (cp = cname; cp < nbuf + size && *cp
+                                   && isprint(*cp); cp++)
+                                       continue;
+                               /*
+                                * Linux apparently appends a space at the end
+                                * of the command line: remove it.
+                                */
+                               while (cp > cname && isspace(cp[-1]))
+                                       cp--;
+                               if (file_printf(ms, ", from '%.*s'",
+                                   CAST(int, cp - cname), cname) == -1)
+                                       return -1;
+                               *flags |= FLAGS_DID_CORE;
+                               return 1;
+
+                       tryanother:
+                               ;
+                       }
+               }
+               break;
+       }
+#endif
+       return 0;
+}
+
+private off_t
+get_offset_from_virtaddr(struct magic_set *ms, int swap, int clazz, int fd,
+    off_t off, int num, off_t fsize, uint64_t virtaddr)
+{
+       Elf32_Phdr ph32;
+       Elf64_Phdr ph64;
+
+       /*
+        * Loop through all the program headers and find the header with
+        * virtual address in which the "virtaddr" belongs to.
+        */
+       for ( ; num; num--) {
+               if (pread(fd, xph_addr, xph_sizeof, off) <
+                   CAST(ssize_t, xph_sizeof)) {
+                       file_badread(ms);
+                       return -1;
+               }
+               off += xph_sizeof;
+
+               if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
+                       /* Perhaps warn here */
+                       continue;
+               }
+
+               if (virtaddr >= xph_vaddr && virtaddr < xph_vaddr + xph_filesz)
+                       return xph_offset + (virtaddr - xph_vaddr);
+       }
+       return 0;
+}
+
+private size_t
+get_string_on_virtaddr(struct magic_set *ms,
+    int swap, int clazz, int fd, off_t ph_off, int ph_num,
+    off_t fsize, uint64_t virtaddr, char *buf, ssize_t buflen)
+{
+       char *bptr;
+       off_t offset;
+
+       if (buflen == 0)
+               return 0;
+
+       offset = get_offset_from_virtaddr(ms, swap, clazz, fd, ph_off, ph_num,
+           fsize, virtaddr);
+       if (offset < 0 ||
+           (buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) {
+               file_badread(ms);
+               return 0;
+       }
+
+       buf[buflen - 1] = '\0';
+
+       /* We expect only printable characters, so return if buffer contains
+        * non-printable character before the '\0' or just '\0'. */
+       for (bptr = buf; *bptr && isprint(CAST(unsigned char, *bptr)); bptr++)
+               continue;
+       if (*bptr != '\0')
+               return 0;
+
+       return bptr - buf;
+}
+
+
+/*ARGSUSED*/
+private int
+do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
+    int swap, uint32_t namesz __attribute__((__unused__)),
+    uint32_t descsz __attribute__((__unused__)),
+    size_t noff __attribute__((__unused__)), size_t doff,
+    int *flags, size_t size __attribute__((__unused__)), int clazz,
+    int fd, off_t ph_off, int ph_num, off_t fsize)
+{
+#ifdef ELFCORE
+       Aux32Info auxv32;
+       Aux64Info auxv64;
+       size_t elsize = xauxv_sizeof;
+       const char *tag;
+       int is_string;
+       size_t nval;
+
+       if ((*flags & (FLAGS_IS_CORE|FLAGS_DID_CORE_STYLE)) !=
+           (FLAGS_IS_CORE|FLAGS_DID_CORE_STYLE))
+               return 0;
+
+       switch (*flags & FLAGS_CORE_STYLE) {
+       case OS_STYLE_SVR4:
+               if (type != NT_AUXV)
+                       return 0;
+               break;
+#ifdef notyet
+       case OS_STYLE_NETBSD:
+               if (type != NT_NETBSD_CORE_AUXV)
+                       return 0;
+               break;
+       case OS_STYLE_FREEBSD:
+               if (type != NT_FREEBSD_PROCSTAT_AUXV)
+                       return 0;
+               break;
+#endif
+       default:
+               return 0;
+       }
+
+       *flags |= FLAGS_DID_AUXV;
+
+       nval = 0;
+       for (size_t off = 0; off + elsize <= descsz; off += elsize) {
+               memcpy(xauxv_addr, &nbuf[doff + off], xauxv_sizeof);
+               /* Limit processing to 50 vector entries to prevent DoS */
+               if (nval++ >= 50) {
+                       file_error(ms, 0, "Too many ELF Auxv elements");
+                       return 1;
+               }
+
+               switch(xauxv_type) {
+               case AT_LINUX_EXECFN:
+                       is_string = 1;
+                       tag = "execfn";
+                       break;
+               case AT_LINUX_PLATFORM:
+                       is_string = 1;
+                       tag = "platform";
+                       break;
+               case AT_LINUX_UID:
+                       is_string = 0;
+                       tag = "real uid";
+                       break;
+               case AT_LINUX_GID:
+                       is_string = 0;
+                       tag = "real gid";
+                       break;
+               case AT_LINUX_EUID:
+                       is_string = 0;
+                       tag = "effective uid";
+                       break;
+               case AT_LINUX_EGID:
+                       is_string = 0;
+                       tag = "effective gid";
+                       break;
+               default:
+                       is_string = 0;
+                       tag = NULL;
+                       break;
+               }
+
+               if (tag == NULL)
+                       continue;
+
+               if (is_string) {
+                       char buf[256];
+                       ssize_t buflen;
+                       buflen = get_string_on_virtaddr(ms, swap, clazz, fd,
+                           ph_off, ph_num, fsize, xauxv_val, buf, sizeof(buf));
+
+                       if (buflen == 0)
+                               continue;
+
+                       if (file_printf(ms, ", %s: '%s'", tag, buf) == -1)
+                               return -1;
+               } else {
+                       if (file_printf(ms, ", %s: %d", tag,
+                           CAST(int, xauxv_val)) == -1)
+                               return -1;
+               }
+       }
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+private size_t
+dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
+    int clazz, int swap)
+{
+       Elf32_Dyn dh32;
+       Elf64_Dyn dh64;
+       unsigned char *dbuf = CAST(unsigned char *, vbuf);
+
+       if (xdh_sizeof + offset > size) {
+               /*
+                * We're out of note headers.
+                */
+               return xdh_sizeof + offset;
+       }
+
+       memcpy(xdh_addr, &dbuf[offset], xdh_sizeof);
+       offset += xdh_sizeof;
+
+       switch (xdh_tag) {
+       case DT_FLAGS_1:
+               if (xdh_val & DF_1_PIE)
+                       ms->mode |= 0111;
+               else
+                       ms->mode &= ~0111;
+               break;
+       default:
+               break;
+       }
+       return offset;
+}
+
+
+private size_t
+donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
+    int clazz, int swap, size_t align, int *flags, uint16_t *notecount,
+    int fd, off_t ph_off, int ph_num, off_t fsize)
+{
+       Elf32_Nhdr nh32;
+       Elf64_Nhdr nh64;
+       size_t noff, doff;
+       uint32_t namesz, descsz;
+       unsigned char *nbuf = CAST(unsigned char *, vbuf);
+
+       if (*notecount == 0)
+               return 0;
+       --*notecount;
+
+       if (xnh_sizeof + offset > size) {
+               /*
+                * We're out of note headers.
+                */
+               return xnh_sizeof + offset;
+       }
+
+       memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
+       offset += xnh_sizeof;
+
+       namesz = xnh_namesz;
+       descsz = xnh_descsz;
+
+       if ((namesz == 0) && (descsz == 0)) {
+               /*
+                * We're out of note headers.
+                */
+               return (offset >= size) ? offset : size;
+       }
+
+       if (namesz & 0x80000000) {
+               if (file_printf(ms, ", bad note name size %#lx",
+                   CAST(unsigned long, namesz)) == -1)
+                       return -1;
+           return 0;
+       }
+
+       if (descsz & 0x80000000) {
+               if (file_printf(ms, ", bad note description size %#lx",
+                   CAST(unsigned long, descsz)) == -1)
+                       return -1;
+           return 0;
+       }
+
+       noff = offset;
+       doff = ELF_ALIGN(offset + namesz);
+
+       if (offset + namesz > size) {
+               /*
+                * We're past the end of the buffer.
+                */
+               return doff;
+       }
+
+       offset = ELF_ALIGN(doff + descsz);
+       if (doff + descsz > size) {
+               /*
+                * We're past the end of the buffer.
+                */
+               return (offset >= size) ? offset : size;
+       }
+
+
+       if ((*flags & FLAGS_DID_OS_NOTE) == 0) {
+               if (do_os_note(ms, nbuf, xnh_type, swap,
+                   namesz, descsz, noff, doff, flags))
+                       return offset;
+       }
+
+       if ((*flags & FLAGS_DID_BUILD_ID) == 0) {
+               if (do_bid_note(ms, nbuf, xnh_type, swap,
+                   namesz, descsz, noff, doff, flags))
+                       return offset;
+       }
+
+       if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
+               if (do_pax_note(ms, nbuf, xnh_type, swap,
+                   namesz, descsz, noff, doff, flags))
+                       return offset;
+       }
+
+       if ((*flags & FLAGS_DID_CORE) == 0) {
+               if (do_core_note(ms, nbuf, xnh_type, swap,
+                   namesz, descsz, noff, doff, flags, size, clazz))
+                       return offset;
+       }
+
+       if ((*flags & FLAGS_DID_AUXV) == 0) {
+               if (do_auxv_note(ms, nbuf, xnh_type, swap,
+                       namesz, descsz, noff, doff, flags, size, clazz,
+                       fd, ph_off, ph_num, fsize))
+                       return offset;
+       }
+
+       if (namesz == 7 && strcmp(RCAST(char *, &nbuf[noff]), "NetBSD") == 0) {
+               int descw, flag;
+               const char *str, *tag;
+               if (descsz > 100)
+                       descsz = 100;
+               switch (xnh_type) {
+               case NT_NETBSD_VERSION:
+                       return offset;
+               case NT_NETBSD_MARCH:
+                       flag = FLAGS_DID_NETBSD_MARCH;
+                       tag = "compiled for";
+                       break;
+               case NT_NETBSD_CMODEL:
+                       flag = FLAGS_DID_NETBSD_CMODEL;
+                       tag = "compiler model";
+                       break;
+               case NT_NETBSD_EMULATION:
+                       flag = FLAGS_DID_NETBSD_EMULATION;
+                       tag = "emulation:";
+                       break;
+               default:
+                       if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
+                               return offset;
+                       *flags |= FLAGS_DID_NETBSD_UNKNOWN;
+                       if (file_printf(ms, ", note=%u", xnh_type) == -1)
+                               return offset;
+                       return offset;
+               }
+
+               if (*flags & flag)
+                       return offset;
+               str = RCAST(const char *, &nbuf[doff]);
+               descw = CAST(int, descsz);
+               *flags |= flag;
+               file_printf(ms, ", %s: %.*s", tag, descw, str);
+               return offset;
+       }
+
+       return offset;
+}
+
+/* SunOS 5.x hardware capability descriptions */
+typedef struct cap_desc {
+       uint64_t cd_mask;
+       const char *cd_name;
+} cap_desc_t;
+
+static const cap_desc_t cap_desc_sparc[] = {
+       { AV_SPARC_MUL32,               "MUL32" },
+       { AV_SPARC_DIV32,               "DIV32" },
+       { AV_SPARC_FSMULD,              "FSMULD" },
+       { AV_SPARC_V8PLUS,              "V8PLUS" },
+       { AV_SPARC_POPC,                "POPC" },
+       { AV_SPARC_VIS,                 "VIS" },
+       { AV_SPARC_VIS2,                "VIS2" },
+       { AV_SPARC_ASI_BLK_INIT,        "ASI_BLK_INIT" },
+       { AV_SPARC_FMAF,                "FMAF" },
+       { AV_SPARC_FJFMAU,              "FJFMAU" },
+       { AV_SPARC_IMA,                 "IMA" },
+       { 0, NULL }
+};
+
+static const cap_desc_t cap_desc_386[] = {
+       { AV_386_FPU,                   "FPU" },
+       { AV_386_TSC,                   "TSC" },
+       { AV_386_CX8,                   "CX8" },
+       { AV_386_SEP,                   "SEP" },
+       { AV_386_AMD_SYSC,              "AMD_SYSC" },
+       { AV_386_CMOV,                  "CMOV" },
+       { AV_386_MMX,                   "MMX" },
+       { AV_386_AMD_MMX,               "AMD_MMX" },
+       { AV_386_AMD_3DNow,             "AMD_3DNow" },
+       { AV_386_AMD_3DNowx,            "AMD_3DNowx" },
+       { AV_386_FXSR,                  "FXSR" },
+       { AV_386_SSE,                   "SSE" },
+       { AV_386_SSE2,                  "SSE2" },
+       { AV_386_PAUSE,                 "PAUSE" },
+       { AV_386_SSE3,                  "SSE3" },
+       { AV_386_MON,                   "MON" },
+       { AV_386_CX16,                  "CX16" },
+       { AV_386_AHF,                   "AHF" },
+       { AV_386_TSCP,                  "TSCP" },
+       { AV_386_AMD_SSE4A,             "AMD_SSE4A" },
+       { AV_386_POPCNT,                "POPCNT" },
+       { AV_386_AMD_LZCNT,             "AMD_LZCNT" },
+       { AV_386_SSSE3,                 "SSSE3" },
+       { AV_386_SSE4_1,                "SSE4.1" },
+       { AV_386_SSE4_2,                "SSE4.2" },
+       { 0, NULL }
+};
+
+private int
+doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
+    size_t size, off_t fsize, int mach, int strtab, int *flags,
+    uint16_t *notecount)
+{
+       Elf32_Shdr sh32;
+       Elf64_Shdr sh64;
+       int stripped = 1, has_debug_info = 0;
+       size_t nbadcap = 0;
+       void *nbuf;
+       off_t noff, coff, name_off;
+       uint64_t cap_hw1 = 0;   /* SunOS 5.x hardware capabilities */
+       uint64_t cap_sf1 = 0;   /* SunOS 5.x software capabilities */
+       char name[50];
+       ssize_t namesize;
+
+       if (num == 0) {
+               if (file_printf(ms, ", no section header") == -1)
+                       return -1;
+               return 0;
+       }
+       if (size != xsh_sizeof) {
+               if (file_printf(ms, ", corrupted section header size") == -1)
+                       return -1;
+               return 0;
+       }
+
+       /* Read offset of name section to be able to read section names later */
+       if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab)))
+           < CAST(ssize_t, xsh_sizeof)) {
+               if (file_printf(ms, ", missing section headers") == -1)
+                       return -1;
+               return 0;
+       }
+       name_off = xsh_offset;
+
+       for ( ; num; num--) {
+               /* Read the name of this section. */
+               if ((namesize = pread(fd, name, sizeof(name) - 1,
+                   name_off + xsh_name)) == -1) {
+                       file_badread(ms);
+                       return -1;
+               }
+               name[namesize] = '\0';
+               if (strcmp(name, ".debug_info") == 0) {
+                       has_debug_info = 1;
+                       stripped = 0;
+               }
+
+               if (pread(fd, xsh_addr, xsh_sizeof, off) <
+                   CAST(ssize_t, xsh_sizeof)) {
+                       file_badread(ms);
+                       return -1;
+               }
+               off += size;
+
+               /* Things we can determine before we seek */
+               switch (xsh_type) {
+               case SHT_SYMTAB:
+#if 0
+               case SHT_DYNSYM:
+#endif
+                       stripped = 0;
+                       break;
+               default:
+                       if (fsize != SIZE_UNKNOWN && xsh_offset > fsize) {
+                               /* Perhaps warn here */
+                               continue;
+                       }
+                       break;
+               }
+
+
+               /* Things we can determine when we seek */
+               switch (xsh_type) {
+               case SHT_NOTE:
+                       if (CAST(uintmax_t, (xsh_size + xsh_offset)) >
+                           CAST(uintmax_t, fsize)) {
+                               if (file_printf(ms,
+                                   ", note offset/size %#" INTMAX_T_FORMAT
+                                   "x+%#" INTMAX_T_FORMAT "x exceeds"
+                                   " file size %#" INTMAX_T_FORMAT "x",
+                                   CAST(uintmax_t, xsh_offset),
+                                   CAST(uintmax_t, xsh_size),
+                                   CAST(uintmax_t, fsize)) == -1)
+                                       return -1;
+                               return 0;
+                       }
+                       if ((nbuf = malloc(xsh_size)) == NULL) {
+                               file_error(ms, errno, "Cannot allocate memory"
+                                   " for note");
+                               return -1;
+                       }
+                       if (pread(fd, nbuf, xsh_size, xsh_offset) <
+                           CAST(ssize_t, xsh_size)) {
+                               file_badread(ms);
+                               free(nbuf);
+                               return -1;
+                       }
+
+                       noff = 0;
+                       for (;;) {
+                               if (noff >= CAST(off_t, xsh_size))
+                                       break;
+                               noff = donote(ms, nbuf, CAST(size_t, noff),
+                                   xsh_size, clazz, swap, 4, flags, notecount,
+                                   fd, 0, 0, 0);
+                               if (noff == 0)
+                                       break;
+                       }
+                       free(nbuf);
+                       break;
+               case SHT_SUNW_cap:
+                       switch (mach) {
+                       case EM_SPARC:
+                       case EM_SPARCV9:
+                       case EM_IA_64:
+                       case EM_386:
+                       case EM_AMD64:
+                               break;
+                       default:
+                               goto skip;
+                       }
+
+                       if (nbadcap > 5)
+                               break;
+                       if (lseek(fd, xsh_offset, SEEK_SET)
+                           == CAST(off_t, -1)) {
+                               file_badseek(ms);
+                               return -1;
+                       }
+                       coff = 0;
+                       for (;;) {
+                               Elf32_Cap cap32;
+                               Elf64_Cap cap64;
+                               char cbuf[/*CONSTCOND*/
+                                   MAX(sizeof(cap32), sizeof(cap64))];
+                               if ((coff += xcap_sizeof) >
+                                   CAST(off_t, xsh_size))
+                                       break;
+                               if (read(fd, cbuf, CAST(size_t, xcap_sizeof)) !=
+                                   CAST(ssize_t, xcap_sizeof)) {
+                                       file_badread(ms);
+                                       return -1;
+                               }
+                               if (cbuf[0] == 'A') {
+#ifdef notyet
+                                       char *p = cbuf + 1;
+                                       uint32_t len, tag;
+                                       memcpy(&len, p, sizeof(len));
+                                       p += 4;
+                                       len = getu32(swap, len);
+                                       if (memcmp("gnu", p, 3) != 0) {
+                                           if (file_printf(ms,
+                                               ", unknown capability %.3s", p)
+                                               == -1)
+                                               return -1;
+                                           break;
+                                       }
+                                       p += strlen(p) + 1;
+                                       tag = *p++;
+                                       memcpy(&len, p, sizeof(len));
+                                       p += 4;
+                                       len = getu32(swap, len);
+                                       if (tag != 1) {
+                                           if (file_printf(ms, ", unknown gnu"
+                                               " capability tag %d", tag)
+                                               == -1)
+                                               return -1;
+                                           break;
+                                       }
+                                       // gnu attributes
+#endif
+                                       break;
+                               }
+                               memcpy(xcap_addr, cbuf, xcap_sizeof);
+                               switch (xcap_tag) {
+                               case CA_SUNW_NULL:
+                                       break;
+                               case CA_SUNW_HW_1:
+                                       cap_hw1 |= xcap_val;
+                                       break;
+                               case CA_SUNW_SF_1:
+                                       cap_sf1 |= xcap_val;
+                                       break;
+                               default:
+                                       if (file_printf(ms,
+                                           ", with unknown capability "
+                                           "%#" INT64_T_FORMAT "x = %#"
+                                           INT64_T_FORMAT "x",
+                                           CAST(unsigned long long, xcap_tag),
+                                           CAST(unsigned long long, xcap_val))
+                                           == -1)
+                                               return -1;
+                                       if (nbadcap++ > 2)
+                                               coff = xsh_size;
+                                       break;
+                               }
+                       }
+                       /*FALLTHROUGH*/
+               skip:
+               default:
+                       break;
+               }
+       }
+
+       if (has_debug_info) {
+               if (file_printf(ms, ", with debug_info") == -1)
+                       return -1;
+       }
+       if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
+               return -1;
+       if (cap_hw1) {
+               const cap_desc_t *cdp;
+               switch (mach) {
+               case EM_SPARC:
+               case EM_SPARC32PLUS:
+               case EM_SPARCV9:
+                       cdp = cap_desc_sparc;
+                       break;
+               case EM_386:
+               case EM_IA_64:
+               case EM_AMD64:
+                       cdp = cap_desc_386;
+                       break;
+               default:
+                       cdp = NULL;
+                       break;
+               }
+               if (file_printf(ms, ", uses") == -1)
+                       return -1;
+               if (cdp) {
+                       while (cdp->cd_name) {
+                               if (cap_hw1 & cdp->cd_mask) {
+                                       if (file_printf(ms,
+                                           " %s", cdp->cd_name) == -1)
+                                               return -1;
+                                       cap_hw1 &= ~cdp->cd_mask;
+                               }
+                               ++cdp;
+                       }
+                       if (cap_hw1)
+                               if (file_printf(ms,
+                                   " unknown hardware capability %#"
+                                   INT64_T_FORMAT "x",
+                                   CAST(unsigned long long, cap_hw1)) == -1)
+                                       return -1;
+               } else {
+                       if (file_printf(ms,
+                           " hardware capability %#" INT64_T_FORMAT "x",
+                           CAST(unsigned long long, cap_hw1)) == -1)
+                               return -1;
+               }
+       }
+       if (cap_sf1) {
+               if (cap_sf1 & SF1_SUNW_FPUSED) {
+                       if (file_printf(ms,
+                           (cap_sf1 & SF1_SUNW_FPKNWN)
+                           ? ", uses frame pointer"
+                           : ", not known to use frame pointer") == -1)
+                               return -1;
+               }
+               cap_sf1 &= ~SF1_SUNW_MASK;
+               if (cap_sf1)
+                       if (file_printf(ms,
+                           ", with unknown software capability %#"
+                           INT64_T_FORMAT "x",
+                           CAST(unsigned long long, cap_sf1)) == -1)
+                               return -1;
+       }
+       return 0;
+}
+
+/*
+ * Look through the program headers of an executable image, searching
+ * for a PT_INTERP section; if one is found, it's dynamically linked,
+ * otherwise it's statically linked.
+ */
+private int
+dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
+    int num, size_t size, off_t fsize, int sh_num, int *flags,
+    uint16_t *notecount)
+{
+       Elf32_Phdr ph32;
+       Elf64_Phdr ph64;
+       const char *linking_style = "statically";
+       unsigned char nbuf[BUFSIZ];
+       char ibuf[BUFSIZ];
+       char interp[BUFSIZ];
+       ssize_t bufsize;
+       size_t offset, align, len;
+
+       if (num == 0) {
+               if (file_printf(ms, ", no program header") == -1)
+                       return -1;
+               return 0;
+       }
+       if (size != xph_sizeof) {
+               if (file_printf(ms, ", corrupted program header size") == -1)
+                       return -1;
+               return 0;
+       }
+
+       interp[0] = '\0';
+       for ( ; num; num--) {
+               int doread;
+               if (pread(fd, xph_addr, xph_sizeof, off) <
+                   CAST(ssize_t, xph_sizeof)) {
+                       file_badread(ms);
+                       return -1;
+               }
+
+               off += size;
+               bufsize = 0;
+               align = 4;
+
+               /* Things we can determine before we seek */
+               switch (xph_type) {
+               case PT_DYNAMIC:
+                       linking_style = "dynamically";
+                       doread = 1;
+                       break;
+               case PT_NOTE:
+                       if (sh_num)     /* Did this through section headers */
+                               continue;
+                       if (((align = xph_align) & 0x80000000UL) != 0 ||
+                           align < 4) {
+                               if (file_printf(ms,
+                                   ", invalid note alignment %#lx",
+                                   CAST(unsigned long, align)) == -1)
+                                       return -1;
+                               align = 4;
+                       }
+                       /*FALLTHROUGH*/
+               case PT_INTERP:
+                       doread = 1;
+                       break;
+               default:
+                       doread = 0;
+                       if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
+                               /* Maybe warn here? */
+                               continue;
+                       }
+                       break;
+               }
+
+               if (doread) {
+                       len = xph_filesz < sizeof(nbuf) ? xph_filesz
+                           : sizeof(nbuf);
+                       bufsize = pread(fd, nbuf, len, xph_offset);
+                       if (bufsize == -1) {
+                               file_badread(ms);
+                               return -1;
+                       }
+               } else
+                       len = 0;
+
+               /* Things we can determine when we seek */
+               switch (xph_type) {
+               case PT_DYNAMIC:
+                       offset = 0;
+                       // Let DF_1 determine if we are PIE or not.
+                       ms->mode &= ~0111;
+                       for (;;) {
+                               if (offset >= CAST(size_t, bufsize))
+                                       break;
+                               offset = dodynamic(ms, nbuf, offset,
+                                   CAST(size_t, bufsize), clazz, swap);
+                               if (offset == 0)
+                                       break;
+                       }
+                       break;
+
+               case PT_INTERP:
+                       if (bufsize && nbuf[0]) {
+                               nbuf[bufsize - 1] = '\0';
+                               memcpy(interp, nbuf, CAST(size_t, bufsize));
+                       } else
+                               strlcpy(interp, "*empty*", sizeof(interp));
+                       break;
+               case PT_NOTE:
+                       /*
+                        * This is a PT_NOTE section; loop through all the notes
+                        * in the section.
+                        */
+                       offset = 0;
+                       for (;;) {
+                               if (offset >= CAST(size_t, bufsize))
+                                       break;
+                               offset = donote(ms, nbuf, offset,
+                                   CAST(size_t, bufsize), clazz, swap, align,
+                                   flags, notecount, fd, 0, 0, 0);
+                               if (offset == 0)
+                                       break;
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       if (file_printf(ms, ", %s linked", linking_style)
+           == -1)
+               return -1;
+       if (interp[0])
+               if (file_printf(ms, ", interpreter %s",
+                   file_printable(ibuf, sizeof(ibuf), interp, sizeof(interp)))
+                       == -1)
+                       return -1;
+       return 0;
+}
+
+
+protected int
+file_tryelf(struct magic_set *ms, const struct buffer *b)
+{
+       int fd = b->fd;
+       const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
+       size_t nbytes = b->flen;
+       union {
+               int32_t l;
+               char c[sizeof(int32_t)];
+       } u;
+       int clazz;
+       int swap;
+       struct stat st;
+       const struct stat *stp;
+       off_t fsize;
+       int flags = 0;
+       Elf32_Ehdr elf32hdr;
+       Elf64_Ehdr elf64hdr;
+       uint16_t type, phnum, shnum, notecount;
+
+       if (ms->flags & (MAGIC_MIME|MAGIC_APPLE|MAGIC_EXTENSION))
+               return 0;
+       /*
+        * ELF executables have multiple section headers in arbitrary
+        * file locations and thus file(1) cannot determine it from easily.
+        * Instead we traverse thru all section headers until a symbol table
+        * one is found or else the binary is stripped.
+        * Return immediately if it's not ELF (so we avoid pipe2file unless
+        * needed).
+        */
+       if (buf[EI_MAG0] != ELFMAG0
+           || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
+           || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
+               return 0;
+
+       /*
+        * If we cannot seek, it must be a pipe, socket or fifo.
+        */
+       if((lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1))
+           && (errno == ESPIPE))
+               fd = file_pipe2file(ms, fd, buf, nbytes);
+
+       if (fd == -1) {
+               file_badread(ms);
+               return -1;
+       }
+
+       stp = &b->st;
+       /*
+        * b->st.st_size != 0 if previous fstat() succeeded,
+        * which is likely, we can avoid extra stat() call.
+        */
+       if (b->st.st_size == 0) {
+               stp = &st;
+               if (fstat(fd, &st) == -1) {
+                       file_badread(ms);
+                       return -1;
+               }
+       }
+       if (S_ISREG(stp->st_mode) || stp->st_size != 0)
+               fsize = stp->st_size;
+       else
+               fsize = SIZE_UNKNOWN;
+
+       clazz = buf[EI_CLASS];
+
+       switch (clazz) {
+       case ELFCLASS32:
+#undef elf_getu
+#define elf_getu(a, b) elf_getu32(a, b)
+#undef elfhdr
+#define elfhdr elf32hdr
+#include "elfclass.h"
+       case ELFCLASS64:
+#undef elf_getu
+#define elf_getu(a, b) elf_getu64(a, b)
+#undef elfhdr
+#define elfhdr elf64hdr
+#include "elfclass.h"
+       default:
+           if (file_printf(ms, ", unknown class %d", clazz) == -1)
+                   return -1;
+           break;
+       }
+       return 0;
+}
+#endif
diff --git a/src/readelf.h b/src/readelf.h
new file mode 100644 (file)
index 0000000..809d3f7
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * @(#)Id: readelf.h,v 1.9 2002/05/16 18:45:56 christos Exp
+ *
+ * Provide elf data structures for non-elf machines, allowing file
+ * non-elf hosts to determine if an elf binary is stripped.
+ * Note: cobbled from the linux header file, with modifications
+ */
+#ifndef __fake_elf_h__
+#define        __fake_elf_h__
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+typedef uint32_t       Elf32_Addr;
+typedef uint32_t       Elf32_Off;
+typedef uint16_t       Elf32_Half;
+typedef uint32_t       Elf32_Word;
+typedef uint8_t                Elf32_Char;
+
+typedef        uint64_t        Elf64_Addr;
+typedef        uint64_t        Elf64_Off;
+typedef uint64_t       Elf64_Xword;
+typedef uint16_t       Elf64_Half;
+typedef uint32_t       Elf64_Word;
+typedef uint8_t                Elf64_Char;
+
+#define        EI_NIDENT       16
+
+typedef struct {
+       Elf32_Word      a_type;         /* 32-bit id */
+       Elf32_Word      a_v;            /* 32-bit id */
+} Aux32Info;
+
+typedef struct {
+       Elf64_Xword     a_type;         /* 64-bit id */
+       Elf64_Xword     a_v;            /* 64-bit id */
+} Aux64Info;
+
+#define AT_NULL   0     /* end of vector */
+#define AT_IGNORE 1     /* entry should be ignored */
+#define AT_EXECFD 2     /* file descriptor of program */
+#define AT_PHDR   3     /* program headers for program */
+#define AT_PHENT  4     /* size of program header entry */
+#define AT_PHNUM  5     /* number of program headers */
+#define AT_PAGESZ 6     /* system page size */
+#define AT_BASE   7     /* base address of interpreter */
+#define AT_FLAGS  8     /* flags */
+#define AT_ENTRY  9     /* entry point of program */
+#define AT_LINUX_NOTELF 10    /* program is not ELF */
+#define AT_LINUX_UID    11    /* real uid */
+#define AT_LINUX_EUID   12    /* effective uid */
+#define AT_LINUX_GID    13    /* real gid */
+#define AT_LINUX_EGID   14    /* effective gid */
+#define AT_LINUX_PLATFORM 15  /* string identifying CPU for optimizations */
+#define AT_LINUX_HWCAP  16    /* arch dependent hints at CPU capabilities */
+#define AT_LINUX_CLKTCK 17    /* frequency at which times() increments */
+/* AT_* values 18 through 22 are reserved */
+#define AT_LINUX_SECURE 23   /* secure mode boolean */
+#define AT_LINUX_BASE_PLATFORM 24     /* string identifying real platform, may
+                                 * differ from AT_PLATFORM. */
+#define AT_LINUX_RANDOM 25    /* address of 16 random bytes */
+#define AT_LINUX_HWCAP2 26    /* extension of AT_HWCAP */
+#define AT_LINUX_EXECFN 31   /* filename of program */
+
+typedef struct {
+    Elf32_Char e_ident[EI_NIDENT];
+    Elf32_Half e_type;
+    Elf32_Half e_machine;
+    Elf32_Word e_version;
+    Elf32_Addr e_entry;  /* Entry point */
+    Elf32_Off  e_phoff;
+    Elf32_Off  e_shoff;
+    Elf32_Word e_flags;
+    Elf32_Half e_ehsize;
+    Elf32_Half e_phentsize;
+    Elf32_Half e_phnum;
+    Elf32_Half e_shentsize;
+    Elf32_Half e_shnum;
+    Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+    Elf64_Char e_ident[EI_NIDENT];
+    Elf64_Half e_type;
+    Elf64_Half e_machine;
+    Elf64_Word e_version;
+    Elf64_Addr e_entry;  /* Entry point */
+    Elf64_Off  e_phoff;
+    Elf64_Off  e_shoff;
+    Elf64_Word e_flags;
+    Elf64_Half e_ehsize;
+    Elf64_Half e_phentsize;
+    Elf64_Half e_phnum;
+    Elf64_Half e_shentsize;
+    Elf64_Half e_shnum;
+    Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* e_type */
+#define        ET_REL          1
+#define        ET_EXEC         2
+#define        ET_DYN          3
+#define        ET_CORE         4
+
+/* e_machine (used only for SunOS 5.x hardware capabilities) */
+#define        EM_SPARC        2
+#define        EM_386          3
+#define        EM_SPARC32PLUS  18
+#define        EM_SPARCV9      43
+#define        EM_IA_64        50
+#define        EM_AMD64        62
+
+/* sh_type */
+#define        SHT_SYMTAB      2
+#define        SHT_NOTE        7
+#define        SHT_DYNSYM      11
+#define        SHT_SUNW_cap    0x6ffffff5      /* SunOS 5.x hw/sw capabilities */
+
+/* elf type */
+#define        ELFDATANONE     0               /* e_ident[EI_DATA] */
+#define        ELFDATA2LSB     1
+#define        ELFDATA2MSB     2
+
+/* elf class */
+#define        ELFCLASSNONE    0
+#define        ELFCLASS32      1
+#define        ELFCLASS64      2
+
+/* magic number */
+#define        EI_MAG0         0               /* e_ident[] indexes */
+#define        EI_MAG1         1
+#define        EI_MAG2         2
+#define        EI_MAG3         3
+#define        EI_CLASS        4
+#define        EI_DATA         5
+#define        EI_VERSION      6
+#define        EI_PAD          7
+
+#define        ELFMAG0         0x7f            /* EI_MAG */
+#define        ELFMAG1         'E'
+#define        ELFMAG2         'L'
+#define        ELFMAG3         'F'
+#define        ELFMAG          "\177ELF"
+
+#define        OLFMAG1         'O'
+#define        OLFMAG          "\177OLF"
+
+typedef struct {
+    Elf32_Word p_type;
+    Elf32_Off  p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf32_Word p_filesz;
+    Elf32_Word p_memsz;
+    Elf32_Word p_flags;
+    Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct {
+    Elf64_Word p_type;
+    Elf64_Word p_flags;
+    Elf64_Off  p_offset;
+    Elf64_Addr p_vaddr;
+    Elf64_Addr p_paddr;
+    Elf64_Xword        p_filesz;
+    Elf64_Xword        p_memsz;
+    Elf64_Xword        p_align;
+} Elf64_Phdr;
+
+#define        PT_NULL         0               /* p_type */
+#define        PT_LOAD         1
+#define        PT_DYNAMIC      2
+#define        PT_INTERP       3
+#define        PT_NOTE         4
+#define        PT_SHLIB        5
+#define        PT_PHDR         6
+#define        PT_NUM          7
+
+typedef struct {
+    Elf32_Word sh_name;
+    Elf32_Word sh_type;
+    Elf32_Word sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off  sh_offset;
+    Elf32_Word sh_size;
+    Elf32_Word sh_link;
+    Elf32_Word sh_info;
+    Elf32_Word sh_addralign;
+    Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+    Elf64_Word sh_name;
+    Elf64_Word sh_type;
+    Elf64_Off  sh_flags;
+    Elf64_Addr sh_addr;
+    Elf64_Off  sh_offset;
+    Elf64_Off  sh_size;
+    Elf64_Word sh_link;
+    Elf64_Word sh_info;
+    Elf64_Off  sh_addralign;
+    Elf64_Off  sh_entsize;
+} Elf64_Shdr;
+
+#define        NT_NETBSD_CORE_PROCINFO         1
+#define        NT_NETBSD_CORE_AUXV             2
+
+struct NetBSD_elfcore_procinfo {
+       /* Version 1 fields start here. */
+       uint32_t        cpi_version;            /* our version */
+       uint32_t        cpi_cpisize;            /* sizeof(this struct) */
+       uint32_t        cpi_signo;              /* killing signal */
+       uint32_t        cpi_sigcode;            /* signal code */
+       uint32_t        cpi_sigpend[4];         /* pending signals */
+       uint32_t        cpi_sigmask[4];         /* blocked signals */
+       uint32_t        cpi_sigignore[4];       /* ignored signals */
+       uint32_t        cpi_sigcatch[4];        /* caught signals */
+       int32_t         cpi_pid;                /* process ID */
+       int32_t         cpi_ppid;               /* parent process ID */
+       int32_t         cpi_pgrp;               /* process group ID */
+       int32_t         cpi_sid;                /* session ID */
+       uint32_t        cpi_ruid;               /* real user ID */
+       uint32_t        cpi_euid;               /* effective user ID */
+       uint32_t        cpi_svuid;              /* saved user ID */
+       uint32_t        cpi_rgid;               /* real group ID */
+       uint32_t        cpi_egid;               /* effective group ID */
+       uint32_t        cpi_svgid;              /* saved group ID */
+       uint32_t        cpi_nlwps;              /* number of LWPs */
+       int8_t          cpi_name[32];           /* copy of p->p_comm */
+       /* Add version 2 fields below here. */
+       int32_t         cpi_siglwp;     /* LWP target of killing signal */
+};
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+    Elf32_Word n_namesz;       /* Name size */
+    Elf32_Word n_descsz;       /* Content size */
+    Elf32_Word n_type;         /* Content type */
+} Elf32_Nhdr;
+
+typedef struct {
+    Elf64_Word n_namesz;
+    Elf64_Word n_descsz;
+    Elf64_Word n_type;
+} Elf64_Nhdr;
+
+/* Notes used in ET_CORE */
+#define        NT_PRSTATUS     1
+#define        NT_PRFPREG      2
+#define        NT_PRPSINFO     3
+#define        NT_PRXREG       4
+#define        NT_TASKSTRUCT   4
+#define        NT_PLATFORM     5
+#define        NT_AUXV         6
+
+/* Note types used in executables */
+/* NetBSD executables (name = "NetBSD") */
+#define        NT_NETBSD_VERSION       1
+#define        NT_NETBSD_EMULATION     2
+#define        NT_FREEBSD_VERSION      1
+#define        NT_OPENBSD_VERSION      1
+#define        NT_DRAGONFLY_VERSION    1
+/*
+ * GNU executables (name = "GNU")
+ * word[0]: GNU OS tags
+ * word[1]: major version
+ * word[2]: minor version
+ * word[3]: tiny version
+ */
+#define        NT_GNU_VERSION          1
+
+/* GNU OS tags */
+#define        GNU_OS_LINUX    0
+#define        GNU_OS_HURD     1
+#define        GNU_OS_SOLARIS  2
+#define        GNU_OS_KFREEBSD 3
+#define        GNU_OS_KNETBSD  4
+
+/*
+ * GNU Hardware capability information
+ * word[0]: Number of entries
+ * word[1]: Bitmask of enabled entries
+ * Followed by a byte id, and a NUL terminated string per entry
+ */
+#define        NT_GNU_HWCAP            2
+
+/*
+ * GNU Build ID generated by ld
+ * 160 bit SHA1 [default]
+ * 128 bit md5 or uuid
+ */
+#define        NT_GNU_BUILD_ID         3
+
+/*
+ * NetBSD-specific note type: PaX.
+ * There should be 1 NOTE per executable.
+ * name: PaX\0
+ * namesz: 4
+ * desc:
+ *     word[0]: capability bitmask
+ * descsz: 4
+ */
+#define NT_NETBSD_PAX          3
+#define NT_NETBSD_PAX_MPROTECT         0x01    /* Force enable Mprotect */
+#define NT_NETBSD_PAX_NOMPROTECT       0x02    /* Force disable Mprotect */
+#define NT_NETBSD_PAX_GUARD            0x04    /* Force enable Segvguard */
+#define NT_NETBSD_PAX_NOGUARD          0x08    /* Force disable Servguard */
+#define NT_NETBSD_PAX_ASLR             0x10    /* Force enable ASLR */
+#define NT_NETBSD_PAX_NOASLR           0x20    /* Force disable ASLR */
+
+/*
+ * NetBSD-specific note type: MACHINE_ARCH.
+ * There should be 1 NOTE per executable.
+ * name:       NetBSD\0
+ * namesz:     7
+ * desc:       string
+ * descsz:     variable
+ */
+#define NT_NETBSD_MARCH                5
+
+/*
+ * NetBSD-specific note type: COMPILER MODEL.
+ * There should be 1 NOTE per executable.
+ * name:       NetBSD\0
+ * namesz:     7
+ * desc:       string
+ * descsz:     variable
+ */
+#define NT_NETBSD_CMODEL       6
+
+/*
+ * Golang-specific note type
+ * name: Go\0\0
+ * namesz: 4
+ * desc: base-64 build id.
+ * descsz: < 128
+ */
+#define NT_GO_BUILD_ID 4
+
+/*
+ * FreeBSD specific notes
+ */
+#define NT_FREEBSD_PROCSTAT_AUXV       16
+
+#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
+#define ELFSIZE ARCH_ELFSIZE
+#endif
+/* SunOS 5.x hardware/software capabilities */
+typedef struct {
+       Elf32_Word      c_tag;
+       union {
+               Elf32_Word      c_val;
+               Elf32_Addr      c_ptr;
+       } c_un;
+} Elf32_Cap;
+
+typedef struct {
+       Elf64_Xword     c_tag;
+       union {
+               Elf64_Xword     c_val;
+               Elf64_Addr      c_ptr;
+       } c_un;
+} Elf64_Cap;
+
+/* SunOS 5.x hardware/software capability tags */
+#define        CA_SUNW_NULL    0
+#define        CA_SUNW_HW_1    1
+#define        CA_SUNW_SF_1    2
+
+/* SunOS 5.x software capabilities */
+#define        SF1_SUNW_FPKNWN 0x01
+#define        SF1_SUNW_FPUSED 0x02
+#define        SF1_SUNW_MASK   0x03
+
+/* SunOS 5.x hardware capabilities: sparc */
+#define        AV_SPARC_MUL32          0x0001
+#define        AV_SPARC_DIV32          0x0002
+#define        AV_SPARC_FSMULD         0x0004
+#define        AV_SPARC_V8PLUS         0x0008
+#define        AV_SPARC_POPC           0x0010
+#define        AV_SPARC_VIS            0x0020
+#define        AV_SPARC_VIS2           0x0040
+#define        AV_SPARC_ASI_BLK_INIT   0x0080
+#define        AV_SPARC_FMAF           0x0100
+#define        AV_SPARC_FJFMAU         0x4000
+#define        AV_SPARC_IMA            0x8000
+
+/* SunOS 5.x hardware capabilities: 386 */
+#define        AV_386_FPU              0x00000001
+#define        AV_386_TSC              0x00000002
+#define        AV_386_CX8              0x00000004
+#define        AV_386_SEP              0x00000008
+#define        AV_386_AMD_SYSC         0x00000010
+#define        AV_386_CMOV             0x00000020
+#define        AV_386_MMX              0x00000040
+#define        AV_386_AMD_MMX          0x00000080
+#define        AV_386_AMD_3DNow        0x00000100
+#define        AV_386_AMD_3DNowx       0x00000200
+#define        AV_386_FXSR             0x00000400
+#define        AV_386_SSE              0x00000800
+#define        AV_386_SSE2             0x00001000
+#define        AV_386_PAUSE            0x00002000
+#define        AV_386_SSE3             0x00004000
+#define        AV_386_MON              0x00008000
+#define        AV_386_CX16             0x00010000
+#define        AV_386_AHF              0x00020000
+#define        AV_386_TSCP             0x00040000
+#define        AV_386_AMD_SSE4A        0x00080000
+#define        AV_386_POPCNT           0x00100000
+#define        AV_386_AMD_LZCNT        0x00200000
+#define        AV_386_SSSE3            0x00400000
+#define        AV_386_SSE4_1           0x00800000
+#define        AV_386_SSE4_2           0x01000000
+
+/*
+ * Dynamic Section structure array
+ */
+typedef struct {
+       Elf32_Word              d_tag;  /* entry tag value */
+       union {
+               Elf32_Addr      d_ptr;
+               Elf32_Word      d_val;
+       } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+       Elf64_Xword             d_tag;  /* entry tag value */
+       union {
+               Elf64_Addr      d_ptr;
+               Elf64_Xword     d_val;
+       } d_un;
+} Elf64_Dyn;
+
+/* d_tag */
+#define DT_NULL                0       /* Marks end of dynamic array */
+#define DT_NEEDED      1       /* Name of needed library (DT_STRTAB offset) */
+#define DT_PLTRELSZ    2       /* Size, in bytes, of relocations in PLT */
+#define DT_PLTGOT      3       /* Address of PLT and/or GOT */
+#define DT_HASH                4       /* Address of symbol hash table */
+#define DT_STRTAB      5       /* Address of string table */
+#define DT_SYMTAB      6       /* Address of symbol table */
+#define DT_RELA                7       /* Address of Rela relocation table */
+#define DT_RELASZ      8       /* Size, in bytes, of DT_RELA table */
+#define DT_RELAENT     9       /* Size, in bytes, of one DT_RELA entry */
+#define DT_STRSZ       10      /* Size, in bytes, of DT_STRTAB table */
+#define DT_SYMENT      11      /* Size, in bytes, of one DT_SYMTAB entry */
+#define DT_INIT                12      /* Address of initialization function */
+#define DT_FINI                13      /* Address of termination function */
+#define DT_SONAME      14      /* Shared object name (DT_STRTAB offset) */
+#define DT_RPATH       15      /* Library search path (DT_STRTAB offset) */
+#define DT_SYMBOLIC    16      /* Start symbol search within local object */
+#define DT_REL         17      /* Address of Rel relocation table */
+#define DT_RELSZ       18      /* Size, in bytes, of DT_REL table */
+#define DT_RELENT      19      /* Size, in bytes, of one DT_REL entry */
+#define DT_PLTREL      20      /* Type of PLT relocation entries */
+#define DT_DEBUG       21      /* Used for debugging; unspecified */
+#define DT_TEXTREL     22      /* Relocations might modify non-writable seg */
+#define DT_JMPREL      23      /* Address of relocations associated with PLT */
+#define DT_BIND_NOW    24      /* Process all relocations at load-time */
+#define DT_INIT_ARRAY  25      /* Address of initialization function array */
+#define DT_FINI_ARRAY  26      /* Size, in bytes, of DT_INIT_ARRAY array */
+#define DT_INIT_ARRAYSZ 27     /* Address of termination function array */
+#define DT_FINI_ARRAYSZ 28     /* Size, in bytes, of DT_FINI_ARRAY array*/
+#define DT_RUNPATH     29      /* overrides DT_RPATH */
+#define DT_FLAGS       30      /* Encodes ORIGIN, SYMBOLIC, TEXTREL, BIND_NOW, STATIC_TLS */
+#define DT_ENCODING    31      /* ??? */
+#define DT_PREINIT_ARRAY 32    /* Address of pre-init function array */
+#define DT_PREINIT_ARRAYSZ 33  /* Size, in bytes, of DT_PREINIT_ARRAY array */
+#define DT_NUM         34
+
+#define DT_LOOS                0x60000000      /* Operating system specific range */
+#define DT_VERSYM      0x6ffffff0      /* Symbol versions */
+#define DT_FLAGS_1     0x6ffffffb      /* ELF dynamic flags */
+#define DT_VERDEF      0x6ffffffc      /* Versions defined by file */
+#define DT_VERDEFNUM   0x6ffffffd      /* Number of versions defined by file */
+#define DT_VERNEED     0x6ffffffe      /* Versions needed by file */
+#define DT_VERNEEDNUM  0x6fffffff      /* Number of versions needed by file */
+#define DT_HIOS                0x6fffffff
+#define DT_LOPROC      0x70000000      /* Processor-specific range */
+#define DT_HIPROC      0x7fffffff
+
+/* Flag values for DT_FLAGS */
+#define DF_ORIGIN      0x00000001      /* uses $ORIGIN */
+#define DF_SYMBOLIC    0x00000002      /* */
+#define DF_TEXTREL     0x00000004      /* */
+#define DF_BIND_NOW    0x00000008      /* */
+#define DF_STATIC_TLS  0x00000010      /* */
+
+/* Flag values for DT_FLAGS_1 */
+#define        DF_1_NOW        0x00000001      /* Same as DF_BIND_NOW */
+#define        DF_1_GLOBAL     0x00000002      /* Unused */
+#define        DF_1_GROUP      0x00000004      /* Is member of group */
+#define        DF_1_NODELETE   0x00000008      /* Cannot be deleted from process */
+#define        DF_1_LOADFLTR   0x00000010      /* Immediate loading of filters */
+#define        DF_1_INITFIRST  0x00000020      /* init/fini takes priority */
+#define        DF_1_NOOPEN     0x00000040      /* Do not allow loading on dlopen() */
+#define        DF_1_ORIGIN     0x00000080      /* Require $ORIGIN processing */
+#define        DF_1_DIRECT     0x00000100      /* Enable direct bindings */
+#define        DF_1_INTERPOSE  0x00000400      /* Is an interposer */
+#define        DF_1_NODEFLIB   0x00000800      /* Ignore default library search path */
+#define        DF_1_NODUMP     0x00001000      /* Cannot be dumped with dldump(3C) */
+#define        DF_1_CONFALT    0x00002000      /* Configuration alternative */
+#define        DF_1_ENDFILTEE  0x00004000      /* Filtee ends filter's search */
+#define        DF_1_DISPRELDNE 0x00008000      /* Did displacement relocation */
+#define        DF_1_DISPRELPND 0x00010000      /* Pending displacement relocation */
+#define        DF_1_NODIRECT   0x00020000      /* Has non-direct bindings */
+#define        DF_1_IGNMULDEF  0x00040000      /* Used internally */
+#define        DF_1_NOKSYMS    0x00080000      /* Used internally */
+#define        DF_1_NOHDR      0x00100000      /* Used internally */
+#define        DF_1_EDITED     0x00200000      /* Has been modified since build */
+#define        DF_1_NORELOC    0x00400000      /* Used internally */
+#define        DF_1_SYMINTPOSE 0x00800000      /* Has individual symbol interposers */
+#define        DF_1_GLOBAUDIT  0x01000000      /* Require global auditing */
+#define        DF_1_SINGLETON  0x02000000      /* Has singleton symbols */
+#define        DF_1_STUB       0x04000000      /* Stub */
+#define        DF_1_PIE        0x08000000      /* Position Independent Executable */
+
+#endif
diff --git a/src/seccomp.c b/src/seccomp.c
new file mode 100644 (file)
index 0000000..1b9d9b8
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * libseccomp hooks.
+ */
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: seccomp.c,v 1.8 2019/02/24 18:12:04 christos Exp $")
+#endif /* lint */
+
+#if HAVE_LIBSECCOMP
+#include <seccomp.h> /* libseccomp */
+#include <sys/prctl.h> /* prctl */
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define DENY_RULE(call) \
+    do \
+       if (seccomp_rule_add (ctx, SCMP_ACT_KILL, SCMP_SYS(call), 0) == -1) \
+           goto out; \
+    while (/*CONSTCOND*/0)
+#define ALLOW_RULE(call) \
+    do \
+       if (seccomp_rule_add (ctx, SCMP_ACT_ALLOW, SCMP_SYS(call), 0) == -1) \
+           goto out; \
+    while (/*CONSTCOND*/0)
+
+static scmp_filter_ctx ctx;
+
+
+int
+enable_sandbox_basic(void)
+{
+
+       if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
+               return -1;
+
+       if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
+               return -1;
+
+       // initialize the filter
+       ctx = seccomp_init(SCMP_ACT_ALLOW);
+       if (ctx == NULL)
+           return 1;
+
+       DENY_RULE(_sysctl);
+       DENY_RULE(acct);
+       DENY_RULE(add_key);
+       DENY_RULE(adjtimex);
+       DENY_RULE(chroot);
+       DENY_RULE(clock_adjtime);
+       DENY_RULE(create_module);
+       DENY_RULE(delete_module);
+       DENY_RULE(fanotify_init);
+       DENY_RULE(finit_module);
+       DENY_RULE(get_kernel_syms);
+       DENY_RULE(get_mempolicy);
+       DENY_RULE(init_module);
+       DENY_RULE(io_cancel);
+       DENY_RULE(io_destroy);
+       DENY_RULE(io_getevents);
+       DENY_RULE(io_setup);
+       DENY_RULE(io_submit);
+       DENY_RULE(ioperm);
+       DENY_RULE(iopl);
+       DENY_RULE(ioprio_set);
+       DENY_RULE(kcmp);
+#ifdef __NR_kexec_file_load
+       DENY_RULE(kexec_file_load);
+#endif
+       DENY_RULE(kexec_load);
+       DENY_RULE(keyctl);
+       DENY_RULE(lookup_dcookie);
+       DENY_RULE(mbind);
+       DENY_RULE(nfsservctl);
+       DENY_RULE(migrate_pages);
+       DENY_RULE(modify_ldt);
+       DENY_RULE(mount);
+       DENY_RULE(move_pages);
+       DENY_RULE(name_to_handle_at);
+       DENY_RULE(open_by_handle_at);
+       DENY_RULE(perf_event_open);
+       DENY_RULE(pivot_root);
+       DENY_RULE(process_vm_readv);
+       DENY_RULE(process_vm_writev);
+       DENY_RULE(ptrace);
+       DENY_RULE(reboot);
+       DENY_RULE(remap_file_pages);
+       DENY_RULE(request_key);
+       DENY_RULE(set_mempolicy);
+       DENY_RULE(swapoff);
+       DENY_RULE(swapon);
+       DENY_RULE(sysfs);
+       DENY_RULE(syslog);
+       DENY_RULE(tuxcall);
+       DENY_RULE(umount2);
+       DENY_RULE(uselib);
+       DENY_RULE(vmsplice);
+
+       // blocking dangerous syscalls that file should not need
+       DENY_RULE (execve);
+       DENY_RULE (socket);
+       // ...
+
+
+       // applying filter...
+       if (seccomp_load (ctx) == -1)
+               goto out;
+       // free ctx after the filter has been loaded into the kernel
+       seccomp_release(ctx);
+       return 0;
+
+out:
+       seccomp_release(ctx);
+       return -1;
+}
+
+
+int
+enable_sandbox_full(void)
+{
+
+       // prevent child processes from getting more priv e.g. via setuid,
+       // capabilities, ...
+       if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1)
+               return -1;
+
+       if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
+               return -1;
+
+       // initialize the filter
+       ctx = seccomp_init(SCMP_ACT_KILL);
+       if (ctx == NULL)
+               return -1;
+
+       ALLOW_RULE(access);
+       ALLOW_RULE(brk);
+       ALLOW_RULE(close);
+       ALLOW_RULE(dup2);
+       ALLOW_RULE(exit);
+       ALLOW_RULE(exit_group);
+       ALLOW_RULE(fcntl);
+       ALLOW_RULE(fcntl64);
+       ALLOW_RULE(fstat);
+       ALLOW_RULE(fstat64);
+       ALLOW_RULE(getdents);
+#ifdef __NR_getdents64
+       ALLOW_RULE(getdents64);
+#endif
+       ALLOW_RULE(ioctl);
+       ALLOW_RULE(lseek);
+       ALLOW_RULE(_llseek);
+       ALLOW_RULE(lstat);
+       ALLOW_RULE(lstat64);
+       ALLOW_RULE(madvise);
+       ALLOW_RULE(mmap);
+       ALLOW_RULE(mmap2);
+       ALLOW_RULE(mprotect);
+       ALLOW_RULE(mremap);
+       ALLOW_RULE(munmap);
+#ifdef __NR_newfstatat
+       ALLOW_RULE(newfstatat);
+#endif
+       ALLOW_RULE(open);
+       ALLOW_RULE(openat);
+       ALLOW_RULE(pread64);
+       ALLOW_RULE(read);
+       ALLOW_RULE(readlink);
+       ALLOW_RULE(rt_sigaction);
+       ALLOW_RULE(rt_sigprocmask);
+       ALLOW_RULE(rt_sigreturn);
+       ALLOW_RULE(select);
+       ALLOW_RULE(stat);
+       ALLOW_RULE(stat64);
+       ALLOW_RULE(sysinfo);
+       ALLOW_RULE(unlink);
+       ALLOW_RULE(write);
+
+
+#if 0
+       // needed by valgrind
+       ALLOW_RULE(gettid);
+       ALLOW_RULE(getpid);
+       ALLOW_RULE(rt_sigtimedwait);
+#endif
+
+#if 0
+        /* special restrictions for socket, only allow AF_UNIX/AF_LOCAL */
+        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
+            SCMP_CMP(0, SCMP_CMP_EQ, AF_UNIX)) == -1)
+               goto out;
+
+        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
+            SCMP_CMP(0, SCMP_CMP_EQ, AF_LOCAL)) == -1)
+               goto out;
+
+
+        /* special restrictions for open, prevent opening files for writing */
+        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
+            SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) == -1)
+               goto out;
+
+        if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), 1,
+            SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) == -1)
+               goto out;
+
+        if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(open), 1,
+            SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) == -1)
+               goto out;
+
+
+        /* allow stderr */
+        if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1,
+            SCMP_CMP(0, SCMP_CMP_EQ, 2)) == -1)
+                goto out;
+#endif
+
+       // applying filter...
+       if (seccomp_load(ctx) == -1)
+               goto out;
+       // free ctx after the filter has been loaded into the kernel
+       seccomp_release(ctx);
+       return 0;
+
+out:
+       // something went wrong
+       seccomp_release(ctx);
+       return -1;
+}
+#endif
diff --git a/src/softmagic.c b/src/softmagic.c
new file mode 100644 (file)
index 0000000..2edae41
--- /dev/null
@@ -0,0 +1,2326 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * softmagic - interpret variable magic from MAGIC
+ */
+
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: softmagic.c,v 1.286 2019/05/17 02:24:59 christos Exp $")
+#endif /* lint */
+
+#include "magic.h"
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <time.h>
+#include "der.h"
+
+private int match(struct magic_set *, struct magic *, uint32_t,
+    const struct buffer *, size_t, int, int, int, uint16_t *,
+    uint16_t *, int *, int *, int *, int *);
+private int mget(struct magic_set *, struct magic *, const struct buffer *,
+    const unsigned char *, size_t,
+    size_t, unsigned int, int, int, int, uint16_t *,
+    uint16_t *, int *, int *, int *, int *);
+private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
+    const struct buffer *, size_t, unsigned int);
+private int magiccheck(struct magic_set *, struct magic *);
+private int32_t mprint(struct magic_set *, struct magic *);
+private int moffset(struct magic_set *, struct magic *, const struct buffer *,
+    int32_t *);
+private void mdebug(uint32_t, const char *, size_t);
+private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
+    const unsigned char *, uint32_t, size_t, struct magic *);
+private int mconvert(struct magic_set *, struct magic *, int);
+private int print_sep(struct magic_set *, int);
+private int handle_annotation(struct magic_set *, struct magic *, int);
+private int cvt_8(union VALUETYPE *, const struct magic *);
+private int cvt_16(union VALUETYPE *, const struct magic *);
+private int cvt_32(union VALUETYPE *, const struct magic *);
+private int cvt_64(union VALUETYPE *, const struct magic *);
+
+#define OFFSET_OOB(n, o, i)    ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o)))
+#define BE64(p) ( \
+    (CAST(uint64_t, (p)->hq[0])<<56)| \
+    (CAST(uint64_t, (p)->hq[1])<<48)| \
+    (CAST(uint64_t, (p)->hq[2])<<40)| \
+    (CAST(uint64_t, (p)->hq[3])<<32)| \
+    (CAST(uint64_t, (p)->hq[4])<<24)| \
+    (CAST(uint64_t, (p)->hq[5])<<16)| \
+    (CAST(uint64_t, (p)->hq[6])<<8)| \
+    (CAST(uint64_t, (p)->hq[7])))
+#define LE64(p) ( \
+    (CAST(uint64_t, (p)->hq[7])<<56)| \
+    (CAST(uint64_t, (p)->hq[6])<<48)| \
+    (CAST(uint64_t, (p)->hq[5])<<40)| \
+    (CAST(uint64_t, (p)->hq[4])<<32)| \
+    (CAST(uint64_t, (p)->hq[3])<<24)| \
+    (CAST(uint64_t, (p)->hq[2])<<16)| \
+    (CAST(uint64_t, (p)->hq[1])<<8)| \
+    (CAST(uint64_t, (p)->hq[0])))
+#define LE32(p) ( \
+    (CAST(uint32_t, (p)->hl[3])<<24)| \
+    (CAST(uint32_t, (p)->hl[2])<<16)| \
+    (CAST(uint32_t, (p)->hl[1])<<8)| \
+    (CAST(uint32_t, (p)->hl[0])))
+#define BE32(p) ( \
+    (CAST(uint32_t, (p)->hl[0])<<24)| \
+    (CAST(uint32_t, (p)->hl[1])<<16)| \
+    (CAST(uint32_t, (p)->hl[2])<<8)| \
+    (CAST(uint32_t, (p)->hl[3])))
+#define ME32(p) ( \
+    (CAST(uint32_t, (p)->hl[1])<<24)| \
+    (CAST(uint32_t, (p)->hl[0])<<16)| \
+    (CAST(uint32_t, (p)->hl[3])<<8)| \
+    (CAST(uint32_t, (p)->hl[2])))
+
+#define BE16(p) ((CAST(uint16_t, (p)->hs[0])<<8)|(CAST(uint16_t, (p)->hs[1])))
+#define LE16(p) ((CAST(uint16_t, (p)->hs[1])<<8)|(CAST(uint16_t, (p)->hs[0])))
+#define SEXT(s,v,p) ((s) ? \
+       CAST(intmax_t, CAST(int##v##_t, p)) : \
+       CAST(intmax_t, CAST(uint##v##_t, p)))
+
+/*
+ * softmagic - lookup one file in parsed, in-memory copy of database
+ * Passed the name and FILE * of one file to be typed.
+ */
+/*ARGSUSED1*/          /* nbytes passed for regularity, maybe need later */
+protected int
+file_softmagic(struct magic_set *ms, const struct buffer *b,
+    uint16_t *indir_count, uint16_t *name_count, int mode, int text)
+{
+       struct mlist *ml;
+       int rv, printed_something = 0, need_separator = 0;
+       uint16_t nc, ic;
+
+       if (name_count == NULL) {
+               nc = 0;
+               name_count = &nc;
+       }
+       if (indir_count == NULL) {
+               ic = 0;
+               indir_count = &ic;
+       }
+
+       for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
+               if ((rv = match(ms, ml->magic, ml->nmagic, b, 0, mode,
+                   text, 0, indir_count, name_count,
+                   &printed_something, &need_separator, NULL, NULL)) != 0)
+                       return rv;
+
+       return 0;
+}
+
+#define FILE_FMTDEBUG
+#ifdef FILE_FMTDEBUG
+#define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
+
+private const char * __attribute__((__format_arg__(3)))
+file_fmtcheck(struct magic_set *ms, const char *desc, const char *def,
+       const char *file, size_t line)
+{
+       const char *ptr;
+
+       if (strchr(desc, '%') == NULL)
+               return desc;
+
+       ptr = fmtcheck(desc, def);
+       if (ptr == def)
+               file_magerror(ms,
+                   "%s, %" SIZE_T_FORMAT "u: format `%s' does not match"
+                   " with `%s'", file, line, desc, def);
+       return ptr;
+}
+#else
+#define F(a, b, c) fmtcheck((b), (c))
+#endif
+
+/*
+ * Go through the whole list, stopping if you find a match.  Process all
+ * the continuations of that match before returning.
+ *
+ * We support multi-level continuations:
+ *
+ *     At any time when processing a successful top-level match, there is a
+ *     current continuation level; it represents the level of the last
+ *     successfully matched continuation.
+ *
+ *     Continuations above that level are skipped as, if we see one, it
+ *     means that the continuation that controls them - i.e, the
+ *     lower-level continuation preceding them - failed to match.
+ *
+ *     Continuations below that level are processed as, if we see one,
+ *     it means we've finished processing or skipping higher-level
+ *     continuations under the control of a successful or unsuccessful
+ *     lower-level continuation, and are now seeing the next lower-level
+ *     continuation and should process it.  The current continuation
+ *     level reverts to the level of the one we're seeing.
+ *
+ *     Continuations at the current level are processed as, if we see
+ *     one, there's no lower-level continuation that may have failed.
+ *
+ *     If a continuation matches, we bump the current continuation level
+ *     so that higher-level continuations are processed.
+ */
+private int
+match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
+    const struct buffer *b, size_t offset, int mode, int text,
+    int flip, uint16_t *indir_count, uint16_t *name_count,
+    int *printed_something, int *need_separator, int *returnval,
+    int *found_match)
+{
+       uint32_t magindex = 0;
+       unsigned int cont_level = 0;
+       int found_matchv = 0; /* if a match is found it is set to 1*/
+       int returnvalv = 0, e;
+       int firstline = 1; /* a flag to print X\n  X\n- X */
+       struct buffer bb;
+       int print = (ms->flags & MAGIC_NODESC) == 0;
+
+       /*
+        * returnval can be 0 if a match is found, but there was no
+        * annotation to be printed.
+        */
+       if (returnval == NULL)
+               returnval = &returnvalv;
+       if (found_match == NULL)
+               found_match = &found_matchv;
+
+       if (file_check_mem(ms, cont_level) == -1)
+               return -1;
+
+       for (magindex = 0; magindex < nmagic; magindex++) {
+               int flush = 0;
+               struct magic *m = &magic[magindex];
+
+               if (m->type != FILE_NAME)
+               if ((IS_STRING(m->type) &&
+#define FLT (STRING_BINTEST | STRING_TEXTTEST)
+                    ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
+                     (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
+                   (m->flag & mode) != mode) {
+flush:
+                       /* Skip sub-tests */
+                       while (magindex < nmagic - 1 &&
+                           magic[magindex + 1].cont_level != 0)
+                               magindex++;
+                       cont_level = 0;
+                       continue; /* Skip to next top-level test*/
+               }
+
+               if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
+                       goto flush;
+               ms->line = m->lineno;
+
+               /* if main entry matches, print it... */
+               switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
+                   bb.flen, offset, cont_level,
+                   mode, text, flip, indir_count, name_count,
+                   printed_something, need_separator, returnval, found_match))
+               {
+               case -1:
+                       return -1;
+               case 0:
+                       flush = m->reln != '!';
+                       break;
+               default:
+                       if (m->type == FILE_INDIRECT) {
+                               *found_match = 1;
+                               *returnval = 1;
+                       }
+
+                       switch (magiccheck(ms, m)) {
+                       case -1:
+                               return -1;
+                       case 0:
+                               flush++;
+                               break;
+                       default:
+                               flush = 0;
+                               break;
+                       }
+                       break;
+               }
+               if (flush) {
+                       /*
+                        * main entry didn't match,
+                        * flush its continuations
+                        */
+                       goto flush;
+               }
+
+               if (*m->desc)
+                       *found_match = 1;
+
+               if ((e = handle_annotation(ms, m, firstline)) != 0)
+               {
+                       *need_separator = 1;
+                       *printed_something = 1;
+                       *returnval = 1;
+                       return e;
+               }
+
+               /*
+                * If we are going to print something, we'll need to print
+                * a blank before we print something else.
+                */
+               if (print && *m->desc) {
+                       *need_separator = 1;
+                       *printed_something = 1;
+                       *returnval = 1;
+                       if (print_sep(ms, firstline) == -1)
+                               return -1;
+                       if (mprint(ms, m) == -1)
+                               return -1;
+               }
+
+               switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
+               case -1:
+               case 0:
+                       goto flush;
+               default:
+                       break;
+               }
+
+               /* and any continuations that match */
+               if (file_check_mem(ms, ++cont_level) == -1)
+                       return -1;
+
+               while (magindex + 1 < nmagic &&
+                   magic[magindex + 1].cont_level != 0) {
+                       m = &magic[++magindex];
+                       ms->line = m->lineno; /* for messages */
+
+                       if (cont_level < m->cont_level)
+                               continue;
+                       if (cont_level > m->cont_level) {
+                               /*
+                                * We're at the end of the level
+                                * "cont_level" continuations.
+                                */
+                               cont_level = m->cont_level;
+                       }
+                       if (msetoffset(ms, m, &bb, b, offset, cont_level) == -1)
+                               goto flush;
+                       if (m->flag & OFFADD) {
+                               ms->offset +=
+                                   ms->c.li[cont_level - 1].off;
+                       }
+
+#ifdef ENABLE_CONDITIONALS
+                       if (m->cond == COND_ELSE ||
+                           m->cond == COND_ELIF) {
+                               if (ms->c.li[cont_level].last_match == 1)
+                                       continue;
+                       }
+#endif
+                       switch (mget(ms, m, b, CAST(const unsigned char *,
+                           bb.fbuf), bb.flen, offset,
+                           cont_level, mode, text, flip, indir_count,
+                           name_count, printed_something, need_separator,
+                           returnval, found_match)) {
+                       case -1:
+                               return -1;
+                       case 0:
+                               if (m->reln != '!')
+                                       continue;
+                               flush = 1;
+                               break;
+                       default:
+                               if (m->type == FILE_INDIRECT) {
+                                       *found_match = 1;
+                                       *returnval = 1;
+                               }
+                               flush = 0;
+                               break;
+                       }
+
+                       switch (flush ? 1 : magiccheck(ms, m)) {
+                       case -1:
+                               return -1;
+                       case 0:
+#ifdef ENABLE_CONDITIONALS
+                               ms->c.li[cont_level].last_match = 0;
+#endif
+                               break;
+                       default:
+#ifdef ENABLE_CONDITIONALS
+                               ms->c.li[cont_level].last_match = 1;
+#endif
+                               if (m->type == FILE_CLEAR)
+                                       ms->c.li[cont_level].got_match = 0;
+                               else if (ms->c.li[cont_level].got_match) {
+                                       if (m->type == FILE_DEFAULT)
+                                               break;
+                               } else
+                                       ms->c.li[cont_level].got_match = 1;
+
+                               if (*m->desc)
+                                       *found_match = 1;
+
+                               if ((e = handle_annotation(ms, m, firstline))
+                                   != 0) {
+                                       *need_separator = 1;
+                                       *printed_something = 1;
+                                       *returnval = 1;
+                                       return e;
+                               }
+                               if (print && *m->desc) {
+                                       /*
+                                        * This continuation matched.  Print
+                                        * its message, with a blank before it
+                                        * if the previous item printed and
+                                        * this item isn't empty.
+                                        */
+                                       /*
+                                        * If we are going to print something,
+                                        * make sure that we have a separator
+                                        * first.
+                                        */
+                                       if (!*printed_something) {
+                                               *printed_something = 1;
+                                               if (print_sep(ms, firstline)
+                                                   == -1)
+                                                       return -1;
+                                       }
+                                       /* space if previous printed */
+                                       if (*need_separator
+                                           && (m->flag & NOSPACE) == 0) {
+                                               if (file_printf(ms, " ") == -1)
+                                                       return -1;
+                                       }
+                                       *returnval = 1;
+                                       *need_separator = 0;
+                                       if (mprint(ms, m) == -1)
+                                               return -1;
+                                       *need_separator = 1;
+                               }
+
+                               switch (moffset(ms, m, &bb,
+                                   &ms->c.li[cont_level].off)) {
+                               case -1:
+                               case 0:
+                                       flush = 1;
+                                       cont_level--;
+                                       break;
+                               default:
+                                       break;
+                               }
+
+                               /*
+                                * If we see any continuations
+                                * at a higher level,
+                                * process them.
+                                */
+                               if (file_check_mem(ms, ++cont_level) == -1)
+                                       return -1;
+                               break;
+                       }
+               }
+               if (*printed_something) {
+                       firstline = 0;
+               }
+               if (*found_match) {
+                   if ((ms->flags & MAGIC_CONTINUE) == 0)
+                       return *returnval; /* don't keep searching */
+                   // So that we print a separator
+                   *printed_something = 0;
+                   firstline = 0;
+               }
+               cont_level = 0;
+       }
+       return *returnval;  /* This is hit if -k is set or there is no match */
+}
+
+private int
+check_fmt(struct magic_set *ms, const char *fmt)
+{
+       file_regex_t rx;
+       int rc, rv = -1;
+
+       if (strchr(fmt, '%') == NULL)
+               return 0;
+
+       rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
+       if (rc) {
+               file_regerror(&rx, rc, ms);
+       } else {
+               rc = file_regexec(&rx, fmt, 0, 0, 0);
+               rv = !rc;
+       }
+       file_regfree(&rx);
+       return rv;
+}
+
+#if !defined(HAVE_STRNDUP) || defined(__aiws__)
+# ifdef __aiws__
+#  define strndup aix_strndup  /* aix is broken */
+# endif
+char *strndup(const char *, size_t);
+
+char *
+strndup(const char *str, size_t n)
+{
+       size_t len;
+       char *copy;
+
+       for (len = 0; len < n && str[len]; len++)
+               continue;
+       if ((copy = malloc(len + 1)) == NULL)
+               return NULL;
+       (void)memcpy(copy, str, len);
+       copy[len] = '\0';
+       return copy;
+}
+#endif /* HAVE_STRNDUP */
+
+static int
+varexpand(struct magic_set *ms, char *buf, size_t len, const char *str)
+{
+       const char *ptr, *sptr, *e, *t, *ee, *et;
+       size_t l;
+
+       for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) {
+               l = CAST(size_t, ptr - sptr);
+               if (l >= len)
+                       return -1;
+               memcpy(buf, sptr, l);
+               buf += l;
+               len -= l;
+               ptr += 2;
+               if (!*ptr || ptr[1] != '?')
+                       return -1;
+               for (et = t = ptr + 2; *et && *et != ':'; et++)
+                       continue;
+               if (*et != ':')
+                       return -1;
+               for (ee = e = et + 1; *ee && *ee != '}'; ee++)
+                       continue;
+               if (*ee != '}')
+                       return -1;
+               switch (*ptr) {
+               case 'x':
+                       if (ms->mode & 0111) {
+                               ptr = t;
+                               l = et - t;
+                       } else {
+                               ptr = e;
+                               l = ee - e;
+                       }
+                       break;
+               default:
+                       return -1;
+               }
+               if (l >= len)
+                       return -1;
+               memcpy(buf, ptr, l);
+               buf += l;
+               len -= l;
+               sptr = ee + 1;
+       }
+
+       l = strlen(sptr);
+       if (l >= len)
+               return -1;
+
+       memcpy(buf, sptr, l);
+       buf[l] = '\0';
+       return 0;
+}
+
+
+private int32_t
+mprint(struct magic_set *ms, struct magic *m)
+{
+       uint64_t v;
+       float vf;
+       double vd;
+       int64_t t = 0;
+       char buf[128], tbuf[26], sbuf[512], ebuf[512];
+       const char *desc;
+       union VALUETYPE *p = &ms->ms_value;
+
+       if (varexpand(ms, ebuf, sizeof(ebuf), m->desc) == -1)
+               desc = m->desc;
+       else
+               desc = ebuf;
+
+       switch (m->type) {
+       case FILE_BYTE:
+               v = file_signextend(ms, m, CAST(uint64_t, p->b));
+               switch (check_fmt(ms, desc)) {
+               case -1:
+                       return -1;
+               case 1:
+                       (void)snprintf(buf, sizeof(buf), "%d",
+                           CAST(unsigned char, v));
+                       if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, F(ms, desc, "%d"),
+                           CAST(unsigned char, v)) == -1)
+                               return -1;
+                       break;
+               }
+               t = ms->offset + sizeof(char);
+               break;
+
+       case FILE_SHORT:
+       case FILE_BESHORT:
+       case FILE_LESHORT:
+               v = file_signextend(ms, m, CAST(uint64_t, p->h));
+               switch (check_fmt(ms, desc)) {
+               case -1:
+                       return -1;
+               case 1:
+                       (void)snprintf(buf, sizeof(buf), "%u",
+                           CAST(unsigned short, v));
+                       if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, F(ms, desc, "%u"),
+                           CAST(unsigned short, v)) == -1)
+                               return -1;
+                       break;
+               }
+               t = ms->offset + sizeof(short);
+               break;
+
+       case FILE_LONG:
+       case FILE_BELONG:
+       case FILE_LELONG:
+       case FILE_MELONG:
+               v = file_signextend(ms, m, CAST(uint64_t, p->l));
+               switch (check_fmt(ms, desc)) {
+               case -1:
+                       return -1;
+               case 1:
+                       (void)snprintf(buf, sizeof(buf), "%u",
+                           CAST(uint32_t, v));
+                       if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, F(ms, desc, "%u"),
+                           CAST(uint32_t, v)) == -1)
+                               return -1;
+                       break;
+               }
+               t = ms->offset + sizeof(int32_t);
+               break;
+
+       case FILE_QUAD:
+       case FILE_BEQUAD:
+       case FILE_LEQUAD:
+               v = file_signextend(ms, m, p->q);
+               switch (check_fmt(ms, desc)) {
+               case -1:
+                       return -1;
+               case 1:
+                       (void)snprintf(buf, sizeof(buf), "%" INT64_T_FORMAT "u",
+                           CAST(unsigned long long, v));
+                       if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, F(ms, desc, "%" INT64_T_FORMAT "u"),
+                           CAST(unsigned long long, v)) == -1)
+                               return -1;
+                       break;
+               }
+               t = ms->offset + sizeof(int64_t);
+               break;
+
+       case FILE_STRING:
+       case FILE_PSTRING:
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               if (m->reln == '=' || m->reln == '!') {
+                       if (file_printf(ms, F(ms, desc, "%s"),
+                           file_printable(sbuf, sizeof(sbuf), m->value.s,
+                           sizeof(m->value.s))) == -1)
+                               return -1;
+                       t = ms->offset + m->vallen;
+               }
+               else {
+                       char *str = p->s;
+
+                       /* compute t before we mangle the string? */
+                       t = ms->offset + strlen(str);
+
+                       if (*m->value.s == '\0')
+                               str[strcspn(str, "\r\n")] = '\0';
+
+                       if (m->str_flags & STRING_TRIM) {
+                               char *last;
+                               while (isspace(CAST(unsigned char, *str)))
+                                       str++;
+                               last = str;
+                               while (*last)
+                                       last++;
+                               --last;
+                               while (isspace(CAST(unsigned char, *last)))
+                                       last--;
+                               *++last = '\0';
+                       }
+
+                       if (file_printf(ms, F(ms, desc, "%s"),
+                           file_printable(sbuf, sizeof(sbuf), str,
+                               sizeof(p->s) - (str - p->s))) == -1)
+                               return -1;
+
+                       if (m->type == FILE_PSTRING)
+                               t += file_pstring_length_size(m);
+               }
+               break;
+
+       case FILE_DATE:
+       case FILE_BEDATE:
+       case FILE_LEDATE:
+       case FILE_MEDATE:
+               if (file_printf(ms, F(ms, desc, "%s"),
+                   file_fmttime(p->l, 0, tbuf)) == -1)
+                       return -1;
+               t = ms->offset + sizeof(uint32_t);
+               break;
+
+       case FILE_LDATE:
+       case FILE_BELDATE:
+       case FILE_LELDATE:
+       case FILE_MELDATE:
+               if (file_printf(ms, F(ms, desc, "%s"),
+                   file_fmttime(p->l, FILE_T_LOCAL, tbuf)) == -1)
+                       return -1;
+               t = ms->offset + sizeof(uint32_t);
+               break;
+
+       case FILE_QDATE:
+       case FILE_BEQDATE:
+       case FILE_LEQDATE:
+               if (file_printf(ms, F(ms, desc, "%s"),
+                   file_fmttime(p->q, 0, tbuf)) == -1)
+                       return -1;
+               t = ms->offset + sizeof(uint64_t);
+               break;
+
+       case FILE_QLDATE:
+       case FILE_BEQLDATE:
+       case FILE_LEQLDATE:
+               if (file_printf(ms, F(ms, desc, "%s"),
+                   file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1)
+                       return -1;
+               t = ms->offset + sizeof(uint64_t);
+               break;
+
+       case FILE_QWDATE:
+       case FILE_BEQWDATE:
+       case FILE_LEQWDATE:
+               if (file_printf(ms, F(ms, desc, "%s"),
+                   file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1)
+                       return -1;
+               t = ms->offset + sizeof(uint64_t);
+               break;
+
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               vf = p->f;
+               switch (check_fmt(ms, desc)) {
+               case -1:
+                       return -1;
+               case 1:
+                       (void)snprintf(buf, sizeof(buf), "%g", vf);
+                       if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, F(ms, desc, "%g"), vf) == -1)
+                               return -1;
+                       break;
+               }
+               t = ms->offset + sizeof(float);
+               break;
+
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               vd = p->d;
+               switch (check_fmt(ms, desc)) {
+               case -1:
+                       return -1;
+               case 1:
+                       (void)snprintf(buf, sizeof(buf), "%g", vd);
+                       if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
+                               return -1;
+                       break;
+               default:
+                       if (file_printf(ms, F(ms, desc, "%g"), vd) == -1)
+                               return -1;
+                       break;
+               }
+               t = ms->offset + sizeof(double);
+               break;
+
+       case FILE_SEARCH:
+       case FILE_REGEX: {
+               char *cp;
+               int rval;
+
+               cp = strndup(RCAST(const char *, ms->search.s),
+                   ms->search.rm_len);
+               if (cp == NULL) {
+                       file_oomem(ms, ms->search.rm_len);
+                       return -1;
+               }
+               rval = file_printf(ms, F(ms, desc, "%s"),
+                   file_printable(sbuf, sizeof(sbuf), cp, ms->search.rm_len));
+               free(cp);
+
+               if (rval == -1)
+                       return -1;
+
+               if ((m->str_flags & REGEX_OFFSET_START))
+                       t = ms->search.offset;
+               else
+                       t = ms->search.offset + ms->search.rm_len;
+               break;
+       }
+
+       case FILE_DEFAULT:
+       case FILE_CLEAR:
+               if (file_printf(ms, "%s", m->desc) == -1)
+                       return -1;
+               t = ms->offset;
+               break;
+
+       case FILE_INDIRECT:
+       case FILE_USE:
+       case FILE_NAME:
+               t = ms->offset;
+               break;
+       case FILE_DER:
+               if (file_printf(ms, F(ms, desc, "%s"),
+                   file_printable(sbuf, sizeof(sbuf), ms->ms_value.s,
+                       sizeof(ms->ms_value.s))) == -1)
+                       return -1;
+               t = ms->offset;
+               break;
+       default:
+               file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
+               return -1;
+       }
+       return CAST(int32_t, t);
+}
+
+private int
+moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
+    int32_t *op)
+{
+       size_t nbytes = b->flen;
+       int32_t o;
+
+       switch (m->type) {
+       case FILE_BYTE:
+               o = CAST(int32_t, (ms->offset + sizeof(char)));
+               break;
+
+       case FILE_SHORT:
+       case FILE_BESHORT:
+       case FILE_LESHORT:
+               o = CAST(int32_t, (ms->offset + sizeof(short)));
+               break;
+
+       case FILE_LONG:
+       case FILE_BELONG:
+       case FILE_LELONG:
+       case FILE_MELONG:
+               o = CAST(int32_t, (ms->offset + sizeof(int32_t)));
+               break;
+
+       case FILE_QUAD:
+       case FILE_BEQUAD:
+       case FILE_LEQUAD:
+               o = CAST(int32_t, (ms->offset + sizeof(int64_t)));
+               break;
+
+       case FILE_STRING:
+       case FILE_PSTRING:
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               if (m->reln == '=' || m->reln == '!') {
+                       o = ms->offset + m->vallen;
+               } else {
+                       union VALUETYPE *p = &ms->ms_value;
+
+                       if (*m->value.s == '\0')
+                               p->s[strcspn(p->s, "\r\n")] = '\0';
+                       o = CAST(uint32_t, (ms->offset + strlen(p->s)));
+                       if (m->type == FILE_PSTRING)
+                               o += CAST(uint32_t,
+                                   file_pstring_length_size(m));
+               }
+               break;
+
+       case FILE_DATE:
+       case FILE_BEDATE:
+       case FILE_LEDATE:
+       case FILE_MEDATE:
+               o = CAST(int32_t, (ms->offset + sizeof(uint32_t)));
+               break;
+
+       case FILE_LDATE:
+       case FILE_BELDATE:
+       case FILE_LELDATE:
+       case FILE_MELDATE:
+               o = CAST(int32_t, (ms->offset + sizeof(uint32_t)));
+               break;
+
+       case FILE_QDATE:
+       case FILE_BEQDATE:
+       case FILE_LEQDATE:
+               o = CAST(int32_t, (ms->offset + sizeof(uint64_t)));
+               break;
+
+       case FILE_QLDATE:
+       case FILE_BEQLDATE:
+       case FILE_LEQLDATE:
+               o = CAST(int32_t, (ms->offset + sizeof(uint64_t)));
+               break;
+
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               o = CAST(int32_t, (ms->offset + sizeof(float)));
+               break;
+
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               o = CAST(int32_t, (ms->offset + sizeof(double)));
+               break;
+
+       case FILE_REGEX:
+               if ((m->str_flags & REGEX_OFFSET_START) != 0)
+                       o = CAST(int32_t, ms->search.offset);
+               else
+                       o = CAST(int32_t,
+                           (ms->search.offset + ms->search.rm_len));
+               break;
+
+       case FILE_SEARCH:
+               if ((m->str_flags & REGEX_OFFSET_START) != 0)
+                       o = CAST(int32_t, ms->search.offset);
+               else
+                       o = CAST(int32_t, (ms->search.offset + m->vallen));
+               break;
+
+       case FILE_CLEAR:
+       case FILE_DEFAULT:
+       case FILE_INDIRECT:
+               o = ms->offset;
+               break;
+
+       case FILE_DER:
+               {
+                       o = der_offs(ms, m, nbytes);
+                       if (o == -1 || CAST(size_t, o) > nbytes) {
+                               if ((ms->flags & MAGIC_DEBUG) != 0) {
+                                       (void)fprintf(stderr,
+                                           "Bad DER offset %d nbytes=%"
+                                           SIZE_T_FORMAT "u", o, nbytes);
+                               }
+                               *op = 0;
+                               return 0;
+                       }
+                       break;
+               }
+
+       default:
+               o = 0;
+               break;
+       }
+
+       if (CAST(size_t, o) > nbytes) {
+#if 0
+               file_error(ms, 0, "Offset out of range %" SIZE_T_FORMAT
+                   "u > %" SIZE_T_FORMAT "u", (size_t)o, nbytes);
+#endif
+               return -1;
+       }
+       *op = o;
+       return 1;
+}
+
+private uint32_t
+cvt_id3(struct magic_set *ms, uint32_t v)
+{
+       v = ((((v >>  0) & 0x7f) <<  0) |
+            (((v >>  8) & 0x7f) <<  7) |
+            (((v >> 16) & 0x7f) << 14) |
+            (((v >> 24) & 0x7f) << 21));
+       if ((ms->flags & MAGIC_DEBUG) != 0)
+               fprintf(stderr, "id3 offs=%u\n", v);
+       return v;
+}
+
+private int
+cvt_flip(int type, int flip)
+{
+       if (flip == 0)
+               return type;
+       switch (type) {
+       case FILE_BESHORT:
+               return FILE_LESHORT;
+       case FILE_BELONG:
+               return FILE_LELONG;
+       case FILE_BEDATE:
+               return FILE_LEDATE;
+       case FILE_BELDATE:
+               return FILE_LELDATE;
+       case FILE_BEQUAD:
+               return FILE_LEQUAD;
+       case FILE_BEQDATE:
+               return FILE_LEQDATE;
+       case FILE_BEQLDATE:
+               return FILE_LEQLDATE;
+       case FILE_BEQWDATE:
+               return FILE_LEQWDATE;
+       case FILE_LESHORT:
+               return FILE_BESHORT;
+       case FILE_LELONG:
+               return FILE_BELONG;
+       case FILE_LEDATE:
+               return FILE_BEDATE;
+       case FILE_LELDATE:
+               return FILE_BELDATE;
+       case FILE_LEQUAD:
+               return FILE_BEQUAD;
+       case FILE_LEQDATE:
+               return FILE_BEQDATE;
+       case FILE_LEQLDATE:
+               return FILE_BEQLDATE;
+       case FILE_LEQWDATE:
+               return FILE_BEQWDATE;
+       case FILE_BEFLOAT:
+               return FILE_LEFLOAT;
+       case FILE_LEFLOAT:
+               return FILE_BEFLOAT;
+       case FILE_BEDOUBLE:
+               return FILE_LEDOUBLE;
+       case FILE_LEDOUBLE:
+               return FILE_BEDOUBLE;
+       default:
+               return type;
+       }
+}
+#define DO_CVT(fld, type) \
+       if (m->num_mask) \
+               switch (m->mask_op & FILE_OPS_MASK) { \
+               case FILE_OPAND: \
+                       p->fld &= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPOR: \
+                       p->fld |= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPXOR: \
+                       p->fld ^= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPADD: \
+                       p->fld += CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPMINUS: \
+                       p->fld -= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPMULTIPLY: \
+                       p->fld *= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPDIVIDE: \
+                       if (CAST(type, m->num_mask) == 0) \
+                               return -1; \
+                       p->fld /= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPMODULO: \
+                       if (CAST(type, m->num_mask) == 0) \
+                               return -1; \
+                       p->fld %= CAST(type, m->num_mask); \
+                       break; \
+               } \
+       if (m->mask_op & FILE_OPINVERSE) \
+               p->fld = ~p->fld \
+
+private int
+cvt_8(union VALUETYPE *p, const struct magic *m)
+{
+       DO_CVT(b, uint8_t);
+       return 0;
+}
+
+private int
+cvt_16(union VALUETYPE *p, const struct magic *m)
+{
+       DO_CVT(h, uint16_t);
+       return 0;
+}
+
+private int
+cvt_32(union VALUETYPE *p, const struct magic *m)
+{
+       DO_CVT(l, uint32_t);
+       return 0;
+}
+
+private int
+cvt_64(union VALUETYPE *p, const struct magic *m)
+{
+       DO_CVT(q, uint64_t);
+       return 0;
+}
+
+#define DO_CVT2(fld, type) \
+       if (m->num_mask) \
+               switch (m->mask_op & FILE_OPS_MASK) { \
+               case FILE_OPADD: \
+                       p->fld += CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPMINUS: \
+                       p->fld -= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPMULTIPLY: \
+                       p->fld *= CAST(type, m->num_mask); \
+                       break; \
+               case FILE_OPDIVIDE: \
+                       if (CAST(type, m->num_mask) == 0) \
+                               return -1; \
+                       p->fld /= CAST(type, m->num_mask); \
+                       break; \
+               } \
+
+private int
+cvt_float(union VALUETYPE *p, const struct magic *m)
+{
+       DO_CVT2(f, float);
+       return 0;
+}
+
+private int
+cvt_double(union VALUETYPE *p, const struct magic *m)
+{
+       DO_CVT2(d, double);
+       return 0;
+}
+
+/*
+ * Convert the byte order of the data we are looking at
+ * While we're here, let's apply the mask operation
+ * (unless you have a better idea)
+ */
+private int
+mconvert(struct magic_set *ms, struct magic *m, int flip)
+{
+       union VALUETYPE *p = &ms->ms_value;
+
+       switch (cvt_flip(m->type, flip)) {
+       case FILE_BYTE:
+               if (cvt_8(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_SHORT:
+               if (cvt_16(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_LONG:
+       case FILE_DATE:
+       case FILE_LDATE:
+               if (cvt_32(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_QUAD:
+       case FILE_QDATE:
+       case FILE_QLDATE:
+       case FILE_QWDATE:
+               if (cvt_64(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_STRING:
+       case FILE_BESTRING16:
+       case FILE_LESTRING16: {
+               /* Null terminate and eat *trailing* return */
+               p->s[sizeof(p->s) - 1] = '\0';
+               return 1;
+       }
+       case FILE_PSTRING: {
+               size_t sz = file_pstring_length_size(m);
+               char *ptr1 = p->s, *ptr2 = ptr1 + sz;
+               size_t len = file_pstring_get_length(m, ptr1);
+               sz = sizeof(p->s) - sz; /* maximum length of string */
+               if (len >= sz) {
+                       /*
+                        * The size of the pascal string length (sz)
+                        * is 1, 2, or 4. We need at least 1 byte for NUL
+                        * termination, but we've already truncated the
+                        * string by p->s, so we need to deduct sz.
+                        * Because we can use one of the bytes of the length
+                        * after we shifted as NUL termination.
+                        */
+                       len = sz;
+               }
+               while (len--)
+                       *ptr1++ = *ptr2++;
+               *ptr1 = '\0';
+               return 1;
+       }
+       case FILE_BESHORT:
+               p->h = CAST(short, BE16(p));
+               if (cvt_16(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_BELONG:
+       case FILE_BEDATE:
+       case FILE_BELDATE:
+               p->l = CAST(int32_t, BE32(p));
+               if (cvt_32(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_BEQUAD:
+       case FILE_BEQDATE:
+       case FILE_BEQLDATE:
+       case FILE_BEQWDATE:
+               p->q = CAST(uint64_t, BE64(p));
+               if (cvt_64(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_LESHORT:
+               p->h = CAST(short, LE16(p));
+               if (cvt_16(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_LELONG:
+       case FILE_LEDATE:
+       case FILE_LELDATE:
+               p->l = CAST(int32_t, LE32(p));
+               if (cvt_32(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_LEQUAD:
+       case FILE_LEQDATE:
+       case FILE_LEQLDATE:
+       case FILE_LEQWDATE:
+               p->q = CAST(uint64_t, LE64(p));
+               if (cvt_64(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_MELONG:
+       case FILE_MEDATE:
+       case FILE_MELDATE:
+               p->l = CAST(int32_t, ME32(p));
+               if (cvt_32(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_FLOAT:
+               if (cvt_float(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_BEFLOAT:
+               p->l = BE32(p);
+               if (cvt_float(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_LEFLOAT:
+               p->l = LE32(p);
+               if (cvt_float(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_DOUBLE:
+               if (cvt_double(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_BEDOUBLE:
+               p->q = BE64(p);
+               if (cvt_double(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_LEDOUBLE:
+               p->q = LE64(p);
+               if (cvt_double(p, m) == -1)
+                       goto out;
+               return 1;
+       case FILE_REGEX:
+       case FILE_SEARCH:
+       case FILE_DEFAULT:
+       case FILE_CLEAR:
+       case FILE_NAME:
+       case FILE_USE:
+       case FILE_DER:
+               return 1;
+       default:
+               file_magerror(ms, "invalid type %d in mconvert()", m->type);
+               return 0;
+       }
+out:
+       file_magerror(ms, "zerodivide in mconvert()");
+       return 0;
+}
+
+
+private void
+mdebug(uint32_t offset, const char *str, size_t len)
+{
+       (void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset);
+       file_showstr(stderr, str, len);
+       (void) fputc('\n', stderr);
+       (void) fputc('\n', stderr);
+}
+
+private int
+mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
+    const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
+{
+       /*
+        * Note: FILE_SEARCH and FILE_REGEX do not actually copy
+        * anything, but setup pointers into the source
+        */
+       if (indir == 0) {
+               switch (type) {
+               case FILE_DER:
+               case FILE_SEARCH:
+                       if (offset > nbytes)
+                               offset = CAST(uint32_t, nbytes);
+                       ms->search.s = RCAST(const char *, s) + offset;
+                       ms->search.s_len = nbytes - offset;
+                       ms->search.offset = offset;
+                       return 0;
+
+               case FILE_REGEX: {
+                       const char *b;
+                       const char *c;
+                       const char *last;       /* end of search region */
+                       const char *buf;        /* start of search region */
+                       const char *end;
+                       size_t lines, linecnt, bytecnt;
+
+                       if (s == NULL || nbytes < offset) {
+                               ms->search.s_len = 0;
+                               ms->search.s = NULL;
+                               return 0;
+                       }
+
+                       if (m->str_flags & REGEX_LINE_COUNT) {
+                               linecnt = m->str_range;
+                               bytecnt = linecnt * 80;
+                       } else {
+                               linecnt = 0;
+                               bytecnt = m->str_range;
+                       }
+
+                       if (bytecnt == 0 || bytecnt > nbytes - offset)
+                               bytecnt = nbytes - offset;
+                       if (bytecnt > ms->regex_max)
+                               bytecnt = ms->regex_max;
+
+                       buf = RCAST(const char *, s) + offset;
+                       end = last = RCAST(const char *, s) + bytecnt + offset;
+                       /* mget() guarantees buf <= last */
+                       for (lines = linecnt, b = buf; lines && b < end &&
+                            ((b = CAST(const char *,
+                                memchr(c = b, '\n', CAST(size_t, (end - b)))))
+                            || (b = CAST(const char *,
+                                memchr(c, '\r', CAST(size_t, (end - c))))));
+                            lines--, b++) {
+                               if (b < end - 1 && b[0] == '\r' && b[1] == '\n')
+                                       b++;
+                               if (b < end - 1 && b[0] == '\n')
+                                       b++;
+                               last = b;
+                       }
+                       if (lines)
+                               last = end;
+
+                       ms->search.s = buf;
+                       ms->search.s_len = last - buf;
+                       ms->search.offset = offset;
+                       ms->search.rm_len = 0;
+                       return 0;
+               }
+               case FILE_BESTRING16:
+               case FILE_LESTRING16: {
+                       const unsigned char *src = s + offset;
+                       const unsigned char *esrc = s + nbytes;
+                       char *dst = p->s;
+                       char *edst = &p->s[sizeof(p->s) - 1];
+
+                       if (type == FILE_BESTRING16)
+                               src++;
+
+                       /* check that offset is within range */
+                       if (offset >= nbytes)
+                               break;
+                       for (/*EMPTY*/; src < esrc; src += 2, dst++) {
+                               if (dst < edst)
+                                       *dst = *src;
+                               else
+                                       break;
+                               if (*dst == '\0') {
+                                       if (type == FILE_BESTRING16 ?
+                                           *(src - 1) != '\0' :
+                                           ((src + 1 < esrc) &&
+                                           *(src + 1) != '\0'))
+                                               *dst = ' ';
+                               }
+                       }
+                       *edst = '\0';
+                       return 0;
+               }
+               case FILE_STRING:       /* XXX - these two should not need */
+               case FILE_PSTRING:      /* to copy anything, but do anyway. */
+               default:
+                       break;
+               }
+       }
+
+       if (offset >= nbytes) {
+               (void)memset(p, '\0', sizeof(*p));
+               return 0;
+       }
+       if (nbytes - offset < sizeof(*p))
+               nbytes = nbytes - offset;
+       else
+               nbytes = sizeof(*p);
+
+       (void)memcpy(p, s + offset, nbytes);
+
+       /*
+        * the usefulness of padding with zeroes eludes me, it
+        * might even cause problems
+        */
+       if (nbytes < sizeof(*p))
+               (void)memset(RCAST(char *, RCAST(void *, p)) + nbytes, '\0',
+                   sizeof(*p) - nbytes);
+       return 0;
+}
+
+private uint32_t
+do_ops(struct magic *m, intmax_t lhs, intmax_t off)
+{
+       intmax_t offset;
+       if (off) {
+               switch (m->in_op & FILE_OPS_MASK) {
+               case FILE_OPAND:
+                       offset = lhs & off;
+                       break;
+               case FILE_OPOR:
+                       offset = lhs | off;
+                       break;
+               case FILE_OPXOR:
+                       offset = lhs ^ off;
+                       break;
+               case FILE_OPADD:
+                       offset = lhs + off;
+                       break;
+               case FILE_OPMINUS:
+                       offset = lhs - off;
+                       break;
+               case FILE_OPMULTIPLY:
+                       offset = lhs * off;
+                       break;
+               case FILE_OPDIVIDE:
+                       offset = lhs / off;
+                       break;
+               case FILE_OPMODULO:
+                       offset = lhs % off;
+                       break;
+               }
+       } else
+               offset = lhs;
+       if (m->in_op & FILE_OPINVERSE)
+               offset = ~offset;
+
+       return CAST(uint32_t, offset);
+}
+
+private int
+msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
+    const struct buffer *b, size_t o, unsigned int cont_level)
+{
+       if (m->offset < 0) {
+               if (cont_level > 0) {
+                       if (m->flag & (OFFADD|INDIROFFADD))
+                               goto normal;
+#if 0
+                       file_error(ms, 0, "negative offset %d at continuation"
+                           "level %u", m->offset, cont_level);
+                       return -1;
+#endif
+               }
+               if (buffer_fill(b) == -1)
+                       return -1;
+               if (o != 0) {
+                       // Not yet!
+                       file_magerror(ms, "non zero offset %" SIZE_T_FORMAT
+                           "u at level %u", o, cont_level);
+                       return -1;
+               }
+               if (CAST(size_t, -m->offset) > b->elen)
+                       return -1;
+               buffer_init(bb, -1, NULL, b->ebuf, b->elen);
+               ms->eoffset = ms->offset = CAST(int32_t, b->elen + m->offset);
+       } else {
+               if (cont_level == 0) {
+normal:
+                       // XXX: Pass real fd, then who frees bb?
+                       buffer_init(bb, -1, NULL, b->fbuf, b->flen);
+                       ms->offset = m->offset;
+                       ms->eoffset = 0;
+               } else {
+                       ms->offset = ms->eoffset + m->offset;
+               }
+       }
+       if ((ms->flags & MAGIC_DEBUG) != 0) {
+               fprintf(stderr, "bb=[%p,%" SIZE_T_FORMAT "u], %d [b=%p,%"
+                   SIZE_T_FORMAT "u], [o=%#x, c=%d]\n",
+                   bb->fbuf, bb->flen, ms->offset, b->fbuf, b->flen,
+                   m->offset, cont_level);
+       }
+       return 0;
+}
+
+private int
+mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
+    const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
+    int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
+    int *printed_something, int *need_separator, int *returnval,
+    int *found_match)
+{
+       uint32_t offset = ms->offset;
+       struct buffer bb;
+       intmax_t lhs;
+       file_pushbuf_t *pb;
+       int rv, oneed_separator, in_type;
+       char *rbuf;
+       union VALUETYPE *p = &ms->ms_value;
+       struct mlist ml;
+
+       if (*indir_count >= ms->indir_max) {
+               file_error(ms, 0, "indirect count (%hu) exceeded",
+                   *indir_count);
+               return -1;
+       }
+
+       if (*name_count >= ms->name_max) {
+               file_error(ms, 0, "name use count (%hu) exceeded",
+                   *name_count);
+               return -1;
+       }
+
+
+
+       if (mcopy(ms, p, m->type, m->flag & INDIR, s,
+           CAST(uint32_t, offset + o), CAST(uint32_t, nbytes), m) == -1)
+               return -1;
+
+       if ((ms->flags & MAGIC_DEBUG) != 0) {
+               fprintf(stderr, "mget(type=%d, flag=%#x, offset=%u, o=%"
+                   SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
+                   "u, il=%hu, nc=%hu)\n",
+                   m->type, m->flag, offset, o, nbytes,
+                   *indir_count, *name_count);
+               mdebug(offset, RCAST(char *, RCAST(void *, p)),
+                   sizeof(union VALUETYPE));
+#ifndef COMPILE_ONLY
+               file_mdump(m);
+#endif
+       }
+
+       if (m->flag & INDIR) {
+               intmax_t off = m->in_offset;
+               const int sgn = m->in_op & FILE_OPSIGNED;
+               if (m->in_op & FILE_OPINDIRECT) {
+                       const union VALUETYPE *q = CAST(const union VALUETYPE *,
+                           RCAST(const void *, s + offset + off));
+                       switch (cvt_flip(m->in_type, flip)) {
+                       case FILE_BYTE:
+                               if (OFFSET_OOB(nbytes, offset + off, 1))
+                                       return 0;
+                               off = SEXT(sgn,8,q->b);
+                               break;
+                       case FILE_SHORT:
+                               if (OFFSET_OOB(nbytes, offset + off, 2))
+                                       return 0;
+                               off = SEXT(sgn,16,q->h);
+                               break;
+                       case FILE_BESHORT:
+                               if (OFFSET_OOB(nbytes, offset + off, 2))
+                                       return 0;
+                               off = SEXT(sgn,16,BE16(q));
+                               break;
+                       case FILE_LESHORT:
+                               if (OFFSET_OOB(nbytes, offset + off, 2))
+                                       return 0;
+                               off = SEXT(sgn,16,LE16(q));
+                               break;
+                       case FILE_LONG:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
+                               off = SEXT(sgn,32,q->l);
+                               break;
+                       case FILE_BELONG:
+                       case FILE_BEID3:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
+                               off = SEXT(sgn,32,BE32(q));
+                               break;
+                       case FILE_LEID3:
+                       case FILE_LELONG:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
+                               off = SEXT(sgn,32,LE32(q));
+                               break;
+                       case FILE_MELONG:
+                               if (OFFSET_OOB(nbytes, offset + off, 4))
+                                       return 0;
+                               off = SEXT(sgn,32,ME32(q));
+                               break;
+                       case FILE_BEQUAD:
+                               if (OFFSET_OOB(nbytes, offset + off, 8))
+                                       return 0;
+                               off = SEXT(sgn,64,BE64(q));
+                               break;
+                       case FILE_LEQUAD:
+                               if (OFFSET_OOB(nbytes, offset + off, 8))
+                                       return 0;
+                               off = SEXT(sgn,64,LE64(q));
+                               break;
+                       default:
+                               abort();
+                       }
+                       if ((ms->flags & MAGIC_DEBUG) != 0)
+                               fprintf(stderr, "indirect offs=%jd\n", off);
+               }
+               switch (in_type = cvt_flip(m->in_type, flip)) {
+               case FILE_BYTE:
+                       if (OFFSET_OOB(nbytes, offset, 1))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,8,p->b), off);
+                       break;
+               case FILE_BESHORT:
+                       if (OFFSET_OOB(nbytes, offset, 2))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,16,BE16(p)), off);
+                       break;
+               case FILE_LESHORT:
+                       if (OFFSET_OOB(nbytes, offset, 2))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,16,LE16(p)), off);
+                       break;
+               case FILE_SHORT:
+                       if (OFFSET_OOB(nbytes, offset, 2))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,16,p->h), off);
+                       break;
+               case FILE_BELONG:
+               case FILE_BEID3:
+                       if (OFFSET_OOB(nbytes, offset, 4))
+                               return 0;
+                       lhs = BE32(p);
+                       if (in_type == FILE_BEID3)
+                               lhs = cvt_id3(ms, CAST(uint32_t, lhs));
+                       offset = do_ops(m, SEXT(sgn,32,lhs), off);
+                       break;
+               case FILE_LELONG:
+               case FILE_LEID3:
+                       if (OFFSET_OOB(nbytes, offset, 4))
+                               return 0;
+                       lhs = LE32(p);
+                       if (in_type == FILE_LEID3)
+                               lhs = cvt_id3(ms, CAST(uint32_t, lhs));
+                       offset = do_ops(m, SEXT(sgn,32,lhs), off);
+                       break;
+               case FILE_MELONG:
+                       if (OFFSET_OOB(nbytes, offset, 4))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,32,ME32(p)), off);
+                       break;
+               case FILE_LONG:
+                       if (OFFSET_OOB(nbytes, offset, 4))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,32,p->l), off);
+                       break;
+               case FILE_LEQUAD:
+                       if (OFFSET_OOB(nbytes, offset, 8))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,64,LE64(p)), off);
+                       break;
+               case FILE_BEQUAD:
+                       if (OFFSET_OOB(nbytes, offset, 8))
+                               return 0;
+                       offset = do_ops(m, SEXT(sgn,64,BE64(p)), off);
+                       break;
+               default:
+                       abort();
+               }
+
+               if (m->flag & INDIROFFADD) {
+                       offset += ms->c.li[cont_level-1].off;
+                       if (offset == 0) {
+                               if ((ms->flags & MAGIC_DEBUG) != 0)
+                                       fprintf(stderr,
+                                           "indirect *zero* offset\n");
+                               return 0;
+                       }
+                       if ((ms->flags & MAGIC_DEBUG) != 0)
+                               fprintf(stderr, "indirect +offs=%u\n", offset);
+               }
+               if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
+                       return -1;
+               ms->offset = offset;
+
+               if ((ms->flags & MAGIC_DEBUG) != 0) {
+                       mdebug(offset, RCAST(char *, RCAST(void *, p)),
+                           sizeof(union VALUETYPE));
+#ifndef COMPILE_ONLY
+                       file_mdump(m);
+#endif
+               }
+       }
+
+       /* Verify we have enough data to match magic type */
+       switch (m->type) {
+       case FILE_BYTE:
+               if (OFFSET_OOB(nbytes, offset, 1))
+                       return 0;
+               break;
+
+       case FILE_SHORT:
+       case FILE_BESHORT:
+       case FILE_LESHORT:
+               if (OFFSET_OOB(nbytes, offset, 2))
+                       return 0;
+               break;
+
+       case FILE_LONG:
+       case FILE_BELONG:
+       case FILE_LELONG:
+       case FILE_MELONG:
+       case FILE_DATE:
+       case FILE_BEDATE:
+       case FILE_LEDATE:
+       case FILE_MEDATE:
+       case FILE_LDATE:
+       case FILE_BELDATE:
+       case FILE_LELDATE:
+       case FILE_MELDATE:
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               if (OFFSET_OOB(nbytes, offset, 4))
+                       return 0;
+               break;
+
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               if (OFFSET_OOB(nbytes, offset, 8))
+                       return 0;
+               break;
+
+       case FILE_STRING:
+       case FILE_PSTRING:
+       case FILE_SEARCH:
+               if (OFFSET_OOB(nbytes, offset, m->vallen))
+                       return 0;
+               break;
+
+       case FILE_REGEX:
+               if (nbytes < offset)
+                       return 0;
+               break;
+
+       case FILE_INDIRECT:
+               if (m->str_flags & INDIRECT_RELATIVE)
+                       offset += CAST(uint32_t, o);
+               if (offset == 0)
+                       return 0;
+
+               if (nbytes < offset)
+                       return 0;
+
+               if ((pb = file_push_buffer(ms)) == NULL)
+                       return -1;
+
+               (*indir_count)++;
+               bb = *b;
+               bb.fbuf = s + offset;
+               bb.flen = nbytes - offset;
+               rv = file_softmagic(ms, &bb,
+                   indir_count, name_count, BINTEST, text);
+
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
+
+               rbuf = file_pop_buffer(ms, pb);
+               if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
+                       return -1;
+
+               if (rv == 1) {
+                       if ((ms->flags & MAGIC_NODESC) == 0 &&
+                           file_printf(ms, F(ms, m->desc, "%u"), offset) == -1)
+                       {
+                               free(rbuf);
+                               return -1;
+                       }
+                       if (file_printf(ms, "%s", rbuf) == -1) {
+                               free(rbuf);
+                               return -1;
+                       }
+               }
+               free(rbuf);
+               return rv;
+
+       case FILE_USE:
+               if (nbytes < offset)
+                       return 0;
+               rbuf = m->value.s;
+               if (*rbuf == '^') {
+                       rbuf++;
+                       flip = !flip;
+               }
+               if (file_magicfind(ms, rbuf, &ml) == -1) {
+                       file_error(ms, 0, "cannot find entry `%s'", rbuf);
+                       return -1;
+               }
+               (*name_count)++;
+               oneed_separator = *need_separator;
+               if (m->flag & NOSPACE)
+                       *need_separator = 0;
+               rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
+                   mode, text, flip, indir_count, name_count,
+                   printed_something, need_separator, returnval, found_match);
+               (*name_count)--;
+               if (rv != 1)
+                   *need_separator = oneed_separator;
+               return rv;
+
+       case FILE_NAME:
+               if (ms->flags & MAGIC_NODESC)
+                       return 1;
+               if (file_printf(ms, "%s", m->desc) == -1)
+                       return -1;
+               return 1;
+       case FILE_DER:
+       case FILE_DEFAULT:      /* nothing to check */
+       case FILE_CLEAR:
+       default:
+               break;
+       }
+       if (!mconvert(ms, m, flip))
+               return 0;
+       return 1;
+}
+
+private uint64_t
+file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
+{
+       /*
+        * Convert the source args to unsigned here so that (1) the
+        * compare will be unsigned as it is in strncmp() and (2) so
+        * the ctype functions will work correctly without extra
+        * casting.
+        */
+       const unsigned char *a = RCAST(const unsigned char *, s1);
+       const unsigned char *b = RCAST(const unsigned char *, s2);
+       const unsigned char *eb = b + len;
+       uint64_t v;
+
+       /*
+        * What we want here is v = strncmp(s1, s2, len),
+        * but ignoring any nulls.
+        */
+       v = 0;
+       if (0L == flags) { /* normal string: do it fast */
+               while (len-- > 0)
+                       if ((v = *b++ - *a++) != '\0')
+                               break;
+       }
+       else { /* combine the others */
+               while (len-- > 0) {
+                       if (b >= eb) {
+                               v = 1;
+                               break;
+                       }
+                       if ((flags & STRING_IGNORE_LOWERCASE) &&
+                           islower(*a)) {
+                               if ((v = tolower(*b++) - *a++) != '\0')
+                                       break;
+                       }
+                       else if ((flags & STRING_IGNORE_UPPERCASE) &&
+                           isupper(*a)) {
+                               if ((v = toupper(*b++) - *a++) != '\0')
+                                       break;
+                       }
+                       else if ((flags & STRING_COMPACT_WHITESPACE) &&
+                           isspace(*a)) {
+                               a++;
+                               if (isspace(*b++)) {
+                                       if (!isspace(*a))
+                                               while (b < eb && isspace(*b))
+                                                       b++;
+                               }
+                               else {
+                                       v = 1;
+                                       break;
+                               }
+                       }
+                       else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
+                           isspace(*a)) {
+                               a++;
+                               while (b < eb && isspace(*b))
+                                       b++;
+                       }
+                       else {
+                               if ((v = *b++ - *a++) != '\0')
+                                       break;
+                       }
+               }
+       }
+       return v;
+}
+
+private uint64_t
+file_strncmp16(const char *a, const char *b, size_t len, uint32_t flags)
+{
+       /*
+        * XXX - The 16-bit string compare probably needs to be done
+        * differently, especially if the flags are to be supported.
+        * At the moment, I am unsure.
+        */
+       flags = 0;
+       return file_strncmp(a, b, len, flags);
+}
+
+private int
+magiccheck(struct magic_set *ms, struct magic *m)
+{
+       uint64_t l = m->value.q;
+       uint64_t v;
+       float fl, fv;
+       double dl, dv;
+       int matched;
+       union VALUETYPE *p = &ms->ms_value;
+
+       switch (m->type) {
+       case FILE_BYTE:
+               v = p->b;
+               break;
+
+       case FILE_SHORT:
+       case FILE_BESHORT:
+       case FILE_LESHORT:
+               v = p->h;
+               break;
+
+       case FILE_LONG:
+       case FILE_BELONG:
+       case FILE_LELONG:
+       case FILE_MELONG:
+       case FILE_DATE:
+       case FILE_BEDATE:
+       case FILE_LEDATE:
+       case FILE_MEDATE:
+       case FILE_LDATE:
+       case FILE_BELDATE:
+       case FILE_LELDATE:
+       case FILE_MELDATE:
+               v = p->l;
+               break;
+
+       case FILE_QUAD:
+       case FILE_LEQUAD:
+       case FILE_BEQUAD:
+       case FILE_QDATE:
+       case FILE_BEQDATE:
+       case FILE_LEQDATE:
+       case FILE_QLDATE:
+       case FILE_BEQLDATE:
+       case FILE_LEQLDATE:
+       case FILE_QWDATE:
+       case FILE_BEQWDATE:
+       case FILE_LEQWDATE:
+               v = p->q;
+               break;
+
+       case FILE_FLOAT:
+       case FILE_BEFLOAT:
+       case FILE_LEFLOAT:
+               fl = m->value.f;
+               fv = p->f;
+               switch (m->reln) {
+               case 'x':
+                       matched = 1;
+                       break;
+
+               case '!':
+                       matched = fv != fl;
+                       break;
+
+               case '=':
+                       matched = fv == fl;
+                       break;
+
+               case '>':
+                       matched = fv > fl;
+                       break;
+
+               case '<':
+                       matched = fv < fl;
+                       break;
+
+               default:
+                       file_magerror(ms, "cannot happen with float: invalid relation `%c'",
+                           m->reln);
+                       return -1;
+               }
+               return matched;
+
+       case FILE_DOUBLE:
+       case FILE_BEDOUBLE:
+       case FILE_LEDOUBLE:
+               dl = m->value.d;
+               dv = p->d;
+               switch (m->reln) {
+               case 'x':
+                       matched = 1;
+                       break;
+
+               case '!':
+                       matched = dv != dl;
+                       break;
+
+               case '=':
+                       matched = dv == dl;
+                       break;
+
+               case '>':
+                       matched = dv > dl;
+                       break;
+
+               case '<':
+                       matched = dv < dl;
+                       break;
+
+               default:
+                       file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln);
+                       return -1;
+               }
+               return matched;
+
+       case FILE_DEFAULT:
+       case FILE_CLEAR:
+               l = 0;
+               v = 0;
+               break;
+
+       case FILE_STRING:
+       case FILE_PSTRING:
+               l = 0;
+               v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen),
+                   m->str_flags);
+               break;
+
+       case FILE_BESTRING16:
+       case FILE_LESTRING16:
+               l = 0;
+               v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen),
+                   m->str_flags);
+               break;
+
+       case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
+               size_t slen;
+               size_t idx;
+
+               if (ms->search.s == NULL)
+                       return 0;
+
+               slen = MIN(m->vallen, sizeof(m->value.s));
+               l = 0;
+               v = 0;
+#ifdef HAVE_MEMMEM
+               if (slen > 0 && m->str_flags == 0) {
+                       const char *found;
+                       idx = m->str_range + slen;
+                       if (m->str_range == 0 || ms->search.s_len < idx)
+                               idx = ms->search.s_len;
+                       found = CAST(const char *, memmem(ms->search.s, idx,
+                           m->value.s, slen));
+                       if (!found)
+                               return 0;
+                       idx = found - ms->search.s;
+                       ms->search.offset += idx;
+                       ms->search.rm_len = ms->search.s_len - idx;
+                       break;
+               }
+#endif
+
+               for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
+                       if (slen + idx > ms->search.s_len)
+                               return 0;
+
+                       v = file_strncmp(m->value.s, ms->search.s + idx, slen,
+                           m->str_flags);
+                       if (v == 0) {   /* found match */
+                               ms->search.offset += idx;
+                               ms->search.rm_len = ms->search.s_len - idx;
+                               break;
+                       }
+               }
+               break;
+       }
+       case FILE_REGEX: {
+               int rc;
+               file_regex_t rx;
+               const char *search;
+
+               if (ms->search.s == NULL)
+                       return 0;
+
+               l = 0;
+               rc = file_regcomp(&rx, m->value.s,
+                   REG_EXTENDED|REG_NEWLINE|
+                   ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
+               if (rc) {
+                       file_regerror(&rx, rc, ms);
+                       v = CAST(uint64_t, -1);
+               } else {
+                       regmatch_t pmatch;
+                       size_t slen = ms->search.s_len;
+                       char *copy;
+                       if (slen != 0) {
+                           copy = CAST(char *, malloc(slen));
+                           if (copy == NULL)  {
+                               file_regfree(&rx);
+                               file_error(ms, errno,
+                                   "can't allocate %" SIZE_T_FORMAT "u bytes",
+                                   slen);
+                               return -1;
+                           }
+                           memcpy(copy, ms->search.s, slen);
+                           copy[--slen] = '\0';
+                           search = copy;
+                       } else {
+                           search = CCAST(char *, "");
+                           copy = NULL;
+                       }
+                       rc = file_regexec(&rx, RCAST(const char *, search),
+                           1, &pmatch, 0);
+                       free(copy);
+                       switch (rc) {
+                       case 0:
+                               ms->search.s += CAST(int, pmatch.rm_so);
+                               ms->search.offset += CAST(size_t, pmatch.rm_so);
+                               ms->search.rm_len = CAST(size_t, 
+                                   pmatch.rm_eo - pmatch.rm_so);
+                               v = 0;
+                               break;
+
+                       case REG_NOMATCH:
+                               v = 1;
+                               break;
+
+                       default:
+                               file_regerror(&rx, rc, ms);
+                               v = CAST(uint64_t, -1);
+                               break;
+                       }
+               }
+               file_regfree(&rx);
+               if (v == CAST(uint64_t, -1))
+                       return -1;
+               break;
+       }
+       case FILE_INDIRECT:
+       case FILE_USE:
+       case FILE_NAME:
+               return 1;
+       case FILE_DER:
+               matched = der_cmp(ms, m);
+               if (matched == -1) {
+                       if ((ms->flags & MAGIC_DEBUG) != 0) {
+                               (void) fprintf(stderr,
+                                   "EOF comparing DER entries");
+                       }
+                       return 0;
+               }
+               return matched;
+       default:
+               file_magerror(ms, "invalid type %d in magiccheck()", m->type);
+               return -1;
+       }
+
+       v = file_signextend(ms, m, v);
+
+       switch (m->reln) {
+       case 'x':
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void) fprintf(stderr, "%" INT64_T_FORMAT
+                           "u == *any* = 1\n", CAST(unsigned long long, v));
+               matched = 1;
+               break;
+
+       case '!':
+               matched = v != l;
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
+                           INT64_T_FORMAT "u = %d\n",
+                           CAST(unsigned long long, v),
+                           CAST(unsigned long long, l), matched);
+               break;
+
+       case '=':
+               matched = v == l;
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
+                           INT64_T_FORMAT "u = %d\n",
+                           CAST(unsigned long long, v),
+                           CAST(unsigned long long, l), matched);
+               break;
+
+       case '>':
+               if (m->flag & UNSIGNED) {
+                       matched = v > l;
+                       if ((ms->flags & MAGIC_DEBUG) != 0)
+                               (void) fprintf(stderr, "%" INT64_T_FORMAT
+                                   "u > %" INT64_T_FORMAT "u = %d\n",
+                                   CAST(unsigned long long, v),
+                                   CAST(unsigned long long, l), matched);
+               }
+               else {
+                       matched = CAST(int64_t, v) > CAST(int64_t, l);
+                       if ((ms->flags & MAGIC_DEBUG) != 0)
+                               (void) fprintf(stderr, "%" INT64_T_FORMAT
+                                   "d > %" INT64_T_FORMAT "d = %d\n",
+                                   CAST(long long, v),
+                                   CAST(long long, l), matched);
+               }
+               break;
+
+       case '<':
+               if (m->flag & UNSIGNED) {
+                       matched = v < l;
+                       if ((ms->flags & MAGIC_DEBUG) != 0)
+                               (void) fprintf(stderr, "%" INT64_T_FORMAT
+                                   "u < %" INT64_T_FORMAT "u = %d\n",
+                                   CAST(unsigned long long, v),
+                                   CAST(unsigned long long, l), matched);
+               }
+               else {
+                       matched = CAST(int64_t, v) < CAST(int64_t, l);
+                       if ((ms->flags & MAGIC_DEBUG) != 0)
+                               (void) fprintf(stderr, "%" INT64_T_FORMAT
+                                   "d < %" INT64_T_FORMAT "d = %d\n",
+                                    CAST(long long, v),
+                                    CAST(long long, l), matched);
+               }
+               break;
+
+       case '&':
+               matched = (v & l) == l;
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
+                           INT64_T_FORMAT "x) == %" INT64_T_FORMAT
+                           "x) = %d\n", CAST(unsigned long long, v),
+                           CAST(unsigned long long, l),
+                           CAST(unsigned long long, l),
+                           matched);
+               break;
+
+       case '^':
+               matched = (v & l) != l;
+               if ((ms->flags & MAGIC_DEBUG) != 0)
+                       (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
+                           INT64_T_FORMAT "x) != %" INT64_T_FORMAT
+                           "x) = %d\n", CAST(unsigned long long, v),
+                           CAST(unsigned long long, l),
+                           CAST(unsigned long long, l), matched);
+               break;
+
+       default:
+               file_magerror(ms, "cannot happen: invalid relation `%c'",
+                   m->reln);
+               return -1;
+       }
+
+       return matched;
+}
+
+private int
+handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
+{
+       if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
+               if (print_sep(ms, firstline) == -1)
+                       return -1;
+               if (file_printf(ms, "%.8s", m->apple) == -1)
+                       return -1;
+               return 1;
+       }
+       if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) {
+               if (print_sep(ms, firstline) == -1)
+                       return -1;
+               if (file_printf(ms, "%s", m->ext) == -1)
+                       return -1;
+               return 1;
+       }
+       if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
+               char buf[1024];
+               const char *p;
+               if (print_sep(ms, firstline) == -1)
+                       return -1;
+               if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1)
+                       p = m->mimetype;
+               else
+                       p = buf;
+               if (file_printf(ms, "%s", p) == -1)
+                       return -1;
+               return 1;
+       }
+       return 0;
+}
+
+private int
+print_sep(struct magic_set *ms, int firstline)
+{
+       if (firstline)
+               return 0;
+       /*
+        * we found another match
+        * put a newline and '-' to do some simple formatting
+        */
+       return file_separator(ms);
+}
diff --git a/src/strcasestr.c b/src/strcasestr.c
new file mode 100644 (file)
index 0000000..3db407f
--- /dev/null
@@ -0,0 +1,84 @@
+/*     $NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $  */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $");
+__RCSID("$NetBSD: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "file.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+
+static int
+_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+       if (n != 0) {
+               const unsigned char *us1 = (const unsigned char *)s1,
+                               *us2 = (const unsigned char *)s2;
+
+               do {
+                       if (tolower(*us1) != tolower(*us2++))
+                               return tolower(*us1) - tolower(*--us2);
+                       if (*us1++ == '\0')
+                               break;
+               } while (--n != 0);
+       }
+       return 0;
+}
+
+/*
+ * Find the first occurrence of find in s, ignore case.
+ */
+char *
+strcasestr(const char *s, const char *find)
+{
+       char c, sc;
+       size_t len;
+
+       if ((c = *find++) != 0) {
+               c = tolower((unsigned char)c);
+               len = strlen(find);
+               do {
+                       do {
+                               if ((sc = *s++) == 0)
+                                       return (NULL);
+                       } while ((char)tolower((unsigned char)sc) != c);
+               } while (_strncasecmp(s, find, len) != 0);
+               s--;
+       }
+       return (char *)(intptr_t)(s);
+}
diff --git a/src/strlcat.c b/src/strlcat.c
new file mode 100644 (file)
index 0000000..9692bc1
--- /dev/null
@@ -0,0 +1,58 @@
+/*     $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $      */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
+#include "file.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left).  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+       char *d = dst;
+       const char *s = src;
+       size_t n = siz;
+       size_t dlen;
+
+       /* Find the end of dst and adjust bytes left but don't go past end */
+       while (n-- != 0 && *d != '\0')
+               d++;
+       dlen = d - dst;
+       n = siz - dlen;
+
+       if (n == 0)
+               return(dlen + strlen(s));
+       while (*s != '\0') {
+               if (n != 1) {
+                       *d++ = *s;
+                       n--;
+               }
+               s++;
+       }
+       *d = '\0';
+
+       return(dlen + (s - src));       /* count does not include NUL */
+}
diff --git a/src/strlcpy.c b/src/strlcpy.c
new file mode 100644 (file)
index 0000000..992501c
--- /dev/null
@@ -0,0 +1,54 @@
+/*     $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $      */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
+#include "file.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+       char *d = dst;
+       const char *s = src;
+       size_t n = siz;
+
+       /* Copy as many bytes as will fit */
+       if (n != 0 && --n != 0) {
+               do {
+                       if ((*d++ = *s++) == 0)
+                               break;
+               } while (--n != 0);
+       }
+
+       /* Not enough room in dst, add NUL and traverse rest of src */
+       if (n == 0) {
+               if (siz != 0)
+                       *d = '\0';              /* NUL-terminate dst */
+               while (*s++)
+                       ;
+       }
+
+       return(s - src - 1);    /* count does not include NUL */
+}
diff --git a/src/tar.h b/src/tar.h
new file mode 100644 (file)
index 0000000..c3d0297
--- /dev/null
+++ b/src/tar.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * Header file for public domain tar (tape archive) program.
+ *
+ * @(#)tar.h 1.20 86/10/29     Public Domain.
+ *
+ * Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
+ *
+ * $File: tar.h,v 1.12 2008/02/07 00:58:52 christos Exp $ # checkin only
+ */
+
+/*
+ * Header block on tape.
+ *
+ * I'm going to use traditional DP naming conventions here.
+ * A "block" is a big chunk of stuff that we do I/O on.
+ * A "record" is a piece of info that we care about.
+ * Typically many "record"s fit into a "block".
+ */
+#define        RECORDSIZE      512
+#define        NAMSIZ  100
+#define        TUNMLEN 32
+#define        TGNMLEN 32
+
+union record {
+       unsigned char   charptr[RECORDSIZE];
+       struct header {
+               char    name[NAMSIZ];
+               char    mode[8];
+               char    uid[8];
+               char    gid[8];
+               char    size[12];
+               char    mtime[12];
+               char    chksum[8];
+               char    linkflag;
+               char    linkname[NAMSIZ];
+               char    magic[8];
+               char    uname[TUNMLEN];
+               char    gname[TGNMLEN];
+               char    devmajor[8];
+               char    devminor[8];
+       } header;
+};
+
+/* The magic field is filled with this if uname and gname are valid. */
+#define        TMAGIC          "ustar"         /* 5 chars and a null */
+#define        GNUTMAGIC       "ustar  "       /* 7 chars and a null */
diff --git a/src/teststrchr.c b/src/teststrchr.c
new file mode 100644 (file)
index 0000000..4a8ad10
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef TEST
+#include <stdio.h>
+#include <err.h>
+#include <string.h>
+int
+main(void)
+{
+       char    *strchr();
+
+       if (strchr(1, "abc", 'c') == NULL)
+               errx(1, "error 1");
+       if (strchr("abc", 'd') != NULL)
+               errx(1, "error 2");
+       if (strchr("abc", 'a') == NULL)
+               errx(1, "error 3");
+       if (strchr("abc", 'c') == NULL)
+               errx(1, "error 4");
+       return 0;
+}
+#endif
diff --git a/src/vasprintf.c b/src/vasprintf.c
new file mode 100644 (file)
index 0000000..c87465b
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) Ian F. Darwin 1986-1995.
+ * Software written by Ian F. Darwin and others;
+ * maintained 1995-present by Christos Zoulas and others.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*###########################################################################
+  #                                                                           #
+  #                                vasprintf                                  #
+  #                                                                           #
+  #               Copyright (c) 2002-2005 David TAILLANDIER                   #
+  #                                                                           #
+  ###########################################################################*/
+
+/*
+
+This software is distributed under the "modified BSD licence".
+
+This software is also released with GNU license (GPL) in another file (same
+source-code, only license differ).
+
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer. Redistributions in binary
+form must reproduce the above copyright notice, this list of conditions and
+the following disclaimer in the documentation and/or other materials
+provided with the distribution. The name of the author may not be used to
+endorse or promote products derived from this software without specific
+prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+====================
+
+Hacked from xnprintf version of 26th February 2005 to provide only
+vasprintf by Reuben Thomas <rrt@sc3d.org>.
+
+====================
+
+
+'printf' function family use the following format string:
+
+%[flag][width][.prec][modifier]type
+
+%% is the escape sequence to print a '%'
+%  followed by an unknown format will print the characters without
+trying to do any interpretation
+
+flag:   none   +     -     #     (blank)
+width:  n    0n    *
+prec:   none   .0    .n     .*
+modifier:    F N L h l ll z t    ('F' and 'N' are ms-dos/16-bit specific)
+type:  d i o u x X f e g E G c s p n
+
+
+The function needs to allocate memory to store the full text before to
+actually writing it.  i.e if you want to fnprintf() 1000 characters, the
+functions will allocate 1000 bytes.
+This behaviour can be modified: you have to customise the code to flush the
+internal buffer (writing to screen or file) when it reach a given size. Then
+the buffer can have a shorter length. But what? If you really need to write
+HUGE string, don't use printf!
+During the process, some other memory is allocated (1024 bytes minimum)
+to handle the output of partial sprintf() calls. If you have only 10000 bytes
+free in memory, you *may* not be able to nprintf() a 8000 bytes-long text.
+
+note: if a buffer overflow occurs, exit() is called. This situation should
+never appear ... but if you want to be *really* sure, you have to modify the
+code to handle those situations (only one place to modify).
+A buffer overflow can only occur if your sprintf() do strange things or when
+you use strange formats.
+
+*/
+#include "file.h"
+
+#ifndef        lint
+FILE_RCSID("@(#)$File: vasprintf.c,v 1.16 2018/10/01 18:45:39 christos Exp $")
+#endif /* lint */
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+
+#define ALLOC_CHUNK 2048
+#define ALLOC_SECURITY_MARGIN 1024   /* big value because some platforms have very big 'G' exponent */
+#if ALLOC_CHUNK < ALLOC_SECURITY_MARGIN
+#    error  !!! ALLOC_CHUNK < ALLOC_SECURITY_MARGIN !!!
+#endif
+/* note: to have some interest, ALLOC_CHUNK should be much greater than ALLOC_SECURITY_MARGIN */
+
+/*
+ *  To save a lot of push/pop, every variable are stored into this
+ *  structure, which is passed among nearly every sub-functions.
+ */
+typedef struct {
+  const char * src_string;        /* current position into intput string */
+  char *       buffer_base;       /* output buffer */
+  char *       dest_string;       /* current position into output string */
+  size_t       buffer_len;        /* length of output buffer */
+  size_t       real_len;          /* real current length of output text */
+  size_t       pseudo_len;        /* total length of output text if it were not limited in size */
+  size_t       maxlen;
+  va_list      vargs;             /* pointer to current position into vargs */
+  char *       sprintf_string;
+  FILE *       fprintf_file;
+} xprintf_struct;
+
+/*
+ *  Realloc buffer if needed
+ *  Return value:  0 = ok
+ *               EOF = not enought memory
+ */
+static int realloc_buff(xprintf_struct *s, size_t len)
+{
+  char * ptr;
+
+  if (len + ALLOC_SECURITY_MARGIN + s->real_len > s->buffer_len) {
+    len += s->real_len + ALLOC_CHUNK;
+    ptr = (char *)realloc((void *)(s->buffer_base), len);
+    if (ptr == NULL) {
+      s->buffer_base = NULL;
+      return EOF;
+    }
+
+    s->dest_string = ptr + (size_t)(s->dest_string - s->buffer_base);
+    s->buffer_base = ptr;
+    s->buffer_len = len;
+
+    (s->buffer_base)[s->buffer_len - 1] = 1; /* overflow marker */
+  }
+
+  return 0;
+}
+
+/*
+ *  Prints 'usual' characters    up to next '%'
+ *                            or up to end of text
+ */
+static int usual_char(xprintf_struct * s)
+{
+  size_t len;
+
+  len = strcspn(s->src_string, "%");     /* reachs the next '%' or end of input string */
+  /* note: 'len' is never 0 because the presence of '%' */
+  /* or end-of-line is checked in the calling function  */
+
+  if (realloc_buff(s,len) == EOF)
+    return EOF;
+
+  memcpy(s->dest_string, s->src_string, len);
+  s->src_string += len;
+  s->dest_string += len;
+  s->real_len += len;
+  s->pseudo_len += len;
+
+  return 0;
+}
+
+/*
+ *  Return value: 0 = ok
+ *                EOF = error
+ */
+static int print_it(xprintf_struct *s, size_t approx_len,
+                    const char *format_string, ...)
+{
+  va_list varg;
+  int vsprintf_len;
+  size_t len;
+
+  if (realloc_buff(s,approx_len) == EOF)
+    return EOF;
+
+  va_start(varg, format_string);
+  vsprintf_len = vsprintf(s->dest_string, format_string, varg);
+  va_end(varg);
+
+  /* Check for overflow */
+  assert((s->buffer_base)[s->buffer_len - 1] == 1);
+
+  if (vsprintf_len == EOF) /* must be done *after* overflow-check */
+    return EOF;
+
+  s->pseudo_len += vsprintf_len;
+  len = strlen(s->dest_string);
+  s->real_len += len;
+  s->dest_string += len;
+
+  return 0;
+}
+
+/*
+ *  Prints a string (%s)
+ *  We need special handling because:
+ *     a: the length of the string is unknown
+ *     b: when .prec is used, we must not access any extra byte of the
+ *        string (of course, if the original sprintf() does... what the
+ *        hell, not my problem)
+ *
+ *  Return value: 0 = ok
+ *                EOF = error
+ */
+static int type_s(xprintf_struct *s, int width, int prec,
+                  const char *format_string, const char *arg_string)
+{
+  size_t string_len;
+
+  if (arg_string == NULL)
+    return print_it(s, (size_t)6, "(null)", 0);
+
+  /* hand-made strlen() whitch stops when 'prec' is reached. */
+  /* if 'prec' is -1 then it is never reached. */
+  string_len = 0;
+  while (arg_string[string_len] != 0 && (size_t)prec != string_len)
+    string_len++;
+
+  if (width != -1 && string_len < (size_t)width)
+    string_len = (size_t)width;
+
+  return print_it(s, string_len, format_string, arg_string);
+}
+
+/*
+ *  Read a serie of digits. Stop when non-digit is found.
+ *  Return value: the value read (between 0 and 32767).
+ *  Note: no checks are made against overflow. If the string contain a big
+ *  number, then the return value won't be what we want (but, in this case,
+ *  the programmer don't know whatr he wants, then no problem).
+ */
+static int getint(const char **string)
+{
+  int i = 0;
+
+  while (isdigit((unsigned char)**string) != 0) {
+    i = i * 10 + (**string - '0');
+    (*string)++;
+  }
+
+  if (i < 0 || i > 32767)
+    i = 32767; /* if we have i==-10 this is not because the number is */
+  /* negative; this is because the number is big */
+  return i;
+}
+
+/*
+ *  Read a part of the format string. A part is 'usual characters' (ie "blabla")
+ *  or '%%' escape sequence (to print a single '%') or any combination of
+ *  format specifier (ie "%i" or "%10.2d").
+ *  After the current part is managed, the function returns to caller with
+ *  everything ready to manage the following part.
+ *  The caller must ensure than the string is not empty, i.e. the first byte
+ *  is not zero.
+ *
+ *  Return value:  0 = ok
+ *                 EOF = error
+ */
+static int dispatch(xprintf_struct *s)
+{
+  const char *initial_ptr;
+  char format_string[24]; /* max length may be something like  "% +-#032768.32768Ld" */
+  char *format_ptr;
+  int flag_plus, flag_minus, flag_space, flag_sharp, flag_zero;
+  int width, prec, modifier, approx_width;
+  char type;
+  /* most of those variables are here to rewrite the format string */
+
+#define SRCTXT  (s->src_string)
+#define DESTTXT (s->dest_string)
+
+  /* incoherent format string. Characters after the '%' will be printed with the next call */
+#define INCOHERENT()         do {SRCTXT=initial_ptr; return 0;} while (0)     /* do/while to avoid */
+#define INCOHERENT_TEST()    do {if(*SRCTXT==0)   INCOHERENT();} while (0)    /* a null statement  */
+
+  /* 'normal' text */
+  if (*SRCTXT != '%')
+    return usual_char(s);
+
+  /* we then have a '%' */
+  SRCTXT++;
+  /* don't check for end-of-string ; this is done later */
+
+  /* '%%' escape sequence */
+  if (*SRCTXT == '%') {
+    if (realloc_buff(s, (size_t)1) == EOF) /* because we can have "%%%%%%%%..." */
+      return EOF;
+    *DESTTXT = '%';
+    DESTTXT++;
+    SRCTXT++;
+    (s->real_len)++;
+    (s->pseudo_len)++;
+    return 0;
+  }
+
+  /* '%' managing */
+  initial_ptr = SRCTXT;   /* save current pointer in case of incorrect */
+  /* 'decoding'. Points just after the '%' so the '%' */
+  /* won't be printed in any case, as required. */
+
+  /* flag */
+  flag_plus = flag_minus = flag_space = flag_sharp = flag_zero = 0;
+
+  for (;; SRCTXT++) {
+    if (*SRCTXT == ' ')
+      flag_space = 1;
+    else if (*SRCTXT == '+')
+      flag_plus = 1;
+    else if (*SRCTXT == '-')
+      flag_minus = 1;
+    else if (*SRCTXT == '#')
+      flag_sharp = 1;
+    else if (*SRCTXT == '0')
+      flag_zero = 1;
+    else
+      break;
+  }
+
+  INCOHERENT_TEST();    /* here is the first test for end of string */
+
+  /* width */
+  if (*SRCTXT == '*') {         /* width given by next argument */
+    SRCTXT++;
+    width = va_arg(s->vargs, int);
+    if ((size_t)width > 0x3fffU) /* 'size_t' to check against negative values too */
+      width = 0x3fff;
+  } else if (isdigit((unsigned char)*SRCTXT)) /* width given as ASCII number */
+    width = getint(&SRCTXT);
+  else
+    width = -1;                 /* no width specified */
+
+  INCOHERENT_TEST();
+
+  /* .prec */
+  if (*SRCTXT == '.') {
+    SRCTXT++;
+    if (*SRCTXT == '*') {       /* .prec given by next argument */
+      SRCTXT++;
+      prec = va_arg(s->vargs, int);
+      if ((size_t)prec >= 0x3fffU) /* 'size_t' to check against negative values too */
+        prec = 0x3fff;
+    } else {                    /* .prec given as ASCII number */
+      if (isdigit((unsigned char)*SRCTXT) == 0)
+        INCOHERENT();
+      prec = getint(&SRCTXT);
+    }
+    INCOHERENT_TEST();
+  } else
+    prec = -1;                  /* no .prec specified */
+
+  /* modifier */
+  switch (*SRCTXT) {
+  case 'L':
+  case 'h':
+  case 'l':
+  case 'z':
+  case 't':
+    modifier = *SRCTXT;
+    SRCTXT++;
+    if (modifier=='l' && *SRCTXT=='l') {
+      SRCTXT++;
+      modifier = 'L';  /* 'll' == 'L'      long long == long double */
+    } /* only for compatibility ; not portable */
+    INCOHERENT_TEST();
+    break;
+  default:
+    modifier = -1;              /* no modifier specified */
+    break;
+  }
+
+  /* type */
+  type = *SRCTXT;
+  if (strchr("diouxXfegEGcspn",type) == NULL)
+    INCOHERENT();               /* unknown type */
+  SRCTXT++;
+
+  /* rewrite format-string */
+  format_string[0] = '%';
+  format_ptr = &(format_string[1]);
+
+  if (flag_plus) {
+    *format_ptr = '+';
+    format_ptr++;
+  }
+  if (flag_minus) {
+    *format_ptr = '-';
+    format_ptr++;
+  }
+  if (flag_space) {
+    *format_ptr = ' ';
+    format_ptr++;
+  }
+  if (flag_sharp) {
+    *format_ptr = '#';
+    format_ptr++;
+  }
+  if (flag_zero) {
+    *format_ptr = '0';
+    format_ptr++;
+  } /* '0' *must* be the last one */
+
+  if (width != -1) {
+    sprintf(format_ptr, "%i", width);
+    format_ptr += strlen(format_ptr);
+  }
+
+  if (prec != -1) {
+    *format_ptr = '.';
+    format_ptr++;
+    sprintf(format_ptr, "%i", prec);
+    format_ptr += strlen(format_ptr);
+  }
+
+  if (modifier != -1) {
+    if (modifier == 'L' && strchr("diouxX",type) != NULL) {
+      *format_ptr = 'l';
+      format_ptr++;
+      *format_ptr = 'l';
+      format_ptr++;
+    } else {
+      *format_ptr = modifier;
+      format_ptr++;
+    }
+  }
+
+  *format_ptr = type;
+  format_ptr++;
+  *format_ptr = 0;
+
+  /* vague approximation of minimal length if width or prec are specified */
+  approx_width = width + prec;
+  if (approx_width < 0) /* because width == -1 and/or prec == -1 */
+    approx_width = 0;
+
+  switch (type) {
+    /* int */
+  case 'd':
+  case 'i':
+  case 'o':
+  case 'u':
+  case 'x':
+  case 'X':
+    switch (modifier) {
+    case -1 :
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
+    case 'L':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long long int));
+    case 'l':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long int));
+    case 'h':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
+    case 'z':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, size_t));
+    case 't':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, ptrdiff_t));
+      /* 'int' instead of 'short int' because default promotion is 'int' */
+    default:
+      INCOHERENT();
+    }
+
+    /* char */
+  case 'c':
+    if (modifier != -1)
+      INCOHERENT();
+    return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, int));
+    /* 'int' instead of 'char' because default promotion is 'int' */
+
+    /* math */
+  case 'e':
+  case 'f':
+  case 'g':
+  case 'E':
+  case 'G':
+    switch (modifier) {
+    case -1 : /* because of default promotion, no modifier means 'l' */
+    case 'l':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, double));
+    case 'L':
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, long double));
+    default:
+      INCOHERENT();
+    }
+
+    /* string */
+  case 's':
+    return type_s(s, width, prec, format_string, va_arg(s->vargs, const char*));
+
+    /* pointer */
+  case 'p':
+    if (modifier == -1)
+      return print_it(s, (size_t)approx_width, format_string, va_arg(s->vargs, void *));
+    INCOHERENT();
+
+    /* store */
+  case 'n':
+    if (modifier == -1) {
+      int * p;
+      p = va_arg(s->vargs, int *);
+      if (p != NULL) {
+        *p = s->pseudo_len;
+        return 0;
+      }
+      return EOF;
+    }
+    INCOHERENT();
+
+  } /* switch */
+
+  INCOHERENT();                 /* unknown type */
+
+#undef INCOHERENT
+#undef INCOHERENT_TEST
+#undef SRCTXT
+#undef DESTTXT
+}
+
+/*
+ *  Return value: number of *virtually* written characters
+ *                EOF = error
+ */
+static int core(xprintf_struct *s)
+{
+  size_t save_len;
+  char *dummy_base;
+
+  /* basic checks */
+  if ((int)(s->maxlen) <= 0) /* 'int' to check against some conversion */
+    return EOF;           /* error for example if value is (int)-10 */
+  s->maxlen--;      /* because initial maxlen counts final 0 */
+  /* note: now 'maxlen' _can_ be zero */
+
+  if (s->src_string == NULL)
+    s->src_string = "(null)";
+
+  /* struct init and memory allocation */
+  s->buffer_base = NULL;
+  s->buffer_len = 0;
+  s->real_len = 0;
+  s->pseudo_len = 0;
+  if (realloc_buff(s, (size_t)0) == EOF)
+    return EOF;
+  s->dest_string = s->buffer_base;
+
+  /* process source string */
+  for (;;) {
+    /* up to end of source string */
+    if (*(s->src_string) == 0) {
+      *(s->dest_string) = '\0';    /* final NUL */
+      break;
+    }
+
+    if (dispatch(s) == EOF)
+      goto free_EOF;
+
+    /* up to end of dest string */
+    if (s->real_len >= s->maxlen) {
+      (s->buffer_base)[s->maxlen] = '\0'; /* final NUL */
+      break;
+    }
+  }
+
+  /* for (v)asnprintf */
+  dummy_base = s->buffer_base;
+
+  dummy_base = s->buffer_base + s->real_len;
+  save_len = s->real_len;
+
+  /* process the remaining of source string to compute 'pseudo_len'. We
+   * overwrite again and again, starting at 'dummy_base' because we don't
+   * need the text, only char count. */
+  while(*(s->src_string) != 0) { /* up to end of source string */
+    s->real_len = 0;
+    s->dest_string = dummy_base;
+    if (dispatch(s) == EOF)
+      goto free_EOF;
+  }
+
+  s->buffer_base = (char *)realloc((void *)(s->buffer_base), save_len + 1);
+  if (s->buffer_base == NULL)
+    return EOF; /* should rarely happen because we shrink the buffer */
+  return s->pseudo_len;
+
+ free_EOF:
+  free(s->buffer_base);
+  return EOF;
+}
+
+int vasprintf(char **ptr, const char *format_string, va_list vargs)
+{
+  xprintf_struct s;
+  int retval;
+
+  s.src_string = format_string;
+#ifdef va_copy
+  va_copy (s.vargs, vargs);
+#else
+# ifdef __va_copy
+  __va_copy (s.vargs, vargs);
+# else
+#  ifdef WIN32
+  s.vargs = vargs;
+#  else
+  memcpy (&s.vargs, &vargs, sizeof (s.va_args));
+#  endif /* WIN32 */
+# endif /* __va_copy */
+#endif /* va_copy */
+  s.maxlen = (size_t)INT_MAX;
+
+  retval = core(&s);
+  va_end(s.vargs);
+  if (retval == EOF) {
+    *ptr = NULL;
+    return EOF;
+  }
+
+  *ptr = s.buffer_base;
+  return retval;
+}
diff --git a/tests/.cvsignore b/tests/.cvsignore
new file mode 100644 (file)
index 0000000..7ac3439
--- /dev/null
@@ -0,0 +1,5 @@
+.deps
+.libs
+Makefile.in
+Makefile
+test
diff --git a/tests/CVE-2014-1943.result b/tests/CVE-2014-1943.result
new file mode 100644 (file)
index 0000000..68b5089
--- /dev/null
@@ -0,0 +1 @@
+Apple Driver Map, blocksize 0
\ No newline at end of file
diff --git a/tests/CVE-2014-1943.testfile b/tests/CVE-2014-1943.testfile
new file mode 100644 (file)
index 0000000..3fc252b
Binary files /dev/null and b/tests/CVE-2014-1943.testfile differ
diff --git a/tests/JW07022A.mp3.result b/tests/JW07022A.mp3.result
new file mode 100644 (file)
index 0000000..2252c52
--- /dev/null
@@ -0,0 +1 @@
+Audio file with ID3 version 2.2.0, contains:MPEG ADTS, layer III, v1,  96 kbps, 44.1 kHz, Monaural
\ No newline at end of file
diff --git a/tests/JW07022A.mp3.testfile b/tests/JW07022A.mp3.testfile
new file mode 100644 (file)
index 0000000..8b0a577
Binary files /dev/null and b/tests/JW07022A.mp3.testfile differ
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..e84ca13
--- /dev/null
@@ -0,0 +1,88 @@
+check_PROGRAMS = test
+test_LDADD = $(top_builddir)/src/libmagic.la
+test_CPPFLAGS = -I$(top_builddir)/src
+
+EXTRA_DIST = \
+regex-eol.magic \
+CVE-2014-1943.testfile \
+JW07022A.mp3.testfile \
+escapevel.testfile \
+fit-map-data.testfile \
+gedcom.testfile \
+hddrawcopytool.testfile \
+issue311docx.testfile \
+issue359xlsx.testfile \
+json1.testfile \
+json2.testfile \
+json3.testfile \
+regex-eol.testfile \
+zstd-v0.2-FF.testfile \
+zstd-v0.3-FF.testfile \
+zstd-v0.4-FF.testfile \
+zstd-v0.5-FF.testfile \
+zstd-v0.6-FF.testfile \
+zstd-v0.7-21.testfile \
+zstd-v0.7-22.testfile \
+zstd-v0.8-01.testfile \
+zstd-v0.8-02.testfile \
+zstd-v0.8-03.testfile \
+zstd-v0.8-16.testfile \
+zstd-v0.8-20.testfile \
+zstd-v0.8-21.testfile \
+zstd-v0.8-22.testfile \
+zstd-v0.8-23.testfile \
+zstd-v0.8-F4.testfile \
+zstd-v0.8-FF.testfile \
+CVE-2014-1943.result \
+JW07022A.mp3.result \
+escapevel.result \
+fit-map-data.result \
+gedcom.result \
+hddrawcopytool.result \
+issue311docx.result \
+issue359xlsx.result \
+json1.result \
+json2.result \
+json3.result \
+regex-eol.result \
+zstd-3-skippable-frames.result \
+zstd-dictionary-0.result \
+zstd-dictionary-1.result \
+zstd-dictionary-2.result \
+zstd-skippable-frame-0.result \
+zstd-skippable-frame-4.result \
+zstd-skippable-frame-8.result \
+zstd-skippable-frame-C.result \
+zstd-v0.2-FF.result \
+zstd-v0.3-FF.result \
+zstd-v0.4-FF.result \
+zstd-v0.5-FF.result \
+zstd-v0.6-FF.result \
+zstd-v0.7-00.result \
+zstd-v0.7-21.result \
+zstd-v0.7-22.result \
+zstd-v0.8-00.result \
+zstd-v0.8-01.result \
+zstd-v0.8-02.result \
+zstd-v0.8-03.result \
+zstd-v0.8-16.result \
+zstd-v0.8-20.result \
+zstd-v0.8-21.result \
+zstd-v0.8-22.result \
+zstd-v0.8-23.result \
+zstd-v0.8-F4.result \
+zstd-v0.8-FF.result
+
+T = $(top_srcdir)/tests
+check-local:
+       MAGIC=$(top_builddir)/magic/magic ./test
+       set -e; \
+       for i in $T/*.testfile; do \
+               echo Running test: $$i; \
+               if [ -f $${i%%.testfile}.magic ]; then \
+                       m=$${i%%.testfile}.magic; \
+               else \
+                       m=$(top_builddir)/magic/magic; \
+               fi; \
+               TZ=UTC MAGIC=$$m ./test $$i $${i%%.testfile}.result; \
+       done
diff --git a/tests/README b/tests/README
new file mode 100644 (file)
index 0000000..5826773
--- /dev/null
@@ -0,0 +1,14 @@
+file tests
+==========
+
+This directory contains tests for file. It is highly encouraged to add
+one each time a bug is found, and each time new magic is added. Each
+test consists of two files:
+
+  TEST.testfile
+  TEST.result
+
+where TEST is the base name of the test, TEST.testfile is the input,
+and TEST.result is the desired output from file.
+
+To add a new test just add the test files to the directory.
diff --git a/tests/escapevel.result b/tests/escapevel.result
new file mode 100644 (file)
index 0000000..c0a265c
--- /dev/null
@@ -0,0 +1 @@
+Zip data (MIME type "application/vnd.nz.gen.geek_central.ti5x"?)
\ No newline at end of file
diff --git a/tests/escapevel.testfile b/tests/escapevel.testfile
new file mode 100644 (file)
index 0000000..2857260
Binary files /dev/null and b/tests/escapevel.testfile differ
diff --git a/tests/fit-map-data.result b/tests/fit-map-data.result
new file mode 100644 (file)
index 0000000..0dbbb1b
--- /dev/null
@@ -0,0 +1 @@
+FIT Map data, unit id 65536, serial 3879446968, Sat May 31 10:00:34 2014, manufacturer 1 (garmin), product 1632, type 4 (Activity)
\ No newline at end of file
diff --git a/tests/fit-map-data.testfile b/tests/fit-map-data.testfile
new file mode 100644 (file)
index 0000000..4f1d46a
Binary files /dev/null and b/tests/fit-map-data.testfile differ
diff --git a/tests/gedcom.result b/tests/gedcom.result
new file mode 100644 (file)
index 0000000..1fd8161
--- /dev/null
@@ -0,0 +1 @@
+GEDCOM genealogy text version 5.5, ASCII text
\ No newline at end of file
diff --git a/tests/gedcom.testfile b/tests/gedcom.testfile
new file mode 100644 (file)
index 0000000..3d9607e
--- /dev/null
@@ -0,0 +1,8 @@
+0 HEAD
+1 SOUR GENJ
+2 VERS 2.x
+1 GEDC
+2 VERS 5.5
+2 FORM Lineage-Linked
+1 CHAR UNICODE
+1 LANG Italian
diff --git a/tests/hddrawcopytool.result b/tests/hddrawcopytool.result
new file mode 100644 (file)
index 0000000..0fe077d
--- /dev/null
@@ -0,0 +1 @@
+HDD Raw Copy Tool 1.10 - HD model: ST500DM0 02-1BD142 serial: 51D20233A7C0
\ No newline at end of file
diff --git a/tests/hddrawcopytool.testfile b/tests/hddrawcopytool.testfile
new file mode 100644 (file)
index 0000000..36ad7c6
Binary files /dev/null and b/tests/hddrawcopytool.testfile differ
diff --git a/tests/issue311docx.result b/tests/issue311docx.result
new file mode 100644 (file)
index 0000000..646ee85
--- /dev/null
@@ -0,0 +1 @@
+Microsoft Word 2007+
\ No newline at end of file
diff --git a/tests/issue311docx.testfile b/tests/issue311docx.testfile
new file mode 100644 (file)
index 0000000..e4328ec
Binary files /dev/null and b/tests/issue311docx.testfile differ
diff --git a/tests/issue359xlsx.result b/tests/issue359xlsx.result
new file mode 100644 (file)
index 0000000..d1e15b4
--- /dev/null
@@ -0,0 +1 @@
+Microsoft Excel 2007+
\ No newline at end of file
diff --git a/tests/issue359xlsx.testfile b/tests/issue359xlsx.testfile
new file mode 100644 (file)
index 0000000..9d751c4
Binary files /dev/null and b/tests/issue359xlsx.testfile differ
diff --git a/tests/json1.result b/tests/json1.result
new file mode 100644 (file)
index 0000000..01442dc
--- /dev/null
@@ -0,0 +1 @@
+JSON data
\ No newline at end of file
diff --git a/tests/json1.testfile b/tests/json1.testfile
new file mode 100644 (file)
index 0000000..3fb5760
--- /dev/null
@@ -0,0 +1,14 @@
+      {
+        "Image": {
+            "Width":  800,
+            "Height": 600,
+            "Title":  "View from 15th Floor",
+            "Thumbnail": {
+                "Url":    "http://www.example.com/image/481989943",
+                "Height": 125,
+                "Width":  100
+            },
+            "Animated" : false,
+            "IDs": [116, 943, 234, 38793]
+          }
+      }
diff --git a/tests/json2.result b/tests/json2.result
new file mode 100644 (file)
index 0000000..01442dc
--- /dev/null
@@ -0,0 +1 @@
+JSON data
\ No newline at end of file
diff --git a/tests/json2.testfile b/tests/json2.testfile
new file mode 100644 (file)
index 0000000..669007a
--- /dev/null
@@ -0,0 +1,22 @@
+  [
+        {
+           "precision": "zip",
+           "Latitude":  37.7668,
+           "Longitude": -122.3959,
+           "Address":   "",
+           "City":      "SAN FRANCISCO",
+           "State":     "CA",
+           "Zip":       "94107",
+           "Country":   "US"
+        },
+        {
+           "precision": "zip",
+           "Latitude":  37.371991,
+           "Longitude": -122.026020,
+           "Address":   "",
+           "City":      "SUNNYVALE",
+           "State":     "CA",
+           "Zip":       "94085",
+           "Country":   "US"
+        }
+      ]
diff --git a/tests/json3.result b/tests/json3.result
new file mode 100644 (file)
index 0000000..01442dc
--- /dev/null
@@ -0,0 +1 @@
+JSON data
\ No newline at end of file
diff --git a/tests/json3.testfile b/tests/json3.testfile
new file mode 100644 (file)
index 0000000..9f31ac1
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "abc": "edf",
+    "json": "crab",
+    "ololo": [
+        1,
+        2,
+        3
+    ],
+    "subcrab": {
+        "name": "crab",
+        "surname": "subcrab"
+    }
+}
diff --git a/tests/regex-eol.magic b/tests/regex-eol.magic
new file mode 100644 (file)
index 0000000..883d74c
--- /dev/null
@@ -0,0 +1,6 @@
+## Ansible Vault files
+0     string    $ANSIBLE_VAULT     Ansible Vault text
+>&1   regex/1l  [0-9]+(\.[0-9]+)+  \b, version %s
+>>&1  regex/1l  [^;]+$             \b, using %s encryption
+!:mime application/ansible-vault
+!:strength +60
diff --git a/tests/regex-eol.result b/tests/regex-eol.result
new file mode 100644 (file)
index 0000000..5b1a7db
--- /dev/null
@@ -0,0 +1 @@
+Ansible Vault text, version 1.1, using AES256 encryption
\ No newline at end of file
diff --git a/tests/regex-eol.testfile b/tests/regex-eol.testfile
new file mode 100644 (file)
index 0000000..607a852
--- /dev/null
@@ -0,0 +1,24 @@
+$ANSIBLE_VAULT;1.1;AES256
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000
diff --git a/tests/test.c b/tests/test.c
new file mode 100644 (file)
index 0000000..330a357
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) Christos Zoulas 2003.
+ * All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice immediately at the beginning of the file, without modification,
+ *    this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "magic.h"
+
+static void *
+xrealloc(void *p, size_t n)
+{
+       p = realloc(p, n);
+       if (p == NULL) {
+               (void)fprintf(stderr, "ERROR slurping file: out of memory\n");
+               exit(10);
+       }
+       return p;
+}
+
+static char *
+slurp(FILE *fp, size_t *final_len)
+{
+       size_t len = 256;
+       int c;
+       char *l = (char *)xrealloc(NULL, len), *s = l;
+
+       for (c = getc(fp); c != EOF; c = getc(fp)) {
+               if (s == l + len) {
+                       l = (char *)xrealloc(l, len * 2);
+                       len *= 2;
+               }
+               *s++ = c;
+       }
+       if (s == l + len)
+               l = (char *)xrealloc(l, len + 1);
+       *s++ = '\0';
+
+       *final_len = s - l;
+       l = (char *)xrealloc(l, s - l);
+       return l;
+}
+
+int
+main(int argc, char **argv)
+{
+       struct magic_set *ms;
+       const char *result;
+       char *desired;
+       size_t desired_len;
+       int i;
+       FILE *fp;
+
+       ms = magic_open(MAGIC_NONE);
+       if (ms == NULL) {
+               (void)fprintf(stderr, "ERROR opening MAGIC_NONE: out of memory\n");
+               return 10;
+       }
+       if (magic_load(ms, NULL) == -1) {
+               (void)fprintf(stderr, "ERROR loading with NULL file: %s\n",
+                   magic_error(ms));
+               return 11;
+       }
+
+       if (argc > 1) {
+               if (argc != 3) {
+                       (void)fprintf(stderr, "Usage: test TEST-FILE RESULT\n");
+               } else {
+                       if ((result = magic_file(ms, argv[1])) == NULL) {
+                               (void)fprintf(stderr, "ERROR loading file %s: %s\n", argv[1], magic_error(ms));
+                               return 12;
+                       } else {
+                               fp = fopen(argv[2], "r");
+                               if (fp == NULL) {
+                                       (void)fprintf(stderr, "ERROR opening `%s': ", argv[2]);
+                                       perror(NULL);
+                                       return 13;
+                               }
+                               desired = slurp(fp, &desired_len);
+                               fclose(fp);
+                               (void)printf("%s: %s\n", argv[1], result);
+                                if (strcmp(result, desired) != 0) {
+                                       (void)fprintf(stderr, "Error: result was\n%s\nexpected:\n%s\n", result, desired);
+                                       return 1;
+                                }
+                       }
+               }
+       }
+
+       magic_close(ms);
+       return 0;
+}
diff --git a/tests/zstd-3-skippable-frames.result b/tests/zstd-3-skippable-frames.result
new file mode 100644 (file)
index 0000000..468070c
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 1
\ No newline at end of file
diff --git a/tests/zstd-dictionary-0.result b/tests/zstd-dictionary-0.result
new file mode 100644 (file)
index 0000000..e1b9c62
--- /dev/null
@@ -0,0 +1 @@
+Zstandard dictionary (ID 0)
\ No newline at end of file
diff --git a/tests/zstd-dictionary-1.result b/tests/zstd-dictionary-1.result
new file mode 100644 (file)
index 0000000..dd9f5f1
--- /dev/null
@@ -0,0 +1 @@
+Zstandard dictionary (ID 1)
\ No newline at end of file
diff --git a/tests/zstd-dictionary-2.result b/tests/zstd-dictionary-2.result
new file mode 100644 (file)
index 0000000..e1ac5b3
--- /dev/null
@@ -0,0 +1 @@
+Zstandard dictionary (ID 285212672)
\ No newline at end of file
diff --git a/tests/zstd-skippable-frame-0.result b/tests/zstd-skippable-frame-0.result
new file mode 100644 (file)
index 0000000..a4e3e48
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.2)
\ No newline at end of file
diff --git a/tests/zstd-skippable-frame-4.result b/tests/zstd-skippable-frame-4.result
new file mode 100644 (file)
index 0000000..cecb5e7
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.3)
\ No newline at end of file
diff --git a/tests/zstd-skippable-frame-8.result b/tests/zstd-skippable-frame-8.result
new file mode 100644 (file)
index 0000000..528f701
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.4)
\ No newline at end of file
diff --git a/tests/zstd-skippable-frame-C.result b/tests/zstd-skippable-frame-C.result
new file mode 100644 (file)
index 0000000..468070c
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 1
\ No newline at end of file
diff --git a/tests/zstd-v0.2-FF.result b/tests/zstd-v0.2-FF.result
new file mode 100644 (file)
index 0000000..a4e3e48
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.2)
\ No newline at end of file
diff --git a/tests/zstd-v0.2-FF.testfile b/tests/zstd-v0.2-FF.testfile
new file mode 100644 (file)
index 0000000..6fe4f27
--- /dev/null
@@ -0,0 +1 @@
+"µ/ýÿ\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.3-FF.result b/tests/zstd-v0.3-FF.result
new file mode 100644 (file)
index 0000000..cecb5e7
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.3)
\ No newline at end of file
diff --git a/tests/zstd-v0.3-FF.testfile b/tests/zstd-v0.3-FF.testfile
new file mode 100644 (file)
index 0000000..dc50469
--- /dev/null
@@ -0,0 +1 @@
+#µ/ýÿ\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.4-FF.result b/tests/zstd-v0.4-FF.result
new file mode 100644 (file)
index 0000000..528f701
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.4)
\ No newline at end of file
diff --git a/tests/zstd-v0.4-FF.testfile b/tests/zstd-v0.4-FF.testfile
new file mode 100644 (file)
index 0000000..f2768a2
--- /dev/null
@@ -0,0 +1 @@
+$µ/ýÿ\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.5-FF.result b/tests/zstd-v0.5-FF.result
new file mode 100644 (file)
index 0000000..815c80d
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.5)
\ No newline at end of file
diff --git a/tests/zstd-v0.5-FF.testfile b/tests/zstd-v0.5-FF.testfile
new file mode 100644 (file)
index 0000000..a25f337
--- /dev/null
@@ -0,0 +1 @@
+%µ/ýÿ\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.6-FF.result b/tests/zstd-v0.6-FF.result
new file mode 100644 (file)
index 0000000..b28af6b
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.6)
\ No newline at end of file
diff --git a/tests/zstd-v0.6-FF.testfile b/tests/zstd-v0.6-FF.testfile
new file mode 100644 (file)
index 0000000..1c8ca59
--- /dev/null
@@ -0,0 +1 @@
+&µ/ýÿ\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.7-00.result b/tests/zstd-v0.7-00.result
new file mode 100644 (file)
index 0000000..72e0e27
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.7), Dictionary ID: None
\ No newline at end of file
diff --git a/tests/zstd-v0.7-21.result b/tests/zstd-v0.7-21.result
new file mode 100644 (file)
index 0000000..a4d43c8
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.7), Dictionary ID: 1
\ No newline at end of file
diff --git a/tests/zstd-v0.7-21.testfile b/tests/zstd-v0.7-21.testfile
new file mode 100644 (file)
index 0000000..b40294e
--- /dev/null
@@ -0,0 +1 @@
+'µ/ý!\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.7-22.result b/tests/zstd-v0.7-22.result
new file mode 100644 (file)
index 0000000..b4336c9
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.7), Dictionary ID: 513
\ No newline at end of file
diff --git a/tests/zstd-v0.7-22.testfile b/tests/zstd-v0.7-22.testfile
new file mode 100644 (file)
index 0000000..8b72d68
--- /dev/null
@@ -0,0 +1 @@
+'µ/ý"\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-00.result b/tests/zstd-v0.8-00.result
new file mode 100644 (file)
index 0000000..67edebd
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: None
\ No newline at end of file
diff --git a/tests/zstd-v0.8-01.result b/tests/zstd-v0.8-01.result
new file mode 100644 (file)
index 0000000..a1239a7
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 2
\ No newline at end of file
diff --git a/tests/zstd-v0.8-01.testfile b/tests/zstd-v0.8-01.testfile
new file mode 100644 (file)
index 0000000..88735e4
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý\ 1\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-02.result b/tests/zstd-v0.8-02.result
new file mode 100644 (file)
index 0000000..82beab8
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 770
\ No newline at end of file
diff --git a/tests/zstd-v0.8-02.testfile b/tests/zstd-v0.8-02.testfile
new file mode 100644 (file)
index 0000000..db55433
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý\ 2\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-03.result b/tests/zstd-v0.8-03.result
new file mode 100644 (file)
index 0000000..6aaaa19
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 84148994
\ No newline at end of file
diff --git a/tests/zstd-v0.8-03.testfile b/tests/zstd-v0.8-03.testfile
new file mode 100644 (file)
index 0000000..506b344
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý\ 3\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-16.result b/tests/zstd-v0.8-16.result
new file mode 100644 (file)
index 0000000..82beab8
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 770
\ No newline at end of file
diff --git a/tests/zstd-v0.8-16.testfile b/tests/zstd-v0.8-16.testfile
new file mode 100644 (file)
index 0000000..3f87f79
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý\16\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-20.result b/tests/zstd-v0.8-20.result
new file mode 100644 (file)
index 0000000..67edebd
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: None
\ No newline at end of file
diff --git a/tests/zstd-v0.8-20.testfile b/tests/zstd-v0.8-20.testfile
new file mode 100644 (file)
index 0000000..76fdbb8
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý \ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-21.result b/tests/zstd-v0.8-21.result
new file mode 100644 (file)
index 0000000..468070c
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 1
\ No newline at end of file
diff --git a/tests/zstd-v0.8-21.testfile b/tests/zstd-v0.8-21.testfile
new file mode 100644 (file)
index 0000000..9ebeff4
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý!\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-22.result b/tests/zstd-v0.8-22.result
new file mode 100644 (file)
index 0000000..9869d24
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 513
\ No newline at end of file
diff --git a/tests/zstd-v0.8-22.testfile b/tests/zstd-v0.8-22.testfile
new file mode 100644 (file)
index 0000000..f2e55bf
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý"\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-23.result b/tests/zstd-v0.8-23.result
new file mode 100644 (file)
index 0000000..d38420f
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 67305985
\ No newline at end of file
diff --git a/tests/zstd-v0.8-23.testfile b/tests/zstd-v0.8-23.testfile
new file mode 100644 (file)
index 0000000..f66a18f
--- /dev/null
@@ -0,0 +1 @@
+(µ/ý#\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-F4.result b/tests/zstd-v0.8-F4.result
new file mode 100644 (file)
index 0000000..67edebd
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: None
\ No newline at end of file
diff --git a/tests/zstd-v0.8-F4.testfile b/tests/zstd-v0.8-F4.testfile
new file mode 100644 (file)
index 0000000..a4e4240
--- /dev/null
@@ -0,0 +1 @@
+(µ/ýô\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/tests/zstd-v0.8-FF.result b/tests/zstd-v0.8-FF.result
new file mode 100644 (file)
index 0000000..d38420f
--- /dev/null
@@ -0,0 +1 @@
+Zstandard compressed data (v0.8+), Dictionary ID: 67305985
\ No newline at end of file
diff --git a/tests/zstd-v0.8-FF.testfile b/tests/zstd-v0.8-FF.testfile
new file mode 100644 (file)
index 0000000..bc63911
--- /dev/null
@@ -0,0 +1 @@
+(µ/ýÿ\ 1\ 2\ 3\ 4\ 5
\ No newline at end of file
diff --git a/visibility.m4 b/visibility.m4
new file mode 100644 (file)
index 0000000..7b24d39
--- /dev/null
@@ -0,0 +1,77 @@
+# visibility.m4 serial 4 (gettext-0.18.2)
+dnl Copyright (C) 2005, 2008, 2010-2012 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl Tests whether the compiler supports the command-line option
+dnl -fvisibility=hidden and the function and variable attributes
+dnl __attribute__((__visibility__("hidden"))) and
+dnl __attribute__((__visibility__("default"))).
+dnl Does *not* test for __visibility__("protected") - which has tricky
+dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on
+dnl MacOS X.
+dnl Does *not* test for __visibility__("internal") - which has processor
+dnl dependent semantics.
+dnl Does *not* test for #pragma GCC visibility push(hidden) - which is
+dnl "really only recommended for legacy code".
+dnl Set the variable CFLAG_VISIBILITY.
+dnl Defines and sets the variable HAVE_VISIBILITY.
+
+AC_DEFUN([gl_VISIBILITY],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  CFLAG_VISIBILITY=
+  HAVE_VISIBILITY=0
+  if test -n "$GCC"; then
+    dnl First, check whether -Werror can be added to the command line, or
+    dnl whether it leads to an error because of some other option that the
+    dnl user has put into $CC $CFLAGS $CPPFLAGS.
+    AC_MSG_CHECKING([whether the -Werror option is usable])
+    AC_CACHE_VAL([gl_cv_cc_vis_werror], [
+      gl_save_CFLAGS="$CFLAGS"
+      CFLAGS="$CFLAGS -Werror"
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM([[]], [[]])],
+        [gl_cv_cc_vis_werror=yes],
+        [gl_cv_cc_vis_werror=no])
+      CFLAGS="$gl_save_CFLAGS"])
+    AC_MSG_RESULT([$gl_cv_cc_vis_werror])
+    dnl Now check whether visibility declarations are supported.
+    AC_MSG_CHECKING([for simple visibility declarations])
+    AC_CACHE_VAL([gl_cv_cc_visibility], [
+      gl_save_CFLAGS="$CFLAGS"
+      CFLAGS="$CFLAGS -fvisibility=hidden"
+      dnl We use the option -Werror and a function dummyfunc, because on some
+      dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
+      dnl "visibility attribute not supported in this configuration; ignored"
+      dnl at the first function definition in every compilation unit, and we
+      dnl don't want to use the option in this case.
+      if test $gl_cv_cc_vis_werror = yes; then
+        CFLAGS="$CFLAGS -Werror"
+      fi
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
+             extern __attribute__((__visibility__("default"))) int exportedvar;
+             extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
+             extern __attribute__((__visibility__("default"))) int exportedfunc (void);
+             void dummyfunc (void) {}
+           ]],
+           [[]])],
+        [gl_cv_cc_visibility=yes],
+        [gl_cv_cc_visibility=no])
+      CFLAGS="$gl_save_CFLAGS"])
+    AC_MSG_RESULT([$gl_cv_cc_visibility])
+    if test $gl_cv_cc_visibility = yes; then
+      CFLAG_VISIBILITY="-fvisibility=hidden"
+      HAVE_VISIBILITY=1
+    fi
+  fi
+  AC_SUBST([CFLAG_VISIBILITY])
+  AC_SUBST([HAVE_VISIBILITY])
+  AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY],
+    [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.])
+])