diff options
author | obrien <obrien@FreeBSD.org> | 2007-05-24 21:59:38 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2007-05-24 21:59:38 +0000 |
commit | 240c77918bbcf0d5f67799916b808b8a65d434c5 (patch) | |
tree | f1050a93b4cf4d5e56408bc87c1da5741ccf4e65 /contrib/file | |
parent | 09615277daeb6e2f432f5fd5dbc254e4b0428f99 (diff) | |
download | FreeBSD-src-240c77918bbcf0d5f67799916b808b8a65d434c5.zip FreeBSD-src-240c77918bbcf0d5f67799916b808b8a65d434c5.tar.gz |
Virgin import of Christos Zoulas's FILE 4.21.
Diffstat (limited to 'contrib/file')
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); |