summaryrefslogtreecommitdiffstats
path: root/contrib/file
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2007-05-24 21:59:38 +0000
committerobrien <obrien@FreeBSD.org>2007-05-24 21:59:38 +0000
commit240c77918bbcf0d5f67799916b808b8a65d434c5 (patch)
treef1050a93b4cf4d5e56408bc87c1da5741ccf4e65 /contrib/file
parent09615277daeb6e2f432f5fd5dbc254e4b0428f99 (diff)
downloadFreeBSD-src-240c77918bbcf0d5f67799916b808b8a65d434c5.zip
FreeBSD-src-240c77918bbcf0d5f67799916b808b8a65d434c5.tar.gz
Virgin import of Christos Zoulas's FILE 4.21.
Diffstat (limited to 'contrib/file')
-rw-r--r--contrib/file/ChangeLog105
-rw-r--r--contrib/file/FREEBSD-upgrade20
-rw-r--r--contrib/file/LEGAL.NOTICE2
-rw-r--r--contrib/file/Localstuff2
-rw-r--r--contrib/file/MAINT12
-rw-r--r--contrib/file/Magdir/animation6
-rw-r--r--contrib/file/Magdir/archive10
-rw-r--r--contrib/file/Magdir/audio19
-rw-r--r--contrib/file/Magdir/c-lang4
-rw-r--r--contrib/file/Magdir/commands2
-rw-r--r--contrib/file/Magdir/console26
-rw-r--r--contrib/file/Magdir/database4
-rw-r--r--contrib/file/Magdir/editors3
-rw-r--r--contrib/file/Magdir/elf4
-rw-r--r--contrib/file/Magdir/filesystems394
-rw-r--r--contrib/file/Magdir/fonts3
-rw-r--r--contrib/file/Magdir/images7
-rw-r--r--contrib/file/Magdir/linux10
-rw-r--r--contrib/file/Magdir/lisp14
-rw-r--r--contrib/file/Magdir/mathematica2
-rw-r--r--contrib/file/Magdir/mime2
-rw-r--r--contrib/file/Magdir/mips4
-rw-r--r--contrib/file/Magdir/misctools4
-rw-r--r--contrib/file/Magdir/msdos9
-rw-r--r--contrib/file/Magdir/os22
-rw-r--r--contrib/file/Magdir/os40049
-rw-r--r--contrib/file/Magdir/perl16
-rw-r--r--contrib/file/Magdir/revision6
-rw-r--r--contrib/file/Magdir/sgml3
-rw-r--r--contrib/file/Magdir/sql19
-rw-r--r--contrib/file/Magdir/tex28
-rw-r--r--contrib/file/Magdir/tgif2
-rw-r--r--contrib/file/Magdir/varied.out6
-rw-r--r--contrib/file/Magdir/varied.script2
-rw-r--r--contrib/file/Magdir/wordprocessors2
-rw-r--r--contrib/file/README2
-rw-r--r--contrib/file/apprentice.c547
-rw-r--r--contrib/file/apptype.c2
-rw-r--r--contrib/file/ascmagic.c25
-rw-r--r--contrib/file/compress.c45
-rw-r--r--contrib/file/config.h.in9
-rwxr-xr-xcontrib/file/configure11
-rw-r--r--contrib/file/configure.in8
-rw-r--r--contrib/file/file.c46
-rw-r--r--contrib/file/file.h236
-rw-r--r--contrib/file/fsmagic.c2
-rw-r--r--contrib/file/funcs.c166
-rw-r--r--contrib/file/is_tar.c2
-rw-r--r--contrib/file/magic.c45
-rw-r--r--contrib/file/magic.h31
-rw-r--r--contrib/file/magic.mime25
-rwxr-xr-xcontrib/file/magic2mime2
-rw-r--r--contrib/file/names.h4
-rw-r--r--contrib/file/patchlevel.h13
-rw-r--r--contrib/file/print.c58
-rw-r--r--contrib/file/readelf.c8
-rw-r--r--contrib/file/softmagic.c744
-rw-r--r--contrib/file/tar.h72
-rw-r--r--contrib/file/test.c8
59 files changed, 1959 insertions, 955 deletions
diff --git a/contrib/file/ChangeLog b/contrib/file/ChangeLog
index 8c58f74..e2c8418 100644
--- a/contrib/file/ChangeLog
+++ b/contrib/file/ChangeLog
@@ -1,3 +1,108 @@
+2007-05-24 10:00 Christos Zoulas <christos@zoulas.com>
+
+ * Fix another integer overflow (Colin Percival)
+
+2007-03-26 13:58 Christos Zoulas <christos@zoulas.com>
+
+ * make sure that all of struct magic_set is initialized appropriately
+ (Brett)
+
+2007-03-25 17:44 Christos Zoulas <christos@zoulas.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@zoulas.com>
+
+ * fix fortran and nroff reversed tests (Dmitry V. Levin)
+
+ * fix exclude option (Dmitry V. Levin)
+
+2007-02-08 17:30 Christos Zoulas <christos@zoulas.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@zoulas.com>
+
+ * make socket/pipe reading more robust
+
+2007-01-25 16:01 Christos Zoulas <christos@zoulas.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@zoulas.com>
* fix byteswapping issue
diff --git a/contrib/file/FREEBSD-upgrade b/contrib/file/FREEBSD-upgrade
index f86aad8..f6657bc 100644
--- a/contrib/file/FREEBSD-upgrade
+++ b/contrib/file/FREEBSD-upgrade
@@ -6,13 +6,25 @@ Christos Zoulas `file'
Imported by:
- cvs import -m 'Virgin import of Christos Zoulas's FILE 3.33.' \
- src/contrib/file ZOULAS file_3_33
+ mv magic/* .
+ rmdir magic
+ mv -i src/* .
+ rm -rf src
+ mv -i doc/* .
+ rm -rf doc
+ rm -rf python
+ rm -f lt*
+ rm -f missing depcomp
+ rm -f config.{guess,sub}
+
+ cvs import -m "Virgin import of Christos Zoulas's FILE 4.21." \
+ src/contrib/file ZOULAS file_4_21
Never make local changes to ZOULAS `file'. Christos is very willing to
work with us to meet our FreeBSD needs. Thus submit any desired changes
-to him <> and wait for the next release and vendor import to get them.
+to him <christos@zoulas.com> and wait for the next release and vendor
+import to get them.
obrien@NUXI.com
-24-November-2000
+15-Sept-2002
diff --git a/contrib/file/LEGAL.NOTICE b/contrib/file/LEGAL.NOTICE
index d1ea556..68148e2 100644
--- a/contrib/file/LEGAL.NOTICE
+++ b/contrib/file/LEGAL.NOTICE
@@ -1,4 +1,4 @@
-$Id: LEGAL.NOTICE,v 1.15 2006/05/03 18:48:33 christos Exp $
+$File: LEGAL.NOTICE,v 1.15 2006/05/03 18:48:33 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.
diff --git a/contrib/file/Localstuff b/contrib/file/Localstuff
index 914d449..419855f 100644
--- a/contrib/file/Localstuff
+++ b/contrib/file/Localstuff
@@ -2,6 +2,6 @@
#------------------------------------------------------------------------------
# Localstuff: file(1) magic for locally observed files
#
-# $Id: Localstuff,v 1.4 2003/03/23 04:17:27 christos Exp $
+# $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/contrib/file/MAINT b/contrib/file/MAINT
index 2a51470..077f9d6 100644
--- a/contrib/file/MAINT
+++ b/contrib/file/MAINT
@@ -1,20 +1,10 @@
-$Id: MAINT,v 1.7 2006/06/01 18:19:41 ian Exp $
+$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:
-- Don't change the version numbers!
-
-If your changes are extensive, I will have to work hard to
-integrate them into my version. If you check it into SCCS locally,
-the version numbers will likely be kept. IF you check it into RCS
-or CVS locally, please use -k to keep the version numbers, and
-please use branch deltas (1.21.1, 1.21.2, ...). If you don't do
-this, I will likely be unable to use your changes; life's just too
-short.
-
- Do not distribute changed versions.
People trying to be helpful occasionally put up their hacked versions
diff --git a/contrib/file/Magdir/animation b/contrib/file/Magdir/animation
index 95c842e..b2cdd74 100644
--- a/contrib/file/Magdir/animation
+++ b/contrib/file/Magdir/animation
@@ -320,11 +320,11 @@
#>3 byte&0x03 3 \b, NR: CCIT J.17
# MPA, M1A
-# modified by Joerg Jenderek
+# updated by Joerg Jenderek
# GRR the original test are too common for many DOS files, so test 32 <= kbits <= 448
0 beshort&0xFFFE 0xFFFE
->2 byte&0xF0 >0x0F
->>2 byte&0xF0 <0xE1 MPEG ADTS, layer I, v1
+>2 ubyte&0xF0 >0x0F
+>>2 ubyte&0xF0 <0xE1 MPEG ADTS, layer I, v1
# rate
>>>2 byte&0xF0 0x10 \b, 32 kBits
>>>2 byte&0xF0 0x20 \b, 64 kBits
diff --git a/contrib/file/Magdir/archive b/contrib/file/Magdir/archive
index e110fd4..6aed3c8 100644
--- a/contrib/file/Magdir/archive
+++ b/contrib/file/Magdir/archive
@@ -478,7 +478,7 @@
0 string HPAK HPACK archive data
# JAM Archive volume format, by Dmitry.Kohmanyuk@UA.net
-0 string \351,\001JAM\ JAM archive,
+0 string \351,\001JAM\ JAM archive,
>7 string >\0 version %.4s
>0x26 byte =0x27 -
>>0x2b string >\0 label %.11s,
@@ -723,3 +723,11 @@
>14 byte 0x54 end slice
>14 beshort 0x4e4e multi-part
>14 beshort 0x4e53 multi-part, with -S
+
+# Symbian installation files
+# http://www.thouky.co.uk/software/psifs/sis.html
+# http://developer.symbian.com/main/downloads/papers/SymbianOSv91/softwareinstallsis.pdf
+8 lelong 0x10000419 Symbian installation file
+>4 lelong 0x1000006D (EPOC release 3/4/5)
+>4 lelong 0x10003A12 (EPOC release 6)
+0 lelong 0x10201A7A Symbian installation file (Symbian OS 9.x)
diff --git a/contrib/file/Magdir/audio b/contrib/file/Magdir/audio
index fd9d771..e199988 100644
--- a/contrib/file/Magdir/audio
+++ b/contrib/file/Magdir/audio
@@ -500,13 +500,13 @@
# 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
+0 string [Equalizer\ preset] XMMS equalizer preset
# .m3u
-0 string \#EXTM3U M3U playlist
+0 string #EXTM3U M3U playlist
# .pls
-0 string \[playlist\] PLS playlist
+0 string [playlist] PLS playlist
# licq.conf
-1 string \[licq\] LICQ configuration file
+1 string [licq] LICQ configuration file
# Atari ST audio files by Dirk Jagdmann <doj@cubic.org>
0 string ICE! SNDH Atari ST music
@@ -545,3 +545,14 @@
>>27 byte 113 \b, Alpha 1.13
>>27 byte 114 \b, Beta 1.14
>>27 byte 115 \b, Alpha 1.15
+
+# IMY
+# from http://filext.com/detaillist.php?extdetail=IMY
+# http://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: Matthew Flaschen <matthew.flaschen@gatech.edu>
+0 string #EXTM3U M3U playlist text
+
diff --git a/contrib/file/Magdir/c-lang b/contrib/file/Magdir/c-lang
index 1dcf636..fd3f9aa 100644
--- a/contrib/file/Magdir/c-lang
+++ b/contrib/file/Magdir/c-lang
@@ -20,5 +20,5 @@
# The inverted index functionality was added some time betwen
# versions 11 and 15, so look for -q if version is above 14:
>7 string >14
->>10 regex .+\ -q\ with inverted index
->10 regex .+\ -c\ text (non-compressed)
+>>10 regex .+\ -q\ with inverted index
+>10 regex .+\ -c\ text (non-compressed)
diff --git a/contrib/file/Magdir/commands b/contrib/file/Magdir/commands
index 2bdffbe..288d3cd 100644
--- a/contrib/file/Magdir/commands
+++ b/contrib/file/Magdir/commands
@@ -53,4 +53,4 @@
0 string Zend\x00 PHP script Zend Optimizer data
-0 string \$! DCL command file
+0 string $! DCL command file
diff --git a/contrib/file/Magdir/console b/contrib/file/Magdir/console
index 65fe327..40a3c2e 100644
--- a/contrib/file/Magdir/console
+++ b/contrib/file/Magdir/console
@@ -165,3 +165,29 @@
# From: Serge van den Boom <svdb@stack.nl>
0 string \x01ZZZZZ\x01 3DO "Opera" file system
+# From Gürkan Sengün <gurkan@linuks.mine.nu>, www.linuks.mine.nu
+0 string GBS Nintendo Gameboy Music/Audio Data
+12 string GameBoy\ Music\ Module Nintendo Gameboy Music Module
+
+# 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
diff --git a/contrib/file/Magdir/database b/contrib/file/Magdir/database
index b2f68d9..aef8469 100644
--- a/contrib/file/Magdir/database
+++ b/contrib/file/Magdir/database
@@ -210,7 +210,3 @@
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
-
-# SQLite (Ty Sarna)
-0 string **\ This\ file\ contains\ an\ SQLite SQLite Database
->&1 regex [^\ ]+ Version %s
diff --git a/contrib/file/Magdir/editors b/contrib/file/Magdir/editors
index 02826fa..0b15bf8 100644
--- a/contrib/file/Magdir/editors
+++ b/contrib/file/Magdir/editors
@@ -13,4 +13,5 @@
0 string VimCrypt~ Vim encrypted file data
# Vi IMproved Swap file
# by Sven Wegener <swegener@gentoo.org>
-0 string b0VIM\ Vim swap file, version %s
+0 string b0VIM\ Vim swap file
+>&0 string >\0 \b, version %s
diff --git a/contrib/file/Magdir/elf b/contrib/file/Magdir/elf
index 6c9976f..52b5e4c 100644
--- a/contrib/file/Magdir/elf
+++ b/contrib/file/Magdir/elf
@@ -101,6 +101,7 @@
>>18 leshort 88 Renesas M32R,
>>18 leshort 94 Tensilica Xtensa,
>>18 leshort 97 NatSemi 32k,
+>>18 leshort 106 Analog Devices Blackfin,
>>18 leshort 0x9026 Alpha (unofficial),
>>20 lelong 0 invalid version
>>20 lelong 1 version 1
@@ -167,8 +168,9 @@
>>>36 belong&0xffff00 &0x000400 HaL R1 Extensions Required,
>>>36 belong&0xffff00 &0x000800 Sun UltraSPARC3 Extensions Required,
>>18 beshort 20 PowerPC or cisco 4500,
->>18 beshort 21 cisco 7500,
+>>18 beshort 21 64-bit PowerPC or cisco 7500,
>>18 beshort 22 IBM S/390,
+>>18 beshort 23 Cell SPU,
>>18 beshort 24 cisco SVIP,
>>18 beshort 25 cisco 7200,
>>18 beshort 36 NEC V800 or cisco 12000,
diff --git a/contrib/file/Magdir/filesystems b/contrib/file/Magdir/filesystems
index dd4910a..eadfeb3 100644
--- a/contrib/file/Magdir/filesystems
+++ b/contrib/file/Magdir/filesystems
@@ -5,22 +5,25 @@
0 string \366\366\366\366 PC formatted floppy with no filesystem
# Sun disk labels
# From /usr/include/sun/dklabel.h:
-0774 beshort 0xdabe 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 %ld,
->0770 long x %ld blocks
+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 %ld,
+>>0770 long x %ld 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 41 byte header + first sectors of disc
@@ -100,75 +103,140 @@
>>96 string read\ error\ while\ reading\ drive \b, FREE-DOS Beta 0.9 MBR
>271 string Operating\ system\ loading
>>296 string error\r \b, SYSLINUX MBR (2.10)
+# http://www.acronis.de/
+>362 string MBR\ Error\ \0\r
+>>376 string ress\ any\ key\ to\
+>>>392 string boot\ from\ floppy...\0 \b, Acronis MBR
+# added by Joerg Jenderek
+# http://www.visopsys.org/
+# http://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
->43 string SMART\ BTMGRFAT12\ \ \
->>430 string SBMK\ Bad!\r
->>>3 string SBM \b, Smart Boot Manager
->>>>6 string >\0 \b, version %s
+>0x40 string SBML
+# label with 11 characters of FAT 12 bit filesystem
+>>43 string SMART\ BTMGR
+>>>430 string SBMK\ Bad!\r
+>>>>3 string SBM \b, Smart Boot Manager
+>>>>>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
->402 string Geom\0Hard\ Disk\0Read\0\ Error\0
->>394 string stage1 \b, GRand Unified Bootloader (0.5.95)
->343 string Geom\0Read\0\ Error\0
->>321 string Loading\ stage1.5 \b, Grand Unified Bootloader
->380 string Geom\0Hard\ Disk\0Read\0\ Error\0
->>374 string GRUB\ \0 \b, GRand Unified Bootloader
->382 string Geom\0Hard\ Disk\0Read\0\ Error\0
->>376 string GRUB\ \0 \b, GRand Unified Bootloader (0.93)
->383 string Geom\0Hard\ Disk\0Read\0\ Error\0
->>377 string GRUB\ \0 \b, GRand Unified Bootloader (0.94)
->385 string Geom\0Hard\ Disk\0Read\0\ Error\0
->>379 string GRUB\ \0 \b, GRand Unified Bootloader (0.95)
+# updated by Joerg Jenderek
+# variables according to grub-0.97/stage1/stage1.S or
+# http://www.gnu.org/software/grub/manual/grub.html#Embedded-data
+# usual values are marked with comments to get only informations of strange GRUB loaders
+>0 ulelong 0x009048EB
+>>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
+#unkown 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
+# http://syslinux.zytor.com/
+>478 string Boot\ failed\r
+>>495 string LDLINUX\ SYS \b, SYSLINUX bootloader (1.62)
>480 string Boot\ failed\r
->>495 string LDLINUX\ SYS \b, SYSLINUX bootloader (2.06)
+>>495 string LDLINUX\ SYS \b, SYSLINUX bootloader (2.06 or 2.11)
+>484 string Boot\ error\r \b, SYSLINUX bootloader (3.11)
>395 string chksum\0\ ERROR!\0 \b, Gujin bootloader
-# mbr partion table entries, if not fat boot secor, activ flag 0 or 0x80 and type > 0
+# http://www.bcdwb.de/bcdw/index_e.htm
+>3 string BCDL
+>>498 string BCDL\ \ \ \ BIN \b, Bootable CD Loader (1.50Z)
+# mbr partion table entries
+# OEM-ID not Microsoft,SYSLINUX,or MTOOLs
>3 string !MS
>>3 string !SYSLINUX
->>>82 string !FAT32
->>>>446 ubyte <0x81
->>>>>446 ubyte&0x7F 0
->>>>>>450 ubyte >0 \b; partition 1: ID=0x%x
->>>>>>>446 ubyte 0x80 \b, active
->>>>>>>447 ubyte x \b, starthead %u
-#>>>>>>>448 ubyte x \b, start C_S: 0x%x
-#>>>>>>448 ubeshort&1023 x \b, startcylinder? %d
->>>>>>>454 ulelong x \b, startsector %u
->>>>>>>458 ulelong x \b, %u sectors
+>>>3 string !MTOOL
+# not FAT (32 bit)
+>>>>82 string !FAT32
+#not IO.SYS
+>>>>>472 string !IO\ \ \ \ \ \ SYS
+#not Linux kernel
+>>>>>>514 string !HdrS
+# active flag 0 or 0x80 and type > 0
+>>>>>>>446 ubyte <0x81
+>>>>>>>>446 ubyte&0x7F 0
+>>>>>>>>>>>450 ubyte >0 \b; partition 1: ID=0x%x
+>>>>>>>>>>446 ubyte 0x80 \b, active
+>>>>>>>>>>447 ubyte x \b, starthead %u
+#>>>>>>>>>>448 ubyte x \b, start C_S: 0x%x
+#>>>>>>>>>>448 ubeshort&1023 x \b, startcylinder? %d
+>>>>>>>>>>454 ulelong x \b, startsector %u
+>>>>>>>>>>458 ulelong x \b, %u sectors
#
->>>>462 ubyte <0x81
->>>>>462 ubyte&0x7F 0
->>>>>>466 ubyte >0 \b; partition 2: ID=0x%x
->>>>>>>462 ubyte 0x80 \b, active
->>>>>>>463 ubyte x \b, starthead %u
-#>>>>>>>464 ubyte x \b, start C_S: 0x%x
-#>>>>>>>464 ubeshort&1023 x \b, startcylinder? %d
->>>>>>>470 ulelong x \b, startsector %u
->>>>>>>474 ulelong x \b, %u sectors
+>>>>>>>462 ubyte <0x81
+>>>>>>>>462 ubyte&0x7F 0
+>>>>>>>>>466 ubyte >0 \b; partition 2: ID=0x%x
+>>>>>>>>>>462 ubyte 0x80 \b, active
+>>>>>>>>>>463 ubyte x \b, starthead %u
+#>>>>>>>>>>464 ubyte x \b, start C_S: 0x%x
+#>>>>>>>>>>464 ubeshort&1023 x \b, startcylinder? %d
+>>>>>>>>>>470 ulelong x \b, startsector %u
+>>>>>>>>>>474 ulelong x \b, %u sectors
#
->>>>478 ubyte <0x81
->>>>>478 ubyte&0x7F 0
->>>>>>482 ubyte >0 \b; partition 3: ID=0x%x
->>>>>>>478 ubyte 0x80 \b, active
->>>>>>>479 ubyte x \b, starthead %u
-#>>>>>>>480 ubyte x \b, start C_S: 0x%x
-#>>>>>>>481 ubyte x \b, start C2S: 0x%x
-#>>>>>>>480 ubeshort&1023 x \b, startcylinder? %d
->>>>>>>486 ulelong x \b, startsector %u
->>>>>>>490 ulelong x \b, %u sectors
+>>>>>>>478 ubyte <0x81
+>>>>>>>>478 ubyte&0x7F 0
+>>>>>>>>>482 ubyte >0 \b; partition 3: ID=0x%x
+>>>>>>>>>>478 ubyte 0x80 \b, active
+>>>>>>>>>>479 ubyte x \b, starthead %u
+#>>>>>>>>>>480 ubyte x \b, start C_S: 0x%x
+#>>>>>>>>>>481 ubyte x \b, start C2S: 0x%x
+#>>>>>>>>>>480 ubeshort&1023 x \b, startcylinder? %d
+>>>>>>>>>>486 ulelong x \b, startsector %u
+>>>>>>>>>>490 ulelong x \b, %u sectors
#
->>>>494 ubyte <0x81
->>>>>494 ubyte&0x7F 0
->>>>>>498 ubyte >0 \b; partition 4: ID=0x%x
->>>>>>>494 ubyte 0x80 \b, active
->>>>>>>495 ubyte x \b, starthead %u
-#>>>>>>>496 ubyte x \b, start C_S: 0x%x
-#>>>>>>>496 ubeshort&1023 x \b, startcylinder? %d
->>>>>>>502 ulelong x \b, startsector %u
->>>>>>>506 ulelong x \b, %u sectors
+>>>>>>>494 ubyte <0x81
+>>>>>>>>494 ubyte&0x7F 0
+>>>>>>>>>498 ubyte >0 \b; partition 4: ID=0x%x
+>>>>>>>>>>494 ubyte 0x80 \b, active
+>>>>>>>>>>495 ubyte x \b, starthead %u
+#>>>>>>>>>>496 ubyte x \b, start C_S: 0x%x
+#>>>>>>>>>>496 ubeshort&1023 x \b, startcylinder? %d
+>>>>>>>>>>502 ulelong x \b, startsector %u
+>>>>>>>>>>506 ulelong x \b, %u sectors
# mbr partion table entries end
+# http://www.acronis.de/
+#FAT label=ACRONIS\ SZ
+#OEM-ID=BOOTWIZ0
+>442 string Non-system\ disk,\
+>>459 string press\ any\ key...\x7\0 \b, Acronis Startup Recovery Loader
+# DOS names like F11.SYS are 8 right space padded bytes+3 bytes
+>>>477 ubyte&0xDF >0
+>>>>477 string x \b %-.3s
+>>>>>480 ubyte&0xDF >0
+>>>>>>480 string x \b%-.5s
+>>>>485 ubyte&0xDF >0
+>>>>>485 string x \b.%-.3s
+#
>185 string FDBOOT\ Version\
>>204 string \rNo\ Systemdisk.\
>>>220 string Booting\ from\ harddisk.\n\r
@@ -251,13 +319,12 @@
>>>>>>>422 string x \b%-.3s
>>>>>425 ubyte&0xDF >0
>>>>>>425 string >\ \b.%-.3s
-#
->>>>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
+# 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
@@ -528,6 +595,90 @@
>>>>>>>>504 string x \b%-.1s
>>>>505 ubyte&0xDF >0
>>>>>505 string x \b.%-.3s
+# added by Joerg Jenderek
+# http://www.visopsys.org/
+# http://partitionlogic.org.uk/
+# OEM-ID=Visopsys
+>478 ulelong 0
+>>(1.b+326) string I/O\ Error\ reading\
+>>>(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 string x \b %-.1s
+>>>>>>500 ubyte&0xDF >0
+>>>>>>>500 string x \b%-.1s
+>>>>>>>>501 ubyte&0xDF >0
+>>>>>>>>>501 string x \b%-.1s
+>>>>>>>>>>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%-.1s
+>>>>>>>>>>>>>>>>>>506 ubyte&0xDF >0
+>>>>>>>>>>>>>>>>>>>506 string x \b%-.1s
+#name extension
+>>>>>507 ubyte&0xDF >0 \b.
+>>>>>>507 string x \b%-.1s
+>>>>>>>508 ubyte&0xDF >0
+>>>>>>>>508 string x \b%-.1s
+>>>>>>>>>509 ubyte&0xDF >0
+>>>>>>>>>>509 string x \b%-.1s
+#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)
+# 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 string x \b %-.1s
+>>>>>>500 ubyte&0xDF >0
+>>>>>>>500 string x \b%-.1s
+>>>>>>>>501 ubyte&0xDF >0
+>>>>>>>>>501 string x \b%-.1s
+>>>>>>>>>>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%-.1s
+>>>>>>>>>>>>>>>>>>506 ubyte&0xDF >0
+>>>>>>>>>>>>>>>>>>>506 string x \b%-.1s
+#name extension
+>>>>>507 ubyte&0xDF >0 \b.
+>>>>>>507 string x \b%-.1s
+>>>>>>>508 ubyte&0xDF >0
+>>>>>>>>508 string x \b%-.1s
+>>>>>>>>>509 ubyte&0xDF >0
+>>>>>>>>>>509 string x \b%-.1s
+#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)
# loader end
# Joerg Jenderek
>446 ubyte 0
@@ -658,6 +809,61 @@
0x18b string OS/2 OS/2 Boot Manager
+# 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
+# http://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, %u (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
+
9564 lelong 0x00011954 Unix Fast File system [v1] (little-endian),
>8404 string x last mounted on %s,
#>9504 ledate x last checked at %s,
@@ -979,10 +1185,28 @@
>>>>>>>>&0 bedate =0 full dump
>>>>>>>>&0 bedate !0 incremental since: %s
+#----------------------------------------------------------
# VMS backup savesets - gerardo.cacciari@gmail.com
-# had to comment out GEM Image and G3 raw data entries due to conflict
-#0 byte x
-#>(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')
+#
+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)
+
+# Compaq/HP RILOE floppy image
+# From: Dirk Jagdmann <doj@cubic.org>
+0 string CPQRFBLO Compaq/HP RILOE floppy image
+
+#------------------------------------------------------------------------------
+# Files-11 On-Disk Structure (OpenVMS file system) - gerardo.cacciari@gmail.com
+# These bits come from LBN 1 (home block) of ODS-2 and ODS-5 volumes, which is
+# mapped to VBN 2 of [000000]INDEXF.SYS;1
+#
+1008 string DECFILE11B Files-11 On-Disk Structure
+>525 byte x Level %d
+>525 byte x (ODS-%d OpenVMS file system),
+>984 string x volume label is '%-12.12s'
diff --git a/contrib/file/Magdir/fonts b/contrib/file/Magdir/fonts
index 6a1ad34..cf6e0d7 100644
--- a/contrib/file/Magdir/fonts
+++ b/contrib/file/Magdir/fonts
@@ -59,3 +59,6 @@
# Opentype font data from Avi Bercovich
0 string OTTO OpenType font data
+# Gürkan Sengün <gurkan@linuks.mine.nu>, www.linuks.mine.nu
+0 string SplineFontDB: Spline Font Database
+>14 string x version %s
diff --git a/contrib/file/Magdir/images b/contrib/file/Magdir/images
index 155e99e..fd9e14f 100644
--- a/contrib/file/Magdir/images
+++ b/contrib/file/Magdir/images
@@ -267,9 +267,6 @@
#
0 beshort 0x1010 PEX Binary Archive
-# Tgif files
-0 string \%TGIF\ x Tgif file version %s
-
# DICOM medical imaging data
128 string DICM DICOM medical imaging data
@@ -310,6 +307,10 @@
>5 byte 0x00 (white background)
>5 byte 0xFF (black background)
+# Gürkan Sengün <gurkan@linuks.mine.nu>, www.linuks.mine.nu
+# http://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.
diff --git a/contrib/file/Magdir/linux b/contrib/file/Magdir/linux
index fc0c42d..fe68013 100644
--- a/contrib/file/Magdir/linux
+++ b/contrib/file/Magdir/linux
@@ -236,3 +236,13 @@
>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
+
diff --git a/contrib/file/Magdir/lisp b/contrib/file/Magdir/lisp
index c72b06c..e9c8ba8 100644
--- a/contrib/file/Magdir/lisp
+++ b/contrib/file/Magdir/lisp
@@ -10,12 +10,14 @@
# lisp files are mainly created on unix system with LF as line end
>2 search/2048 !\r Lisp/Scheme program text
>2 search/2048 \r Windows INF file
-0 string (
->1 string if\ Lisp/Scheme program text
->1 string setq\ Lisp/Scheme program text
->1 string defvar\ Lisp/Scheme program text
->1 string autoload\ Lisp/Scheme program text
->1 string custom-set-variables Lisp/Scheme program text
+
+0 search/256 (if\ Lisp/Scheme program text
+0 search/256 (setq\ Lisp/Scheme program text
+0 search/256 (defvar\ Lisp/Scheme program text
+0 search/256 (defparam\ Lisp/Scheme program text
+0 search/256 (defun\ Lisp/Scheme program text
+0 search/256 (autoload\ Lisp/Scheme program text
+0 search/256 (custom-set-variables\ Lisp/Scheme program text
# Emacs 18 - this is always correct, but not very magical.
0 string \012( Emacs v18 byte-compiled Lisp data
diff --git a/contrib/file/Magdir/mathematica b/contrib/file/Magdir/mathematica
index b9d3405..0eca5d4 100644
--- a/contrib/file/Magdir/mathematica
+++ b/contrib/file/Magdir/mathematica
@@ -24,7 +24,7 @@
# generic:
0 string (*^\r\r::[\011 Mathematica notebook version 2.x
-0 string \(\*\^\r\n\r\n\:\:\[\011 Mathematica notebook version 2.x
+0 string (*^\r\n\r\n::[\011 Mathematica notebook version 2.x
0 string (*^\015 Mathematica notebook version 2.x
0 string (*^\n\r\n\r::[\011 Mathematica notebook version 2.x
0 string (*^\r::[\011 Mathematica notebook version 2.x
diff --git a/contrib/file/Magdir/mime b/contrib/file/Magdir/mime
index 0102709..2219094 100644
--- a/contrib/file/Magdir/mime
+++ b/contrib/file/Magdir/mime
@@ -1,7 +1,7 @@
#------------------------------------------------------------------------------
# mime: file(1) magic for MIME encoded files
#
-0 string Content-Type:\
+0 string Content-Type:\
>14 string >\0 %s
0 string Content-Type:
>13 string >\0 %s
diff --git a/contrib/file/Magdir/mips b/contrib/file/Magdir/mips
index 9333bde..634eff4 100644
--- a/contrib/file/Magdir/mips
+++ b/contrib/file/Magdir/mips
@@ -165,8 +165,8 @@
0 string WNGZWZSS Wingz spreadsheet
0 string WNGZWZHP Wingz help file
#
-0 string \#Inventor V IRIS Inventor 1.0 file
-0 string \#Inventor V2 Open Inventor 2.0 file
+0 string #Inventor V IRIS Inventor 1.0 file
+0 string #Inventor V2 Open Inventor 2.0 file
# GLF is OpenGL stream encoding
0 string glfHeadMagic(); GLF_TEXT
4 belong 0x7d000000 GLF_BINARY_LSB_FIRST
diff --git a/contrib/file/Magdir/misctools b/contrib/file/Magdir/misctools
index 488779c..bb995ba 100644
--- a/contrib/file/Magdir/misctools
+++ b/contrib/file/Magdir/misctools
@@ -2,8 +2,8 @@
# misctools: file(1) magic for miscelanous UNIX tools.
#
0 string %%!! X-Post-It-Note text
-0 string BEGIN:VCALENDAR vCalendar calendar file
-0 string BEGIN:VCARD vCard visiting card
+0 string/c BEGIN:VCALENDAR vCalendar calendar file
+0 string/c BEGIN:VCARD vCard visiting card
# From: Alex Beregszaszi <alex@fsn.hu>
4 string gtktalog GNOME Catalogue (gtktalog)
diff --git a/contrib/file/Magdir/msdos b/contrib/file/Magdir/msdos
index 4f226dd..6143a26 100644
--- a/contrib/file/Magdir/msdos
+++ b/contrib/file/Magdir/msdos
@@ -14,7 +14,11 @@
# 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 regex/c =^\\s*call\s+rxfuncadd.*sysloadfu OS/2 REXX batch file text
+100 regex/c =^[\ \t]{0,10}call[\ \t]{1,10}rxfunc OS/2 REXX batch file text
+100 regex/c =^[\ \t]{0,10}say\ ['"] OS/2 REXX batch file text
+
+
+100 regex/c =^\\s*call\\s+rxfuncadd.*sysloadfu OS/2 REXX batch file text
100 regex/c =^\\s*say\ ['"] OS/2 REXX batch file text
0 leshort 0x14c MS Windows COFF Intel 80386 object file
@@ -558,6 +562,9 @@
# Outlook Personal Folders
0 lelong 0x4E444221 Microsoft Outlook binary email folder
+>10 leshort 0x0e (Outlook <=2002)
+>10 leshort 0x17 (Outlook >=2003)
+
# From: Dirk Jagdmann <doj@cubic.org>
0 lelong 0x00035f3f Windows 3.x help file
diff --git a/contrib/file/Magdir/os2 b/contrib/file/Magdir/os2
index e492031..99dd63a 100644
--- a/contrib/file/Magdir/os2
+++ b/contrib/file/Magdir/os2
@@ -6,7 +6,7 @@
# Provided 1998/08/22 by
# David Mediavilla <davidme.news@REMOVEIFNOTSPAMusa.net>
1 string InternetShortcut MS Windows 95 Internet shortcut text
->24 string >\ (URL=<%s>)
+>24 string >\ (URL=<%s>)
# OS/2 URL objects
# Provided 1998/08/22 by
diff --git a/contrib/file/Magdir/os400 b/contrib/file/Magdir/os400
index bee3660..3dc05bf 100644
--- a/contrib/file/Magdir/os400
+++ b/contrib/file/Magdir/os400
@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
# 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
@@ -9,24 +9,29 @@
# 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.
-40 string @@@@@@@@
->1089 search/7394 \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 0x0B \b, created with SAVDLO
->>&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
+#
+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/contrib/file/Magdir/perl b/contrib/file/Magdir/perl
index a00c642..a8daee4 100644
--- a/contrib/file/Magdir/perl
+++ b/contrib/file/Magdir/perl
@@ -13,10 +13,18 @@
0 string eval\ "exec\ /usr/local/bin/perl perl script text executable
0 string eval\ '(exit\ $?0)'\ &&\ eval\ 'exec perl script text
-# a couple more, by me
-# XXX: christos matches
-#0 regex package Perl5 module source text (via regex)
-0 string package Perl5 module source text
+
+# by Dmitry V. Levin and Alexey Tourbin
+# check the first line
+0 string package
+>1 regex \^package[\ \t]+[A-Za-z_]
+>>1 regex \^package[\ \t]+[0-9A-Za-z_:]*\ *; Perl5 module source text
+# not 'p', check other lines
+0 byte !0x70
+>0 regex \^package[\ \t]+[0-9A-Za-z_:]+\ *;
+>>0 regex \^1\ *;|\^(use|sub|my)\ .*[(;{=] Perl5 module source text
+
+
# Perl POD documents
# From: Tom Hukins <tom@eborcom.com>
diff --git a/contrib/file/Magdir/revision b/contrib/file/Magdir/revision
index 36a829b..e47416a 100644
--- a/contrib/file/Magdir/revision
+++ b/contrib/file/Magdir/revision
@@ -2,4 +2,8 @@
#------------------------------------------------------------------------------
# file(1) magic for revision control files
# From Hendrik Scholz <hendrik@scholz.net>
-0 string /1\ :pserver: cvs password text file
+0 string /1\ :pserver: cvs password text file
+
+# Conary changesets
+# From: Jonathan Smith <smithj@rpath.com>
+0 belong 0xea3f81bb Conary changeset data
diff --git a/contrib/file/Magdir/sgml b/contrib/file/Magdir/sgml
index 9f33529..ba6c3ef 100644
--- a/contrib/file/Magdir/sgml
+++ b/contrib/file/Magdir/sgml
@@ -12,8 +12,9 @@
# Extensible markup language (XML), a subset of SGML
# from Marc Prud'hommeaux (marc@apocalypse.org)
0 string/cb \<?xml XML document text
-0 string \<?xml\ version " XML
+0 string \<?xml\ version\ " XML
0 string \<?xml\ version=" XML
+0 string \<?xml\ version=' XML
>15 string >\0 %.3s document text
>>23 string \<xsl:stylesheet (XSL stylesheet)
>>24 string \<xsl:stylesheet (XSL stylesheet)
diff --git a/contrib/file/Magdir/sql b/contrib/file/Magdir/sql
index 016e030..21c6e51 100644
--- a/contrib/file/Magdir/sql
+++ b/contrib/file/Magdir/sql
@@ -27,8 +27,19 @@
>39 string iHP-100 [H Series]
#------------------------------------------------------------------------------
-# SQLite database file
-# From Ken Guest <ken@linux.ie>
+# 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.
#
-0 string SQLite SQLite database
->14 string >\0 (Version %s)
+# 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. Detect this and distinguish those files.
+
+0 string SQLite\ format\ 3
+>60 string _MTN Monotone source repository
+>60 belong !0 SQLite 3.x database, user version %u
+>60 belong 0 SQLite 3.x database
diff --git a/contrib/file/Magdir/tex b/contrib/file/Magdir/tex
index a6c734e..52adb87 100644
--- a/contrib/file/Magdir/tex
+++ b/contrib/file/Magdir/tex
@@ -29,25 +29,25 @@
0 string This\ is\ Info\ file GNU Info text
# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
-0 string \\input TeX document text
-0 string \\section LaTeX document text
-0 string \\setlength LaTeX document text
-0 string \\documentstyle LaTeX document text
-0 string \\chapter LaTeX document text
-0 string \\documentclass LaTeX 2e document text
-0 string \\relax LaTeX auxiliary file
-0 string \\contentsline LaTeX table of contents
-0 string %\ -*-latex-*- LaTeX document text
+0 search/400 \\input TeX document text
+0 search/400 \\section LaTeX document text
+0 search/400 \\setlength LaTeX document text
+0 search/400 \\documentstyle LaTeX document text
+0 search/400 \\chapter LaTeX document text
+0 search/400 \\documentclass LaTeX 2e document text
+0 search/400 \\relax LaTeX auxiliary file
+0 search/400 \\contentsline LaTeX table of contents
+0 search/400 %\ -*-latex-*- LaTeX document text
# Tex document, from Hendrik Scholz <hendrik@scholz.net>
0 string \\ifx TeX document text
# Index and glossary files
-0 string \\indexentry LaTeX raw index file
-0 string \\begin{theindex} LaTeX sorted index
-0 string \\glossaryentry LaTeX raw glossary
-0 string \\begin{theglossary} LaTeX sorted glossary
-0 string This\ is\ makeindex Makeindex log file
+0 search/400 \\indexentry LaTeX raw index file
+0 search/400 \\begin{theindex} LaTeX sorted index
+0 search/400 \\glossaryentry LaTeX raw glossary
+0 search/400 \\begin{theglossary} LaTeX sorted glossary
+0 search/400 This\ is\ makeindex Makeindex log file
# End of TeX
diff --git a/contrib/file/Magdir/tgif b/contrib/file/Magdir/tgif
index a6ffe36..779883a 100644
--- a/contrib/file/Magdir/tgif
+++ b/contrib/file/Magdir/tgif
@@ -2,5 +2,5 @@
# file(1) magic for tgif(1) files
# From Hendrik Scholz <hendrik@scholz.net>
-0 string %TGIF\ 4 tgif version 4 object file
+0 string %TGIF\ x Tgif file version %s
diff --git a/contrib/file/Magdir/varied.out b/contrib/file/Magdir/varied.out
index 6126f36..6df6fd9 100644
--- a/contrib/file/Magdir/varied.out
+++ b/contrib/file/Magdir/varied.out
@@ -34,3 +34,9 @@
# 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/contrib/file/Magdir/varied.script b/contrib/file/Magdir/varied.script
index a3e0972..ab5bece 100644
--- a/contrib/file/Magdir/varied.script
+++ b/contrib/file/Magdir/varied.script
@@ -3,7 +3,7 @@
0 string #!\ / a
>3 string >\0 %s script text executable
-0 string #!\ / a
+0 string #!\t/ a
>3 string >\0 %s script text executable
0 string #!/ a
>2 string >\0 %s script text executable
diff --git a/contrib/file/Magdir/wordprocessors b/contrib/file/Magdir/wordprocessors
index 9c06d8d..546d261 100644
--- a/contrib/file/Magdir/wordprocessors
+++ b/contrib/file/Magdir/wordprocessors
@@ -3,7 +3,7 @@
# 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
+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
diff --git a/contrib/file/README b/contrib/file/README
index b4223f4..b7e9d55 100644
--- a/contrib/file/README
+++ b/contrib/file/README
@@ -1,5 +1,5 @@
** README for file(1) Command **
-@(#) $Id: README,v 1.34 2006/05/03 18:48:33 christos Exp $
+@(#) $File: README,v 1.34 2006/05/03 18:48:33 christos Exp $
This is Release 4.x of Ian Darwin's (copyright but distributable)
file(1) command. This version is the standard "file" command for Linux,
diff --git a/contrib/file/apprentice.c b/contrib/file/apprentice.c
index 974fae9..d5a5bec 100644
--- a/contrib/file/apprentice.c
+++ b/contrib/file/apprentice.c
@@ -46,7 +46,7 @@
#endif
#ifndef lint
-FILE_RCSID("@(#)$Id: apprentice.c,v 1.100 2006/12/11 21:48:49 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.105 2007/05/16 20:51:40 christos Exp $")
#endif /* lint */
#define EATAB {while (isascii((unsigned char) *l) && \
@@ -75,27 +75,21 @@ FILE_RCSID("@(#)$Id: apprentice.c,v 1.100 2006/12/11 21:48:49 christos Exp $")
#define MAXPATHLEN 1024
#endif
-#define IS_PLAINSTRING(t) ((t) == FILE_STRING || (t) == FILE_PSTRING || \
- (t) == FILE_BESTRING16 || (t) == FILE_LESTRING16)
-
-#define IS_STRING(t) (IS_PLAINSTRING(t) || (t) == FILE_REGEX || \
- (t) == FILE_SEARCH)
-
struct magic_entry {
struct magic *mp;
uint32_t cont_count;
uint32_t max_count;
};
-const int file_formats[] = { FILE_FORMAT_STRING };
-const size_t file_nformats = sizeof(file_formats) / sizeof(file_formats[0]);
-const char *file_names[] = { FILE_FORMAT_NAME };
-const size_t file_nnames = sizeof(file_names) / sizeof(file_names[0]);
+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 **);
+private int getvalue(struct magic_set *ms, struct magic *, const char **, int);
private int hextoint(int);
private const char *getstr(struct magic_set *, const char *, char *, int,
- int *);
+ int *, int);
private int parse(struct magic_set *, struct magic_entry **, uint32_t *,
const char *, size_t, int);
private void eatsize(const char **);
@@ -154,6 +148,82 @@ main(int argc, char *argv[])
}
#endif /* COMPILE_ONLY */
+static const struct type_tbl_s {
+ const char *name;
+ const size_t len;
+ const int type;
+ const int format;
+} type_tbl[] = {
+# define XX(s) s, (sizeof(s) - 1)
+# define XX_NULL NULL, 0
+ { XX("byte"), FILE_BYTE, FILE_FMT_NUM },
+ { XX("short"), FILE_SHORT, FILE_FMT_NUM },
+ { XX("default"), FILE_DEFAULT, FILE_FMT_STR },
+ { 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_NULL, FILE_INVALID, FILE_FMT_NONE },
+# undef XX
+# undef XX_NULL
+};
+
+private int
+get_type(const char *l, const char **t)
+{
+ const struct type_tbl_s *p;
+
+ for (p = type_tbl; p->name; p++) {
+ if (strncmp(l, p->name, p->len) == 0) {
+ if (t)
+ *t = l + p->len;
+ break;
+ }
+ }
+ return p->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->name; p++) {
+ assert(p->type < FILE_NAMES_SIZE);
+ file_names[p->type] = p->name;
+ file_formats[p->type] = p->format;
+ }
+}
/*
* Handle one file.
@@ -241,7 +311,6 @@ file_delmagic(struct magic *p, int type, size_t entries)
}
}
-
/* const char *fn: list of magic files */
protected struct mlist *
file_apprentice(struct magic_set *ms, const char *fn, int action)
@@ -251,15 +320,18 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
struct mlist *mlist;
static const char mime[] = ".mime";
+ init_file_tables();
+
if (fn == NULL)
fn = getenv("MAGIC");
if (fn == NULL)
fn = MAGIC;
- if ((fn = mfn = strdup(fn)) == NULL) {
+ if ((mfn = strdup(fn)) == NULL) {
file_oomem(ms, strlen(fn));
return NULL;
}
+ fn = mfn;
if ((mlist = malloc(sizeof(*mlist))) == NULL) {
free(mfn);
@@ -316,6 +388,9 @@ apprentice_magic_strength(const struct magic *m)
size_t val = 2 * MULT; /* baseline strength */
switch (m->type) {
+ case FILE_DEFAULT: /* make sure this sorts last */
+ return 0;
+
case FILE_BYTE:
val += 1 * MULT;
break;
@@ -401,6 +476,10 @@ apprentice_magic_strength(const struct magic *m)
(void)fprintf(stderr, "Bad relation %c\n", m->reln);
abort();
}
+
+ if (val == 0) /* ensure we only return 0 for FILE_DEFAULT */
+ val = 1;
+
return val;
}
@@ -485,6 +564,23 @@ apprentice_file(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
#ifndef NOORDER
qsort(marray, marraycount, sizeof(*marray), apprentice_sort);
+ /*
+ * Make sure that any level 0 "default" line is last (if one exists).
+ */
+ for (i = 0; i < marraycount; i++) {
+ if (marray[i].mp->cont_level == 0 &&
+ marray[i].mp->type == FILE_DEFAULT) {
+ while (++i < marraycount)
+ if (marray[i].mp->cont_level == 0)
+ break;
+ if (i != marraycount) {
+ ms->line = marray[i].mp->lineno; /* XXX - Ugh! */
+ file_magwarn(ms,
+ "level 0 \"default\" did not sort last");
+ }
+ break;
+ }
+ }
#endif
for (i = 0; i < marraycount; i++)
@@ -523,7 +619,7 @@ out:
protected uint64_t
file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
{
- if (!(m->flag & UNSIGNED))
+ if (!(m->flag & UNSIGNED)) {
switch(m->type) {
/*
* Do not remove the casts below. They are
@@ -569,6 +665,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_LESTRING16:
case FILE_REGEX:
case FILE_SEARCH:
+ case FILE_DEFAULT:
break;
default:
if (ms->flags & MAGIC_CHECK)
@@ -576,9 +673,150 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
m->type);
return ~0U;
}
+ }
return v;
}
+private int
+string_modifier_check(struct magic_set *ms, struct magic const *m)
+{
+ if ((ms->flags & MAGIC_CHECK) == 0)
+ return 0;
+
+ 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:
+ break;
+ case FILE_REGEX:
+ if ((m->str_flags & STRING_COMPACT_BLANK) != 0) {
+ file_magwarn(ms, "'/%c' not allowed on regex\n",
+ CHAR_COMPACT_BLANK);
+ return -1;
+ }
+ if ((m->str_flags & STRING_COMPACT_OPTIONAL_BLANK) != 0) {
+ file_magwarn(ms, "'/%c' not allowed on regex\n",
+ CHAR_COMPACT_OPTIONAL_BLANK);
+ 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 struct cond_tbl_s {
+ const char *name;
+ const size_t len;
+ const int cond;
+ } cond_tbl[] = {
+ { "if", 2, COND_IF },
+ { "elif", 4, COND_ELIF },
+ { "else", 4, COND_ELSE },
+ { NULL, 0, COND_NONE },
+ };
+ struct cond_tbl_s *p;
+
+ for (p = cond_tbl; p->name; p++) {
+ if (strncmp(l, p->name, p->len) == 0 &&
+ isspace((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 */
+
/*
* parse one line from magic file, put into magic[index++] if valid
*/
@@ -586,13 +824,15 @@ private int
parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
const char *line, size_t lineno, int action)
{
+#ifdef ENABLE_CONDITIONALS
+ static uint32_t last_cont_level = 0;
+#endif
size_t i;
struct magic_entry *me;
struct magic *m;
const char *l = line;
char *t;
- private const char *fops = FILE_OPS;
- uint64_t val;
+ int op;
uint32_t cont_level;
cont_level = 0;
@@ -601,6 +841,12 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
++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
#define ALLOC_CHUNK (size_t)10
#define ALLOC_INCR (size_t)200
@@ -622,7 +868,7 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
me->max_count = cnt;
}
m = &me->mp[me->cont_count++];
- memset(m, 0, sizeof(*m));
+ (void)memset(m, 0, sizeof(*m));
m->cont_level = cont_level;
} else {
if (*nmentryp == maxmagic) {
@@ -648,26 +894,31 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
me->max_count = ALLOC_CHUNK;
} else
m = me->mp;
- memset(m, 0, sizeof(*m));
+ (void)memset(m, 0, sizeof(*m));
m->cont_level = 0;
me->cont_count = 1;
}
m->lineno = lineno;
- if (m->cont_level != 0 && *l == '&') {
+ if (*l == '&') { /* m->cont_level == 0 checked below. */
++l; /* step over */
m->flag |= OFFADD;
}
- if (m->cont_level != 0 && *l == '(') {
+ 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;
+ }
}
- if (m->cont_level != 0 && *l == '&') {
- ++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");
/* get offset, then skip over it */
m->offset = (uint32_t)strtoul(l, &t, 0);
@@ -717,43 +968,15 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
}
l++;
}
+
+ m->in_op = 0;
if (*l == '~') {
m->in_op |= FILE_OPINVERSE;
l++;
}
- switch (*l) {
- case '&':
- m->in_op |= FILE_OPAND;
- l++;
- break;
- case '|':
- m->in_op |= FILE_OPOR;
- l++;
- break;
- case '^':
- m->in_op |= FILE_OPXOR;
- l++;
- break;
- case '+':
- m->in_op |= FILE_OPADD;
- l++;
- break;
- case '-':
- m->in_op |= FILE_OPMINUS;
- l++;
- break;
- case '*':
- m->in_op |= FILE_OPMULTIPLY;
- l++;
- break;
- case '/':
- m->in_op |= FILE_OPDIVIDE;
- l++;
- break;
- case '%':
- m->in_op |= FILE_OPMODULO;
+ if ((op = get_op(*l)) != -1) {
+ m->in_op |= op;
l++;
- break;
}
if (*l == '(') {
m->in_op |= FILE_OPINDIRECT;
@@ -761,6 +984,10 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
}
if (isdigit((unsigned char)*l) || *l == '-') {
m->in_offset = (int32_t)strtol(l, &t, 0);
+ if (l == t)
+ if (ms->flags & MAGIC_CHECK)
+ file_magwarn(ms,
+ "in_offset `%s' invalid", l);
l = t;
}
if (*l++ != ')' ||
@@ -769,61 +996,85 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
file_magwarn(ms,
"missing ')' in indirect offset");
}
+ EATAB;
+#ifdef ENABLE_CONDITIONALS
+ m->cond = get_cond(l, &l);
+ if (check_cond(ms, m->cond, cont_level) == -1)
+ return -1;
- while (isascii((unsigned char)*l) && isdigit((unsigned char)*l))
- ++l;
EATAB;
+#endif
if (*l == 'u') {
++l;
m->flag |= UNSIGNED;
}
- /* get type, skip it */
- for (i = 0; i < file_nnames; i++) {
- size_t len = strlen(file_names[i]);
- if (strncmp(l, file_names[i], len) == 0) {
- m->type = i;
- l+= len;
- break;
- }
- }
- if (i == file_nnames) {
+ m->type = get_type(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;
}
- if ((t = strchr(fops, *l)) != NULL) {
- uint32_t op = (uint32_t)(t - fops);
- if (op != FILE_OPDIVIDE || !IS_PLAINSTRING(m->type)) {
+ m->str_count = 0;
+ m->str_flags = 0;
+ m->num_mask = 0;
+ if ((op = get_op(*l)) != -1) {
+ if (!IS_STRING(m->type)) {
+ uint64_t val;
++l;
m->mask_op |= op;
val = (uint64_t)strtoull(l, &t, 0);
l = t;
- m->mask = file_signextend(ms, m, val);
+ m->num_mask = file_signextend(ms, m, val);
eatsize(&l);
- } else {
- m->mask = 0L;
+ }
+ else if (op == FILE_OPDIVIDE) {
+ int have_count = 0;
while (!isspace((unsigned char)*++l)) {
switch (*l) {
- case CHAR_IGNORE_LOWERCASE:
- m->mask |= STRING_IGNORE_LOWERCASE;
+ /* for portability avoid "case '0' ... '9':" */
+ case '0': case '1': case '2':
+ case '3': case '4': case '5':
+ case '6': case '7': case '8':
+ case '9': {
+ if (have_count && ms->flags & MAGIC_CHECK)
+ file_magwarn(ms,
+ "multiple counts");
+ have_count = 1;
+ m->str_count = strtoul(l, &t, 0);
+ l = t - 1;
break;
+ }
case CHAR_COMPACT_BLANK:
- m->mask |= STRING_COMPACT_BLANK;
+ m->str_flags |= STRING_COMPACT_BLANK;
break;
case CHAR_COMPACT_OPTIONAL_BLANK:
- m->mask |=
+ m->str_flags |=
STRING_COMPACT_OPTIONAL_BLANK;
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;
default:
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@@ -831,8 +1082,17 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
*l);
return -1;
}
+ /* allow multiple '/' for readability */
+ if (l[1] == '/' && !isspace((unsigned char)l[2]))
+ l++;
}
- ++l;
+ if (string_modifier_check(ms, m) == -1)
+ return -1;
+ }
+ else {
+ if (ms->flags & MAGIC_CHECK)
+ file_magwarn(ms, "invalid string op: %c", *t);
+ return -1;
}
}
/*
@@ -860,19 +1120,20 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
++l;
break;
default:
+ m->reln = '='; /* the default relation */
if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
isspace((unsigned char)l[1])) || !l[1])) {
m->reln = *l;
++l;
- goto GetDesc; /* Bill The Cat */
}
- m->reln = '=';
break;
}
- EATAB;
-
- if (getvalue(ms, m, &l))
+ /*
+ * 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 > HOWMANY-1)
@@ -880,9 +1141,8 @@ parse(struct magic_set *ms, struct magic_entry **mentryp, uint32_t *nmentryp,
*/
/*
- * now get last part - the description
+ * Now get last part - the description
*/
-GetDesc:
EATAB;
if (l[0] == '\b') {
++l;
@@ -1078,7 +1338,7 @@ check_format(struct magic_set *ms, struct magic *m)
* 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)
+getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
{
int slen;
@@ -1089,7 +1349,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p)
case FILE_PSTRING:
case FILE_REGEX:
case FILE_SEARCH:
- *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen);
+ *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen, action);
if (*p == NULL) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "cannot get string from `%s'",
@@ -1117,7 +1377,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p)
* Return updated scan pointer as function result.
*/
private const char *
-getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen)
+getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int action)
{
const char *origs = s;
char *origp = p;
@@ -1132,16 +1392,66 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen)
file_error(ms, 0, "string too long: `%s'", origs);
return NULL;
}
- if(c == '\\') {
+ if (c == '\\') {
switch(c = *s++) {
case '\0':
+ if (action == FILE_COMPILE)
+ file_magwarn(ms, "incomplete escape");
goto out;
+ case '\t':
+ if (action == FILE_COMPILE) {
+ file_magwarn(ms,
+ "escaped tab found, use \\t instead");
+ action++;
+ }
+ /*FALLTHROUGH*/
default:
+ if (action == FILE_COMPILE) {
+ if (isprint((unsigned char)c))
+ 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++ = (char) c;
break;
+ case 'a':
+ *p++ = '\a';
+ break;
+
+ case 'b':
+ *p++ = '\b';
+ break;
+
+ case 'f':
+ *p++ = '\f';
+ break;
+
case 'n':
*p++ = '\n';
break;
@@ -1150,18 +1460,10 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen)
*p++ = '\r';
break;
- case 'b':
- *p++ = '\b';
- break;
-
case 't':
*p++ = '\t';
break;
- case 'f':
- *p++ = '\f';
- break;
-
case 'v':
*p++ = '\v';
break;
@@ -1177,11 +1479,11 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen)
case '7':
val = c - '0';
c = *s++; /* try for 2 */
- if(c >= '0' && c <= '7') {
- val = (val<<3) | (c - '0');
+ 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');
+ if (c >= '0' && c <= '7')
+ val = (val << 3) | (c-'0');
else
--s;
}
@@ -1224,9 +1526,9 @@ hextoint(int c)
return -1;
if (isdigit((unsigned char) c))
return c - '0';
- if ((c >= 'a')&&(c <= 'f'))
+ if ((c >= 'a') && (c <= 'f'))
return c + 10 - 'a';
- if (( c>= 'A')&&(c <= 'F'))
+ if (( c>= 'A') && (c <= 'F'))
return c + 10 - 'A';
return -1;
}
@@ -1250,12 +1552,23 @@ file_showstr(FILE *fp, const char *s, size_t len)
if (len-- == 0)
break;
}
- if(c >= 040 && c <= 0176) /* TODO isprint && !iscntrl */
+ 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;
@@ -1264,18 +1577,10 @@ file_showstr(FILE *fp, const char *s, size_t len)
(void) fputc('r', fp);
break;
- case '\b':
- (void) fputc('b', fp);
- break;
-
case '\t':
(void) fputc('t', fp);
break;
- case '\f':
- (void) fputc('f', fp);
- break;
-
case '\v':
(void) fputc('v', fp);
break;
@@ -1536,7 +1841,13 @@ bs1(struct magic *m)
m->cont_level = swap2(m->cont_level);
m->offset = swap4((uint32_t)m->offset);
m->in_offset = swap4((uint32_t)m->in_offset);
- if (!IS_STRING(m->type))
+ m->lineno = swap4((uint32_t)m->lineno);
+ if (IS_STRING(m->type)) {
+ m->str_count = swap4(m->str_count);
+ m->str_flags = swap4(m->str_flags);
+ }
+ else {
m->value.q = swap8(m->value.q);
- m->mask = swap8(m->mask);
+ m->num_mask = swap8(m->num_mask);
+ }
}
diff --git a/contrib/file/apptype.c b/contrib/file/apptype.c
index 73b0687..42cee40 100644
--- a/contrib/file/apptype.c
+++ b/contrib/file/apptype.c
@@ -32,7 +32,7 @@
#ifndef lint
-FILE_RCSID("@(#)$Id: apptype.c,v 1.6 2003/11/11 20:01:45 christos Exp $")
+FILE_RCSID("@(#)$File: apptype.c,v 1.7 2007/01/12 17:38:27 christos Exp $")
#endif /* lint */
#ifdef __EMX__
diff --git a/contrib/file/ascmagic.c b/contrib/file/ascmagic.c
index 81525c8..564556d 100644
--- a/contrib/file/ascmagic.c
+++ b/contrib/file/ascmagic.c
@@ -49,7 +49,7 @@
#include "names.h"
#ifndef lint
-FILE_RCSID("@(#)$Id: ascmagic.c,v 1.46 2006/10/20 21:04:15 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.50 2007/03/15 14:51:00 christos Exp $")
#endif /* lint */
typedef unsigned long unichar;
@@ -92,7 +92,7 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
int n_cr = 0;
int n_nel = 0;
- int last_line_end = -1;
+ size_t last_line_end = (size_t)-1;
int has_long_lines = 0;
/*
@@ -167,7 +167,7 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
* I believe Plan 9 troff allows non-ASCII characters in the names
* of macros, so this test might possibly fail on such a file.
*/
- if (*ubuf == '.') {
+ if ((ms->flags & MAGIC_NO_CHECK_TROFF) == 0 && *ubuf == '.') {
unichar *tp = ubuf + 1;
while (ISSPC(*tp))
@@ -184,7 +184,8 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
}
}
- if ((*buf == 'c' || *buf == 'C') && ISSPC(buf[1])) {
+ if ((ms->flags & MAGIC_NO_CHECK_FORTRAN) == 0 &&
+ (*buf == 'c' || *buf == 'C') && ISSPC(buf[1])) {
subtype_mime = "text/fortran";
subtype = "fortran program";
goto subtype_identified;
@@ -192,6 +193,9 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes)
/* look for tokens from names.h - this is expensive! */
+ if ((ms->flags & MAGIC_NO_CHECK_TOKENS) != 0)
+ goto subtype_identified;
+
i = 0;
while (i < ulen) {
size_t end;
@@ -461,7 +465,7 @@ private int
looks_ascii(const unsigned char *buf, size_t nbytes, unichar *ubuf,
size_t *ulen)
{
- int i;
+ size_t i;
*ulen = 0;
@@ -480,7 +484,7 @@ looks_ascii(const unsigned char *buf, size_t nbytes, unichar *ubuf,
private int
looks_latin1(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
{
- int i;
+ size_t i;
*ulen = 0;
@@ -500,7 +504,7 @@ private int
looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
size_t *ulen)
{
- int i;
+ size_t i;
*ulen = 0;
@@ -519,7 +523,8 @@ looks_extended(const unsigned char *buf, size_t nbytes, unichar *ubuf,
private int
looks_utf8(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
{
- int i, n;
+ size_t i;
+ int n;
unichar c;
int gotone = 0;
@@ -583,7 +588,7 @@ looks_unicode(const unsigned char *buf, size_t nbytes, unichar *ubuf,
size_t *ulen)
{
int bigend;
- int i;
+ size_t i;
if (nbytes < 2)
return 0;
@@ -702,7 +707,7 @@ private unsigned char ebcdic_1047_to_8859[] = {
private void
from_ebcdic(const unsigned char *buf, size_t nbytes, unsigned char *out)
{
- int i;
+ size_t i;
for (i = 0; i < nbytes; i++) {
out[i] = ebcdic_to_ascii[buf[i]];
diff --git a/contrib/file/compress.c b/contrib/file/compress.c
index 5989eb2..2ccbef6 100644
--- a/contrib/file/compress.c
+++ b/contrib/file/compress.c
@@ -46,12 +46,16 @@
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
+#if defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif
+
#ifndef lint
-FILE_RCSID("@(#)$Id: compress.c,v 1.45 2006/10/31 19:37:17 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.51 2007/03/05 02:41:29 christos Exp $")
#endif
private struct {
@@ -74,7 +78,7 @@ private struct {
{ "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */
};
-private int ncompr = sizeof(compr) / sizeof(compr[0]);
+private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
#define NODATA ((size_t)~0)
@@ -88,8 +92,8 @@ private size_t uncompressgzipped(struct magic_set *, const unsigned char *,
#endif
protected int
-file_zmagic(struct magic_set *ms, int fd, const unsigned char *buf,
- size_t nbytes)
+file_zmagic(struct magic_set *ms, int fd, const char *name,
+ const unsigned char *buf, size_t nbytes)
{
unsigned char *newbuf = NULL;
size_t i, nsz;
@@ -106,11 +110,11 @@ file_zmagic(struct magic_set *ms, int fd, const unsigned char *buf,
nbytes)) != NODATA) {
ms->flags &= ~MAGIC_COMPRESS;
rv = -1;
- if (file_buffer(ms, -1, newbuf, nsz) == -1)
+ if (file_buffer(ms, -1, name, newbuf, nsz) == -1)
goto error;
if (file_printf(ms, " (") == -1)
goto error;
- if (file_buffer(ms, -1, buf, nbytes) == -1)
+ if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
goto error;
if (file_printf(ms, ")") == -1)
goto error;
@@ -154,9 +158,9 @@ swrite(int fd, const void *buf, size_t n)
* `safe' read for sockets and pipes.
*/
protected ssize_t
-sread(int fd, void *buf, size_t n)
+sread(int fd, void *buf, size_t n, int canbepipe)
{
- int rv;
+ int rv, cnt;
#ifdef FIONREAD
int t = 0;
#endif
@@ -166,11 +170,12 @@ sread(int fd, void *buf, size_t n)
goto nocheck;
#ifdef FIONREAD
- if ((ioctl(fd, FIONREAD, &t) < 0) || (t == 0)) {
+ if ((canbepipe && (ioctl(fd, FIONREAD, &t) == -1)) || (t == 0)) {
#ifdef FD_ZERO
- for (;;) {
+ for (cnt = 0;; cnt++) {
fd_set check;
struct timeval tout = {0, 100 * 1000};
+ int selrv;
FD_ZERO(&check);
FD_SET(fd, &check);
@@ -179,12 +184,14 @@ sread(int fd, void *buf, size_t n)
* Avoid soft deadlock: do not read if there
* is nothing to read from sockets and pipes.
*/
- if (select(fd + 1, &check, NULL, NULL, &tout) <= 0) {
+ 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;
- }
- break;
+ } else
+ break;
}
#endif
(void)ioctl(fd, FIONREAD, &t);
@@ -245,7 +252,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes)
r = 1;
else {
- while ((r = sread(fd, buf, sizeof(buf))) > 0)
+ while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
if (swrite(tfd, buf, (size_t)r) != r)
break;
}
@@ -341,7 +348,7 @@ uncompressgzipped(struct magic_set *ms, const unsigned char *old,
}
n = (size_t)z.total_out;
- inflateEnd(&z);
+ (void)inflateEnd(&z);
/* let's keep the nul-terminate tradition */
(*newch)[n] = '\0';
@@ -389,8 +396,8 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
(void)close(2);
#endif
- execvp(compr[method].argv[0],
- (char *const *)(intptr_t)compr[method].argv);
+ (void)execvp(compr[method].argv[0],
+ (char *const *)(intptr_t)compr[method].argv);
#ifdef DEBUG
(void)fprintf(stderr, "exec `%s' failed (%s)\n",
compr[method].argv[0], strerror(errno));
@@ -412,7 +419,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
switch (fork()) {
case 0: /* child */
(void)close(fdout[0]);
- if (swrite(fdin[1], old, n) != n) {
+ if (swrite(fdin[1], old, n) != (ssize_t)n) {
#ifdef DEBUG
(void)fprintf(stderr,
"Write failed (%s)\n",
@@ -446,7 +453,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
n = 0;
goto err;
}
- if ((r = sread(fdout[0], *newch, HOWMANY)) <= 0) {
+ if ((r = sread(fdout[0], *newch, HOWMANY, 0)) <= 0) {
#ifdef DEBUG
(void)fprintf(stderr, "Read failed (%s)\n",
strerror(errno));
diff --git a/contrib/file/config.h.in b/contrib/file/config.h.in
index 3fe7a8d..8088355 100644
--- a/contrib/file/config.h.in
+++ b/contrib/file/config.h.in
@@ -27,6 +27,9 @@
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
@@ -66,6 +69,9 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
@@ -82,6 +88,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
diff --git a/contrib/file/configure b/contrib/file/configure
index f39e946..914cb12 100755
--- a/contrib/file/configure
+++ b/contrib/file/configure
@@ -1808,7 +1808,7 @@ fi
# Define the identity of the package.
PACKAGE=file
- VERSION=4.19
+ VERSION=4.21
cat >>confdefs.h <<_ACEOF
@@ -20670,7 +20670,8 @@ done
-for ac_header in utime.h wchar.h wctype.h
+
+for ac_header in utime.h wchar.h wctype.h limits.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -20823,7 +20824,8 @@ done
-for ac_header in sys/mman.h sys/stat.h sys/types.h sys/utime.h
+
+for ac_header in sys/mman.h sys/stat.h sys/types.h sys/utime.h sys/time.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -22612,7 +22614,8 @@ _ACEOF
-for ac_func in mmap strerror strtoul mbrtowc mkstemp getopt_long utimes utime wcwidth snprintf vsnprintf
+
+for ac_func in mmap strerror strndup strtoul mbrtowc mkstemp getopt_long utimes utime wcwidth snprintf vsnprintf
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/contrib/file/configure.in b/contrib/file/configure.in
index 1ca21c0..189edbd 100644
--- a/contrib/file/configure.in
+++ b/contrib/file/configure.in
@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT
AC_CONFIG_SRCDIR([src/file.c])
-AM_INIT_AUTOMAKE(file, 4.19)
+AM_INIT_AUTOMAKE(file, 4.21)
AM_CONFIG_HEADER([config.h])
AM_MAINTAINER_MODE
@@ -80,8 +80,8 @@ AC_HEADER_MAJOR
AC_HEADER_SYS_WAIT
AC_HEADER_STDINT
AC_CHECK_HEADERS(fcntl.h locale.h stdint.h inttypes.h unistd.h getopt.h)
-AC_CHECK_HEADERS(utime.h wchar.h wctype.h)
-AC_CHECK_HEADERS(sys/mman.h sys/stat.h sys/types.h sys/utime.h)
+AC_CHECK_HEADERS(utime.h wchar.h wctype.h limits.h)
+AC_CHECK_HEADERS(sys/mman.h sys/stat.h sys/types.h sys/utime.h sys/time.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -119,7 +119,7 @@ AC_CHECK_SIZEOF_STDC_HEADERS(uint32_t, 0)
AC_CHECK_SIZEOF_STDC_HEADERS(uint64_t, 0)
dnl Checks for functions
-AC_CHECK_FUNCS(mmap strerror strtoul mbrtowc mkstemp getopt_long utimes utime wcwidth snprintf vsnprintf)
+AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp getopt_long utimes utime wcwidth snprintf vsnprintf)
dnl Checks for libraries
AC_CHECK_LIB(z,gzopen)
diff --git a/contrib/file/file.c b/contrib/file/file.c
index f3fae24..0cd55ff 100644
--- a/contrib/file/file.c
+++ b/contrib/file/file.c
@@ -71,7 +71,7 @@
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$Id: file.c,v 1.104 2006/11/25 17:28:54 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.111 2007/05/08 14:44:18 christos Exp $")
#endif /* lint */
@@ -81,7 +81,7 @@ FILE_RCSID("@(#)$Id: file.c,v 1.104 2006/11/25 17:28:54 christos Exp $")
#define SYMLINKFLAG ""
#endif
-# define USAGE "Usage: %s [-bcik" SYMLINKFLAG "nNrsvz0] [-f namefile] [-F separator] [-m magicfiles] file...\n %s -C -m magicfiles\n"
+# define USAGE "Usage: %s [-bcik" SYMLINKFLAG "nNrsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] file...\n %s -C -m magicfiles\n"
#ifndef MAXPATHLEN
#define MAXPATHLEN 512
@@ -122,13 +122,13 @@ private void load(const char *, int);
int
main(int argc, char *argv[])
{
- int c;
+ int c, i;
int action = 0, didsomefiles = 0, errflg = 0;
int flags = 0;
char *home, *usermagic;
struct stat sb;
static const char hmagic[] = "/.magic";
-#define OPTSTRING "bcCdf:F:hikLm:nNprsvz0"
+#define OPTSTRING "bcCde:f:F:hikLm:nNprsvz0"
#ifdef HAVE_GETOPT_LONG
int longindex;
static const struct option long_options[] =
@@ -138,6 +138,7 @@ main(int argc, char *argv[])
{"brief", 0, 0, 'b'},
{"checking-printout", 0, 0, 'c'},
{"debug", 0, 0, 'd'},
+ {"exclude", 1, 0, 'e' },
{"files-from", 1, 0, 'f'},
{"separator", 1, 0, 'F'},
{"mime", 0, 0, 'i'},
@@ -161,6 +162,21 @@ main(int argc, char *argv[])
};
#endif
+ static const struct {
+ const char *name;
+ int value;
+ } nv[] = {
+ { "apptype", MAGIC_NO_CHECK_APPTYPE },
+ { "ascii", MAGIC_NO_CHECK_ASCII },
+ { "compress", MAGIC_NO_CHECK_COMPRESS },
+ { "elf", MAGIC_NO_CHECK_ELF },
+ { "fortran", MAGIC_NO_CHECK_FORTRAN },
+ { "soft", MAGIC_NO_CHECK_SOFT },
+ { "tar", MAGIC_NO_CHECK_TAR },
+ { "tokens", MAGIC_NO_CHECK_TOKENS },
+ { "troff", MAGIC_NO_CHECK_TROFF },
+ };
+
#ifdef LC_CTYPE
/* makes islower etc work for other langs */
(void)setlocale(LC_CTYPE, "");
@@ -223,6 +239,17 @@ main(int argc, char *argv[])
case 'd':
flags |= MAGIC_DEBUG|MAGIC_CHECK;
break;
+ case 'e':
+ for (i = 0; i < sizeof(nv) / sizeof(nv[0]); i++)
+ if (strcmp(nv[i].name, optarg) == 0)
+ break;
+
+ if (i == sizeof(nv) / sizeof(nv[0]))
+ errflg++;
+ else
+ flags |= nv[i].value;
+ break;
+
case 'f':
if(action)
usage();
@@ -333,7 +360,7 @@ private void
/*ARGSUSED*/
load(const char *m, int flags)
{
- if (magic)
+ if (magic || m == NULL)
return;
magic = magic_open(flags);
if (magic == NULL) {
@@ -404,7 +431,7 @@ process(const char *inname, int wid)
if (wid > 0 && !bflag) {
(void)printf("%s", std_in ? "/dev/stdin" : inname);
if (nulsep)
- (void)puts('\0');
+ (void)putc('\0', stdout);
else
(void)printf("%s", separator);
(void)printf("%*s ",
@@ -535,6 +562,9 @@ help(void)
" -c, --checking-printout 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"
+" -e, --exclude exclude test from the list of test to be\n"
+" performed for file. Valid tests are:\n"
+" ascii, apptype, elf, compress, soft, tar\n"
" -f, --files-from FILE read the filenames to be examined from FILE\n"
" -F, --separator string use string as separator instead of `:'\n"
" -i, --mime output mime type strings\n"
@@ -546,8 +576,12 @@ help(void)
" -r, --raw don't translate unprintable chars to \\ooo\n"
" -s, --special-files treat special (block/char devices) files as\n"
" ordinary ones\n"
+"or\n"
" --help display this help and exit\n"
+"or\n"
" --version output version information and exit\n"
+"or\n"
+" -C, --compile compile file specified by -m\n"
);
exit(0);
}
diff --git a/contrib/file/file.h b/contrib/file/file.h
index bb2fc16..cc8b4d2 100644
--- a/contrib/file/file.h
+++ b/contrib/file/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$Id: file.h,v 1.83 2006/12/11 21:48:49 christos Exp $
+ * @(#)$File: file.h,v 1.91 2007/03/25 03:13:47 christos Exp $
*/
#ifndef __file_h__
@@ -46,10 +46,13 @@
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
+#include <regex.h>
#include <sys/types.h>
/* Do this here and now, because struct stat gets re-defined on solaris */
#include <sys/stat.h>
+#define ENABLE_CONDITIONALS
+
#ifndef MAGIC
#define MAGIC "/etc/magic"
#endif
@@ -66,6 +69,20 @@
#endif
#define public
+#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 MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
#ifndef HOWMANY
# define HOWMANY (256 * 1024) /* how much of the file to look at */
#endif
@@ -74,7 +91,7 @@
#define MAXstring 32 /* max leng of "string" types */
#define MAGICNO 0xF11E041C
-#define VERSIONNO 3
+#define VERSIONNO 4
#define FILE_MAGICSIZE (32 * 4)
#define FILE_LOAD 0
@@ -86,17 +103,20 @@ struct magic {
uint16_t cont_level; /* level of ">" */
uint8_t nospflag; /* supress space character */
uint8_t flag;
-#define INDIR 1 /* if '>(...)' appears, */
-#define UNSIGNED 2 /* comparison is unsigned */
-#define OFFADD 4 /* if '>&' appears, */
-#define INDIROFFADD 8 /* if '>&(' appears, */
+#define INDIR 1 /* if '(...)' appears */
+#define OFFADD 2 /* if '>&' or '>...(&' appears */
+#define INDIROFFADD 4 /* if '>&(' appears */
+#define UNSIGNED 8 /* comparison is unsigned */
+
/* Word 2 */
uint8_t reln; /* relation (0=eq, '>'=gt, etc) */
uint8_t vallen; /* length of string value, if any */
uint8_t type; /* int, short, long or string. */
uint8_t in_type; /* type of indirrection */
+#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
@@ -126,89 +146,33 @@ struct magic {
#define FILE_QLDATE 30
#define FILE_LEQLDATE 31
#define FILE_BEQLDATE 32
+#define FILE_NAMES_SIZE 33/* size of array to contain all names */
-#define FILE_FORMAT_NAME \
-/* 0 */ "invalid 0", \
-/* 1 */ "byte", \
-/* 2 */ "short", \
-/* 3 */ "invalid 3", \
-/* 4 */ "long", \
-/* 5 */ "string", \
-/* 6 */ "date", \
-/* 7 */ "beshort", \
-/* 8 */ "belong", \
-/* 9 */ "bedate", \
-/* 10 */ "leshort", \
-/* 11 */ "lelong", \
-/* 12 */ "ledate", \
-/* 13 */ "pstring", \
-/* 14 */ "ldate", \
-/* 15 */ "beldate", \
-/* 16 */ "leldate", \
-/* 17 */ "regex", \
-/* 18 */ "bestring16", \
-/* 19 */ "lestring16", \
-/* 20 */ "search", \
-/* 21 */ "medate", \
-/* 22 */ "meldate", \
-/* 23 */ "melong", \
-/* 24 */ "quad", \
-/* 25 */ "lequad", \
-/* 26 */ "bequad", \
-/* 27 */ "qdate", \
-/* 28 */ "leqdate", \
-/* 29 */ "beqdate", \
-/* 30 */ "qldate", \
-/* 31 */ "leqldate", \
-/* 32 */ "beqldate",
-
+#define IS_STRING(t) \
+ ((t) == FILE_STRING || \
+ (t) == FILE_PSTRING || \
+ (t) == FILE_BESTRING16 || \
+ (t) == FILE_LESTRING16 || \
+ (t) == FILE_REGEX || \
+ (t) == FILE_SEARCH || \
+ (t) == FILE_DEFAULT)
#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_FORMAT_STRING \
-/* 0 */ FILE_FMT_NONE, \
-/* 1 */ FILE_FMT_NUM, \
-/* 2 */ FILE_FMT_NUM, \
-/* 3 */ FILE_FMT_NONE, \
-/* 4 */ FILE_FMT_NUM, \
-/* 5 */ FILE_FMT_STR, \
-/* 6 */ FILE_FMT_STR, \
-/* 7 */ FILE_FMT_NUM, \
-/* 8 */ FILE_FMT_NUM, \
-/* 9 */ FILE_FMT_STR, \
-/* 10 */ FILE_FMT_NUM, \
-/* 11 */ FILE_FMT_NUM, \
-/* 12 */ FILE_FMT_STR, \
-/* 13 */ FILE_FMT_STR, \
-/* 14 */ FILE_FMT_STR, \
-/* 15 */ FILE_FMT_STR, \
-/* 16 */ FILE_FMT_STR, \
-/* 17 */ FILE_FMT_STR, \
-/* 18 */ FILE_FMT_STR, \
-/* 19 */ FILE_FMT_STR, \
-/* 20 */ FILE_FMT_STR, \
-/* 21 */ FILE_FMT_STR, \
-/* 22 */ FILE_FMT_STR, \
-/* 23 */ FILE_FMT_NUM, \
-/* 24 */ FILE_FMT_QUAD, \
-/* 25 */ FILE_FMT_QUAD, \
-/* 26 */ FILE_FMT_QUAD, \
-/* 27 */ FILE_FMT_STR, \
-/* 28 */ FILE_FMT_STR, \
-/* 29 */ FILE_FMT_STR, \
-/* 30 */ FILE_FMT_STR, \
-/* 31 */ FILE_FMT_STR, \
-/* 32 */ FILE_FMT_STR,
-
-
/* Word 3 */
uint8_t in_op; /* operator for indirection */
uint8_t mask_op; /* operator for mask */
+#ifdef ENABLE_CONDITIONALS
+ uint8_t cond; /* conditional type */
+ uint8_t dummy1;
+#else
uint8_t dummy1;
uint8_t dummy2;
+#endif
+
#define FILE_OPS "&|^+-*/%"
#define FILE_OPAND 0
#define FILE_OPOR 1
@@ -218,8 +182,20 @@ struct magic {
#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_UNUSED_3 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 */
uint32_t offset; /* offset to magic number */
/* Word 5 */
@@ -227,33 +203,44 @@ struct magic {
/* Word 6 */
uint32_t lineno; /* line number in magic file */
/* Word 7,8 */
- uint64_t mask; /* mask before comparison with value */
+ 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_count _u._s._count
+#define str_flags _u._s._flags
+
/* Words 9-16 */
union VALUETYPE {
uint8_t b;
uint16_t h;
uint32_t l;
uint64_t q;
- char s[MAXstring];
- struct {
- char *buf;
- size_t buflen;
- } search;
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 */
} value; /* either number or string */
/* Words 17..31 */
char desc[MAXDESC]; /* description */
};
#define BIT(A) (1 << (A))
-#define STRING_IGNORE_LOWERCASE BIT(0)
-#define STRING_COMPACT_BLANK BIT(1)
-#define STRING_COMPACT_OPTIONAL_BLANK BIT(2)
-#define CHAR_IGNORE_LOWERCASE 'c'
+#define STRING_COMPACT_BLANK BIT(0)
+#define STRING_COMPACT_OPTIONAL_BLANK BIT(1)
+#define STRING_IGNORE_LOWERCASE BIT(2)
+#define STRING_IGNORE_UPPERCASE BIT(3)
+#define REGEX_OFFSET_START BIT(4)
#define CHAR_COMPACT_BLANK 'B'
#define CHAR_COMPACT_OPTIONAL_BLANK 'b'
+#define CHAR_IGNORE_LOWERCASE 'c'
+#define CHAR_IGNORE_UPPERCASE 'C'
+#define CHAR_REGEX_OFFSET_START 's'
+#define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE|STRING_IGNORE_UPPERCASE)
/* list of magic entries */
@@ -267,54 +254,77 @@ struct mlist {
};
struct magic_set {
- struct mlist *mlist;
- struct cont {
- size_t len;
- int32_t *off;
- } c;
- struct out {
- /* Accumulation buffer */
- char *buf;
- char *ptr;
- size_t len;
- size_t size;
- /* Printable buffer */
- char *pbuf;
- size_t psize;
- } o;
- uint32_t offset;
- int error;
- int flags;
- int haderr;
- const char *file;
- size_t line;
+ struct mlist *mlist;
+ struct cont {
+ size_t len;
+ 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
+ } *li;
+ } c;
+ struct out {
+ /* Accumulation buffer */
+ char *buf;
+ char *ptr;
+ size_t left;
+ size_t size;
+ /* Printable buffer */
+ char *pbuf;
+ size_t psize;
+ } o;
+ uint32_t offset;
+ int error;
+ int flags;
+ int haderr;
+ const char *file;
+ size_t line; /* current magic line number */
+
+ /* 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;
+
+ union VALUETYPE ms_value; /* either number or string */
};
struct stat;
protected const char *file_fmttime(uint32_t, int);
-protected int file_buffer(struct magic_set *, int, const void *, size_t);
+protected int file_buffer(struct magic_set *, int, 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_printf(struct magic_set *, const char *, ...);
protected int file_reset(struct magic_set *);
-protected int file_tryelf(struct magic_set *, int, const unsigned char *, size_t);
-protected int file_zmagic(struct magic_set *, int, const unsigned char *, size_t);
+protected int file_tryelf(struct magic_set *, int, const unsigned char *,
+ size_t);
+protected int file_zmagic(struct magic_set *, int, const char *,
+ const unsigned char *, size_t);
protected int file_ascmagic(struct magic_set *, const unsigned char *, size_t);
protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
protected int file_softmagic(struct magic_set *, const unsigned char *, size_t);
protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
-protected uint64_t file_signextend(struct magic_set *, struct magic *, uint64_t);
+protected uint64_t file_signextend(struct magic_set *, struct magic *,
+ uint64_t);
protected void file_delmagic(struct magic *, int type, size_t entries);
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 *, ...);
+protected void file_magerror(struct magic_set *, const char *, ...);
protected void file_magwarn(struct magic_set *, const char *, ...);
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);
+protected ssize_t sread(int, void *, size_t, int);
+protected int file_check_mem(struct magic_set *, unsigned int);
#ifndef COMPILE_ONLY
extern const char *file_names[];
diff --git a/contrib/file/fsmagic.c b/contrib/file/fsmagic.c
index 884ffb8..aa3e509 100644
--- a/contrib/file/fsmagic.c
+++ b/contrib/file/fsmagic.c
@@ -57,7 +57,7 @@
#undef HAVE_MAJOR
#ifndef lint
-FILE_RCSID("@(#)$Id: fsmagic.c,v 1.46 2005/06/25 15:52:14 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.47 2007/01/12 17:38:28 christos Exp $")
#endif /* lint */
protected int
diff --git a/contrib/file/funcs.c b/contrib/file/funcs.c
index 824e3a0..47f0e4f 100644
--- a/contrib/file/funcs.c
+++ b/contrib/file/funcs.c
@@ -36,9 +36,19 @@
#if defined(HAVE_WCTYPE_H)
#include <wctype.h>
#endif
+#if defined(HAVE_LIMITS_H)
+#include <limits.h>
+#endif
+#ifndef SIZE_T_MAX
+#ifdef __LP64__
+#define SIZE_T_MAX (size_t)0xfffffffffffffffffU
+#else
+#define SIZE_T_MAX (size_t)0xffffffffU
+#endif
+#endif
#ifndef lint
-FILE_RCSID("@(#)$Id: funcs.c,v 1.23 2006/12/11 21:48:49 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.32 2007/05/24 17:22:27 christos Exp $")
#endif /* lint */
#ifndef HAVE_VSNPRINTF
@@ -52,28 +62,32 @@ protected int
file_printf(struct magic_set *ms, const char *fmt, ...)
{
va_list ap;
- size_t len;
+ size_t len, size;
char *buf;
va_start(ap, fmt);
- if ((len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap)) >= ms->o.len) {
+ if ((len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap)) >= ms->o.left) {
+ long diff; /* XXX: really ptrdiff_t */
+
va_end(ap);
- if ((buf = realloc(ms->o.buf, len + 1024)) == NULL) {
- file_oomem(ms, len + 1024);
+ size = (ms->o.size - ms->o.left) + len + 1024;
+ if ((buf = realloc(ms->o.buf, size)) == NULL) {
+ file_oomem(ms, size);
return -1;
}
- ms->o.ptr = buf + (ms->o.ptr - ms->o.buf);
+ diff = ms->o.ptr - ms->o.buf;
+ ms->o.ptr = buf + diff;
ms->o.buf = buf;
- ms->o.len = ms->o.size - (ms->o.ptr - ms->o.buf);
- ms->o.size = len + 1024;
+ ms->o.left = size - diff;
+ ms->o.size = size;
va_start(ap, fmt);
- len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap);
+ len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap);
}
- ms->o.ptr += len;
- ms->o.len -= len;
va_end(ap);
+ ms->o.ptr += len;
+ ms->o.left -= len;
return 0;
}
@@ -81,18 +95,22 @@ file_printf(struct magic_set *ms, const char *fmt, ...)
* error - print best error message possible
*/
/*VARARGS*/
-protected void
-file_error(struct magic_set *ms, int error, const char *f, ...)
+private void
+file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
+ uint32_t lineno)
{
- va_list va;
+ size_t len;
/* Only the first error is ok */
if (ms->haderr)
return;
- va_start(va, f);
- (void)vsnprintf(ms->o.buf, ms->o.size, f, va);
- va_end(va);
+ len = 0;
+ if (lineno != 0) {
+ (void)snprintf(ms->o.buf, ms->o.size, "line %u: ", lineno);
+ len = strlen(ms->o.buf);
+ }
+ (void)vsnprintf(ms->o.buf + len, ms->o.size - len, f, va);
if (error > 0) {
- size_t len = strlen(ms->o.buf);
+ len = strlen(ms->o.buf);
(void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
strerror(error));
}
@@ -100,6 +118,28 @@ file_error(struct magic_set *ms, int error, const char *f, ...)
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)
@@ -121,17 +161,36 @@ file_badread(struct magic_set *ms)
#ifndef COMPILE_ONLY
protected int
-file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
+file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
+ size_t nb)
{
int m;
+
+#ifdef __EMX__
+ if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
+ switch (file_os2_apptype(ms, inname, buf, nb)) {
+ case -1:
+ return -1;
+ case 0:
+ break;
+ default:
+ return 1;
+ }
+ }
+#endif
+
/* try compression stuff */
- if ((m = file_zmagic(ms, fd, buf, nb)) == 0) {
+ if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
+ (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
/* Check if we have a tar file */
- if ((m = file_is_tar(ms, buf, nb)) == 0) {
+ if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
+ (m = file_is_tar(ms, buf, nb)) == 0) {
/* try tests in /etc/magic (or surrogate magic file) */
- if ((m = file_softmagic(ms, buf, nb)) == 0) {
+ if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
+ (m = file_softmagic(ms, buf, nb)) == 0) {
/* try known keywords, check whether it is ASCII */
- if ((m = file_ascmagic(ms, buf, nb)) == 0) {
+ if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
+ (m = file_ascmagic(ms, buf, nb)) == 0) {
/* abandon hope, all ye who remain here */
if (file_printf(ms, ms->flags & MAGIC_MIME ?
(nb ? "application/octet-stream" :
@@ -144,6 +203,19 @@ file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
}
}
}
+#ifdef BUILTIN_ELF
+ if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && nb > 5 && fd != -1) {
+ /*
+ * 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.
+ */
+ (void)file_tryelf(ms, fd, buf, nb);
+ }
+#endif
return m;
}
#endif
@@ -156,6 +228,7 @@ file_reset(struct magic_set *ms)
return -1;
}
ms->o.ptr = ms->o.buf;
+ ms->o.left = ms->o.size;
ms->haderr = 0;
ms->error = -1;
return 0;
@@ -172,8 +245,8 @@ file_reset(struct magic_set *ms)
protected const char *
file_getbuffer(struct magic_set *ms)
{
- char *nbuf, *op, *np;
- size_t nsize;
+ char *pbuf, *op, *np;
+ size_t psize, len;
if (ms->haderr)
return NULL;
@@ -181,14 +254,20 @@ file_getbuffer(struct magic_set *ms)
if (ms->flags & MAGIC_RAW)
return ms->o.buf;
- nsize = ms->o.len * 4 + 1;
- if (ms->o.psize < nsize) {
- if ((nbuf = realloc(ms->o.pbuf, nsize)) == NULL) {
- file_oomem(ms, nsize);
+ len = ms->o.size - ms->o.left;
+ /* * 4 is for octal representation, + 1 is for NUL */
+ if (len > (SIZE_T_MAX - 1) / 4) {
+ file_oomem(ms, len);
+ return NULL;
+ }
+ psize = len * 4 + 1;
+ if (ms->o.psize < psize) {
+ if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) {
+ file_oomem(ms, psize);
return NULL;
}
- ms->o.psize = nsize;
- ms->o.pbuf = nbuf;
+ ms->o.psize = psize;
+ ms->o.pbuf = pbuf;
}
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
@@ -241,9 +320,30 @@ file_getbuffer(struct magic_set *ms)
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) * sizeof(*ms->c.li);
+ ms->c.li = (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;
+}
/*
- * Yes these wrappers suffer from buffer overflows, but if your OS does not have
- * the real functions, maybe you should consider replacing your OS?
+ * Yes these wrappers suffer from buffer overflows, but if your OS does not
+ * have the real functions, maybe you should consider replacing your OS?
*/
#ifndef HAVE_VSNPRINTF
int
diff --git a/contrib/file/is_tar.c b/contrib/file/is_tar.c
index 6461724..c7d4d4d 100644
--- a/contrib/file/is_tar.c
+++ b/contrib/file/is_tar.c
@@ -45,7 +45,7 @@
#include "tar.h"
#ifndef lint
-FILE_RCSID("@(#)$Id: is_tar.c,v 1.26 2006/05/03 15:19:25 christos Exp $")
+FILE_RCSID("@(#)$File: is_tar.c,v 1.27 2007/01/12 17:38:28 christos Exp $")
#endif
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
diff --git a/contrib/file/magic.c b/contrib/file/magic.c
index 3f24075..54db48b 100644
--- a/contrib/file/magic.c
+++ b/contrib/file/magic.c
@@ -63,7 +63,7 @@
#include "patchlevel.h"
#ifndef lint
-FILE_RCSID("@(#)$Id: magic.c,v 1.35 2006/10/31 19:37:17 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.41 2007/03/26 17:59:50 christos Exp $")
#endif /* lint */
#ifdef __EMX__
@@ -86,7 +86,7 @@ magic_open(int flags)
{
struct magic_set *ms;
- if ((ms = malloc(sizeof(struct magic_set))) == NULL)
+ if ((ms = calloc((size_t)1, sizeof(struct magic_set))) == NULL)
return NULL;
if (magic_setflags(ms, flags) == -1) {
@@ -94,7 +94,7 @@ magic_open(int flags)
goto free1;
}
- ms->o.ptr = ms->o.buf = malloc(ms->o.size = 1024);
+ ms->o.ptr = ms->o.buf = malloc(ms->o.left = ms->o.size = 1024);
if (ms->o.buf == NULL)
goto free1;
@@ -102,14 +102,15 @@ magic_open(int flags)
if (ms->o.pbuf == NULL)
goto free2;
- ms->c.off = malloc((ms->c.len = 10) * sizeof(*ms->c.off));
- if (ms->c.off == NULL)
+ ms->c.li = malloc((ms->c.len = 10) * sizeof(*ms->c.li));
+ if (ms->c.li == NULL)
goto free3;
- ms->o.len = 0;
ms->haderr = 0;
ms->error = -1;
ms->mlist = NULL;
+ ms->file = "unknown";
+ ms->line = 0;
return ms;
free3:
free(ms->o.pbuf);
@@ -162,7 +163,7 @@ magic_close(struct magic_set *ms)
free_mlist(ms->mlist);
free(ms->o.pbuf);
free(ms->o.buf);
- free(ms->c.off);
+ free(ms->c.li);
free(ms);
}
@@ -305,7 +306,7 @@ magic_file(struct magic_set *ms, const char *inname)
ssize_t r = 0;
while ((r = sread(fd, (void *)&buf[nbytes],
- (size_t)(HOWMANY - nbytes))) > 0) {
+ (size_t)(HOWMANY - nbytes), 1)) > 0) {
nbytes += r;
if (r < PIPE_BUF) break;
}
@@ -334,32 +335,8 @@ magic_file(struct magic_set *ms, const char *inname)
goto done;
} else {
(void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
-#ifdef __EMX__
- switch (file_os2_apptype(ms, inname, buf, nbytes)) {
- case -1:
- goto done;
- case 0:
- break;
- default:
- rv = 0;
- goto done;
- }
-#endif
- if (file_buffer(ms, fd, buf, (size_t)nbytes) == -1)
+ if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
goto done;
-#ifdef BUILTIN_ELF
- if (nbytes > 5) {
- /*
- * 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.
- */
- file_tryelf(ms, fd, buf, (size_t)nbytes);
- }
-#endif
}
rv = 0;
done:
@@ -378,7 +355,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
* The main work is done here!
* We have the file name and/or the data buffer to be identified.
*/
- if (file_buffer(ms, -1, buf, nb) == -1) {
+ if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
return NULL;
}
return file_getbuffer(ms);
diff --git a/contrib/file/magic.h b/contrib/file/magic.h
index 869f9ea..39fa2e1 100644
--- a/contrib/file/magic.h
+++ b/contrib/file/magic.h
@@ -29,17 +29,26 @@
#include <sys/types.h>
-#define MAGIC_NONE 0x000 /* No flags */
-#define MAGIC_DEBUG 0x001 /* Turn on debugging */
-#define MAGIC_SYMLINK 0x002 /* Follow symlinks */
-#define MAGIC_COMPRESS 0x004 /* Check inside compressed files */
-#define MAGIC_DEVICES 0x008 /* Look at the contents of devices */
-#define MAGIC_MIME 0x010 /* Return a mime string */
-#define MAGIC_CONTINUE 0x020 /* Return all matches */
-#define MAGIC_CHECK 0x040 /* Print warnings to stderr */
-#define MAGIC_PRESERVE_ATIME 0x080 /* Restore access time on exit */
-#define MAGIC_RAW 0x100 /* Don't translate unprintable chars */
-#define MAGIC_ERROR 0x200 /* Handle ENOENT etc as real errors */
+#define MAGIC_NONE 0x000000 /* No flags */
+#define MAGIC_DEBUG 0x000001 /* Turn on debugging */
+#define MAGIC_SYMLINK 0x000002 /* Follow symlinks */
+#define MAGIC_COMPRESS 0x000004 /* Check inside compressed files */
+#define MAGIC_DEVICES 0x000008 /* Look at the contents of devices */
+#define MAGIC_MIME 0x000010 /* Return a mime string */
+#define MAGIC_CONTINUE 0x000020 /* Return all matches */
+#define MAGIC_CHECK 0x000040 /* Print warnings to stderr */
+#define MAGIC_PRESERVE_ATIME 0x000080 /* Restore access time on exit */
+#define MAGIC_RAW 0x000100 /* Don't translate unprintable chars */
+#define MAGIC_ERROR 0x000200 /* Handle ENOENT etc as real errors */
+#define MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */
+#define MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */
+#define MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */
+#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
+#define MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */
+#define MAGIC_NO_CHECK_ASCII 0x020000 /* Don't check for ascii files */
+#define MAGIC_NO_CHECK_TROFF 0x040000 /* Don't check ascii/troff */
+#define MAGIC_NO_CHECK_FORTRAN 0x080000 /* Don't check ascii/fortran */
+#define MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check ascii/tokens */
#ifdef __cplusplus
extern "C" {
diff --git a/contrib/file/magic.mime b/contrib/file/magic.mime
index 3fa67e5..787a6c8 100644
--- a/contrib/file/magic.mime
+++ b/contrib/file/magic.mime
@@ -193,7 +193,12 @@
0 beshort 0x4De1 audio/MP4A-LATM
# MPEG Layer 3 sound files
-0 beshort &0xffe0 audio/mpeg
+# modified by Joerg Jenderek
+# GRR the original test are too common for many DOS files
+# so test 1 <= kbits nibble <= E
+0 beshort &0xffe0
+>2 ubyte&0xF0 >0x0F
+>>2 ubyte&0xF0 <0xE1 audio/mpeg
#MP3 with ID3 tag
0 string ID3 audio/mpeg
# Ogg/Vorbis
@@ -587,6 +592,14 @@
# RTF - Rich Text Format
0 string {\\rtf text/rtf
+# TeX documents, from Daniel Quinlan (quinlan@yggdrasil.com)
+0 search/400 \\input text/x-tex
+0 search/400 \\section text/x-tex
+0 search/400 \\setlength text/x-tex
+0 search/400 \\documentstyle text/x-tex
+0 search/400 \\chapter text/x-tex
+0 search/400 \\documentclass text/x-tex
+
#------------------------------------------------------------------------------
# animation: file(1) magic for animation/movie formats
#
@@ -674,9 +687,9 @@
#
# KDE
0 string [KDE\ Desktop\ Entry] application/x-kdelnk
-0 string \#\ KDE\ Config\ File application/x-kdelnk
+0 string #\ KDE\ Config\ File application/x-kdelnk
# xmcd database file for kscd
-0 string \#\ xmcd text/xmcd
+0 string #\ xmcd text/xmcd
#------------------------------------------------------------------------------
# pkgadd: file(1) magic for SysV R4 PKG Datastreams
@@ -861,6 +874,8 @@
# miscellaneous formats
0 string LZ application/octet-stream
+# DOS device drivers by Joerg Jenderek
+0 belong 0xffffffff application/octet-stream
# .EXE formats (Greg Roelofs, newt@uchicago.edu)
#
@@ -936,3 +951,7 @@
#
128 string DICM application/dicom
+
+# Symbian installation files
+8 lelong 0x10000419 application/vnd.symbian.install
+0 lelong 0x10201A7A x-epoc/x-sisx-app
diff --git a/contrib/file/magic2mime b/contrib/file/magic2mime
index dfb1260..26f84d28 100755
--- a/contrib/file/magic2mime
+++ b/contrib/file/magic2mime
@@ -1,6 +1,6 @@
#! /usr/bin/env perl
# -*- PERL -*-
-# $Id: magic2mime,v 1.4 2006/11/25 18:36:10 christos Exp $
+# $File: magic2mime,v 1.4 2006/11/25 18:36:10 christos Exp $
# Copyright (c) 1996, 1997 vax@linkdead.paranoia.com (VaX#n8)
#
# Usage: echo 'your-file-output-here' | file_to_ctype.pl
diff --git a/contrib/file/names.h b/contrib/file/names.h
index e71f6aa..f06be17 100644
--- a/contrib/file/names.h
+++ b/contrib/file/names.h
@@ -32,7 +32,7 @@
* appear at fixed offsets into the file. Don't make HOWMANY
* too high unless you have a very fast CPU.
*
- * $Id: names.h,v 1.25 2004/09/11 19:15:57 christos Exp $
+ * $File: names.h,v 1.27 2007/05/08 16:47:03 christos Exp $
*/
/*
@@ -167,6 +167,8 @@ static struct names {
{".text", L_MACH},
{"clr", L_MACH},
{"(input,", L_PAS},
+ {"program", L_PAS},
+ {"record", L_PAS},
{"dcl", L_PLI},
{"Received:", L_MAIL},
{">From", L_MAIL},
diff --git a/contrib/file/patchlevel.h b/contrib/file/patchlevel.h
index 334732c..e46a920 100644
--- a/contrib/file/patchlevel.h
+++ b/contrib/file/patchlevel.h
@@ -1,11 +1,20 @@
#define FILE_VERSION_MAJOR 4
-#define patchlevel 19
+#define patchlevel 21
/*
* Patchlevel file for Ian Darwin's MAGIC command.
- * $Id: patchlevel.h,v 1.62 2006/12/11 21:49:58 christos Exp $
+ * $File: patchlevel.h,v 1.65 2007/05/24 17:22:27 christos Exp $
*
* $Log: patchlevel.h,v $
+ * 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
*
diff --git a/contrib/file/print.c b/contrib/file/print.c
index 28cca18..d1d1ec1 100644
--- a/contrib/file/print.c
+++ b/contrib/file/print.c
@@ -41,7 +41,7 @@
#include <time.h>
#ifndef lint
-FILE_RCSID("@(#)$Id: print.c,v 1.56 2006/12/08 20:31:07 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.59 2007/03/05 02:41:29 christos Exp $")
#endif /* lint */
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
@@ -52,8 +52,8 @@ file_mdump(struct magic *m)
{
private const char optyp[] = { FILE_OPS };
- (void) fprintf(stderr, "[%zu", m->lineno);
- (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
+ (void) fprintf(stderr, "[%u", m->lineno);
+ (void) fprintf(stderr, ">>>>>>>> %u" + 8 - (m->cont_level & 7),
m->offset);
if (m->flag & INDIR) {
@@ -63,9 +63,9 @@ file_mdump(struct magic *m)
file_names[m->in_type] : "*bad*");
if (m->in_op & FILE_OPINVERSE)
(void) fputc('~', stderr);
- (void) fprintf(stderr, "%c%d),",
- ((m->in_op&0x7F) < SZOF(optyp)) ?
- optyp[m->in_op&0x7F] : '?',
+ (void) fprintf(stderr, "%c%u),",
+ ((m->in_op & FILE_OPS_MASK) < SZOF(optyp)) ?
+ optyp[m->in_op & FILE_OPS_MASK] : '?',
m->in_offset);
}
(void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
@@ -73,25 +73,36 @@ file_mdump(struct magic *m)
(m->type < file_nnames) ? file_names[m->type] : "*bad*");
if (m->mask_op & FILE_OPINVERSE)
(void) fputc('~', stderr);
- if (m->mask) {
- if ((m->mask_op & 0x7F) < SZOF(optyp))
- fputc(optyp[m->mask_op&0x7F], stderr);
- else
- fputc('?', stderr);
- if (FILE_STRING != m->type || FILE_PSTRING != m->type)
- (void) fprintf(stderr, "%.8llx",
- (unsigned long long)m->mask);
- else {
- if (m->mask & STRING_IGNORE_LOWERCASE)
- (void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
- if (m->mask & STRING_COMPACT_BLANK)
+
+ if (IS_STRING(m->type)) {
+ if (m->str_flags) {
+ (void) fputc('/', stderr);
+ if (m->str_flags & STRING_COMPACT_BLANK)
(void) fputc(CHAR_COMPACT_BLANK, stderr);
- if (m->mask & STRING_COMPACT_OPTIONAL_BLANK)
+ if (m->str_flags & STRING_COMPACT_OPTIONAL_BLANK)
(void) fputc(CHAR_COMPACT_OPTIONAL_BLANK,
- stderr);
+ 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_count)
+ (void) fprintf(stderr, "/%u", m->str_count);
+ }
+ else {
+ if ((m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
+ (void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
+ else
+ (void) fputc('?', stderr);
+
+ if (m->num_mask) {
+ (void) fprintf(stderr, "%.8llx",
+ (unsigned long long)m->num_mask);
}
}
-
(void) fprintf(stderr, ",%c", m->reln);
if (m->reln != 'x') {
@@ -146,6 +157,9 @@ file_mdump(struct magic *m)
(void)fprintf(stderr, "%s,",
file_fmttime((uint32_t)m->value.q, 0));
break;
+ case FILE_DEFAULT:
+ /* XXX - do anything here? */
+ break;
default:
(void) fputs("*bad*", stderr);
break;
@@ -169,7 +183,7 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
(unsigned long)ms->line);
(void) vfprintf(stderr, f, va);
va_end(va);
- fputc('\n', stderr);
+ (void) fputc('\n', stderr);
}
protected const char *
diff --git a/contrib/file/readelf.c b/contrib/file/readelf.c
index 69318fa..dd9004b 100644
--- a/contrib/file/readelf.c
+++ b/contrib/file/readelf.c
@@ -37,7 +37,7 @@
#include "readelf.h"
#ifndef lint
-FILE_RCSID("@(#)$Id: readelf.c,v 1.61 2006/11/15 15:53:23 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.63 2007/01/16 14:56:45 ljt Exp $")
#endif
#ifdef ELFCORE
@@ -155,7 +155,7 @@ getu64(int swap, uint64_t value)
#define xph_type (class == ELFCLASS32 \
? getu32(swap, ph32.p_type) \
: getu32(swap, ph64.p_type))
-#define xph_offset (class == ELFCLASS32 \
+#define xph_offset (off_t)(class == ELFCLASS32 \
? getu32(swap, ph32.p_offset) \
: getu64(swap, ph64.p_offset))
#define xph_align (size_t)((class == ELFCLASS32 \
@@ -293,7 +293,7 @@ dophn_core(struct magic_set *ms, int class, int swap, int fd, off_t off,
* This is a PT_NOTE section; loop through all the notes
* in the section.
*/
- if (lseek(fd, (off_t)xph_offset, SEEK_SET) == (off_t)-1) {
+ if (lseek(fd, xph_offset, SEEK_SET) == (off_t)-1) {
file_badseek(ms);
return -1;
}
@@ -858,7 +858,7 @@ dophn_exec(struct magic_set *ms, int class, int swap, int fd, off_t off,
* This is a PT_NOTE section; loop through all the notes
* in the section.
*/
- if (lseek(fd, (off_t)xph_offset, SEEK_SET)
+ if (lseek(fd, xph_offset, SEEK_SET)
== (off_t)-1) {
file_badseek(ms);
return -1;
diff --git a/contrib/file/softmagic.c b/contrib/file/softmagic.c
index 7725048..e37517c 100644
--- a/contrib/file/softmagic.c
+++ b/contrib/file/softmagic.c
@@ -35,24 +35,22 @@
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
-#include <regex.h>
#ifndef lint
-FILE_RCSID("@(#)$Id: softmagic.c,v 1.87 2006/12/11 21:48:49 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.99 2007/05/08 14:44:18 christos Exp $")
#endif /* lint */
private int match(struct magic_set *, struct magic *, uint32_t,
const unsigned char *, size_t);
-private int mget(struct magic_set *, union VALUETYPE *, const unsigned char *,
+private int mget(struct magic_set *, const unsigned char *,
struct magic *, size_t, unsigned int);
-private int magiccheck(struct magic_set *, union VALUETYPE *, struct magic *);
-private int32_t mprint(struct magic_set *, union VALUETYPE *, struct magic *);
+private int magiccheck(struct magic_set *, struct magic *);
+private int32_t mprint(struct magic_set *, struct magic *);
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);
-private int mconvert(struct magic_set *, union VALUETYPE *, struct magic *);
-private int check_mem(struct magic_set *, unsigned int);
+ const unsigned char *, uint32_t, size_t, size_t);
+private int mconvert(struct magic_set *, struct magic *);
private int print_sep(struct magic_set *, int);
private void cvt_8(union VALUETYPE *, const struct magic *);
private void cvt_16(union VALUETYPE *, const struct magic *);
@@ -110,25 +108,26 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
uint32_t magindex = 0;
unsigned int cont_level = 0;
int need_separator = 0;
- union VALUETYPE p;
- int32_t oldoff = 0;
int returnval = 0; /* if a match is found it is set to 1*/
int firstline = 1; /* a flag to print X\n X\n- X */
int printed_something = 0;
- if (check_mem(ms, cont_level) == -1)
+ if (file_check_mem(ms, cont_level) == -1)
return -1;
for (magindex = 0; magindex < nmagic; magindex++) {
- /* if main entry matches, print it... */
+ int flush;
+
ms->offset = magic[magindex].offset;
- int flush = !mget(ms, &p, s, &magic[magindex], nbytes,
- cont_level);
+ ms->line = magic[magindex].lineno;
+
+ /* if main entry matches, print it... */
+ flush = !mget(ms, s, &magic[magindex], nbytes, cont_level);
if (flush) {
if (magic[magindex].reln == '!')
flush = 0;
} else {
- switch (magiccheck(ms, &p, &magic[magindex])) {
+ switch (magiccheck(ms, &magic[magindex])) {
case -1:
return -1;
case 0:
@@ -144,8 +143,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* flush its continuations
*/
while (magindex < nmagic - 1 &&
- magic[magindex + 1].cont_level != 0)
- magindex++;
+ magic[magindex + 1].cont_level != 0)
+ magindex++;
continue;
}
@@ -160,16 +159,18 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
return -1;
}
- if ((ms->c.off[cont_level] = mprint(ms, &p, &magic[magindex]))
+ if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex]))
== -1)
return -1;
/* and any continuations that match */
- if (check_mem(ms, ++cont_level) == -1)
+ if (file_check_mem(ms, ++cont_level) == -1)
return -1;
- while (magic[magindex+1].cont_level != 0 &&
- ++magindex < nmagic) {
+ while (magic[magindex+1].cont_level != 0 &&
+ ++magindex < nmagic) {
+ ms->line = magic[magindex].lineno; /* for messages */
+
if (cont_level < magic[magindex].cont_level)
continue;
if (cont_level > magic[magindex].cont_level) {
@@ -182,20 +183,39 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
ms->offset = magic[magindex].offset;
if (magic[magindex].flag & OFFADD) {
ms->offset +=
- ms->c.off[cont_level - 1];
+ ms->c.li[cont_level - 1].off;
}
- flush = !mget(ms, &p, s, &magic[magindex], nbytes,
+#ifdef ENABLE_CONDITIONALS
+ if (magic[magindex].cond == COND_ELSE ||
+ magic[magindex].cond == COND_ELIF) {
+ if (ms->c.li[cont_level].last_match == 1)
+ continue;
+ }
+#endif
+ flush = !mget(ms, s, &magic[magindex], nbytes,
cont_level);
if (flush && magic[magindex].reln != '!')
continue;
- switch (flush ? 1 : magiccheck(ms, &p, &magic[magindex])) {
+ switch (flush ? 1 : magiccheck(ms, &magic[magindex])) {
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 (magic[magindex].type != FILE_DEFAULT)
+ ms->c.li[cont_level].got_match = 1;
+ else if (ms->c.li[cont_level].got_match) {
+ ms->c.li[cont_level].got_match = 0;
+ break;
+ }
/*
* If we are going to print something,
* make sure that we have a separator first.
@@ -206,22 +226,20 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
return -1;
}
/*
- * This continuation matched.
- * Print its message, with
- * a blank before it if
- * the previous item printed
- * and this item isn't empty.
+ * This continuation matched. Print
+ * its message, with a blank before it
+ * if the previous item printed and
+ * this item isn't empty.
*/
/* space if previous printed */
if (need_separator
&& (magic[magindex].nospflag == 0)
- && (magic[magindex].desc[0] != '\0')) {
+ && (magic[magindex].desc[0] != '\0')) {
if (file_printf(ms, " ") == -1)
return -1;
need_separator = 0;
}
- if ((ms->c.off[cont_level] = mprint(ms, &p,
- &magic[magindex])) == -1)
+ if ((ms->c.li[cont_level].off = mprint(ms, &magic[magindex])) == -1)
return -1;
if (magic[magindex].desc[0])
need_separator = 1;
@@ -231,8 +249,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* at a higher level,
* process them.
*/
- if (check_mem(ms, ++cont_level) == -1)
+ if (file_check_mem(ms, ++cont_level) == -1)
return -1;
+ break;
}
}
firstline = 0;
@@ -246,22 +265,6 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
}
private int
-check_mem(struct magic_set *ms, unsigned int level)
-{
- size_t len;
-
- if (level < ms->c.len)
- return 0;
-
- len = (ms->c.len += 20) * sizeof(*ms->c.off);
- ms->c.off = (ms->c.off == NULL) ? malloc(len) : realloc(ms->c.off, len);
- if (ms->c.off != NULL)
- return 0;
- file_oomem(ms, len);
- return -1;
-}
-
-private int
check_fmt(struct magic_set *ms, struct magic *m)
{
regex_t rx;
@@ -273,8 +276,8 @@ check_fmt(struct magic_set *ms, struct magic *m)
rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
if (rc) {
char errmsg[512];
- regerror(rc, &rx, errmsg, sizeof(errmsg));
- file_error(ms, 0, "regex error %d, (%s)", rc, errmsg);
+ (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
+ file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
return -1;
} else {
rc = regexec(&rx, m->desc, 0, 0, 0);
@@ -283,13 +286,33 @@ check_fmt(struct magic_set *ms, struct magic *m)
}
}
+#ifndef HAVE_STRNDUP
+char * strndup(const char *, size_t);
+
+char *
+strndup(const char *str, size_t n)
+{
+ size_t len;
+ char *copy;
+
+ len = strlen(str);
+ if (len > n)
+ len = n;
+ if (!(copy = malloc(len + 1)))
+ return (NULL);
+ (void) memcpy(copy, str, len + 1);
+ copy[len] = '\0';
+ return (copy);
+}
+#endif /* HAVE_STRNDUP */
+
private int32_t
-mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
+mprint(struct magic_set *ms, struct magic *m)
{
uint64_t v;
- int32_t t = 0;
+ int64_t t = 0;
char buf[512];
-
+ union VALUETYPE *p = &ms->ms_value;
switch (m->type) {
case FILE_BYTE:
@@ -364,6 +387,7 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
return -1;
t = ms->offset + sizeof(int64_t);
break;
+
case FILE_STRING:
case FILE_PSTRING:
case FILE_BESTRING16:
@@ -421,20 +445,45 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
t = ms->offset + sizeof(uint64_t);
break;
- case FILE_REGEX:
- if (file_printf(ms, m->desc, p->s) == -1)
+ case FILE_REGEX: {
+ char *cp;
+ int rval;
+
+ cp = strndup((const char *)ms->search.s, ms->search.rm_len);
+ if (cp == NULL) {
+ file_oomem(ms, ms->search.rm_len);
return -1;
- t = ms->offset + strlen(p->s);
+ }
+ rval = file_printf(ms, m->desc, cp);
+ 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_SEARCH:
if (file_printf(ms, m->desc, m->value.s) == -1)
return -1;
- t = ms->offset + m->vallen;
+ if ((m->str_flags & REGEX_OFFSET_START))
+ t = ms->search.offset;
+ else
+ t = ms->search.offset + m->vallen;
+ break;
+
+ case FILE_DEFAULT:
+ if (file_printf(ms, m->desc, m->value.s) == -1)
+ return -1;
+ t = ms->offset;
break;
default:
- file_error(ms, 0, "invalid m->type (%d) in mprint()", m->type);
+ file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
return -1;
}
return(t);
@@ -442,31 +491,31 @@ mprint(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
#define DO_CVT(fld, cast) \
- if (m->mask) \
- switch (m->mask_op & 0x7F) { \
+ if (m->num_mask) \
+ switch (m->mask_op & FILE_OPS_MASK) { \
case FILE_OPAND: \
- p->fld &= cast m->mask; \
+ p->fld &= cast m->num_mask; \
break; \
case FILE_OPOR: \
- p->fld |= cast m->mask; \
+ p->fld |= cast m->num_mask; \
break; \
case FILE_OPXOR: \
- p->fld ^= cast m->mask; \
+ p->fld ^= cast m->num_mask; \
break; \
case FILE_OPADD: \
- p->fld += cast m->mask; \
+ p->fld += cast m->num_mask; \
break; \
case FILE_OPMINUS: \
- p->fld -= cast m->mask; \
+ p->fld -= cast m->num_mask; \
break; \
case FILE_OPMULTIPLY: \
- p->fld *= cast m->mask; \
+ p->fld *= cast m->num_mask; \
break; \
case FILE_OPDIVIDE: \
- p->fld /= cast m->mask; \
+ p->fld /= cast m->num_mask; \
break; \
case FILE_OPMODULO: \
- p->fld %= cast m->mask; \
+ p->fld %= cast m->num_mask; \
break; \
} \
if (m->mask_op & FILE_OPINVERSE) \
@@ -502,8 +551,10 @@ cvt_64(union VALUETYPE *p, const struct magic *m)
* (unless you have a better idea)
*/
private int
-mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
+mconvert(struct magic_set *ms, struct magic *m)
{
+ union VALUETYPE *p = &ms->ms_value;
+
switch (m->type) {
case FILE_BYTE:
cvt_8(p, m);
@@ -523,31 +574,29 @@ mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
return 1;
case FILE_STRING:
case FILE_BESTRING16:
- case FILE_LESTRING16:
- {
- size_t len;
-
- /* Null terminate and eat *trailing* return */
- p->s[sizeof(p->s) - 1] = '\0';
- len = strlen(p->s);
- if (len-- && p->s[len] == '\n')
- p->s[len] = '\0';
- return 1;
- }
- case FILE_PSTRING:
- {
- char *ptr1 = p->s, *ptr2 = ptr1 + 1;
- size_t len = *p->s;
- if (len >= sizeof(p->s))
- len = sizeof(p->s) - 1;
- while (len--)
- *ptr1++ = *ptr2++;
- *ptr1 = '\0';
- len = strlen(p->s);
- if (len-- && p->s[len] == '\n')
- p->s[len] = '\0';
- return 1;
- }
+ case FILE_LESTRING16: {
+ size_t len;
+
+ /* Null terminate and eat *trailing* return */
+ p->s[sizeof(p->s) - 1] = '\0';
+ len = strlen(p->s);
+ if (len-- && p->s[len] == '\n')
+ p->s[len] = '\0';
+ return 1;
+ }
+ case FILE_PSTRING: {
+ char *ptr1 = p->s, *ptr2 = ptr1 + 1;
+ size_t len = *p->s;
+ if (len >= sizeof(p->s))
+ len = sizeof(p->s) - 1;
+ while (len--)
+ *ptr1++ = *ptr2++;
+ *ptr1 = '\0';
+ len = strlen(p->s);
+ if (len-- && p->s[len] == '\n')
+ p->s[len] = '\0';
+ return 1;
+ }
case FILE_BESHORT:
p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
cvt_16(p, m);
@@ -597,9 +646,10 @@ mconvert(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
return 1;
case FILE_REGEX:
case FILE_SEARCH:
+ case FILE_DEFAULT:
return 1;
default:
- file_error(ms, 0, "invalid type %d in mconvert()", m->type);
+ file_magerror(ms, "invalid type %d in mconvert()", m->type);
return 0;
}
}
@@ -616,61 +666,86 @@ mdebug(uint32_t offset, const char *str, size_t len)
private int
mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
- const unsigned char *s, uint32_t offset, size_t nbytes)
+ const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
{
- if (type == FILE_REGEX && indir == 0) {
- /*
- * offset is interpreted as last line to search,
- * (starting at 1), not as bytes-from start-of-file
- */
- char *b, *c, *last = NULL;
- if (s == NULL) {
- p->search.buflen = 0;
- p->search.buf = NULL;
+ /*
+ * Note: FILE_SEARCH and FILE_REGEX do not actually copy
+ * anything, but setup pointers into the source
+ */
+ if (indir == 0) {
+ switch (type) {
+ case FILE_SEARCH:
+ ms->search.s = (const char *)s + offset;
+ ms->search.s_len = nbytes - offset;
return 0;
- }
- if ((p->search.buf = strdup((const char *)s)) == NULL) {
- file_oomem(ms, strlen((const char *)s));
- return -1;
- }
- for (b = p->search.buf; offset &&
- ((b = strchr(c = b, '\n')) || (b = strchr(c, '\r')));
- offset--, b++) {
- last = b;
- if (b[0] == '\r' && b[1] == '\n') b++;
- }
- if (last != NULL)
- *last = '\0';
- p->search.buflen = last - p->search.buf;
- return 0;
- }
-
- if (indir == 0 && (type == FILE_BESTRING16 || type == FILE_LESTRING16))
- {
- const unsigned char *src = s + offset;
- const unsigned char *esrc = s + nbytes;
- char *dst = p->s, *edst = &p->s[sizeof(p->s) - 1];
-
- if (type == FILE_BESTRING16)
- src++;
- /* check for pointer overflow */
- if (src < s) {
- file_error(ms, 0, "invalid offset %zu in mcopy()",
- offset);
- return -1;
+ case FILE_REGEX: {
+ /*
+ * offset is interpreted as last line to search,
+ * (starting at 1), not as bytes-from start-of-file
+ */
+ const char *b;
+ const char *c;
+ const char *last; /* end of search region */
+ const char *buf; /* start of search region */
+ size_t lines;
+
+ if (s == NULL) {
+ ms->search.s_len = 0;
+ ms->search.s = NULL;
+ return 0;
+ }
+ buf = (const char *)s + offset;
+ last = (const char *)s + nbytes;
+ /* mget() guarantees buf <= last */
+ for (lines = linecnt, b = buf;
+ lines && ((b = strchr(c = b, '\n')) || (b = strchr(c, '\r')));
+ lines--, b++) {
+ last = b;
+ if (b[0] == '\r' && b[1] == '\n')
+ b++;
+ }
+ if (lines)
+ last = (const char *)s + nbytes;
+
+ ms->search.s = buf;
+ ms->search.s_len = last - buf;
+ ms->search.offset = offset;
+ ms->search.rm_len = 0;
+ return 0;
}
-
- for (;src < esrc; src++, dst++) {
- if (dst < edst)
- *dst = *src++;
- else
- break;
- if (*dst == '\0')
- *dst = ' ';
+ 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 for pointer overflow */
+ if (src < s) {
+ file_magerror(ms, "invalid offset %zu in mcopy()",
+ offset);
+ return -1;
+ }
+ for (/*EMPTY*/; src < esrc; src++, dst++) {
+ if (dst < edst)
+ *dst = *src++;
+ else
+ break;
+ if (*dst == '\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;
}
- *edst = '\0';
- return 0;
}
if (offset >= nbytes) {
@@ -695,12 +770,14 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
}
private int
-mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
+mget(struct magic_set *ms, const unsigned char *s,
struct magic *m, size_t nbytes, unsigned int cont_level)
{
uint32_t offset = ms->offset;
+ uint32_t count = m->str_count;
+ union VALUETYPE *p = &ms->ms_value;
- if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes) == -1)
+ if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
@@ -745,9 +822,10 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
}
switch (m->in_type) {
case FILE_BYTE:
- if (nbytes < (offset + 1)) return 0;
+ if (nbytes < (offset + 1))
+ return 0;
if (off) {
- switch (m->in_op & 0x3F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = p->b & off;
break;
@@ -782,7 +860,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 2))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = (short)((p->hs[0]<<8)|
(p->hs[1])) &
@@ -834,7 +912,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 2))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = (short)((p->hs[1]<<8)|
(p->hs[0])) &
@@ -886,7 +964,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 2))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = p->h & off;
break;
@@ -922,7 +1000,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 4))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = (int32_t)((p->hl[0]<<24)|
(p->hl[1]<<16)|
@@ -992,7 +1070,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 4))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = (int32_t)((p->hl[3]<<24)|
(p->hl[2]<<16)|
@@ -1062,7 +1140,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 4))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = (int32_t)((p->hl[1]<<24)|
(p->hl[0]<<16)|
@@ -1132,7 +1210,7 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
if (nbytes < (offset + 4))
return 0;
if (off) {
- switch (m->in_op & 0x7F) {
+ switch (m->in_op & FILE_OPS_MASK) {
case FILE_OPAND:
offset = p->l & off;
break;
@@ -1172,8 +1250,9 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
break;
}
- if (m->flag & INDIROFFADD) offset += ms->c.off[cont_level-1];
- if (mcopy(ms, p, m->type, 0, s, offset, nbytes) == -1)
+ if (m->flag & INDIROFFADD)
+ offset += ms->c.li[cont_level-1].off;
+ if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
return -1;
ms->offset = offset;
@@ -1186,73 +1265,138 @@ mget(struct magic_set *ms, union VALUETYPE *p, const unsigned char *s,
/* Verify we have enough data to match magic type */
switch (m->type) {
- case FILE_BYTE:
- if (nbytes < (offset + 1)) /* should alway be true */
- return 0;
- break;
-
- case FILE_SHORT:
- case FILE_BESHORT:
- case FILE_LESHORT:
- if (nbytes < (offset + 2))
- return 0;
- break;
+ case FILE_BYTE:
+ if (nbytes < (offset + 1)) /* should alway be true */
+ return 0;
+ break;
+
+ case FILE_SHORT:
+ case FILE_BESHORT:
+ case FILE_LESHORT:
+ if (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:
+ if (nbytes < (offset + 4))
+ return 0;
+ break;
+
+ case FILE_STRING:
+ case FILE_PSTRING:
+ case FILE_SEARCH:
+ if (nbytes < (offset + m->vallen))
+ 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:
- if (nbytes < (offset + 4))
- return 0;
- break;
+ case FILE_REGEX:
+ if (nbytes < offset)
+ return 0;
+ break;
- case FILE_STRING:
- case FILE_PSTRING:
- case FILE_SEARCH:
- if (nbytes < (offset + m->vallen))
- return 0;
- break;
- default: break;
+ case FILE_DEFAULT: /* nothing to check */
+ default:
+ break;
}
+ if (!mconvert(ms, m))
+ return 0;
+ return 1;
+}
- if (m->type == FILE_SEARCH) {
- size_t mlen = (size_t)(m->mask + m->vallen);
- size_t flen = nbytes - offset;
- if (flen < mlen)
- mlen = flen;
- p->search.buflen = mlen;
- p->search.buf = malloc(mlen + 1);
- if (p->search.buf == NULL) {
- file_error(ms, errno, "Cannot allocate search buffer");
- return 0;
+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 = (const unsigned char *)s1;
+ const unsigned char *b = (const unsigned char *)s2;
+ uint64_t v;
+
+ /*
+ * What we want here is:
+ * v = strncmp(m->value.s, p->s, m->vallen);
+ * but ignoring any nulls. bcmp doesn't give -/+/0
+ * and isn't universally available anyway.
+ */
+ 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 ((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_BLANK) &&
+ isspace(*a)) {
+ a++;
+ if (isspace(*b++)) {
+ while (isspace(*b))
+ b++;
+ }
+ else {
+ v = 1;
+ break;
+ }
+ }
+ else if ((flags & STRING_COMPACT_OPTIONAL_BLANK) &&
+ isspace(*a)) {
+ a++;
+ while (isspace(*b))
+ b++;
+ }
+ else {
+ if ((v = *b++ - *a++) != '\0')
+ break;
+ }
}
- (void)memcpy(p->search.buf, s + offset, mlen);
- p->search.buf[mlen] = '\0';
}
- if (!mconvert(ms, p, m))
- return 0;
- return 1;
+ 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, union VALUETYPE *p, struct magic *m)
+magiccheck(struct magic_set *ms, struct magic *m)
{
uint64_t l = m->value.q;
uint64_t v;
int matched;
-
- if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
- return 1;
- }
-
+ union VALUETYPE *p = &ms->ms_value;
switch (m->type) {
case FILE_BYTE:
@@ -1292,125 +1436,113 @@ magiccheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
v = p->q;
break;
+ case FILE_DEFAULT:
+ l = 0;
+ v = 0;
+ break;
+
case FILE_STRING:
+ case FILE_PSTRING:
+ l = 0;
+ v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+ break;
+
case FILE_BESTRING16:
case FILE_LESTRING16:
- case FILE_PSTRING:
- {
- /*
- * What we want here is:
- * v = strncmp(m->value.s, p->s, m->vallen);
- * but ignoring any nulls. bcmp doesn't give -/+/0
- * and isn't universally available anyway.
- */
- unsigned char *a = (unsigned char*)m->value.s;
- unsigned char *b = (unsigned char*)p->s;
- int len = m->vallen;
+ l = 0;
+ v = file_strncmp16(m->value.s, p->s, (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;
- if (0L == m->mask) { /* normal string: do it fast */
- while (--len >= 0)
- if ((v = *b++ - *a++) != '\0')
- break;
- } else { /* combine the others */
- while (--len >= 0) {
- if ((m->mask & STRING_IGNORE_LOWERCASE) &&
- islower(*a)) {
- if ((v = tolower(*b++) - *a++) != '\0')
- break;
- } else if ((m->mask & STRING_COMPACT_BLANK) &&
- isspace(*a)) {
- a++;
- if (isspace(*b++)) {
- while (isspace(*b))
- b++;
- } else {
- v = 1;
- break;
- }
- } else if (isspace(*a) &&
- (m->mask & STRING_COMPACT_OPTIONAL_BLANK)) {
- a++;
- while (isspace(*b))
- b++;
- } else {
- if ((v = *b++ - *a++) != '\0')
- break;
- }
+ ms->search.offset = m->offset;
+
+ for (idx = 0; m->str_count == 0 || idx < m->str_count; idx++) {
+ if (slen + idx > ms->search.s_len)
+ break;
+
+ v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags);
+ if (v == 0) { /* found match */
+ ms->search.offset = m->offset + idx;
+ break;
}
}
break;
}
- case FILE_REGEX:
- {
+ case FILE_REGEX: {
int rc;
regex_t rx;
char errmsg[512];
- if (p->search.buf == NULL)
+ if (ms->search.s == NULL)
return 0;
+ l = 0;
rc = regcomp(&rx, m->value.s,
- REG_EXTENDED|REG_NOSUB|REG_NEWLINE|
- ((m->mask & STRING_IGNORE_LOWERCASE) ? REG_ICASE : 0));
+ REG_EXTENDED|REG_NEWLINE|
+ ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
if (rc) {
- free(p->search.buf);
- p->search.buf = NULL;
- regerror(rc, &rx, errmsg, sizeof(errmsg));
- file_error(ms, 0, "regex error %d, (%s)", rc, errmsg);
- return -1;
- } else {
- rc = regexec(&rx, p->search.buf, 0, 0, 0);
- regfree(&rx);
- free(p->search.buf);
- p->search.buf = NULL;
- return !rc;
+ (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
+ file_magerror(ms, "regex error %d, (%s)",
+ rc, errmsg);
+ v = (uint64_t)-1;
}
- }
- case FILE_SEARCH:
- {
- /*
- * search for a string in a certain range
- */
- unsigned char *a = (unsigned char*)m->value.s;
- unsigned char *b = (unsigned char*)p->search.buf;
- size_t len, slen = m->vallen;
- size_t range = 0;
- if (slen > sizeof(m->value.s))
- slen = sizeof(m->value.s);
- l = 0;
- v = 0;
- if (b == NULL)
- return 0;
- len = slen;
- while (++range <= m->mask) {
- while (len-- > 0 && (v = *b++ - *a++) == 0)
- continue;
- if (!v) {
- ms->offset += range - 1;
+ else {
+ regmatch_t pmatch[1];
+#ifndef REG_STARTEND
+#define REG_STARTEND 0
+ size_t l = ms->search.s_len - 1;
+ char c = ms->search.s[l];
+ ((char *)(intptr_t)ms->search.s)[l] = '\0';
+#else
+ pmatch[0].rm_so = 0;
+ pmatch[0].rm_eo = ms->search.s_len;
+#endif
+ rc = regexec(&rx, (const char *)ms->search.s,
+ 1, pmatch, REG_STARTEND);
+#if REG_STARTEND == 0
+ ((char *)(intptr_t)ms->search.s)[l] = c;
+#endif
+ switch (rc) {
+ case 0:
+ ms->search.s += (int)pmatch[0].rm_so;
+ ms->search.offset += (size_t)pmatch[0].rm_so;
+ ms->search.rm_len =
+ (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
+ v = 0;
break;
- }
- if (range + slen >= p->search.buflen) {
+
+ case REG_NOMATCH:
v = 1;
break;
+
+ default:
+ (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
+ file_magerror(ms, "regexec error %d, (%s)",
+ rc, errmsg);
+ v = (uint64_t)-1;
+ break;
}
- len = slen;
- a = (unsigned char*)m->value.s;
- b = (unsigned char*)p->search.buf + range;
+ regfree(&rx);
}
- free(p->search.buf);
- p->search.buf = NULL;
- if (v)
- return 0;
+ if (v == (uint64_t)-1)
+ return -1;
break;
}
default:
- file_error(ms, 0, "invalid type %d in magiccheck()", m->type);
+ file_magerror(ms, "invalid type %d in magiccheck()", m->type);
return -1;
}
- if (m->type != FILE_STRING && m->type != FILE_PSTRING)
- v = file_signextend(ms, m, v);
+ v = file_signextend(ms, m, v);
switch (m->reln) {
case 'x':
@@ -1445,7 +1577,7 @@ magiccheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
(unsigned long long)l, matched);
}
else {
- matched = (int32_t) v > (int32_t) l;
+ matched = (int64_t) v > (int64_t) l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%lld > %lld = %d\n",
(long long)v, (long long)l, matched);
@@ -1461,7 +1593,7 @@ magiccheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
(unsigned long long)l, matched);
}
else {
- matched = (int32_t) v < (int32_t) l;
+ matched = (int64_t) v < (int64_t) l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%lld < %lld = %d\n",
(long long)v, (long long)l, matched);
@@ -1486,7 +1618,7 @@ magiccheck(struct magic_set *ms, union VALUETYPE *p, struct magic *m)
default:
matched = 0;
- file_error(ms, 0, "cannot happen: invalid relation `%c'",
+ file_magerror(ms, "cannot happen: invalid relation `%c'",
m->reln);
return -1;
}
diff --git a/contrib/file/tar.h b/contrib/file/tar.h
index 4fb4276..30d386b 100644
--- a/contrib/file/tar.h
+++ b/contrib/file/tar.h
@@ -32,7 +32,7 @@
*
* Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
*
- * $Id: tar.h,v 1.9 2006/05/03 15:19:25 christos Exp $ # checkin only
+ * $File: tar.h,v 1.11 2007/01/16 14:56:45 ljt Exp $ # checkin only
*/
/*
@@ -106,52 +106,6 @@ union record {
#define EX_BADARCH 3 /* bad archive */
#define EX_SYSTEM 4 /* system gave unexpected error */
-
-/*
- * Global variables
- */
-TAR_EXTERN union record *ar_block; /* Start of block of archive */
-TAR_EXTERN union record *ar_record; /* Current record of archive */
-TAR_EXTERN union record *ar_last; /* Last+1 record of archive block */
-TAR_EXTERN char ar_reading; /* 0 writing, !0 reading archive */
-TAR_EXTERN int blocking; /* Size of each block, in records */
-TAR_EXTERN int blocksize; /* Size of each block, in bytes */
-TAR_EXTERN char *ar_file; /* File containing archive */
-TAR_EXTERN char *name_file; /* File containing names to work on */
-TAR_EXTERN char *tar; /* Name of this program */
-
-/*
- * Flags from the command line
- */
-TAR_EXTERN char f_reblock; /* -B */
-TAR_EXTERN char f_create; /* -c */
-TAR_EXTERN char f_debug; /* -d */
-TAR_EXTERN char f_sayblock; /* -D */
-TAR_EXTERN char f_follow_links; /* -h */
-TAR_EXTERN char f_ignorez; /* -i */
-TAR_EXTERN char f_keep; /* -k */
-TAR_EXTERN char f_modified; /* -m */
-TAR_EXTERN char f_oldarch; /* -o */
-TAR_EXTERN char f_use_protection; /* -p */
-TAR_EXTERN char f_sorted_names; /* -s */
-TAR_EXTERN char f_list; /* -t */
-TAR_EXTERN char f_namefile; /* -T */
-TAR_EXTERN char f_verbose; /* -v */
-TAR_EXTERN char f_extract; /* -x */
-TAR_EXTERN char f_compress; /* -z */
-
-/*
- * We now default to Unix Standard format rather than 4.2BSD tar format.
- * The code can actually produce all three:
- * f_standard ANSI standard
- * f_oldarch V7
- * neither 4.2BSD
- * but we don't bother, since 4.2BSD can read ANSI standard format anyway.
- * The only advantage to the "neither" option is that we can cmp(1) our
- * output to the output of 4.2BSD tar, for debugging.
- */
-#define f_standard (!f_oldarch)
-
/*
* Structure for keeping track of filenames and lists thereof.
*/
@@ -162,12 +116,6 @@ struct name {
char name[NAMSIZ+1];
};
-TAR_EXTERN struct name *namelist; /* Points to first name in list */
-TAR_EXTERN struct name *namelast; /* Points to last name in list */
-
-TAR_EXTERN int archive; /* File descriptor for archive file */
-TAR_EXTERN int errors; /* # of files in error */
-
/*
*
* Due to the next struct declaration, each routine that includes
@@ -185,21 +133,3 @@ struct link {
short linkcount;
char name[NAMSIZ+1];
};
-
-TAR_EXTERN struct link *linklist; /* Points to first link in list */
-
-
-/*
- * Error recovery stuff
- */
-TAR_EXTERN char read_error_flag;
-
-
-#if 0
-/*
- * Declarations of functions available to the world.
- */
-/*LINTLIBRARY*/
-#define annorec(stream, msg) anno(stream, msg, 0) /* Cur rec */
-#define annofile(stream, msg) anno(stream, msg, 1) /* Saved rec */
-#endif
diff --git a/contrib/file/test.c b/contrib/file/test.c
index ab4c105..55b78d3 100644
--- a/contrib/file/test.c
+++ b/contrib/file/test.c
@@ -39,19 +39,19 @@ main(int argc, char **argv)
ms = magic_open(MAGIC_NONE);
if (ms == NULL) {
- printf("ERROR: out of memory\n");
+ (void) printf("ERROR: out of memory\n");
return 1;
}
if (magic_load(ms, NULL) == -1) {
- printf("ERROR: %s\n", magic_error(ms));
+ (void) printf("ERROR: %s\n", magic_error(ms));
return 1;
}
for (i = 1; i < argc; i++) {
if ((m = magic_file(ms, argv[i])) == NULL)
- printf("ERROR: %s\n", magic_error(ms));
+ (void) printf("ERROR: %s\n", magic_error(ms));
else
- printf("%s: %s\n", argv[i], m);
+ (void) printf("%s: %s\n", argv[i], m);
}
magic_close(ms);
OpenPOWER on IntegriCloud